您的位置:首页 > Web前端 > JavaScript

js学习—在canvas画布上的粒子扩散

2017-07-29 20:42 295 查看
本次内容是在看完腾讯课堂的公开课后,结合笔记,自己在电脑上实现的效果(所以有些代码部分可能类似)。

要实现的效果:鼠标移动时,产生颜色大小不同的粒子,粒子移动直至消失。

做出来的效果和和我想要的效果不太一样,还是有些问题。接下来我们还是分析一下。
首先我们很明显的要写一个鼠标移动事件:

canvas.addEventListener('mousemove',create,false);//监听鼠标移动事件


create是鼠标移动后要做的事。

然后我们要做动画,这里采用的是requestAnimationFrame()。这是一个类似于setInterval的函数,区别在于requestAnimationFrame是不间隔执行的。

要产生粒子,即要在canvas上画圆。因为每个圆都有它的坐标,半径,颜色,还有它的运动,所以我们采用面向对象来做,如下:

function Particle(){//创建对象

}

Particle.prototype = {//实例化对象
init:function(x,y,radius){
this.x = x || 0.0;
this.y = y || 0.0;
this.radius = radius || 10;
this.color = colors[random(0,7)];
},

draw:function(){//绘制一个粒子
ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0,Math.PI*2);
ctx.fillStyle = this.color;
ctx.fill();
//Particle::update();
//console.log(x);
//console.log(y);
},

update:function(){//更新粒子的坐标与半径
this.x -= this.radius * Math.cos(Math.random()*Math.PI*2/360);
this.y -= this.radius * Math.sin(Math.random()*Math.PI*2/360);
this.radius *= 0.92;
}
}


这里稍微解释下,random(x,y)是写的一个函数,表示返回x到y之间随机的一个数。ctx是画笔,每个粒子都有自己的运动方式,这里是让x,y坐标都减少,半径以一定的比例减少。所以最后的效果是,粒子往左移动,变得越来越小。

创建画笔:

var canvas=document.querySelector('canvas');//获取canvas对象
var ctx = canvas.getContext('2d');//画布控制器


因为有许多的粒子,我们可以建一个队列,存储粒子的信息。每次鼠标移动,都有:

for(var i = 0;i < random(5,50);i++){//随机产生5-50个粒子
var particle = new Particle();//初始化对象
particle.init(x,y,k*random(1,30));//实例化,x,y为鼠标坐标
particles.push(particle);//加入到队列中
x += random(1,30) * Math.cos(Math.random()*Math.PI*2);
y += random(1,30) * Math.sin(Math.random()*Math.PI*2);
k *= 0.92;//创建的这些粒子的半径与坐标也不相同
}


效果图:



存在的问题:

1.颜色自己随便选的几个,效果可能不怎么好看。

2.本来想在鼠标位置加个高光,但是失败了,看看以后能不能找到方法。

3.本来想粒子移动时,产生随机的角度,但是没弄好。

...

可能还存在其它的问题,欢迎指出!

代码贴上:

<!--作者:natural_live 时间:2017-7-29 -->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>粒子扩散</title>
<style type="text/css">
*{margin:0px;padding:0px;}
canvas{
background:#000;
width:100;
height:100;
display:block;
}
</style>
</head>
<body>
<canvas>

</canvas>
<script type="text/javascript">
var canvas=document.querySelector('canvas');//获取canvas对象 var ctx = canvas.getContext('2d');//画布控制器

var wW = window.innerWidth;
var wH = window.innerHeight;
var colors = ['#FFB90F','#B452CD','#8B6508','#00FFFF','#DB7093','#C4C4C4','#EE3A8C','#CD7054'];
var particles = [];
//var ex,ey;

init();
function init(){//初始化画布
canvas.width = wW;
canvas.height = wH;
}

function Particle(){//创建对象
}

Particle.prototype = {//实例化对象
init:function(x,y,radius){
this.x = x || 0.0;
this.y = y || 0.0;
this.radius = radius || 10;
this.color = colors[random(0,7)];
},

draw:function(){//绘制一个粒子
ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0,Math.PI*2);
ctx.fillStyle = this.color;
ctx.fill();
//Particle::update();
//console.log(x);
//console.log(y);
},

update:function(){//更新粒子的坐标与半径
this.x -= this.radius * Math.cos(Math.random()*Math.PI*2/360);
this.y -= this.radius * Math.sin(Math.random()*Math.PI*2/360);
this.radius *= 0.92;
}
}

canvas.addEventListener('mousemove',create,false);//监听鼠标移动事件
render();

function create(event){
var eX = event.pageX;
var eY = event.pageY;
//ex = eX;
//ey = eY;
spawn(eX,eY);

}

function spawn(x,y){//粒子孵化器
var k = 1;
for(var i = 0;i < random(5,50);i++){//随机产生5-50个粒子 var particle = new Particle();//初始化对象 particle.init(x,y,k*random(1,30));//实例化,x,y为鼠标坐标 particles.push(particle);//加入到队列中 x += random(1,30) * Math.cos(Math.random()*Math.PI*2); y += random(1,30) * Math.sin(Math.random()*Math.PI*2); k *= 0.92;//创建的这些粒子的半径与坐标也不相同 }
//console.log(particles.length);
}

function render(){
ctx.clearRect(0,0,wW,wH);//橡皮擦,全部擦掉
//drawlight();
for(var i = 0,len = particles.length;i < len;i++){
particles[i].draw();//重新绘制
/*if(particles.length > 800){
particles.shift();
}*/
particles[i].update();//更新粒子信息
}
while(particles.length > 800){
particles.shift();//移除最早的粒子,使粒子数始终不超过800个
}
//console.log(particles.length);
requestAnimationFrame(render);//循环
}

/*function drawlight(){
ctx.beginPath();
ctx.arc(ex,ey,random(20,30),0,Math.PI*2);
ctx.fillStyle = '#fffffc';
ctx.fill();
}*/

function random(min,max){
return min + Math.round(Math.random()*(max - min));
}
</script>
</body>
</html>
<!--
粒子扩散。
1.创建粒子池
2.鼠标移动,获取鼠标坐标
3.粒子移动
-->
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: