时间
<style>#papa { left: -214px; width: 1024px; height: 640px; background: #444 url('https://638183.freep.cn/638183/Pic/2022/time.jpg') no-repeat center/cover; display: grid; place-items: center; box-shadow: 3px 3px 20px #000; position: relative; z-index: 1; }
#mplayer { position: absolute; }
#tmsg { font: normal 1em sans-serif; fill: #ccc; }
#lrc { position: absolute; top: 10px; left: 10px; font: bold 2em sans-serif; letter-spacing: 3px; animation: mov 20s linear infinite alternate; }
@keyframes mov { to { left: 614px; } }
</style>
<div id="papa">
<svg id="mplayer" viewBox="0 0 100 100" width="100" height="100">
<circle id="track" cx="50" cy="50" r="45" fill="none" stroke="snow" stroke-width="6" style="cursor: pointer" />
<line id="hand" x1="50" y1="50" x2="50" y2="10" stroke="red" stroke-width="1" />
<circle cx="50" cy="50" r="4" fill="red" />
<path id="curPath" d="M 10 60 Q 50 0 90 60" fill="none" stroke="none"/>
<path id="durPath" d="M 0 38 Q 50 100 100 38" fill="none" stroke="none"/>
<g id="tmsg">
<text x="52%" y="0"><textPath id="curMsg" xlink:href="#curPath" text-anchor="middle" dominant-baseline="text-after-edge">00:00</textPath></text>
<text x="60%" y="0"><textPath id="durMsg" xlink:href="#durPath" text-anchor="middle" dominant-baseline="text-before-edge">00:00</textPath></text>
</g>
<circle id="btnplay" cx="50" cy="50" r="35" fill="transparent" style="cursor: pointer" />
</svg>
<svg id="lrc" width="400" height="60">
<text id="lrctxt" x="50%" y="30" fill="none" stroke="snow" text-anchor="middle" dominant-baseline="middle">纯音乐 - 时间</text>
</svg>
</div>
<script>
let cc = { x: 1*track.getAttribute('cx'), y: 1*track.getAttribute('cy'), };
let aud = new Audio();
aud.src = 'https://music.163.com/song/media/outer/url?id=1920607219.mp3';
aud.autoplay = true;
aud.loop = true;
aud.addEventListener('timeupdate', () => {
let progress = aud.currentTime * 360 / aud.duration;
hand.setAttribute('transform', 'rotate(' + progress +', 50, 50)');
curMsg.textContent = toMin(aud.currentTime);
durMsg.textContent = toMin(aud.duration);
});
track.onclick = (e) => {
let angle = Math.atan2(e.offsetY - cc.y, e.offsetX - cc.x) * 180 / Math.PI;
angle+= (e.offsetX < cc.x && e.offsetY < cc.y) ? 450 : 90;
aud.currentTime = aud.duration * angle / 360;
}
btnplay.onclick = () => aud.paused ? aud.play() : aud.pause();
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 { margin: auto; width: 1024px; height: 640px; background: #444 url('https://638183.freep.cn/638183/Pic/2022/time.jpg') no-repeat center/cover; display: grid; place-items: center; box-shadow: 3px 3px 20px #000; position: relative; z-index: 1; }
#mplayer { position: absolute; }
#tmsg { font: normal 1em sans-serif; fill: #ccc; }
#lrc { position: absolute; top: 10px; left: 10px; font: bold 2em sans-serif; letter-spacing: 3px; animation: mov 20s linear infinite alternate; }
@keyframes mov { to { left: 614px; } }
</style>
<div id="papa">
<svg id="mplayer" viewBox="0 0 100 100" width="100" height="100">
<circle id="track" cx="50" cy="50" r="45" fill="none" stroke="snow" stroke-width="6" style="cursor: pointer" />
<line id="hand" x1="50" y1="50" x2="50" y2="10" stroke="red" stroke-width="1" />
<circle cx="50" cy="50" r="4" fill="red" />
<path id="curPath" d="M 10 60 Q 50 0 90 60" fill="none" stroke="none"/>
<path id="durPath" d="M 0 38 Q 50 100 100 38" fill="none" stroke="none"/>
<g id="tmsg">
<text x="52%" y="0"><textPath id="curMsg" xlink:href="#curPath" text-anchor="middle" dominant-baseline="text-after-edge">00:00</textPath></text>
<text x="60%" y="0"><textPath id="durMsg" xlink:href="#durPath" text-anchor="middle" dominant-baseline="text-before-edge">00:00</textPath></text>
</g>
<circle id="btnplay" cx="50" cy="50" r="35" fill="transparent" style="cursor: pointer" />
</svg>
<svg id="lrc" width="400" height="60">
<text id="lrctxt" x="50%" y="30" fill="none" stroke="snow" text-anchor="middle" dominant-baseline="middle">纯音乐 - 时间</text>
</svg>
</div>
<script>
let cc = { x: 1*track.getAttribute('cx'), y: 1*track.getAttribute('cy'), };
let aud = new Audio();
aud.src = 'https://music.163.com/song/media/outer/url?id=1920607219.mp3';
aud.autoplay = true;
aud.loop = true;
aud.addEventListener('timeupdate', () => {
let progress = aud.currentTime * 360 / aud.duration;
hand.setAttribute('transform', 'rotate(' + progress +', 50, 50)');
curMsg.textContent = toMin(aud.currentTime);
durMsg.textContent = toMin(aud.duration);
});
track.onclick = (e) => {
let angle = Math.atan2(e.offsetY - cc.y, e.offsetX - cc.x) * 180 / Math.PI;
angle+= (e.offsetX < cc.x && e.offsetY < cc.y) ? 450 : 90;
aud.currentTime = aud.duration * angle / 360;
}
btnplay.onclick = () => aud.paused ? aud.play() : aud.pause();
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>
HTML代码中,有两个 svg 标签,前一个是时钟样式的播放器,后一个是标题盒子。
标题盒子的 svg 可以容易改装成lrc歌词显示盒子,改装时请首先在 22 行根据需要修改 width 等值:
<svg id="lrc" width="400" height="60">
并,在 23 行修改文本颜色:
fill="none" stroke="snow"
其中,fill 是填充色,stroke 是描边颜色。
接下来,文本大小在CSS修改,第 5 行。
最后,在JS代码中,第 38 行之后插入以下处理lrc歌词的代码:
for(j=0; j<lrcAr.length; j++) {
if(aud.currentTime >= lrcAr) lrctxt.textContent = lrcAr;
}
当lrc歌词盒子的 svg 宽度修改后,需要修改关键帧动画的相关值,第 6 行:
@keyframes mov { to { left: 614px; } }
计算上面语句的 left 移动值的大概依据是:父元素宽度 - svg宽度 - 预留边缘宽度。例如本帖,父元素是 1024,svg是400,预留 10,则 1024-400-10=614 ,不一定很精准,大概就行。 关于关键帧动画的设置,如果只希望它在指定的区域游移,则可重新设置,例如:
@keyframes mov {
from { left: 400px; }
to { left: 600px; }
}
意思是,从(from)400像素处游移到(to) 600 像素处。这里需要注意的是,此处的设置是针对 svg 元素,不是直接针对文本的移动。不过svg可以直接驱动文本运动,需要设计路径。 等会来学习! 设计合理,浑然一体。。。{:4_187:} 东篱闲人 发表于 2022-9-10 08:18
设计合理,浑然一体。。。
节日好 马黑黑 发表于 2022-9-10 08:47
节日好
快乐!{:4_176:} 马黑黑 发表于 2022-9-10 07:44
关于关键帧动画的设置,如果只希望它在指定的区域游移,则可重新设置,例如:
@keyframes mov {
大大地点赞!{:4_187:} 极北之北 发表于 2022-9-10 09:07
大大地点赞!
我以为是大地点赞{:4_170:} 东篱闲人 发表于 2022-9-10 08:47
快乐!
同乐 欣赏节日美帖,好看好听,祝老师双节幸福快乐!{:4_204:} 梦缘 发表于 2022-9-10 09:34
欣赏节日美帖,好看好听,祝老师双节幸福快乐!
我不是老师 厉害,前面一个帖子还在将SVG的转动,这个帖子就用上了。很漂亮的指针{:4_187:} 红影 发表于 2022-9-10 10:22
厉害,前面一个帖子还在将SVG的转动,这个帖子就用上了。很漂亮的指针
像个秒针吧 哇瑟~~越来越精彩了{:4_178:} 加了指针了{:4_199:} 马黑黑 发表于 2022-9-10 07:44
关于关键帧动画的设置,如果只希望它在指定的区域游移,则可重新设置,例如:
@keyframes mov {
这个不能自己瞎捣鼓的{:4_170:} 小辣椒 发表于 2022-9-10 12:27
这个不能自己瞎捣鼓的
CSS关键帧动画已经不是一个难题了,除非没有认真学或错过学习的机会