?“我对着烟花许愿,希望你永远在我身边”
? “凑不够满天星辰那就去看看烟花吧,人间烟火气,最抚凡人心”
?小tips:喜欢的可以关注博主私信代码噢~ ⚡也可以看看前面两篇烟花噢
今天要实现的效果是将图片做成烟花绽放,非常感谢大家的支持~
这个小demo实现的方法和文字烟花实现的方法大致是相同的~
首先我们需要将需要制作成烟花的图片绘制在画布上
特别注意:
let img1 = new Image();
//随机取一张图片
img1.src = Math.floor(Math.random()*9 +1) + '.jpg'
// 等待图片加载完毕后绘制图片
img1.onload = function () {
let imgWidth = 400
let imgHeight = 400
inCtx.drawImage(img1, 0, 0, imgWidth, imgHeight)
}
这一步的目的是获取到图片每个像素的颜色,这样我们就可以通过这些像素点合成一张图片,也可以排除掉一些像素点,筛出想要的图形
let imgData = inCtx.getImageData(0, 0, imgWidth, imgHeight)
在前面的代码中我们在 (0,0) 的位置绘制了图片,我们通过getImageData
将这块区域的像素信息取出来,返回结果是包含像素点信息的对象,类似于下图,详细可看上篇文章
我们需要实现的烟花效果由许许多多的烟花粒子组成,每个粒子都有它自己的颜色和它的运动轨迹,实现图片烟花的关键就在于它的颜色需要正确,我们可以通过遍历像素点信息imageData
对象,将该像素点的颜色作为烟花粒子颜色存储起来,也就是将图片一点点复制的过程
for (let h = 0; h < imgHeight; h += 8) {
for (let w = 0; w < imgWidth; w += 8) {
let position = (imgWidth * h + w) * 4;
// 返回的数组是rgba的方式存储
let r = imgData.data[position],
g = imgData.data[position + 1],
b = imgData.data[position + 2],
a = imgData.data[position + 3];
if (r + g + b == 0) {
continue
}
let firework = {};
firework.x = x;
firework.y = y;
firework.fx = x + w - imgWidth / 2;
firework.fy = y + h - imgHeight / 2;
firework.size = 1; // Math.floor(Math.random() * 2) + 1
firework.speed = 5;
firework.alpha = 1;
firework.r = r
firework.g = g
firework.b = b
firework.color = "rgba(" + r + "," + g + "," + b + "," + a + ")"
fireworks.push(firework)
}
}
在遍历的过程中因为我们需要实现粒子的效果,因此需要隔几个像素点在取一个,这样绘制出来图像就是粒子状的,我们将烟花粒子渲染即可
渲染的方法就是在粒子该在的位置上画个小圆就可!颜色,位置,半径等信息利用先前给粒子添加的属性,特别需要颜色的书写格式噢~
ctx.beginPath();
ctx.arc(firework.x, firework.y, firework.size, Math.PI * 2, false);
// 结束
ctx.closePath();
ctx.fillStyle = "rgba(" + firework.r + "," + firework.g + "," + firework.b + "," + firework.alpha + ")"
ctx.fill();
我们需要在每次渲染时将烟花粒子当前的位置向下偏移,透明度降低实现烟花降落殆尽的效果,当透明度将低于0时移出粒子
firework.x += (firework.fx - firework.x) / 10;
firework.y += (firework.fy - firework.y) / 10 -(firework.alpha - 1.8)*firework.speed;
firework.alpha -= 0.02;
// 如果透明度小于0就删除这个粒子
if (firework.alpha <= 0) {
fireworks.splice(i, 1);
// 跳过这次循环,不进行绘制
continue;
}
为了让烟花更加的真实,我们需要给烟花粒子添加拖尾的效果,在每一次重新渲染之前给新建一个蒙层从而实现拖尾的效果
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = 'rgba(0,0,0,' + 10 / 100 + ')';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'lighter';
这两篇文章都是实现不同的烟花效果噢,大家可以一起学习一下噢!需要源码可以关注私信博主噢~
烟花的几篇文章就到这里了,期待博主的下个专题吧~
一起学习,共同进步!