马黑黑 发表于 2022-8-22 07:06

盛夏荷塘

本帖最后由 马黑黑 于 2022-8-22 20:18 编辑 <br /><br /><style>
#papa { left: -214px; /*margin: auto;*/ width: 1024px; height: 640px; display: grid; place-items: center; background: teal url('https://638183.freep.cn/638183/t22/hl/vv.webp') no-repeat center/cover; box-shadow: 3px 3px 20px #000; position: relative; z-index: 3; }
#canv { position: absolute; bottom: 30px; cursor: pointer; box-reflect: below 0 linear-gradient(transparent, transparent 50%, rgba(255,255,255,.3)); -webkit-box-reflect: below 0 linear-gradient(transparent, transparent 50%, rgba(255,255,255,.3)); }
#lrcbox { position: absolute; left: 15px; top: 10px; font: bold 30px / 40px sans-serif; color: darkgreen; text-shadow: 1px 1px 2px #000, 10px 10px 10px rgba(0, 0, 0, .35); user-select: none; }
</style>

<div id="papa">
        <canvas id="canv"></canvas>
        <span id="lrcbox">盛夏荷塘</span>
</div>

<script>
let ctx = canv.getContext('2d'),
        w = canv.width = 80,
        h = canv.height = 60,
        lines = [],
        total = 20,
        lineWidth = (w - 2 * total) / total,
        aud = new Audio();

aud.src = 'https://music.163.com/song/media/outer/url?id=490949412.mp3';
aud.loop = true;
aud.autoplay = true;

aud.addEventListener('timeupdate', change);
canv.onclick = () => aud.paused ? aud.play() : aud.pause();

function Line(x1,y1,x2,y2) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        lines.push(this);
}

Line.prototype.draw = function() {
        ctx.beginPath();
        ctx.strokeStyle = this.color;
        ctx.lineWidth = lineWidth;
        ctx.moveTo(this.x1, this.y1);
        ctx.lineTo(this.x2,this.y2);
        ctx.stroke();
}

for(let j = 0; j < total; j ++) {
        let line = new Line();
        line.x1 = j * lineWidth + j*2 + lineWidth / 2 + 1;
        line.y1 = h;
        line.x2 = line.x1;
        line.y2 = 60;
        line.color = 'purple';
        line.draw();
}

function change() {
        ctx.clearRect(0,0,w,h);
        for(let item of lines) {
                item.color = '#' + Math.random().toString(16).substr(-6);
                item.y2 = h - (Math.random() * h);
                item.draw();
        }
}

change();

</script>

马黑黑 发表于 2022-8-22 07:07

本帖是canvas画布频谱播放器的试用,代码如下(全):
<style>
#papa { left: -214px; /*margin: auto;*/ width: 1024px; height: 640px; display: grid; place-items: center; background: teal url('https://638183.freep.cn/638183/t22/hl/vv.webp') no-repeat center/cover; box-shadow: 3px 3px 20px #000; position: relative; z-index: 3; }
#canv { position: absolute; bottom: 30px; cursor: pointer; box-reflect: below 0 linear-gradient(transparent, transparent 50%, rgba(255,255,255,.3)); -webkit-box-reflect: below 0 linear-gradient(transparent, transparent 50%, rgba(255,255,255,.3)); }
#lrcbox { position: absolute; left: 15px; top: 10px; font: bold 30px / 40px sans-serif; color: darkgreen; text-shadow: 1px 1px 2px #000, 10px 10px 10px rgba(0, 0, 0, .35); user-select: none; }
</style>

<div id="papa">
        <canvas id="canv"></canvas>
        <span id="lrcbox">盛夏荷塘</span>
</div>

<script>
let ctx = canv.getContext('2d'),
        w = canv.width = 80,
        h = canv.height = 60,
        lines = [],
        total = 20,
        lineWidth = (w - 2 * total) / total,
        aud = new Audio();

aud.src = 'https://music.163.com/song/media/outer/url?id=490949412.mp3';
aud.loop = true;
aud.autoplay = true;

aud.addEventListener('timeupdate', change);
canv.onclick = () => aud.paused ? aud.play() : aud.pause();

function Line(x1,y1,x2,y2) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        lines.push(this);
}

Line.prototype.draw = function() {
        ctx.beginPath();
        ctx.strokeStyle = this.color;
        ctx.lineWidth = lineWidth;
        ctx.moveTo(this.x1, this.y1);
        ctx.lineTo(this.x2,this.y2);
        ctx.stroke();
}

for(let j = 0; j < total; j ++) {
        let line = new Line();
        line.x1 = j * lineWidth + j*2 + lineWidth / 2 + 1;
        line.y1 = h;
        line.x2 = line.x1;
        line.y2 = 60;
        line.color = 'purple';
        line.draw();
}

function change() {
        ctx.clearRect(0,0,w,h);
        for(let item of lines) {
                item.color = '#' + Math.random().toString(16).substr(-6);
                item.y2 = h - (Math.random() * h);
                item.draw();
        }
}
</script>

马黑黑 发表于 2022-8-22 07:11

相比CSS+HTML标签构建的频谱播放按钮,JS部分的代码多了一些。画布上的操作,JS代码量也难以节省。它的优势是,DOM节点大大减少。

画布频谱相关解释:

https://www.huachaowang.com/forum.php?mod=viewthread&tid=62358&extra=page%3D1

马黑黑 发表于 2022-8-22 07:15

这里再解释一下几个重要变量:

let ctx = canv.getContext('2d'),
      w = canv.width = 80, //画布宽度在此设定
      h = canv.height = 60, //画布高度在此设定
      lines = [], //装载频谱线条的数组
      total = 20, //频谱线条总数
      lineWidth = (w - 2 * total) / total, //频谱线条的厚度:根据画布宽度和线数决定
      aud = new Audio();

马黑黑 发表于 2022-8-22 07:53

本帖最后由 马黑黑 于 2022-8-22 07:55 编辑

关于线条厚度:

lineWidth = (w - 2 * total) / total;

(画布宽度 - 线条总数的2倍)÷ 线条总数,(80-2*20)/20 = 2,线条的厚度是2,会很细,不过,画布用 stroke 方法画线,会多出边缘部分,两侧各占 1 个单位 共 2 个单位,即表现出来的线条真实厚度其实是 4 个单位(程序以2个单位计)。什么单位?像素。

然后,初始化每根线条横向位置时,我们的计算要配套上面的式子,

line.x1 = j * lineWidth + j*2 + lineWidth / 2 + 1;

j 是循环语句的步进变量,从 0 开始,如此,第一根线在画布上的水平方向位置是,

0*2+0*2+2/2+1 = 2,

它从 2px 处开始。最后一根线,j 是 19,它的 x1 位置,

19*2+19*2+2/19+1 = 77.1052631579

这个值很接近右边边缘了,再加上①线宽,②画布的一些不好描述的怪异特性,基本上所有的线条居中平铺在了画布的水平方向了,且线条彼此间一些一定的距离。

马黑黑 发表于 2022-8-22 07:58

需要验证 5# 所描述的,大家可以在本地测试时在 CSS 中给 #canv 加入,
   
   border: 1px solid;

再改变 total 数量为较少(比如5),如此,能更方便地观测效果。

加林森 发表于 2022-8-22 08:52

有意思。这个得好好研究一下了。老黑早晨好!{:4_190:}

红影 发表于 2022-8-22 10:17

马黑黑 发表于 2022-8-22 07:53
关于线条厚度:

lineWidth = (w - 2 * total) / total;


前面就对这个间隔的算法没弄明白,现在也不去管了,就按这个计算就好{:4_173:}

红影 发表于 2022-8-22 10:37

我单位网有问题,没法听到网易云,等晚上回家再欣赏了{:4_187:}

樵歌 发表于 2022-8-22 10:46

弄成那天那从中间开屏的是不是更好看些{:4_173:}

马黑黑 发表于 2022-8-22 11:09

樵歌 发表于 2022-8-22 10:46
弄成那天那从中间开屏的是不是更好看些

那是东篱的东宫才这样开合的

马黑黑 发表于 2022-8-22 11:09

红影 发表于 2022-8-22 10:17
前面就对这个间隔的算法没弄明白,现在也不去管了,就按这个计算就好

差不多的

马黑黑 发表于 2022-8-22 11:10

红影 发表于 2022-8-22 10:37
我单位网有问题,没法听到网易云,等晚上回家再欣赏了

音乐有特点

马黑黑 发表于 2022-8-22 11:10

加林森 发表于 2022-8-22 08:52
有意思。这个得好好研究一下了。老黑早晨好!

数学基础好的话一看就能明白

加林森 发表于 2022-8-22 11:17

马黑黑 发表于 2022-8-22 11:10
数学基础好的话一看就能明白

我数学不好。所以比较吃力的。

马黑黑 发表于 2022-8-22 12:18

加林森 发表于 2022-8-22 11:17
我数学不好。所以比较吃力的。

数学基础不扎实,做帖时的很多计算智能蒙了

加林森 发表于 2022-8-22 12:29

马黑黑 发表于 2022-8-22 12:18
数学基础不扎实,做帖时的很多计算智能蒙了

就是啊。

小辣椒 发表于 2022-8-22 17:41

黑黑新的小频谱播放器{:4_178:}

小辣椒 发表于 2022-8-22 17:42

黑黑精彩连连,小辣椒跟不上了{:4_189:}

马黑黑 发表于 2022-8-22 17:52

小辣椒 发表于 2022-8-22 17:41
黑黑新的小频谱播放器

和过去的频谱没多大区别,仅在实现元素不同
页: [1] 2 3 4
查看完整版本: 盛夏荷塘