失真的梦
<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>
代码分享(全):
<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:42 编辑
本帖主要演示两个内容:
一、原生JS批量预加载图片
画布 drawImage() 方法,图片的来源是img标签、视频或image()对象。根据帖子情况,需要 image() 对象实现,进而需要图片批量预加载。帖子 preload 对象即是,分两部分。
二、canvas 画布 clip() 方法
clip() 是画布的裁剪方法,使用它可以对目标图形对象进行遮罩。本帖使用透明色遮罩(其他颜色也行,透明色能与帖子的背景融合),并动态更改遮罩的尺寸,然后在遮罩层上绘制图片(图片动态从预加载图片中选取)。
本帖对图片尺寸的要求:宽高 1:1 或接近。 小技巧:
clip() 尺寸的变更有两个来回的变化,往大里的变化尺寸设定为 250,原因是图片在画布上的尺寸宽度为500,用其一半可以令往大里的变化结束时保持图片的圆形形态。往小里的变化终结数是0,当是0时,令画布更换图片的 idx(即图片索引),达到换图的目的。 解释一下与图片预加载相关的内容:
在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 原理相似。 都说梦由心生,依看梦生于编程,眼里美媚见多了,自然信手拈来。{:4_173:} 樵歌 发表于 2022-8-15 08:02
都说梦由心生,依看梦生于编程,眼里美媚见多了,自然信手拈来。
编程就是织梦 漂亮的制作。真是有点做梦的感觉。我怎么进来就开始卡了? 新作层出不穷、目不暇接。黑黑朋友“肚子”里的宝贝可真不少。{:4_178:} 马黑黑 发表于 2022-8-15 08:05
编程就是织梦
完全同意{:4_174:} 樵歌 发表于 2022-8-15 10:55
完全同意
{:5_108:} 梦油 发表于 2022-8-15 10:40
新作层出不穷、目不暇接。黑黑朋友“肚子”里的宝贝可真不少。
哈哈,还木有难产{:5_106:} 加林森 发表于 2022-8-15 10:33
漂亮的制作。真是有点做梦的感觉。我怎么进来就开始卡了?
卡卡更健康 马黑黑 发表于 2022-8-15 11:22
卡卡更健康
健康得又重启电脑了。 马黑黑 发表于 2022-8-15 11:22
哈哈,还木有难产
哈哈哈……几个月啦?{:4_170:} 上来看看的,果然。黑黑又有新分享的,黑黑的速度啊。。。。。{:4_178:} 小辣椒 发表于 2022-8-15 15:29
上来看看的,果然。黑黑又有新分享的,黑黑的速度啊。。。。。
速度一般般 加林森 发表于 2022-8-15 12:26
健康得又重启电脑了。
重启后青春焕发 梦油 发表于 2022-8-15 14:26
哈哈哈……几个月啦?
一般不早产也不晚产 马黑黑 发表于 2022-8-15 15:41
速度一般般
我是赤脚都跟不上{:4_170:}