马黑黑 发表于 2022-9-7 09:13

梦驼铃

<style>
        #papa { position: relative; left: -202px; display: block; margin: auto; box-shadow: 2px 2px 10px #000; user-select: none; z-index: 1; }
        #mama { cursor: pointer; }
        #tit { font: bold 3em sans-serif; text-shadow: 4px 4px 0 #000; stroke-width: 0.5px; stroke: snow; fill: none; dominant-baseline: text-before-edge; letter-spacing: 4px; }
        #tmsg { fill: transparent; stroke: gray; stroke-width: 1px; font: bold 1em sans-serif; }
        #btnplay, #btnpause { fill: #ccc; cursor: pointer; display: block; }
        #btnpause { display: none; }
        #btnplay:hover, #btnpause:hover { fill: orange; }
</style>

<svg id="papa" width="1000" height="553">
        <image xlink:href="/data/attachment/forum/202209/07/090849t9n9xgz2rnlaqgbl.jpg" x="0" y="0" width="100%" height="100%" />
        <g id="mama" transform="rotate(-90, 900, 453)">
                <circle id="track" cx="900" cy="453" r="50" fill="none" stroke-width="10" stroke="rgba(255,255,255,0.65)" />
                <circle id="prog" cx="900" cy="453" r="50" fill="none" stroke-width="6" stroke="rgba(57,54,81,0.85)" />
        </g>
        <polygon id="btnplay" points="890 443, 890 463, 910 453" />
        <g id="btnpause">
                <rect x="892" y="443" width="5" height="20" />
                <rect x="900" y="443" width="5" height="20" />
        </g>
        <path id="curPath" d="M 850 463 Q 900 400 950 463" fill="none" stroke="none"/>
        <path id="durPath" d="M 850 443 Q 900 500 950 443" fill="none" stroke="none"/>
        <g id="tmsg">
                <text x="40" y="0"><textPath id="curMsg" xlink:href="#curPath" dominant-baseline="text-after-edge">00:00</textPath></text>
                <text x="38" y="0"><textPath id="durMsg" xlink:href="#durPath" dominant-baseline="text-before-edge">00:00</textPath></text>
        </g>
        <text id="tit" x="20" y="20">梦驼铃</text>
</svg>

<script>

let aud = new Audio();
let cc = {
        x: 1*track.getAttribute('cx'),
        y: 1*track.getAttribute('cy'),
        r: 1*track.getAttribute('r'),
        sw: 1*track.getAttribute('stroke-width'),
        len: track.getTotalLength(),
};

aud.src = 'https://music.163.com/song/media/outer/url?id=1911002130.mp3';
aud.autoplay = true;
aud.loop = true;
prog.style.strokeDasharray = prog.style.strokeDashoffset =cc.len;

aud.addEventListener('pause', () => btnstate());
aud.addEventListener('play',() => btnstate());

aud.addEventListener('timeupdate', () => {
        prog.style.strokeDashoffset = cc.len - cc.len * aud.currentTime / aud.duration;
        curMsg.textContent = toMin(aud.currentTime);
        durMsg.textContent = toMin(aud.duration);
});

btnplay.onclick = btnpause.onclick = () => aud.paused ? aud.play() : aud.pause();

mama.onclick = (e) => {
        let deg = Math.atan2(e.offsetY - cc.y, e.offsetX - cc.x) * 180 / Math.PI;
        deg += (e.offsetX < cc.x && e.offsetY < cc.y) ? 450 : 90;
        aud.currentTime = aud.duration * deg / 360;
};

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>

马黑黑 发表于 2022-9-7 09:13

源码
<style>
        #papa { position: relative; left: 202px; display: block; margin: auto; box-shadow: 2px 2px 10px #000; user-select: none; z-index: 1; }
        #mama { cursor: pointer; }
        #tit { font: bold 3em sans-serif; text-shadow: 4px 4px 0 #000; stroke-width: 0.5px; stroke: snow; fill: none; dominant-baseline: text-before-edge; letter-spacing: 4px; }
        #tmsg { fill: transparent; stroke: gray; stroke-width: 1px; font: bold 1em sans-serif; }
        #btnplay, #btnpause { fill: #ccc; cursor: pointer; display: block; }
        #btnpause { display: none; }
        #btnplay:hover, #btnpause:hover { fill: orange; }
</style>

<svg id="papa" width="1000" height="553">
        <image xlink:href="/data/attachment/forum/202209/07/090849t9n9xgz2rnlaqgbl.jpg" x="0" y="0" width="100%" height="100%" />
        <g id="mama" transform="rotate(-90, 900, 453)">
                <circle id="track" cx="900" cy="453" r="50" fill="none" stroke-width="10" stroke="rgba(255,255,255,0.65)" />
                <circle id="prog" cx="900" cy="453" r="50" fill="none" stroke-width="6" stroke="rgba(57,54,81,0.85)" />
        </g>
        <polygon id="btnplay" points="890 443, 890 463, 910 453" />
        <g id="btnpause">
                <rect x="892" y="443" width="5" height="20" />
                <rect x="900" y="443" width="5" height="20" />
        </g>
        <path id="curPath" d="M 850 463 Q 900 400 950 463" fill="none" stroke="none"/>
        <path id="durPath" d="M 850 443 Q 900 500 950 443" fill="none" stroke="none"/>
        <g id="tmsg">
                <text x="40" y="0"><textPath id="curMsg" xlink:href="#curPath" dominant-baseline="text-after-edge">00:00</textPath></text>
                <text x="38" y="0"><textPath id="durMsg" xlink:href="#durPath" dominant-baseline="text-before-edge">00:00</textPath></text>
        </g>
        <text id="tit" x="20" y="20">梦驼铃</text>
</svg>

<script>

let aud = new Audio();
let cc = {
        x: 1*track.getAttribute('cx'),
        y: 1*track.getAttribute('cy'),
        r: 1*track.getAttribute('r'),
        sw: 1*track.getAttribute('stroke-width'),
        len: track.getTotalLength(),
};

aud.src = 'https://music.163.com/song/media/outer/url?id=1911002130.mp3';
aud.autoplay = true;
aud.loop = true;
prog.style.strokeDasharray = prog.style.strokeDashoffset =cc.len;

aud.addEventListener('pause', () => btnstate());
aud.addEventListener('play',() => btnstate());

aud.addEventListener('timeupdate', () => {
        prog.style.strokeDashoffset = cc.len - cc.len * aud.currentTime / aud.duration;
        curMsg.textContent = toMin(aud.currentTime);
        durMsg.textContent = toMin(aud.duration);
});

btnplay.onclick = btnpause.onclick = () => aud.paused ? aud.play() : aud.pause();

mama.onclick = (e) => {
        let deg = Math.atan2(e.offsetY - cc.y, e.offsetX - cc.x) * 180 / Math.PI;
        deg += (e.offsetX < cc.x && e.offsetY < cc.y) ? 450 : 90;
        aud.currentTime = aud.duration * deg / 360;
};

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>

马黑黑 发表于 2022-9-7 09:22

本帖尝试使用纯 svg 做帖子。帖子就是一个 svg 标签,其内有若干 svg 的子标签。

svg 支持 CSS 对它的诸多元素的定义,也以自己的方式接受 JS 的指令,所以,帖子也是用 CSS、JS。

但 svg 并非易于操控,它的开发,初始意图主要不是人工写代码的,所以语法、语句非常繁琐,不宜掌握、控制,本帖仅作为演示,不建议用来做帖子,除非你可以随意摆布本帖 svg 内的元素,例如,把圆环播放器整体挪个位置。

个人觉得帖子这个圆环播放器也挺漂亮,我会在有空的时候单独封装,令其成为一个 HTML 元素,可以随便调整位置。

加林森 发表于 2022-9-7 09:35

好漂亮的制作。学习学习!老黑辛苦了!{:4_190:}

安宁 发表于 2022-9-7 10:11


我这强迫症……{:5_103:}{:5_117:}
黑黑把这5小只加进去,<br><br><br><br><br>      让你帅得光芒万丈的头像完整展现在世人面前,亮瞎那谁谁


https://pic.imgdb.cn/item/6317fcf016f2c2beb18645d7.png



梦缘 发表于 2022-9-7 10:13

欣赏老师的精彩代码,感谢!{:4_204:}

红影 发表于 2022-9-7 11:14

马黑黑 发表于 2022-9-7 09:22
本帖尝试使用纯 svg 做帖子。帖子就是一个 svg 标签,其内有若干 svg 的子标签。

svg 支持 CSS 对它的诸 ...

在路径上,对于curPath 设置了 d="M 850 463 Q 900 400 950 463",对于durPath设置了d="M 850 443 Q 900 500 950 443",这两个一个朝上弯一个朝下弯,护住了播放按钮,倒也好看呢{:4_187:}

红影 发表于 2022-9-7 11:17

马黑黑 发表于 2022-9-7 09:22
本帖尝试使用纯 svg 做帖子。帖子就是一个 svg 标签,其内有若干 svg 的子标签。

svg 支持 CSS 对它的诸 ...

仔细看了看,移动这个圆环要跟着移动的东西不少,只要都考虑倒了,也是能移动的呀{:4_173:}

加林森 发表于 2022-9-7 11:20

再来欣赏!

红影 发表于 2022-9-7 11:20

这个帖子厉害了,只有CSS和JS,没HTML什么事啊。
等着看你让这些SVG"令其成为一个 HTML 元素"。猜想是多设一个块,都扔里面?

醉美水芙蓉 发表于 2022-9-7 11:40

马黑黑 发表于 2022-9-7 12:00

安宁 发表于 2022-9-7 10:11
我这强迫症……
黑黑把这5小只加进去,      让你帅得光芒万丈的头像完整展现在世 ...

俺习惯不要脸{:4_170:}

其实有更简单的做法:帖子父元素加一个 margin-top: 120px 也是可以的。

马黑黑 发表于 2022-9-7 12:00

醉美水芙蓉 发表于 2022-9-7 11:40
欣赏学习黑黑老师佳作!

感谢支持

马黑黑 发表于 2022-9-7 12:01

梦缘 发表于 2022-9-7 10:13
欣赏老师的精彩代码,感谢!

客气客气

马黑黑 发表于 2022-9-7 12:04

红影 发表于 2022-9-7 11:14
在路径上,对于curPath 设置了 d="M 850 463 Q 900 400 950 463",对于durPath设置了d="M 850 443 Q 900...

路径的设计,我用了二次赛贝尔曲线,M 的数字是曲线起点,Q 的第一组数字是控制点,第二组数字是曲线终点。我想其实可以用弧线 A 代替 Q,可能更好控制。

马黑黑 发表于 2022-9-7 12:06

红影 发表于 2022-9-7 11:20
这个帖子厉害了,只有CSS和JS,没HTML什么事啊。
等着看你让这些SVG"令其成为一个 HTML 元素"。猜想是多设 ...

严格来讲,svg 的这种用法,仍然是HTML,svg是HTML的一个元素,这里只是不需要其他HTML元素而已。

常规封装,svg 将作为父元素的子元素,歌词与按钮或分离或组合,分离的话用到两个svg,组合的话只用一个svg。

马黑黑 发表于 2022-9-7 12:08

红影 发表于 2022-9-7 11:17
仔细看了看,移动这个圆环要跟着移动的东西不少,只要都考虑倒了,也是能移动的呀

对。主要是播放时间信息的路径,需要重新设计。还有就是 <g id="mama" ..>的旋转基点,要改为与两个圆环的圆心一致。

红影 发表于 2022-9-7 14:46

马黑黑 发表于 2022-9-7 12:04
路径的设计,我用了二次赛贝尔曲线,M 的数字是曲线起点,Q 的第一组数字是控制点,第二组数字是曲线终点 ...
弧线A貌似你没讲过,但贝尔曲线你讲解过的,那就贝尔曲线呗{:4_173:}

红影 发表于 2022-9-7 14:48

马黑黑 发表于 2022-9-7 12:08
对。主要是播放时间信息的路径,需要重新设计。还有就是 的旋转基点,要改为与两个圆环的圆心一致。

这个不愁,算了位置都能准确放好的{:4_204:}

小辣椒 发表于 2022-9-7 17:29

黑黑固然一天一个,黑神你太厉害了{:4_178:}
页: [1] 2 3
查看完整版本: 梦驼铃