Canvas 放烟花合集 -- 用粉丝头像做成烟花绽放🧨

1,460 阅读3分钟

💞“我对着烟花许愿,希望你永远在我身边

🌈 “凑不够满天星辰那就去看看烟花吧,人间烟火气,最抚凡人心

🎨小tips:喜欢的可以关注博主私信代码噢~

⚡也可以看看前面两篇烟花噢

🚩 邀你看一场浪漫的烟火 -- canvas放烟花

gif4 🚩 你还在用canvas画爱心吗?看我让你的名字在星空绽放

name

本文实现效果

图片

今天要实现的效果是将图片做成烟花绽放,非常感谢大家的支持~

实现效果

这个小demo实现的方法和文字烟花实现的方法大致是相同的~

1. 将图片绘制在画布上

首先我们需要将需要制作成烟花的图片绘制在画布上

特别注意

  1. 由于这种图片是用来取色用的底图所以我们并不希望这张图片被用户看到,因此我们可以将这张图片渲染在新的画布上,烟花渲染在不同的画布上,这样上面画布就可以盖住下面的画布,这张底图也不会被看见
  2. 由于图片的加载需要一定的时间,所以我们对图片操作的代码需要写在回调函数里面,不然图片可能会未加载而报错
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)
}

2. 获取像素点信息

这一步的目的是获取到图片每个像素的颜色,这样我们就可以通过这些像素点合成一张图片,也可以排除掉一些像素点,筛出想要的图形

let imgData = inCtx.getImageData(0, 0, imgWidth, imgHeight)

在前面的代码中我们在 (0,0) 的位置绘制了图片,我们通过getImageData将这块区域的像素信息取出来,返回结果是包含像素点信息的对象,类似于下图,详细可看上篇文章

对象

3. 给烟花粒子添加属性

我们需要实现的烟花效果由许许多多的烟花粒子组成,每个粒子都有它自己的颜色和它的运动轨迹,实现图片烟花的关键就在于它的颜色需要正确,我们可以通过遍历像素点信息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)
    }
}

在遍历的过程中因为我们需要实现粒子的效果,因此需要隔几个像素点在取一个,这样绘制出来图像就是粒子状的,我们将烟花粒子渲染即可

image-20210623212834848

4. 渲染烟花粒子

渲染的方法就是在粒子该在的位置上画个小圆就可!颜色,位置,半径等信息利用先前给粒子添加的属性,特别需要颜色的书写格式噢~

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();

5. 实现烟花粒子动画

我们需要在每次渲染时将烟花粒子当前的位置向下偏移,透明度降低实现烟花降落殆尽的效果,当透明度将低于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;
}

6. 实现拖尾效果

为了让烟花更加的真实,我们需要给烟花粒子添加拖尾的效果,在每一次重新渲染之前给新建一个蒙层从而实现拖尾的效果

ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = 'rgba(0,0,0,' + 10 / 100 + ')';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'lighter';

烟花合集

邀你看一场浪漫的烟火 -- canvas放烟花

还在用canvas画格子吗?文字烟花效果更不错噢

这两篇文章都是实现不同的烟花效果噢,大家可以一起学习一下噢!需要源码可以关注私信博主噢~


烟花的几篇文章就到这里了,期待博主的下个专题吧~

一起学习,共同进步!