马黑黑 发表于 2022-10-21 19:27

网格布局:制作一个音频播放控制器

<style>
#papa { margin: auto; width: 740px; height: 460px; background: #fff; box-shadow: 3px 3px 20px #000; display: grid; place-items: center; position: relative; }
#mplayer { position: absolute; bottom: 20px; display: grid; grid-template-columns: auto auto auto; place-items: center; gap: 6px; user-select: none; }
#btnplay { width: 40px; height: 40px; text-align: center; font: normal 40px/40px sans-serif; color: green; cursor: pointer; animation: rot linear 4s infinite; }
#prog { --ww: 0px; width: 300px; height: 12px; border: 1px solid green; border-radius: 6px; background: snow; position: relative; }
#prog::before { position: absolute; content: ''; width: var(--ww); height: 12px; border-radius: 6px; background: snow linear-gradient(90deg, green, red); }
#audtime { font: normal 14px sans-serif; color: green; }
@keyframes rot { to { transform: rotate(1turn); } }
</style>

<div id="papa">
        <div id="mplayer">
                <span id="btnplay">❁</span>
                <span id="prog"></span>
                <span id="audtime">00:00 | 00:00</span>
        </div>
</div>

<script>
let aud = new Audio();

aud.autoplay = true;
aud.loop = true;
aud.src = 'https://music.163.com/song/media/outer/url?id=1421117420.mp3';

btnplay.onclick = () => aud.paused ? aud.play() : aud.pause();
prog.onclick = (e) => aud.currentTime = aud.duration * e.offsetX / prog.offsetWidth;

aud.addEventListener('pause', () => mState());
aud.addEventListener('play', () => mState());

aud.addEventListener('timeupdate', () => {
        let prg = aud.currentTime * prog.offsetWidth / aud.duration < 6 ? 6 : aud.currentTime * prog.offsetWidth / aud.duration;
        prog.style.setProperty('--ww', prg + 'px');
        audtime.innerText = toMin(aud.currentTime) + ' | ' + toMin(aud.duration);
});

let mState = () => aud.paused ? (btnplay.style.animationPlayState='paused') : (btnplay.style.animationPlayState='running');
let toMin = (val)=> {if (!val) return '00:00';val = Math.floor(val);let min = parseInt(val / 60), sec = parseFloat(val % 60);if(min < 10) min = '0' + min;if(sec < 10) sec = '0' + sec;return min + ':' + sec;}
if(aud.paused) btnplay.style.animationPlayState = 'paused';
</script>

马黑黑 发表于 2022-10-21 19:29

CSS+HTML。样式和之前的 svg 播放器一样。代码:
<style>
#papa { margin: auto; width: 740px; height: 460px; background: #fff; box-shadow: 3px 3px 20px #000; display: grid; place-items: center; position: relative; }
#mplayer { position: absolute; bottom: 20px; display: grid; grid-template-columns: auto auto auto; place-items: center; gap: 6px; user-select: none; }
#btnplay { width: 40px; height: 40px; text-align: center; font: normal 40px/40px sans-serif; color: green; cursor: pointer; animation: rot linear 4s infinite; }
#prog { --ww: 0px; width: 300px; height: 12px; border: 1px solid green; border-radius: 6px; background: snow; position: relative; }
#prog::before { position: absolute; content: ''; width: var(--ww); height: 12px; border-radius: 6px; background: snow linear-gradient(90deg, green, red); }
#audtime { font: normal 14px sans-serif; color: green; }
@keyframes rot { to { transform: rotate(1turn); } }
</style>

<div id="papa">
        <div id="mplayer">
                <span id="btnplay">❁</span>
                <span id="prog"></span>
                <span id="audtime">00:00 | 00:00</span>
        </div>
</div>

<script>
let aud = new Audio();

aud.autoplay = true;
aud.loop = true;
aud.src = 'https://music.163.com/song/media/outer/url?id=1421117420.mp3';

btnplay.onclick = () => aud.paused ? aud.play() : aud.pause();
prog.onclick = (e) => aud.currentTime = aud.duration * e.offsetX / prog.offsetWidth;

aud.addEventListener('pause', () => mState());
aud.addEventListener('play', () => mState());

aud.addEventListener('timeupdate', () => {
        let prg = aud.currentTime * prog.offsetWidth / aud.duration < 6 ? 6 : aud.currentTime * prog.offsetWidth / aud.duration;
        prog.style.setProperty('--ww', prg + 'px');
        audtime.innerText = toMin(aud.currentTime) + ' | ' + toMin(aud.duration);
});

let mState = () => aud.paused ? (btnplay.style.animationPlayState='paused') : (btnplay.style.animationPlayState='running');
let toMin = (val)=> {if (!val) return '00:00';val = Math.floor(val);let min = parseInt(val / 60), sec = parseFloat(val % 60);if(min < 10) min = '0' + min;if(sec < 10) sec = '0' + sec;return min + ':' + sec;}
if(aud.paused) btnplay.style.animationPlayState = 'paused';
</script>

马黑黑 发表于 2022-10-21 19:34

本帖最后由 马黑黑 于 2022-10-21 22:45 编辑

【解析】

一、HTML主干:

      <div id="mplayer">
                <span id="btnplay">❁</span>
                <span id="prog"></span>
                <span id="audtime">00:00 | 00:00</span>
      </div>


二、网格布局

mplayer 包裹 3 个 span 标签,一个是文本按钮 btnplay,一个是进度条 prog,一个是播放时间信息文本 audtime。mplayer 盒子采用 grid 布局,以父级属性规范 3 个 span 标签的排列:

#mplayer {
      position: absolute;
      bottom: 20px;
      width: auto;
      height: 80px;
      display: grid;
      grid-template-columns: auto auto auto;
      place-items: center;
      gap: 6px;
}


三、关于按钮

按钮预设是特殊符号的文本,可以更换类似圆形的符号。当然,如果需要,可以将按钮改为图片背景而不需要改变其他地方,仅 CSS 部分:

#btnplay {
        width: 40px;
        height: 40px;
        border-radius: 50%;
        background: gray url('图片地址');
        cursor: pointer;
        animation: rot linear 4s infinite;
}


图片如果不是 40*40 的,background 属性需要自己加工一下

小辣椒 发表于 2022-10-21 20:31

越来越漂亮了,那个黄的也是很喜欢的,现在又一个

马黑黑 发表于 2022-10-21 20:38

小辣椒 发表于 2022-10-21 20:31
越来越漂亮了,那个黄的也是很喜欢的,现在又一个

差不多的东东,实现元素和方法不同而已

小辣椒 发表于 2022-10-21 20:40

马黑黑 发表于 2022-10-21 20:38
差不多的东东,实现元素和方法不同而已

播放器样子一样,黑黑厉害,差不多的播放器可以多种元素和方法实现出来{:4_178:}

马黑黑 发表于 2022-10-21 20:41

小辣椒 发表于 2022-10-21 20:40
播放器样子一样,黑黑厉害,差不多的播放器可以多种元素和方法实现出来

还有画布也可以做呢,暂时不鼓捣了{:4_170:}

小辣椒 发表于 2022-10-21 20:44

马黑黑 发表于 2022-10-21 20:41
还有画布也可以做呢,暂时不鼓捣了

是的,得让我们消化了再说,否则学习后面忘记前面

醉美水芙蓉 发表于 2022-10-21 20:51

相约爱晚亭 发表于 2022-10-21 21:06

播放器代码收藏了,谢谢!

马黑黑 发表于 2022-10-21 21:08

相约爱晚亭 发表于 2022-10-21 21:06
播放器代码收藏了,谢谢!

这个不算很复杂吧

马黑黑 发表于 2022-10-21 21:09

醉美水芙蓉 发表于 2022-10-21 20:51
欣赏学习黑黑老师播放器!

{:4_176:}

马黑黑 发表于 2022-10-21 21:09

小辣椒 发表于 2022-10-21 20:44
是的,得让我们消化了再说,否则学习后面忘记前面

有些东西是类功能封装,会修改关键的地方就好

小辣椒 发表于 2022-10-21 21:34

马黑黑 发表于 2022-10-21 21:09
有些东西是类功能封装,会修改关键的地方就好

这个我就是喜欢的会自己瞎修改,对播放器我肯定会花一点时间的{:4_189:}

马黑黑 发表于 2022-10-21 21:39

小辣椒 发表于 2022-10-21 21:34
这个我就是喜欢的会自己瞎修改,对播放器我肯定会花一点时间的

很不错

小辣椒 发表于 2022-10-21 21:52

马黑黑 发表于 2022-10-21 21:39
很不错

其实不用每个播放器都歌词同步吧,做歌词同步花时间{:4_173:}

马黑黑 发表于 2022-10-21 21:57

小辣椒 发表于 2022-10-21 21:52
其实不用每个播放器都歌词同步吧,做歌词同步花时间

懒人的说法

小辣椒 发表于 2022-10-21 21:58

黑黑~~~这个播放器明天做歌词同步

小辣椒 发表于 2022-10-21 21:58

看见有待续2个字,是不是还没有完全好?

马黑黑 发表于 2022-10-21 21:59

小辣椒 发表于 2022-10-21 21:58
看见有待续2个字,是不是还没有完全好?

解释部分,正准备写,突然有人找
页: [1] 2 3
查看完整版本: 网格布局:制作一个音频播放控制器