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

HTML按钮+svg进度条的播放器

<style>
#papa {
        margin: auto;
        width: 740px;
        height: 420px;
        background: gray;
        box-shadow: 3px 3px 20px #000;
        position: relative;
}
#mplayer {
        position: absolute;
        left: calc(50% - 165px);
        bottom: 20px;
        display: grid;
        grid-template-columns: auto auto;
        place-items: center;
}
#btnplay {
        width: 30px;
        height: 30px;
        border-radius: 50%;
        background: linear-gradient(hsla(0,100%,60%,.6), hsla(120,100%,70%,.6));
        cursor: pointer;
        animation: rot linear 3s infinite;
}
@keyframes rot { to { transform: rotate(1turn); } }
</style>

<div id="papa">
        <div id="mplayer">
                <span id="btnplay"></span>
                <svg id="iplay" width="300" height="20">
                        <line id="track" x1="10" y1="10" x2="190" y2="10" stroke="hsla(0,0%,80%,0.5)" stroke-width="10" stroke-linecap="round" />
                        <line id="prog" x1="10" y1="10" x2="190" y2="10" stroke="hsla(0,50%,50%,0.5)" stroke-width="10" stroke-dasharray="180" stroke-dashoffset="180" stroke-linecap="round" />
                        <text id="audtime" x="200" y="15" font-size="14" fill="hsl(0,0%,100%)">00:00 | 00:00</text>
                </svg>
        </div>
</div>

<script>
(function() {
        let len = track.getTotalLength(), aud = new Audio();
        aud.src = 'https://music.163.com/song/media/outer/url?id=1978267012.mp3';
        aud.loop = true;
        aud.autoplay = true;
        btnplay.style.animationPlayState = aud.paused ? 'paused' : 'running';
        btnplay.onclick = () => aud.paused ? aud.play() : aud.pause();
        prog.onclick = track.onclick = (e) => aud.currentTime = aud.duration * (e.offsetX - 10) / len;
        aud.addEventListener('pause', () =>mState());
        aud.addEventListener('play', () =>mState());
        aud.addEventListener('timeupdate', () => {
                prog.style.strokeDashoffset = len - aud.currentTime * len / aud.duration;
                audtime.textContent = 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;}
})();
</script>

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

代码
<style>
#papa {
        margin: auto;
        width: 740px;
        height: 420px;
        background: gray;
        box-shadow: 3px 3px 20px #000;
        position: relative;
}
#mplayer {
        position: absolute;
        left: calc(50% - 165px);
        bottom: 20px;
        display: grid;
        grid-template-columns: auto auto;
        place-items: center;
}
#btnplay {
        width: 30px;
        height: 30px;
        border-radius: 50%;
        background: linear-gradient(hsla(0,100%,60%,.6), hsla(120,100%,70%,.6));
        cursor: pointer;
        animation: rot linear 3s infinite;
}
@keyframes rot { to { transform: rotate(1turn); } }
</style>

<div id="papa">
        <div id="mplayer">
                <span id="btnplay"></span>
                <svg id="iplay" width="300" height="20">
                        <line id="track" x1="10" y1="10" x2="190" y2="10" stroke="hsla(0,0%,80%,0.5)" stroke-width="10" stroke-linecap="round" />
                        <line id="prog" x1="10" y1="10" x2="190" y2="10" stroke="hsla(0,50%,50%,0.5)" stroke-width="10" stroke-dasharray="180" stroke-dashoffset="180" stroke-linecap="round" />
                        <text id="audtime" x="200" y="15" font-size="14" fill="hsl(0,0%,100%)">00:00 | 00:00</text>
                </svg>
        </div>
</div>

<script>
(function() {
        let len = track.getTotalLength(), aud = new Audio();
        aud.src = 'https://music.163.com/song/media/outer/url?id=1978267012.mp3';
        aud.loop = true;
        aud.autoplay = true;
        btnplay.style.animationPlayState = aud.paused ? 'paused' : 'running';
        btnplay.onclick = () => aud.paused ? aud.play() : aud.pause();
        prog.onclick = track.onclick = (e) => aud.currentTime = aud.duration * (e.offsetX - 10) / len;
        aud.addEventListener('pause', () =>mState());
        aud.addEventListener('play', () =>mState());
        aud.addEventListener('timeupdate', () => {
                prog.style.strokeDashoffset = len - aud.currentTime * len / aud.duration;
                audtime.textContent = 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;}
})();
</script>

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

这个没有加入歌词同步,加的话也容易

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

旋转按钮:#btnplay
进度条:svg

它们用 #mplayer 包裹起来,通过设置 #mplayer 在帖子中定位播放器

小辣椒 发表于 2022-10-19 21:08

这个播放器完美了,前面那个光盘可以改颜色吧

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

按钮样式可通过改 background 达到自己想要的效果

进度条颜色请修改 svg 中的两个 line 标签 的 stroke

修改尺寸需要配合 line、text 标签的定位(x值)以及 id="prog" 的 line 的 stroke-dash* 的值以令其配套

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

小辣椒 发表于 2022-10-19 21:08
这个播放器完美了,前面那个光盘可以改颜色吧

在 CSS 对应选择器中修改,可加图片,会的话还可以通过JS动态更换图片

小辣椒 发表于 2022-10-19 21:17

马黑黑 发表于 2022-10-19 21:11
在 CSS 对应选择器中修改,可加图片,会的话还可以通过JS动态更换图片

还不会,这个要等黑黑完全出来学习做一个

马黑黑 发表于 2022-10-19 22:04

小辣椒 发表于 2022-10-19 21:17
还不会,这个要等黑黑完全出来学习做一个

这个已经做出来了

红影 发表于 2022-10-19 22:06

这个简洁又漂亮{:4_187:}

马黑黑 发表于 2022-10-19 22:07

红影 发表于 2022-10-19 22:06
这个简洁又漂亮

这是大致结构,可修饰的空间很大的

红影 发表于 2022-10-20 15:23

马黑黑 发表于 2022-10-19 22:07
这是大致结构,可修饰的空间很大的

看到你提到了,可以添加歌词,按钮也可以换图片{:4_204:}

马黑黑 发表于 2022-10-20 18:10

红影 发表于 2022-10-20 15:23
看到你提到了,可以添加歌词,按钮也可以换图片

对对

小辣椒 发表于 2022-10-20 20:32

马黑黑 发表于 2022-10-19 22:04
这个已经做出来了

看见了,这个我肯定要做一次的

马黑黑 发表于 2022-10-20 20:43

小辣椒 发表于 2022-10-20 20:32
看见了,这个我肯定要做一次的

{:4_173:}

红影 发表于 2022-10-20 21:16

马黑黑 发表于 2022-10-20 18:10
对对

看到黑黑又弄了个新的,厉害的{:4_187:}

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

红影 发表于 2022-10-20 21:16
看到黑黑又弄了个新的,厉害的

前一个用 line,它可以有一个 linecap 线帽,也不错,但 line 没有 fill;rect 没有线帽,但可以设定 rx 和 ry 做圆角,可以模仿进度条两头的线帽,加上有 fill 和 stroke,还是不错的
页: [1]
查看完整版本: HTML按钮+svg进度条的播放器