canvas效果
粒子系统
在粒子系统中,最长出现的概念就是向量
,粒子
,粒子系统
。我们可以把它们各封装成一个类,但根据不同场景也可以把其中一个简化为对象直接作为另一种的一个变量。
向量是每个粒子位置的关键,他定义了粒子坐标位置,以及对坐标位置的操作的方法。粒子是最小的移动元素,它定义了自己的在坐标系中的位置,速度,生命及大小颜色等属性,当然还有绘制规则。粒子系统,在他里面会定义粒子集,并且定了他们的行动和杀死指令,控制他们的渲染
常见的粒子系统封装如下
//向量
Vector = function (x, y) {
this.x = x;
this.y = y;
this.add=function (v) {
return new Vector(this.x + v.x, this.y + v.y); }
};
//粒子
Particle = function(position, velocity, life, color, size) {
this.position = position;
this.velocity = velocity;
this.age = 0;
this.life = life;
this.color = color;
this.size = size;
};
//粒子系统
function ParticleSystem() {
// Private fields
var particles = new Array();
// Public fields
}
常用到的方法
canvas上的方法
toDataURL("image/png")
:将画布内容转化为base64
格式的图片,可直接赋值给image对象的src
context上的方法
getImageData(0,0,canvas.width,canvas.height)
:将范围内的图画数据取出,对象中包括width、height、data。data数据格式是每个像素的rgba
ctx.putImageData(imgData,0,0)
:将值重新付给canvas绘制
以下是方法演示
var imgData=ctx.getImageData(0,0,c.width,c.height);
for (var i=0;i<imgData.data.length;i+=4)
{
imgData.data[i]=255-imgData.data[i];
imgData.data[i+1]=255-imgData.data[i+1];
imgData.data[i+2]=255-imgData.data[i+2];
imgData.data[i+3]=255;
}
ctx.putImageData(imgData,0,0);
利用image每格像素
我们将实现一个像素零散聚合成自己名字的动画
这个动画我们使用面向过程的思想去完成,那么他的实现过程如下
- 画出目标图像
- 筛选出需要移动的像素
- 动画
在这种方法下,我们主要存储的数据是有颜色的格子,因为如果存储所有的格子将极其消耗内存。我们将这些有颜色的像素格子看作是一个粒子,整个画布是粒子系统。
以下为零散聚合示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
body {
color: aqua;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')
var data = []
var dataObj = []
var dataScreen = []
canvas.width = 800
canvas.height = 400
var id = 0;
init()
choose(0.3)
animate(id, 20)
//画出字样、收集数据
function init() {
ctx.font = '200px Arial'
ctx.fillStyle = 'aqua'
ctx.textBaseline = 'top'
ctx.fillText('夏炜轩', 0, canvas.height / 3)
data = ctx.getImageData(0, 0, canvas.width, canvas.height).data
var i = 0, n = 0;
var index=0;
for (var row = 0; row < canvas.height; row++) {
for (var col = 0; col < canvas.width; col++) {
n = row * canvas.width + col//第几个点
i = n * 4//data中对应位置
if (data[i + 3] > 0) {
dataObj[index++] = {
x: col,
y: row,
color: `rgba(${
data[i]},${
data[i + 1]},${
data[i + 2]},${
data[i + 3]})`,
red: data[i],
green: data[i + 1],
blue: data[i + 2],
randomX: Math.floor(Math.random() * canvas.height),
randomY: Math.floor(Math.random() * canvas.width),
}
}
}
}
}
//筛选数据
function choose(op) {
var n = Math.floor(dataObj.length * op);
for (var i = 0; i < n; i++) {
dataScreen.push(dataObj.splice(Math.floor(Math.random() * dataObj.length), 1)[0])
}
}
//聚合动画
function animate( id, n) {
id = setInterval(function () {
ctx.clearRect(0, 0, canvas.width, canvas.height)
for (var i = 0; i < dataScreen.length; i++) {
var temp = dataScreen[i];
var x0