月节
<style>#papa { left: -214px; width: 1024px; height: 640px; background: darkred url('/data/attachment/forum/202209/09/080704lzdl1zpq7qh1bbd1.jpg') no-repeat center/cover; display: grid; place-items: center; box-shadow: 3px 3px 20px #000; user-select: none; position: relative; z-index: 1;}
#mplayer { position: absolute; bottom: 5px; } /* 播放器svg */
#lrc { position: absolute; left: 10px; top: 10px; display: block; } /* 歌词svg */
#lrctxt { dominant-baseline: middle; font: bold 2.6em sans-serif; letter-spacing: 3px; }
#tmsg { fill: #ccc; font: normal 1em sans-serif; dominant-baseline: middle; }
#btnwrap { fill: #ccc; cursor: pointer; }
#btnwrap:hover { fill: orange; }
</style>
<div id="papa">
<!-- 播放器 -->
<svg id="mplayer" width="380" height="60" shape-rendering="geometricPrecision">
<circle cx="30" cy="30" r="20" fill="none" stroke="url(#gradient)" stroke-width="3" />
<g id="mama" style="cursor: pointer">
<line x1="60" y1="30" x2="260" y2="30" stroke="transparent" stroke-width="20" />
<line id="track" x1="60" y1="30" x2="260" y2="30" stroke="snow" shape-rendering="crispEdges" />
<line id="prog" x1="60" y1="30" x2="260" y2="30" stroke="red" shape-rendering="crispEdges" />
</g>
<text id="tmsg" x="270" y="30">00:00 | 00:00</text>
<g id="btnwrap">
<path id="btnplay" d="M 22 20,22 40,42 30 z"></path>
<path d="M 29 20, 29 40, 32 40, 32 20, 29 20 z" fill="transparent"></path>
<path id="btnpause" d="M 24 20,24 40,29 40,29 20,24 20 z M 32 20,32 40,37 40,37 20,32 20 z" style="display: none"></path>
</g>
</svg>
<!-- lrc歌词 -->
<svg id="lrc" width="360" height="60">
<defs>
<linearGradient id="gradient" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="green"/>
<stop offset="50%" stop-color="snow"/>
<stop offset="100%" stop-color="gold"/>
</linearGradient>
</defs>
<text id="lrctxt" x="10" y="30" fill="transparent" stroke="url(#gradient)" shape-rendering="crispEdges">纯音乐 - 秋</text>
</svg>
</div>
<script>
let lrcAr = [
['0.00','纯音乐 - 秋'],
['180.00','祝大家中秋快乐']
];
let cc = {
x: 1*track.getAttribute('x1'),
len: track.getTotalLength(),
};
let aud = new Audio();
aud.src = 'https://music.163.com/song/media/outer/url?id=1409206076.mp3';
aud.autoplay = true;
aud.loop = true;
prog.style.strokeDasharray = prog.style.strokeDashoffset = cc.len;
btnwrap.onclick = () => aud.paused ? aud.play() : aud.pause();
mama.onclick = (e) => aud.currentTime = aud.duration * (e.offsetX - cc.x) / cc.len;
aud.addEventListener('pause', () => btnstate());
aud.addEventListener('play',() => btnstate());
aud.addEventListener('timeupdate', () => {
prog.style.strokeDashoffset = cc.len - cc.len * aud.currentTime / aud.duration + 'px';
tmsg.textContent = toMin(aud.currentTime) + " | " + toMin(aud.duration);
for(j=0; j<lrcAr.length; j++) {
if(aud.currentTime >= lrcAr) lrctxt.textContent = lrcAr;
}
});
let btnstate = () => aud.paused ? (btnplay.style.display = 'block', btnpause.style.display = 'none') : (btnplay.style.display = 'none', btnpause.style.display = 'block');
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>
附代码
<style>
#papa { left: -214px; width: 1024px; height: 640px; background: darkred url('/data/attachment/forum/202209/09/080704lzdl1zpq7qh1bbd1.jpg') no-repeat center/cover; display: grid; place-items: center; box-shadow: 3px 3px 20px #000; user-select: none; position: relative; z-index: 1;}
#mplayer { position: absolute; bottom: 5px; } /* 播放器svg */
#lrc { position: absolute; left: 10px; top: 10px; display: block; } /* 歌词svg */
#lrctxt { dominant-baseline: middle; font: bold 2.6em sans-serif; letter-spacing: 3px; }
#tmsg { fill: #ccc; font: normal 1em sans-serif; dominant-baseline: middle; }
#btnwrap { fill: #ccc; cursor: pointer; }
#btnwrap:hover { fill: orange; }
</style>
<div id="papa">
<!-- 播放器 -->
<svg id="mplayer" width="380" height="60" shape-rendering="geometricPrecision">
<circle cx="30" cy="30" r="20" fill="none" stroke="url(#gradient)" stroke-width="3" />
<g id="mama" style="cursor: pointer">
<line x1="60" y1="30" x2="260" y2="30" stroke="transparent" stroke-width="20" />
<line id="track" x1="60" y1="30" x2="260" y2="30" stroke="snow" shape-rendering="crispEdges" />
<line id="prog" x1="60" y1="30" x2="260" y2="30" stroke="red" shape-rendering="crispEdges" />
</g>
<text id="tmsg" x="270" y="30">00:00 | 00:00</text>
<g id="btnwrap">
<path id="btnplay" d="M 22 20,22 40,42 30 z"></path>
<path d="M 29 20, 29 40, 32 40, 32 20, 29 20 z" fill="transparent"></path>
<path id="btnpause" d="M 24 20,24 40,29 40,29 20,24 20 z M 32 20,32 40,37 40,37 20,32 20 z" style="display: none"></path>
</g>
</svg>
<!-- lrc歌词 -->
<svg id="lrc" width="360" height="60">
<defs>
<linearGradient id="gradient" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="green"/>
<stop offset="50%" stop-color="snow"/>
<stop offset="100%" stop-color="gold"/>
</linearGradient>
</defs>
<text id="lrctxt" x="10" y="30" fill="transparent" stroke="url(#gradient)" shape-rendering="crispEdges">纯音乐 - 秋</text>
</svg>
</div>
<script>
let lrcAr = [
['0.00','纯音乐 - 秋'],
['180.00','祝大家中秋快乐']
];
let cc = {
x: 1*track.getAttribute('x1'),
len: track.getTotalLength(),
};
let aud = new Audio();
aud.src = 'https://music.163.com/song/media/outer/url?id=1409206076.mp3';
aud.autoplay = true;
aud.loop = true;
prog.style.strokeDasharray = prog.style.strokeDashoffset = cc.len;
btnwrap.onclick = () => aud.paused ? aud.play() : aud.pause();
mama.onclick = (e) => aud.currentTime = aud.duration * (e.offsetX - cc.x) / cc.len;
aud.addEventListener('pause', () => btnstate());
aud.addEventListener('play',() => btnstate());
aud.addEventListener('timeupdate', () => {
prog.style.strokeDashoffset = cc.len - cc.len * aud.currentTime / aud.duration + 'px';
tmsg.textContent = toMin(aud.currentTime) + " | " + toMin(aud.duration);
for(j=0; j<lrcAr.length; j++) {
if(aud.currentTime >= lrcAr) lrctxt.textContent = lrcAr;
}
});
let btnstate = () => aud.paused ? (btnplay.style.display = 'block', btnpause.style.display = 'none') : (btnplay.style.display = 'none', btnpause.style.display = 'block');
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>
本帖无多大新意,更多的是整合。表面上,播放器简单明快,lrc歌词简洁干脆。
依然使用两个svg分别部署播放器与lrc歌词。改变播放器与歌词的位置,请在CSS中操作,第03、04行分别对应于二者,可通过 left、right ↔ top、bottom 配对设置进行快速定位。 等会来学习! 祝黑黑先生阖家欢乐幸福安康! 梦油 发表于 2022-9-9 08:49
祝黑黑先生阖家欢乐幸福安康!
一样祝你! 马黑黑 发表于 2022-9-9 09:13
一样祝你!
谢谢! 现在再来好好研究学习了。 感谢老师每天分享好代码,祝老师中秋节快乐!{:4_176:} 梦缘 发表于 2022-9-9 11:16
感谢老师每天分享好代码,祝老师中秋节快乐!
同祝! 醉美水芙蓉 发表于 2022-9-9 11:42
感谢黑黑老师无私奉献,祝老师阖家团圆!中秋节快乐!
谢谢,一样祝你 这个漂亮,节日快乐 绿叶清舟 发表于 2022-9-9 11:51
这个漂亮,节日快乐
之前那个 CSS+HTML 的感觉更漂亮的,这个就是有空心字,svg 擅长弄这个 这个色彩搭配很美,欣赏黑黑好帖,节日快乐{:4_187:} 红影 发表于 2022-9-9 12:11
这个色彩搭配很美,欣赏黑黑好帖,节日快乐
色彩搭配是原图的功劳,俺可木有这能耐,又不是东篱{:4_170:} 马黑黑 发表于 2022-9-9 12:13
色彩搭配是原图的功劳,俺可木有这能耐,又不是东篱
我是说歌词和底图的搭配啊,这个应该是你的功劳的{:4_173:} 红影 发表于 2022-9-9 17:00
我是说歌词和底图的搭配啊,这个应该是你的功劳的
是代码的功劳 马黑黑 发表于 2022-9-9 17:31
是代码的功劳
你就谦虚吧{:4_189:} 马黑黑 发表于 2022-9-9 12:02
之前那个 CSS+HTML 的感觉更漂亮的,这个就是有空心字,svg 擅长弄这个
svg代码看着就头大啊,感觉更不容易记的了