马黑黑 发表于 2022-9-10 07:18

时间

<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>

马黑黑 发表于 2022-9-10 07:24

代码分享
<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>

马黑黑 发表于 2022-9-10 07:33

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;
        }

马黑黑 发表于 2022-9-10 07:40

当lrc歌词盒子的 svg 宽度修改后,需要修改关键帧动画的相关值,第 6 行:

@keyframes mov { to { left: 614px; } }

计算上面语句的 left 移动值的大概依据是:父元素宽度 - svg宽度 - 预留边缘宽度。例如本帖,父元素是 1024,svg是400,预留 10,则 1024-400-10=614 ,不一定很精准,大概就行。

马黑黑 发表于 2022-9-10 07:44

关于关键帧动画的设置,如果只希望它在指定的区域游移,则可重新设置,例如:

@keyframes mov {
    from { left: 400px; }
    to { left: 600px; }
}

意思是,从(from)400像素处游移到(to) 600 像素处。这里需要注意的是,此处的设置是针对 svg 元素,不是直接针对文本的移动。不过svg可以直接驱动文本运动,需要设计路径。

加林森 发表于 2022-9-10 08:18

等会来学习!

东篱闲人 发表于 2022-9-10 08:18

设计合理,浑然一体。。。{:4_187:}

马黑黑 发表于 2022-9-10 08:47

东篱闲人 发表于 2022-9-10 08:18
设计合理,浑然一体。。。

节日好

东篱闲人 发表于 2022-9-10 08:47

马黑黑 发表于 2022-9-10 08:47
节日好

快乐!{:4_176:}

极北之北 发表于 2022-9-10 09:07

马黑黑 发表于 2022-9-10 07:44
关于关键帧动画的设置,如果只希望它在指定的区域游移,则可重新设置,例如:

@keyframes mov {


大大地点赞!{:4_187:}

马黑黑 发表于 2022-9-10 09:08

极北之北 发表于 2022-9-10 09:07
大大地点赞!

我以为是大地点赞{:4_170:}

马黑黑 发表于 2022-9-10 09:08

东篱闲人 发表于 2022-9-10 08:47
快乐!

同乐

梦缘 发表于 2022-9-10 09:34

欣赏节日美帖,好看好听,祝老师双节幸福快乐!{:4_204:}

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

梦缘 发表于 2022-9-10 09:34
欣赏节日美帖,好看好听,祝老师双节幸福快乐!

我不是老师

红影 发表于 2022-9-10 10:22

厉害,前面一个帖子还在将SVG的转动,这个帖子就用上了。很漂亮的指针{:4_187:}

马黑黑 发表于 2022-9-10 10:34

红影 发表于 2022-9-10 10:22
厉害,前面一个帖子还在将SVG的转动,这个帖子就用上了。很漂亮的指针

像个秒针吧

小辣椒 发表于 2022-9-10 12:25

哇瑟~~越来越精彩了{:4_178:}

小辣椒 发表于 2022-9-10 12:26

加了指针了{:4_199:}

小辣椒 发表于 2022-9-10 12:27

马黑黑 发表于 2022-9-10 07:44
关于关键帧动画的设置,如果只希望它在指定的区域游移,则可重新设置,例如:

@keyframes mov {


这个不能自己瞎捣鼓的{:4_170:}

马黑黑 发表于 2022-9-10 13:14

小辣椒 发表于 2022-9-10 12:27
这个不能自己瞎捣鼓的

CSS关键帧动画已经不是一个难题了,除非没有认真学或错过学习的机会
页: [1] 2 3 4 5
查看完整版本: 时间