Skip to content

Canvas粒子汇聚动画

Posted on:2022年9月11日 at 06:06

img

前期准备

const canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const ctx = canvas.getContext("2d");
const img = new Image();
img.src = "../image/队徽_black.png";
// img.src = "../image/test.png";

// 储存图片像素信息
let imgData = null;
let imgW = 600;
let imgH = null;
let flag = true;
let pointArr = [];

定义粒子类

class Point {
  constructor(size, w, h) {
    // 保留图像初始位置
    this.orw = w;
    this.orh = h;
    // 随机位置
    this.x = Math.random() * canvas.width;
    this.y = Math.random() * canvas.height;
    this.size = size;
    this.w = w;
    this.h = h;
    this.opacity = 0;
  }
}

函数绘图原理

canvas有一个叫getImageData的接口,通过该接口可以获取到画布上指定位置的全部像素的数据

我们将ImageData打印 结果如下

img

其中最重要的数据就是data数组

每一个色值占据data数组索引的一个位置,一个像素有个4个值(R、G、B、A)占据数组的4个索引位置。根据数列规则可以知道,要获取第n个位置(n从1开始)的R、G、B像素信息就是:

Rn= (n-1)*4

Gn = (n-1)*4+1

Bn = (n-1)*4+2

粒子绘图核心函数

function pointInit(imgData) {
  const gap = 4;
  for (var h = 0; h < imgH; h += gap) {
    for (var w = 0; w < imgW; w += gap) {
      var position = (imgW * h + w) * 4;
      var r = imgData[position],
        g = imgData[position + 1],
        b = imgData[position + 2];
      // 当rgb都为0时,说明颜色值为黑色
      if (r + g + b === 0) {
        pointArr.push(new Point(1, w, h));
      }
    }
  }
}

添加引力斥力后效果

完整代码

Flame-Y/canvas-Particle-gathering (github.com)