Javascript Canvas 实现粒子动画效果分享

今天和大家一起分享一下用 canvas 实现粒子动画效果的实现,就像下图的效果

要实现这样的效果,我们首先需要一段包含了 canvas 的基础 html 代码

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>粒子动画效果</title>
<meta name="Keywords" content="">
<meta name="Description" content="">
<style type="text/css">
    html, body { width: 100%; height: 100%; padding: 0px; margin: 0px; }
    canvas { display: block; margin: 0px auto; background: #363636; }
</style>
</head>
<body>
    <canvas id="canvas" width="800" height="640"></canvas>
</body>
</html>

然后,我们需要在 canvas 上绘制粒子动画最终要呈现的文本内容

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

ctx.fillStyle = color;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = '100px 微软雅黑';
ctx.fillText('玩具超人', canvas.width / 2, canvas.height / 2, 560);

接下来,我们需要把文字所包含的像素点转变为粒子数组,这里需要用到一个方法 getImageData

getImageData 方法,有四个参数 x / y / width / height,分别指定要获取图像数据的起始位置和尺寸,通过此方法,我们可以获取指定区域的图像数据,数据中保存了每个像素的 RGBA 信息。

for ( var y = 0; y < canvas.height; y++ ){
	for ( var x = 0; x < canvas.width; x++ ){
		
		var pixel = (x + (y * canvas.width)) * 4;
		var sx = Math.floor(Math.random() * canvas.width);
		var sy = Math.floor(Math.random() * canvas.height);
		if ( r + g + b > 0){ // 仅当像素中包含色彩时才保存至粒子数组
			particle.push({
				sx: sx,  //  起始 x 位置
				sy: sy,  //  起始 y 位置
				cx: sx,  //  当前 x 位置
				cy: sy,  //  当前 y 位置
				ex: x,   //  结束 x 位置,及这个像素在图片文本中的原始位置
				ey: y,   //  结束 y 位置,及这个像素在图片文本中的原始位置
				td: Math.floor(Math.random() * frames),
				tc: Math.floor(Math.random() * frames),
				tt: 0,
				r: bitmap.data[pixel + 0],
				g: bitmap.data[pixel + 1],
				b: bitmap.data[pixel + 2],
				a: bitmap.data[pixel + 3]
			});
		}
	}
}

有了粒子数组,剩下的就是动画的核心,我们要让每一个像素点,以动画形式从随机位置运动至原始位置。

具体的实现方法就是通过定时器,定时重绘图片,每一次重绘根据动画进行时间实时更新粒子位置。

for (var i = 0; i < particle.length; i++){
    particle[i].tt ++;
    particle[i].cx = particle[i].sx + (particle[i].ex - particle[i].cx) / 动画时长 * 当前时间;
    particle[i].cy = particle[i].sy + (particle[i].ey - particle[i].cy) / 动画时长 * 当前时间;
}
			

现在我们就实现了一个基本的粒子动画效果,就像下图中的效果

上面虽然实现了我们要的效果,但是动画看起来比较生硬,不够自然。

这是因为我们的动画是匀速的,在现实中很少有运动是匀速的。

在动画中,为了模拟现实中的运动效果,会需要经常用到一个东西,贝塞尔曲线

贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。贝塞尔曲线是计算机图形学中相当重要的参数曲线,在一些比较成熟的位图软件中也有贝塞尔曲线工具,如PhotoShop等。在Flash4中还没有完整的曲线工具,而在Flash5里面已经提供出贝塞尔曲线工具。

根据二次贝塞尔曲线的公式,我们来实现缓动动画函数: 

function easing(s, e, t, d, p1, p2){
			
    var p0 = 0;
    var p3 = 1;
    var tp = t / d;
    var tn = 1 - t / d;

    var p = p0 * Math.pow(tn, 3) + p1 * tp * Math.pow(tn, 2) * 3 + p2 * Math.pow(tp, 2) * tn * 3 + p3 * Math.pow(tp, 3); 

    return Math.floor(s + ( e - s ) * p);
}

现在我们就实现了如开头效果的动画

知道了实现的原理,我们再想做什么效果都会很轻松了,比如,只要我们把粒子起始位置指定图片底部中间,就可以实现下面的效果

//	全部从底部进入
sx = Math.floor(canvas.width / 2);
sy = canvas.height - 10;

或者如果我们指定粒子颗粒螺旋滚动,就可以实现这样的效果

查看演示示例  ( 示例 1 )  查看演示示例  ( 示例 2 )

源代码下载

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值