一般来说,用canvas做粒子都要经过几个步骤
1 先初始化画布的大小,画布的环境
2 计算好各个点对象的位置,半径大小,颜色
3 清空画布
4将所有的粒子对象画在指定的位置
5循环到步骤2
粒子中,静态的用粒子组成一条抛物线
在这个例子中,咱们定义的画布大小等于屏幕大小,所以写了一个函数来返回屏幕的高度和宽度:
var Utils={
getWindowSize: function() {
return {
width: this.getWindowWidth(),
height: this.getWindowHeight()
};
},
getWindowWidth: function() {
//浏览器的兼容
return window.innerWidth || document.documentElement.clientWidth;
},
getWindowHeight: function() {
//浏览器的兼容
return window.innerHeight || document.documentElement.clientHeight;
}
};
通过调用上面的函数,咱们来对画布的环境进行初始化:
init:function () {
var windowSize = Utils.getWindowSize(); // 获取窗口大小
this.canvas = document.getElementById('canvas');
this.ctx = this.canvas.getContext('2d');
if(this.ctx) {
// 设置canvas的宽高
this.canvas.width = windowSize.width;
this.canvas.height = windowSize.height;
//粒子的个数,也是x值
var times = 100;
var tem;
this.particles = [];
while(times--) {
tem=times*times/30;
this.particles.push(new Particle({
//粒子对象集合
x: times,
y: tem,
color: 'black',
scale: 1,
radius: 3
}));
}
}
},
在上面函数里,我们已经得出了粒子集合的位置,大小,颜色,所以只要将他们画在正确的位置即可,为此,我们用组合构造对象模式来构造了粒子对象,用粒子对象的原型函数来实现画粒子:
function Particle(infor) {
this.x=infor.x;
this.y=infor.y;
this.color=infor.color;
this.scale=infor.scale;
this.radius=infor.radius;
}
if(typeof Particle.prototype.draw==='undefined'){
Particle.prototype.draw = function(ctx){
ctx.beginPath();
ctx.fillStyle=this.color;
ctx.strokeStyle=this.color;
ctx.arc(this.x, this.y, this.radius * this.scale, 0, 2 * Math.PI, false);
ctx.closePath();
ctx.fill();
}
}
接下来就是先清空画布,所有的粒子集合里的粒子调用粒子对象的原型函数:
draw: function() {
var _this = this;
// 每次重新绘制之前,需要先清空画布,把上一次的内容清空
var windowSize = Utils.getWindowSize();
this.ctx.clearRect(0, 0, windowSize.width, windowSize.height);
// 绘制粒子
this.particles.forEach(function (item) {
item.draw(_this.ctx);
});
}
然后让window.onload调用初始化函数和上面的函数,就能画出一条模拟抛物线的曲线:
window.οnlοad=function () {
ParticleEffect.init();
ParticleEffect.draw();
}
整个代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>努力画一条抛物线</title>
</head>
<body>
<canvas id="canvas">
<p>
你的浏览器不让我画画
</p>
</canvas>
<script>
function Particle(infor) {
this.x=infor.x;
this.y=infor.y;
this.color=infor.color;
this.scale=infor.scale;
this.radius=infor.radius;
}
if(typeof Particle.prototype.draw==='undefined'){
Particle.prototype.draw = function(ctx){
ctx.beginPath();
ctx.fillStyle=this.color;
ctx.strokeStyle=this.color;
ctx.arc(this.x, this.y, this.radius * this.scale, 0, 2 * Math.PI, false);
ctx.closePath();
ctx.fill();
}
}
var Utils={
getWindowSize: function() {
return {
width: this.getWindowWidth(),
height: this.getWindowHeight()
};
},
getWindowWidth: function() {
//浏览器的兼容
return window.innerWidth || document.documentElement.clientWidth;
},
getWindowHeight: function() {
//浏览器的兼容
return window.innerHeight || document.documentElement.clientHeight;
}
};
var ParticleEffect={
ctx:null,
canvas: null,
init:function () {
var windowSize = Utils.getWindowSize(); // 获取窗口大小
this.canvas = document.getElementById('canvas');
this.ctx = this.canvas.getContext('2d');
if(this.ctx) {
// 设置canvas的宽高
this.canvas.width = windowSize.width;
this.canvas.height = windowSize.height;
//粒子的个数,也是x轴
var times = 100;
var tem;
this.particles = [];
while(times--) {
tem=times*times/30;
this.particles.push(new Particle({
//粒子对象集合
x: times,
y: tem,
color: 'black',
scale: 1,
radius: 3
}));
}
}
},
draw: function() {
var _this = this;
// 每次重新绘制之前,需要先清空画布,把上一次的内容清空
var windowSize = Utils.getWindowSize();
this.ctx.clearRect(0, 0, windowSize.width, windowSize.height);
// 绘制粒子
this.particles.forEach(function (item) {
item.draw(_this.ctx);
});
}
}
window.οnlοad=function () {
ParticleEffect.init();
ParticleEffect.draw();
}
</script>
</body>
</html>
要是需要粒子的随机的飘动,增加定时刷新函数,计算x方向,y方向的速度,做好临界检测即可
move:function () {
var windowSize = Utils.getWindowSize();
this.particles.forEach(function(item){
item.x += item.vx;
item.y += item.vy;
if((item.x - item.radius < 0) || (item.x + item.radius > windowSize.width)) {
item.vx *= -1;
}
// 如果粒子碰到了上墙壁或下墙壁,则改变粒子的纵向运动方向
if((item.y - item.radius < 0) || (item.y + item.radius > windowSize.height)) {
item.vy *= -1;
}
});
}
具体动态图请看另一篇<<用canvas和css做动态雪花和雪人>>https://mp.csdn.net/postedit/79929119