canvas实现一个小星空

来源:互联网 发布:linux vim 删除光标后 编辑:程序博客网 时间:2024/05/06 16:20


     借鉴网上的canvas粒子教程,自己丰富了它的例程,然后封装了一个粒子对象,可以实现画星星和球,并且可以运动,具体功能可以自己根据需求配置相应的options即可。


 ps:个人觉得里面最比较好的一点就是用一个数组去保存每一个实例化的对象,然后通过shift()这个函数去控制画图的数量。

 

github:https://github.com/liuzaijiang/canvas-star-sky

tips:这里虽然没用到requestAnimationFrame(callback)这个函数,不过还是提一下:

         这个函数是新出来的一个专门为动画提供的一个API,这个方法调用起来的效果和setTimeout一样,只运行一次,需要我们再去调用它,不过不用设置间隔时间,它默认就是60HZ的频率,通过递归调用同一方法来不断更新画面以达到动起来的效果,但它优于setTimeout/setInterval的地方在于它是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销。




<!DOCTYPE HTML> <html lang="en">  <meta charset="utf-8">  <head><title>Draw a Circle</title>   <style type="text/css">    body {      background-color: #000000;      margin: 0px;      overflow: hidden;    }   </style>  </head> <body> <canvas id="canvas"></canvas><script>  var canvas=document.getElementById("canvas");  var context = canvas.getContext('2d');  var canvasWidth = window.screen.width;  var canvasHeight = window.screen.height;   var particles = [];  var options={"shape":"circular",//形状,目前就只有星星和圆 参数类型为 start or circular"speed":60,//越小越快,60为最佳"number":20,//越多越卡"variable_Size":true,//体积是否可变"shadow":true,//影子是否需要"shadow_degree":0.2,//0-1 越小影子越明显"x_deviation":5,//X轴的偏移,1-10最好,为0则竖直方向移动"y_deviation":5,//Y轴的偏移,1-10最好"gravity":0.4,//下落的重力加速度,当此值和y-deviation同时为0的时候才会向水平方向移动"radius":10,//当形状为星星时的半径"angle":10,//当形状为星星时的旋转角度"variable_angle":true,//当形状为星星时是否旋转"color":"rgba(255, 255, 255,.8)",//物体的填充颜色"border-color":"#e03"//物体的边框颜色  }    init();    function init() {    canvas.width = canvasWidth;    canvas.height = canvasHeight;     setInterval(loop, options.speed);  }    function loop(){  if(!options.shadow)  {context.clearRect(0,0,canvasWidth, canvasHeight);  }  else{context.fillStyle = "rgba(0,0,0,"+options.shadow_degree+")";        context.fillRect(0,0, canvasWidth, canvasHeight);  }     //在一些随机位置产生并画粒子。   var particle = new Particle(Math.random()*canvasWidth, Math.random()*canvasHeight);   particles.push(particle);     for (i=0; i<particles.length; i++) {     var particle = particles[i];      particle.render(context);      particle.update();  }    if (particles.length>options.number){     particles.shift();//shift() 方法用于把数组的第一个元素从其中删除    }  }    function Particle (xPos, yPos) {    this.xPos = xPos;   this.yPos = yPos;   this.xVel = options.x_deviation;   this.yVel = options.y_deviation;   this.gravity = options.gravity;      this.render = function(context){if(options.shape=="start"){var R=options.variable_Size==true?Math.random() * options.radius:options.radius;var a=options.variable_angle==true?Math.random() * options.angle:options.angle;drawStart(context,this.xPos,this.yPos,R,a);}else if(options.shape=="circular"){var R=options.variable_Size==true?Math.random() * options.radius:options.radius;drawCircular(context,this.xPos,this.yPos,R);}   }      this.update = function(){      this.yVel += this.gravity;     this.yPos += this.yVel;     this.xPos += this.xVel;  } } function drawStart(ctx,x,y,R,a){ctx.beginPath();for(var i=0;i<5;i++){ctx.lineTo(Math.cos( (18 + i * 72 - a) / 180 * Math.PI) * R + x,           -Math.sin( (18 + i * 72 - a) / 180 * Math.PI) * R + y);ctx.lineTo(Math.cos( (54 + i * 72 - a) / 180 * Math.PI)* R / 2+x,  -Math.sin( (54 + i * 72 - a) / 180 * Math.PI)* R / 2+y);}ctx.closePath();ctx.fillStyle=options.color;ctx.strokeStyle=options.border;ctx.stroke();ctx.fill();}function drawCircular(ctx,x,y,R){ctx.beginPath();ctx.fillStyle = options.color;ctx.strokeStyle=options.border;ctx.arc(x,y,R,0, Math.PI*2, true);ctx.stroke();ctx.fill();}</script></body></html> 



0 0