使用Canvas给DOM元素添加粒子效果

注意事项:
如支付后未自动显示完整内容,可点击“已支付?点此查询订单”进行查看。
如遇内容不符或缺失,请联系内容作者或平台客服(工作日 9:00-18:00)。

特别声明,本文根据@ZACH SAUCIER的《Adding Particle Effects to DOM Elements with Canvas》一文整理。

让我们来看看如何将<canvas>的自由度与HTML元素结合起来,使Web页面在视觉上有更好的效果。具体地说,我们将创建一个基于HTML-to-particle的效果,但同样的技术也可以用于实现很多类型的效果。

在开始之前,可以通过Repo获取源代码

创建初始的元素

首先,让我们创建一个HTML元素。这里创建了一个带有简单样式效果的按钮,事实上它可以是任何一个HTML元素。

 

建议使用Chrome、Firefox或Edge等现代浏览器查看这些Demo效果。

但是,如何让canvas“看到”这个元素,以便使用canvas操作每个像素 呢?为了实现这一点,需要对HTML元素进行快照 —— 就像“打印屏幕”一样,但只对希望在canvas中操作的特定元素(比如说按钮)进行快照。

创建canvas版本的元素

尽管浏览器到目前还无法实现这一点,但庆幸的是允许我们通过JavaScript来操作它,较为出名的html2canvas就可以。我们所要做的就是加载这个库,然后调用html2canvas(element),它将返回一个Promise以及一个canvas版本的元素。是不是很棒。

 

上面这个示例,我们有一个HTML版本和Canvas版本的按钮。我们可以使用Canvas版本作为我们的“屏幕快照”,并将其作为信息的来涨势,例如特定像素位置的颜色。

从Canvas中获取数据

为此,我们创建一个新函数来获取Canvas中特定位置的像素信息。我们也不需要显示从Canvas中得到的颜色数据,因为我们显示原始的HTML元素。

function getColorAtPoint(e) {
    // 获取鼠标点击位置的坐标
    let x = e.offsetX;
    let y = e.offsetY;

    // 获取该位置上颜色数据
    let rgbaColorArr = ctx.getImageData(x, y, 1, 1).data;

    // rgbaColorArr相关的处理
}
 

现在我们需要使用这些信息创建一个Canvas的粒子效果。

创建Canvas粒子效果

我们还没有使用Canvas来放置粒子,因为我们想要保留html2canvascanvas用于访问颜色信息。接下来创建粒子效果的函数。

var particleCanvas, particleCtx;
function createParticleCanvas() {
    // 创建用于粒子效果的Canvas
    particleCanvas = document.createElement("canvas");
    particleCtx = particleCanvas.getContext("2d");

    // Canvas的大小
    particleCanvas.width = window.innerWidth;
    particleCanvas.height = window.innerHeight;

    // Canvas的位置 
    particleCanvas.style.position = "absolute";
    particleCanvas.style.top = "0";
    particleCanvas.style.left = "0";

    // 设置Canvas在元素的上面
    particleCanvas.style.zIndex = "1001";

    // 确保它下面的其他元素是可点击的
    particleCanvas.style.pointerEvents = "none";

    // 把Canvas添加到页面中
    document.body.appendChild(particleCanvas);
}

获取坐标数据

我们还需要从本地坐标系统得到颜色相关的数据 —— 不仅仅是按钮的左上角,而且全局坐标的位置(相对整个Web页面),这样做是为了在Canvas的正确地方创建粒子。

我们可以这样做:

btn.addEventListener("click", e => {
    // 获取颜色数据
    let localX = e.offsetX;
    let localY = e.offsetY;
    let rgbaColorArr = ctx.getImageData(localX, localY, 1, 1).data;

    // 根据window获取按钮的位置
    let bcr = btn.getBoundingClientRect();
    let globalX = bcr.left + localX;
    let globalY = bcr.top + localY;

    // 使用window的位置获取颜色数据,创建一个粒子
    createParticleAtPoint(globalX, globalY, rgbaColorArr);
});

创建一个粒子原型

我们还可以创建一个基本粒子,是一个带有参数的绘图函数:

/* 圆形爆炸的粒子效果 */
var ExplodingParticle = function() {

    // 设置想要的粒子动画的时长
    this.animationDuration = 1000; // in ms

    // 设置粒子的速度
    this.speed = {
        x: -5 + Math.random() * 10,
        y: -5 + Math.random() * 10
    };

    // 粒子大小
    this.radius = 5 + Math.random() * 5;

    // 为粒子设定一个最大的生存时间
    this.life = 30 + Math.random() * 10;
    this.remainingLife = this.life;

    // 这个函数稍后将会调用动画相关的逻辑
    this.draw = ctx => {
        let p = this;

        if(this.remainingLife > 0
        && this.radius > 0) {
            // 在当前位置绘制一个圆
            ctx.beginPath();
            ctx.arc(p.startX, p.startY, p.radius, 0, Math.PI * 2);
            ctx.fillStyle = "rgba(" + this.rgbArray[0] + ','
剩余50%内容付费后可查看
看完了?还不过瘾?点此向作者提问