马黑黑 发表于 2022-8-8 06:58

繁华梦

<style>
#papa { left: -214px; width: 1024px; height: 640px; box-shadow: 3px 3px 20px #000; position: relative; }
#canv { position: absolute; width: 100%; height: 100%; background: #000; }
#bgImg { display: none; }
#disc { position: absolute; width: 40px; height: 40px; left: 10px; top: 10px; background: conic-gradient(red,orange,yellow,green,teal,blue,purple); mask: radial-gradient(transparent 4px,red 0); -webkit-mask: radial-gradient(transparent 4px,red 0); border-radius: 50%; cursor: pointer; animation: rot 2s linear infinite; }
#tit { position: absolute; left: 60px; top: 10px;font: bold 22px / 40px sans-serif; color: snow; text-shadow: 2px 2px 4px black; }
@keyframes rot { to { transform: rotate(360deg); } }
</style>

<div id="papa">
        <canvas id="canv"></canvas>
        <img id="bgImg" src="https://638183.freep.cn/638183/Pic/81/fanhuameng.jpg" alt="" />
        <span id="disc"></span>
        <span id="tit">繁华梦 | 琵琶·朱飞霏</span>
</div>

<script>
let ctx = canv.getContext('2d');
let w = papa.clientWidth, h = papa.clientHeight, aud = new Audio();
let dotAr = Array.from({length: 200}, (item,key) => { return { x: Math.random()*w, y: Math.random()*h, r: Math.random()*5, }; });

canv.width = w;
canv.height = h;
aud.src = 'https://music.163.com/song/media/outer/url?id=1466888290.mp3';
aud.loop = true;
aud.autoplay = true;

disc.style.animationPlayState = aud.paused ? 'paused' : 'running';
disc.onclick = () => aud.paused ? aud.play() : aud.pause();
aud.addEventListener('playing',()=> disc.style.animationPlayState = 'running');
aud.addEventListener('pause',()=> disc.style.animationPlayState = 'paused');

function draw() {
        ctx.clearRect(0,0,w,h);
        ctx.drawImage(bgImg, 0, 0, w, h);
        ctx.beginPath();
        for(item of dotAr) {
                ctx.fillStyle = 'rgba(255,255,255,.35)';
                ctx.moveTo(item.x, item.y);
                ctx.arc(item.x, item.y, item.r, 0, Math.PI * 2);
        }
        ctx.fill();
        update();
}

function update() {
        for (key in dotAr) {
                dotAr.y -= (7 - dotAr.r) / 10;
                if(dotAr.y < 0) {
                        dotAr = {
                                x: Math.random() * w,
                                y: h,
                                r: Math.random()*5,
                        }
                }
        }
}

draw();
setInterval(draw,10);
</script>

马黑黑 发表于 2022-8-8 06:59

源码分享:
<style>
#papa { margin: auto; width: 1024px; height: 640px; box-shadow: 3px 3px 20px #000; position: relative; }
#canv { position: absolute; width: 100%; height: 100%; background: #000; }
#bgImg { display: none; }
#disc { position: absolute; width: 40px; height: 40px; left: 10px; top: 10px; background: conic-gradient(red,orange,yellow,green,teal,blue,purple); mask: radial-gradient(transparent 4px,red 0); -webkit-mask: radial-gradient(transparent 4px,red 0); border-radius: 50%; cursor: pointer; animation: rot 2s linear infinite; }
#tit { position: absolute; left: 60px; top: 10px;font: bold 22px / 40px sans-serif; color: snow; text-shadow: 2px 2px 4px black; }
@keyframes rot { to { transform: rotate(360deg); } }
</style>

<div id="papa">
        <canvas id="canv"></canvas>
        <img id="bgImg" src="https://638183.freep.cn/638183/Pic/81/fanhuameng.jpg" alt="" />
        <span id="disc"></span>
        <span id="tit">繁华梦 | 琵琶·朱飞霏</span>
</div>

<script>
let ctx = canv.getContext('2d');
let w = papa.clientWidth, h = papa.clientHeight, aud = new Audio();
let dotAr = Array.from({length: 200}, (item,key) => { return { x: Math.random()*w, y: Math.random()*h, r: Math.random()*5, }; });

canv.width = w;
canv.height = h;
aud.src = 'https://music.163.com/song/media/outer/url?id=1466888290.mp3';
aud.loop = true;
aud.autoplay = true;

disc.style.animationPlayState = aud.paused ? 'paused' : 'running';
disc.onclick = () => aud.paused ? aud.play() : aud.pause();
aud.addEventListener('playing',()=> disc.style.animationPlayState = 'running');
aud.addEventListener('pause',()=> disc.style.animationPlayState = 'paused');

function draw() {
        ctx.clearRect(0,0,w,h);
        ctx.drawImage(bgImg, 0, 0, w, h);
        ctx.beginPath();
        for(item of dotAr) {
                ctx.fillStyle = 'rgba(255,255,255,.35)';
                ctx.moveTo(item.x, item.y);
                ctx.arc(item.x, item.y, item.r, 0, Math.PI * 2);
        }
        ctx.fill();
        update();
}

function update() {
        for (key in dotAr) {
                dotAr.y -= (7 - dotAr.r) / 10;
                if(dotAr.y < 0) {
                        dotAr = {
                                x: Math.random() * w,
                                y: h,
                                r: Math.random()*5,
                        }
                }
        }
}

draw();
setInterval(draw,10);
</script>

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

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

实现原理:

一、播放器及其右边的文本:常规HTML+CSS,播放控制由JS控制。略过。

二、背景及动态效果:canvas画布。重点说说这个。

canvas画布在HTML里是个白板,需要JS去驱动它,JS就相当于作画人。此前我们有过canvas画布的基础专题,介绍过在画布里实现动画就是不停地擦除、重画——本帖背景图和上升的珠子就是不断擦除、重画而得。

初始化时,背景图为一个 img 标签所加载,该标签在CSS里设定为不可见,随后由 JS 使用 drawImage 方法将图片搬到画布上来,在绘画函数 draw() 中每次擦除之后重绘,ctx.drawImage(bgImg, 0, 0, w, h); 语句即是。漂浮的珠子,JS初始变量中通过数组构建给出开始出现的xy坐标位置、半径,语句为(这里将其拆为多行并加注释便于阅读):

let dotAr = Array.from({length: 200}, (item,key) => {
    return {
      x: Math.random()*w, //随机横向位置
      y: Math.random()*h, //随机纵向位置
      r: Math.random()*5, //随机半径(从而决定珠子大小)
    };
});

然后通过 draw() 绘制函数 和 update() 更新函数的配合,实现动态擦除、重绘。update 提供新形态,draw 调用它获得新形态数据并依据这些数据重绘。setInterval 定时器定时调用 draw 函数故而永不间断地在画布上作画,达成动态的效果。

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

这是极其简易的canvas画布动画了。虽简易,比起画单个珠子的运动(之前在我的地儿有过介绍),还是复杂了许多,毕竟这里应对的是200个珠子(可以加减,通过 let dotAr = Array.from({length: 200} ... 初始化珠子语句)。

樵歌 发表于 2022-8-8 07:50

是在王母宫殿里举办的音乐会么,{:4_173:}

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

樵歌 发表于 2022-8-8 07:50
是在王母宫殿里举办的音乐会么,

大约吧,不过也不清楚,高德定位不出来

樵歌 发表于 2022-8-8 07:53

如果要把一首诗词加上去且从下到上滚动,怎么办?{:4_173:}

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

樵歌 发表于 2022-8-8 07:53
如果要把一首诗词加上去且从下到上滚动,怎么办?

这个容易呀,HTML+CSS就能实现,画布也可以处理文字

樵歌 发表于 2022-8-8 07:58

马黑黑 发表于 2022-8-8 07:51
大约吧,不过也不清楚,高德定位不出来

是不是和天宫不在一个空间

马黑黑 发表于 2022-8-8 08:01

樵歌 发表于 2022-8-8 07:58
是不是和天宫不在一个空间

这叫刷屏吧,以前的画外音之类的变迁

樵歌 发表于 2022-8-8 08:04

马黑黑 发表于 2022-8-8 07:57
这个容易呀,HTML+CSS就能实现,画布也可以处理文字

具体弄在代码何外吗{:4_189:}

红影 发表于 2022-8-8 08:46

好吧,又得回去复习画布的相关知识了{:4_173:}

红影 发表于 2022-8-8 08:51

也就是每次刷新是画出背景图和它上面的随机小球吧,但随机小球本来就是均布的,怎样能造成是在上行的感觉,这个倒是难以理解。单个小球好理解。随机小球竟也能这样啊。

红影 发表于 2022-8-8 08:58

dotAr.y -= (7 - dotAr.r) / 10;

这个数据为什么这样取?
代码里没看出来哪句是小球半径极限,哪句是向上语句。
r: Math.random()*5, //随机半径(从而决定珠子大小),极限值是如何设定的?

加林森 发表于 2022-8-8 10:05

好精艳的制作,真漂亮。感觉还是立体的。老黑真厉害!{:4_199:}

梦油 发表于 2022-8-8 10:31

繁花似锦、姹紫嫣红,好美的意境。

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

再来学习。

马黑黑 发表于 2022-8-8 12:31

樵歌 发表于 2022-8-8 08:04
具体弄在代码何外吗

我在文本特效那里有类似的代码

马黑黑 发表于 2022-8-8 12:32

红影 发表于 2022-8-8 08:46
好吧,又得回去复习画布的相关知识了

canvas画布貌似不太难,虽然内容也很多、基本功的掌握是需要点时间的。

马黑黑 发表于 2022-8-8 12:32

梦油 发表于 2022-8-8 10:31
繁花似锦、姹紫嫣红,好美的意境。

谢谢点评
页: [1] 2 3 4 5 6
查看完整版本: 繁华梦