canvas——粒子系统(1)

这个动画在很早之前就见过,当时就没迷住了。最近在学canavs动画,动手实现了一下。代码在这里。展示效果在这里。

这属于粒子系统的一种,粒子系统就是需要管理一堆粒子嘛,动画实现的关键在于,遍历这些粒子,并更新它们的位置。

粒子

每个粒子都需要包含自己的横纵坐标想x、y,半径r,各分量上的加速度ax、ay,速度vx、vy,还有所属的场景owner,这里的粒子加速度均为0。

// 父类class Sprite {
    constructor(args={}) {
        this.x = args.x || 0;
        this.y = args.y || 0;
        this.vx = args.vx || 0;
        this.vy = args.vy || 0;
        this.ax = args.ax || 0;
        this.ay = args.ay || 0;
    }

    moveTo(x, y) {
        this.x = x;
        this.y = y;
    }

    update() {
        this.vx += this.ax;
        this.vy += this.ay;

        this.x += this.vx;
        this.y += this.vy;
    }

    render() {
        return true;
    }
}
// 粒子
class Particle extends Sprite{
    constructor(args) {
        super(args);
        this.owner = args.owner;
        this.r = args.r || 10;
        this.color = args.color || ‘black‘;

        this.adjust = this.adjust.bind(this);
    }

    update() {
        super.update();
        if(this.x < this.r || this.x + this.r > this.owner.w) {
            this.vx *= -1;
            this.x = this.adjust(0, this.owner.w, this.x);
        }

        if(this.y < this.r || this.y + this.r > this.owner.h) {
            this.vy *= -1;
            this.y = this.adjust(0, this.owner.h, this.y);
        }
    }

    render(ctx) {
        ctx.beginPath();
        ctx.fillStyle = this.color;
        ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
        ctx.closePath();
        ctx.fill();
    }

    adjust(min, max, v) {
        return v > max ? max : (v < min ? min : v);
    }
}

父类的update()中用于改变对象的坐标,particle类的update()在调用了父类的update方法之后,进行边界检测。

边界检测

边界检测属于碰撞检测的一种。在改变粒子位置之后,对粒子进行边界检测,防止粒子逃出canvas哦。本例中的粒子是圆形的,可以通过粒子中心点与边界之间的距离进行判断,若小于粒子自身半径,则对粒子坐标进行修正,确保粒子始终位于canvas中。

/*
 * this.x 粒子横坐标
 * this.y 粒子纵坐标
 * this.r 粒子半径
 * this.owner.w 粒子所在场景(canvas)宽度
 * this.owner.h 粒子所在场景(canvas)高度
 */
if(this.x < this.r || this.x + this.r > this.owner.w) {
    this.vx *= -1;
    this.x = this.adjust(0, this.owner.w, this.x);
}

if(this.y < this.r || this.y + this.r > this.owner.h) {
    this.vy *= -1;
    this.y = this.adjust(0, this.owner.h, this.y);
}

当粒子坐标超出边界时,使用adjust()重置粒子坐标,确保粒子在canvas内。

adjust(min, max, v) {
    return v > max ? max : (v < min ? min : v);
}

粒子系统

粒子系统就是对粒子进行管理的。

this.nodes = [];   // 保存粒子
this.edges = [];   // 粒子成对保存,用于连线

存储edges时,使用双层循环,内循环n的从i + 1开始,避免重复保存。

for(let i = 0, len = this.nodes.length; i < len; ++i) {
    for(let n = i + 1; n < len; ++n) {
        this.edges.push({
            from: this.nodes[i],
            to: this.nodes[n]
        })
    }
}

计算两个粒子之间的距离。

lengthOfEdge(edge) {
    let w = Math.abs(edge.from.x - edge.to.x),
        h = Math.abs(edge.from.y - edge.to.y);
    return Math.sqrt(w * w + h * h);
} 

粒子间距离越短,连线越粗、越深。

this.ctx.lineWidth = (1 - l / this.threshold) * 2.5;
this.ctx.globalAlpha = 1 - l / this.threshold;

超出一定距离就不连线。

let l = this.lengthOfEdge(edge);
    if(l > this.threshold) {
    return;
}

鼠标事件

这里为了与用户有互动,加入了鼠标事件。当鼠标在canvas内移动时,第一个粒子nodes[0]的跟随鼠标移动。当鼠标静止或者在canvas外时,则按照原来的速度进行移动。

mouserEnter(e) {
    this.mouse = this.nodes[0];
}

mouseMove(e) {
    this.mouse.x = e.offsetX;
    this.mouse.y = e.offsetY;
}

mouseLeave() {
    this.mouse = null;
}

至于动画的更新,建议使用requestAnimationFrame()。

时间: 2024-10-08 00:26:30

canvas——粒子系统(1)的相关文章

canvas粒子系统的构建

前面的话 本文将从最基本的imageData对象的理论知识说开去,详细介绍canvas粒子系统的构建 效果演示 下面是实例效果演示,博文结尾有全部源码 imageData 关于图像数据imageData共有3个方法,包括getImageData().putImageData().createImageData() [getImageData()] 2D上下文可以通过getImageData()取得原始图像数据.这个方法接收4个参数:画面区域的x和y坐标以及该区域的像素宽度和高度 例如,要取得左上

HTML5 canvas粒子系统打造逼真飘雪特效

这是一款效果非常炫和逼真的HTML5 canvas飘雪效果.该飘雪效果使用canvas的粒子系统来制作,使用粒子来制作各种雪花效果.它的背景使用CSS来渲染,你可以为这个下雪效果更换背景颜色或使用背景图片. 在线演示:http://www.htmleaf.com/Demo/201503191547.html 下载地址:http://www.htmleaf.com/html5/html5-canvas/201503191546.html

canvas动画——粒子系统(1)

这个动画在很早之前就见过,当时就没迷住了.最近在学canavs动画,动手实现了一下.代码在这里.展示效果在这里. 这属于粒子系统的一种,粒子系统就是需要管理一堆粒子嘛,动画实现的关键在于,遍历这些粒子,并更新它们的位置. 粒子 每个粒子都需要包含自己的横纵坐标想x.y,半径r,各分量上的加速度ax.ay,速度vx.vy,还有所属的场景owner,这里的粒子加速度均为0. // 父类class Sprite { constructor(args={}) { this.x = args.x || 0

canvas绘图基础及基于粒子系统的雪花飘落

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> </head> <body> <script> //全局变量 var canvas = document.createElement('canvas'); var canvasContext

Three.js开发指南---粒子和粒子系统(第七章)

使用粒子可以很容易的创建很多细小的物体,例如雨滴雪花等 本章主要内容: 1 使用ParticleBasicMaterial(基础粒子材质)来创建和设计粒子 2 使用ParticleSystem来创建一个粒子集合 3 使用已有的几何体来创建一个粒子系统 4 让粒子和粒子系统动起来 5 用纹理给粒子造型 6 使用ParticleCanvasMaterial在画布上为粒子造型 名称 描述 Sprite粒子 参数是material,生成的sprite可以设置position和scale等属性直接添加到场

粒子和粒子系统

1.粒子材质和粒子几何体 创建粒子系统的点,可以存放在Geometry几何体中.使用Geometry的vertices保存点.colors保存点的颜色.但我们必须使用粒子的专用材质对象PointCloudMaterial(原名叫做ParticleBasicMaterial)设置材质.包含的属性如下列表: 名称/描述 color/PointCloud对象中所有粒子的颜色.如果vertexColors设置为true,而且也指定了几何体的colors属性,那么该属性被忽略 map/可以在粒子上应用某种

HTML5新增Canvas标签及对应属性、API详解(基础一)

知识说明: HTML5新增的canvas标签,通过创建画布,在画布上创建任何想要的形状,下面将canvas的API以及属性做一个整理,并且附上时钟的示例,便于后期复习学习!Fighting! 一.标签原型 <canvas width=”1000” height=”1000” id=”myCanvas”> 您的浏览器版本过低,不支持HTML5新增的canvas标签. </canvas> 使用js获取该画布,并指定对象 <script> Var canvasID = doc

移动端canvas抗锯齿

未抗锯齿效果图: 加入抗锯齿代码效果: var Game = function(){ var H = document.documentElement.clientHeight || document.body.clientHeight; var W = document.documentElement.clientWidth || document.body.clientWidth; this.canvas = document.getElementById("canvas"); t

Canvas

仿百度贴吧客户端 loading 小球 前言 几天前在简书上看到在一篇文章<Android仿百度贴吧客户端Loading小球>,看了一下作者,他写了两个好玩的 demo,效果图如下: 今天趁着周末有空,用 H5 的 Canvas 仿了一下.这篇文章只实现第一个效果图.这是我实现的效果: 实现原理 实现原理是参考简书的那篇文章,这里不再复述.现在我们来一步一步实现这样的效果. 第零步:画一个圆 源码如下: <!DOCTYPE html> <html> <head&g