马黑黑 发表于 2022-10-20 19:59

纯svg音频播放器:rect进度条+text符号按钮

本帖最后由 马黑黑 于 2022-10-23 11:17 编辑 <br /><br /><style>
#papa { margin: auto; width: 740px; height: 460px; background: gray; box-shadow: 3px 3px 20px #000; display: grid; place-items: center; position: relative; }
#mplayer { position: absolute; bottom: 0; }
</style>

<div id="papa">
        <svg id="mplayer" width="360" height="60" style="user-select: none;">
                <rect x="50" y="25" rx="6" ry="6" width="200" height="12" stroke="hsla(60,80%,92%,.75)" fill="hsla(60,100%,92%,.35)" id="track" />
                <rect x="50" y="25" rx="6" ry="6" width="0" height="12" stroke="transparnet" fill="hsla(60,80%,92%,.75)" id="prog" />
                <text x="260" y="31" font-size="14" dominant-baseline="middle" stroke="none" fill="gold" id="audtime">00:00 | 00:00</text>
                <text x="10" y="35" font-family="serif" font-size="40" dominant-baseline="middle" stroke="yellow" fill="gold" id="btnplay" style="cursor: pointer;">☀
                        <animateTransform attributeName="transform" dur="4s" type="rotate" from="0 26.86 30" to="360 26.86 30" repeatCount="indefinite" />
                </text>
        </svg>
</div>

<script>

let mp = { len: track.getAttribute('width')*1, x: track.getAttribute('x')*1 }, aud = new Audio();
aud.src = 'https://music.163.com/song/media/outer/url?id=1911004729.mp3';
aud.autoplay = true;
aud.loop = true;
btnplay.onclick = () => aud.paused ? (aud.play(), mplayer.unpauseAnimations()) : (aud.pause(), mplayer.pauseAnimations());
prog.onclick = track.onclick = (e) => aud.currentTime = aud.duration * (e.offsetX - mp.x) / mp.len;
aud.addEventListener('pause', () => mState());
aud.addEventListener('play', () => mState());
aud.addEventListener('timeupdate', () => {
        prog.style.setProperty('width', aud.currentTime * 200 / aud.duration + 'px');
        audtime.textContent = toMin(aud.currentTime) + ' | ' + toMin(aud.duration);
});
let mState = () => aud.paused ? mplayer.pauseAnimations() : mplayer.unpauseAnimations();
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) mplayer.pauseAnimations();

</script>

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

源码<style>
#papa { margin: auto; width: 740px; height: 640px; background: gray; box-shadow: 3px 3px 20px #000; display: grid; place-items: center; position: relative; }
#mplayer { position: absolute; bottom: 0; }
</style>

<div id="papa">
        <svg id="mplayer" width="360" height="60" style="user-select: none;">
                <rect x="50" y="25" rx="6" ry="6" width="200" height="12" stroke="hsla(60,80%,92%,.75)" fill="hsla(60,100%,92%,.35)" id="track" />
                <rect x="50" y="25" rx="6" ry="6" width="0" height="12" stroke="transparnet" fill="hsla(60,80%,92%,.75)" id="prog" />
                <text x="260" y="31" font-size="14" dominant-baseline="middle" stroke="none" fill="gold" id="audtime">00:00 | 00:00</text>
                <text x="10" y="35" font-size="40" dominant-baseline="middle" stroke="yellow" fill="gold" id="btnplay" style="cursor: pointer;">☀
                        <animateTransform attributeName="transform" dur="4s" type="rotate" from="0 26.86 30" to="360 26.86 30" repeatCount="indefinite" />
                </text>
        </svg>
</div>

<script>

let mp = { len: track.getAttribute('width')*1, x: track.getAttribute('x')*1 }, aud = new Audio();
aud.src = 'https://music.163.com/song/media/outer/url?id=1911004729.mp3';
aud.autoplay = true;
aud.loop = true;
btnplay.onclick = () => aud.paused ? (aud.play(), mplayer.unpauseAnimations()) : (aud.pause(), mplayer.pauseAnimations());
prog.onclick = track.onclick = (e) => aud.currentTime = aud.duration * (e.offsetX - mp.x) / mp.len;
aud.addEventListener('pause', () => mState());
aud.addEventListener('play', () => mState());
aud.addEventListener('timeupdate', () => {
        prog.style.setProperty('width', aud.currentTime * 200 / aud.duration + 'px');
        audtime.textContent = toMin(aud.currentTime) + ' | ' + toMin(aud.duration);
});
let mState = () => aud.paused ? mplayer.pauseAnimations() : mplayer.unpauseAnimations();
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) mplayer.pauseAnimations();

</script>

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

本帖最后由 马黑黑 于 2022-10-20 20:30 编辑

必要说明:

一、播放器定位

修改 CSS 中 #mplayer 选择器,可通过 left、top、right、bottom 等属性的配套使用设定播放器的物理位置。

二、播放器样式修改

基本在 svg 标签中操作,主要可以修改:

① 按钮文本符号

id="btnplay" 的 text 标签,示例中使用☀ ,可以尝试其他的。

② 播放时间信息文本颜色

id="audtime" 的 text 标签,修改 fill="颜色" 处。

③ 进度条颜色

第一是轨道颜色,id="track" 的 rect 标签,stroke="颜色" 是描边、fill="颜色" 是内部填充;
第二是进度条颜色,id="prog" 的 rect 标签,与轨道颜色设置同。

④ 播放器尺寸问题

不建议修改,如果必须修改,则请处理好各个元素的位置等问题,保证元素间和谐相处。此外,文本按钮对rotate动画的基点理念上不同于CSS,须通过精细计算,要懂得充分使用控制台和相关算法,所以移动svg内部元素的物理位置要做到心中有数。

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

JS代码中,已对可能出现的进度条长度的改变做了处理,修改进度条组合的 rect 标签的 width 值不会影响JS对进度条的控制,但需要注意的是,track 和 prog 的尺寸应当一致。

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

本示例所使用音乐来自 @东篱闲人 先生的精美帖子 《雪落倾城》 所使用的背景音乐,在此表示衷心感谢!

东篱闲人 发表于 2022-10-20 20:30

马黑黑 发表于 2022-10-20 20:20
本示例所使用音乐来自 @东篱闲人 先生的精美帖子 《雪落倾城》 所使用的背景音乐,在此表示衷心感谢!

别客气,随便使,没外人。。。。{:5_117:}

东篱闲人 发表于 2022-10-20 20:31

咋看着黑屏了。。。。{:5_115:}

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

东篱闲人 发表于 2022-10-20 20:30
别客气,随便使,没外人。。。。

也没内人{:4_170:}

东篱闲人 发表于 2022-10-20 20:34

马黑黑 发表于 2022-10-20 20:31
也没内人

你属于内人。。。。{:5_117:}

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

东篱闲人 发表于 2022-10-20 20:34
你属于内人。。。。
大内高手?俺有那功夫,但没那心思

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

东篱闲人 发表于 2022-10-20 20:31
咋看着黑屏了。。。。

灰色

红影 发表于 2022-10-20 20:47

东篱闲人 发表于 2022-10-20 20:31
咋看着黑屏了。。。。

不是黑屏,是背景什么也没放,就是个颜色{:4_173:}

红影 发表于 2022-10-20 20:48

黑黑潇洒,进度条和按钮想配什么就配什么,任意组合{:4_199:}

东篱闲人 发表于 2022-10-20 20:53

红影 发表于 2022-10-20 20:47
不是黑屏,是背景什么也没放,就是个颜色

{:4_181:}

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

这个播放器制作修改讲的很仔细,黄的也是漂亮,可以随便按图的色系修改,非常的棒!

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

黑黑辛苦,每天分享这么多,小辣椒笨蛋作业每天不能按时完成的

马黑黑 发表于 2022-10-20 22:00

小辣椒 发表于 2022-10-20 21:06
黑黑辛苦,每天分享这么多,小辣椒笨蛋作业每天不能按时完成的

关键是动原理和方法吧,懂了就好办

马黑黑 发表于 2022-10-20 22:00

红影 发表于 2022-10-20 20:48
黑黑潇洒,进度条和按钮想配什么就配什么,任意组合

这个没什么潇洒的,关键是去做

马黑黑 发表于 2022-10-20 22:01

小辣椒 发表于 2022-10-20 21:05
这个播放器制作修改讲的很仔细,黄的也是漂亮,可以随便按图的色系修改,非常的棒!

这个不需要那么多的东拉西扯的东东,一个整体

醉美水芙蓉 发表于 2022-10-20 23:14

页: [1] 2
查看完整版本: 纯svg音频播放器:rect进度条+text符号按钮