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

失真的梦

<style>
        #papa { left: -214px; display: grid; place-items: center; width: 1024px; height: 640px; background: url('https://638183.freep.cn/638183/Pic/38/333.png') no-repeat center/cover; position: relative; }
        #canv { position: absolute; }
        #disc { position: absolute; width: 40px; height: 40px; left: 10px; bottom: 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; }
        #lrcbox { position: absolute; left: 60px; bottom: 10px;font: bold 22px / 40px sans-serif; color: snow; text-shadow: 2px 2px 4px #222; }
        @keyframes rot { to { transform: rotate(360deg); } }
</style>

<div id="papa">
        <span id="lrcbox">失真的梦</span>
        <canvas id="canv"></canvas>
        <span id="disc"></span>
</div>

<script type="text/javascript">
let num = (min, max) => Math.floor(Math.random() * (max-min+1)) + min;
let r = 10, speed = 0.5, idx = 0;
let w = canv.width = 500, h = canv.height = 600;
let ctx = canv.getContext('2d');
let images = new Array(), aud = new Audio();

aud.src = 'https://music.163.com/song/media/outer/url?id=1425398486.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 preload() {
        for (j = 0; j < preload.arguments.length; j++) {
                images = new Image()
                images.src = preload.arguments
        }
}
preload(
        'https://638183.freep.cn/638183/Pic/38/3-1.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-2.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-3.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-4.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-5.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-6.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-7.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-8.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-9.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-10.jpg',
)

idx = num(0, images.length - 1);

(function draw() {
        ctx.clearRect(0, 0, w, h);
        ctx.save();
        ctx.beginPath();
        ctx.arc(w / 2, h / 2, r, 0, Math.PI*2);
        ctx.closePath();
        ctx.fillStyle = "transparent";
        ctx.fill();
        ctx.clip();
        ctx.drawImage(images, 0, 0, w, h);
        ctx.restore();
        r += speed;
        if (r > 250 || r <= 0) speed = -speed;
        if(r <= 0) idx = num(0, images.length - 1);
        requestAnimationFrame(draw);
})();

</script>

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

代码分享(全):
<style>
        #papa { margin: auto; display: grid; place-items: center; width: 1024px; height: 640px; background: url('https://638183.freep.cn/638183/Pic/38/333.png') no-repeat center/cover; position: relative; }
        #canv { position: absolute; }
        #disc { position: absolute; width: 40px; height: 40px; left: 10px; bottom: 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; }
        #lrcbox { position: absolute; left: 60px; bottom: 10px;font: bold 22px / 40px sans-serif; color: snow; text-shadow: 2px 2px 4px #222; }
        @keyframes rot { to { transform: rotate(360deg); } }
</style>

<div id="papa">
        <span id="lrcbox">失真的梦</span>
        <canvas id="canv"></canvas>
        <span id="disc"></span>
</div>

<script type="text/javascript">
let num = (min, max) => Math.floor(Math.random() * (max-min+1)) + min;
let r = 10, speed = 0.5, idx = 0;
let w = canv.width = 500, h = canv.height = 600;
let ctx = canv.getContext('2d');
let images = new Array(), aud = new Audio();

aud.src = 'https://music.163.com/song/media/outer/url?id=1425398486.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 preload() {
        for (j = 0; j < preload.arguments.length; j++) {
                images = new Image()
                images.src = preload.arguments
        }
}
preload(
        'https://638183.freep.cn/638183/Pic/38/3-1.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-2.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-3.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-4.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-5.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-6.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-7.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-8.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-9.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-10.jpg',
)

idx = num(0, images.length - 1);

(function draw() {
        ctx.clearRect(0, 0, w, h);
        ctx.save();
        ctx.beginPath();
        ctx.arc(w / 2, h / 2, r, 0, Math.PI*2);
        ctx.closePath();
        ctx.fillStyle = "transparent";
        ctx.fill();
        ctx.clip();
        ctx.drawImage(images, 0, 0, w, h);
        ctx.restore();
        r += speed;
        if (r > 250 || r <= 0) speed = -speed;
        if(r <= 0) idx = num(0, images.length - 1);
        requestAnimationFrame(draw);
})();

</script>



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

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

本帖主要演示两个内容:

一、原生JS批量预加载图片

      画布 drawImage() 方法,图片的来源是img标签、视频或image()对象。根据帖子情况,需要 image() 对象实现,进而需要图片批量预加载。帖子 preload 对象即是,分两部分。

二、canvas 画布 clip() 方法

      clip() 是画布的裁剪方法,使用它可以对目标图形对象进行遮罩。本帖使用透明色遮罩(其他颜色也行,透明色能与帖子的背景融合),并动态更改遮罩的尺寸,然后在遮罩层上绘制图片(图片动态从预加载图片中选取)。

本帖对图片尺寸的要求:宽高 1:1 或接近。

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

小技巧:

clip() 尺寸的变更有两个来回的变化,往大里的变化尺寸设定为 250,原因是图片在画布上的尺寸宽度为500,用其一半可以令往大里的变化结束时保持图片的圆形形态。往小里的变化终结数是0,当是0时,令画布更换图片的 idx(即图片索引),达到换图的目的。

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

解释一下与图片预加载相关的内容:

在JS里,当生命一个变量为 new Image() 对象,并给出其 src,则图片将自动得到预加载,我们要做的就是将图片 URL 变成 Image() 对象且给出 src 即可。

先声明一个对象:

function preload() {
        for (j = 0; j < preload.arguments.length; j++) {
                images = new Image();
                images.src = preload.arguments;
        }
}

然后给出内置对象元素(这里是图片URL):

preload(
        'https://638183.freep.cn/638183/Pic/38/3-1.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-2.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-3.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-4.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-5.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-6.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-7.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-8.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-9.jpg',
        'https://638183.freep.cn/638183/Pic/38/3-10.jpg',
);

for 语句中的 preload.arguments.length 就是对象内置元素项目总数的统计,与数组中的 数组名称.length 原理相似。

樵歌 发表于 2022-8-15 08:02

都说梦由心生,依看梦生于编程,眼里美媚见多了,自然信手拈来。{:4_173:}

马黑黑 发表于 2022-8-15 08:05

樵歌 发表于 2022-8-15 08:02
都说梦由心生,依看梦生于编程,眼里美媚见多了,自然信手拈来。

编程就是织梦

加林森 发表于 2022-8-15 10:33

漂亮的制作。真是有点做梦的感觉。我怎么进来就开始卡了?

梦油 发表于 2022-8-15 10:40

新作层出不穷、目不暇接。黑黑朋友“肚子”里的宝贝可真不少。{:4_178:}

樵歌 发表于 2022-8-15 10:55

马黑黑 发表于 2022-8-15 08:05
编程就是织梦

完全同意{:4_174:}

马黑黑 发表于 2022-8-15 11:21

樵歌 发表于 2022-8-15 10:55
完全同意

{:5_108:}

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

梦油 发表于 2022-8-15 10:40
新作层出不穷、目不暇接。黑黑朋友“肚子”里的宝贝可真不少。

哈哈,还木有难产{:5_106:}

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

加林森 发表于 2022-8-15 10:33
漂亮的制作。真是有点做梦的感觉。我怎么进来就开始卡了?

卡卡更健康

加林森 发表于 2022-8-15 12:26

马黑黑 发表于 2022-8-15 11:22
卡卡更健康

健康得又重启电脑了。

梦油 发表于 2022-8-15 14:26

马黑黑 发表于 2022-8-15 11:22
哈哈,还木有难产

哈哈哈……几个月啦?{:4_170:}

小辣椒 发表于 2022-8-15 15:29

上来看看的,果然。黑黑又有新分享的,黑黑的速度啊。。。。。{:4_178:}

马黑黑 发表于 2022-8-15 15:41

小辣椒 发表于 2022-8-15 15:29
上来看看的,果然。黑黑又有新分享的,黑黑的速度啊。。。。。

速度一般般

马黑黑 发表于 2022-8-15 15:41

加林森 发表于 2022-8-15 12:26
健康得又重启电脑了。

重启后青春焕发

马黑黑 发表于 2022-8-15 15:42

梦油 发表于 2022-8-15 14:26
哈哈哈……几个月啦?

一般不早产也不晚产

小辣椒 发表于 2022-8-15 15:45

马黑黑 发表于 2022-8-15 15:41
速度一般般

我是赤脚都跟不上{:4_170:}
页: [1] 2 3
查看完整版本: 失真的梦