本例中的粒子就是實實在在的像素,由js代碼在canvas上動態生成的像素點!這些像素點通過一個運動方法有規律地動了起來。透過這個思路,我們可以想到很多很炫的效果,但是這個性能有待考察。實驗證明,動態控制太多像素點的話絕對會卡的!在做效果方面有經驗的朋友,請提出寶貴意見!這個思路走得通么?
<!doctype html> <html> <head> <title>智能粒子</title> <meta charset='utf-8' /> <style type="text/css"> body{background-color:black;} #Canvas{margin:50px auto;display:block;border:1px red solid;} </style> </head> <body> <canvas width='300' height='300' id='Canvas'>您的瀏覽器不支持canvas</canvas> </body> <script type="text/javascript"> /* *用面向對象編程方法實現的粒子 *by @謝帥shawn */ //初始化畫布 var canvas=document.getElementById('Canvas'); var ctx=canvas.getContext('2d'); /* *創建一個圓環類Circle,智能圓環的模型 */ var Circle=function(x,y,speeds){ this.x=x; this.y=y; this.speed=speeds; } Circle.prototype={ //draw方法,畫出像素 draw:function(){ var n=this.y*imgdata.width+this.x; var i=n*4; data[i]+=207; data[i+1]+=14; data[i+2]+=139; data[i+3]+=150; }, //move方法,圓環坐標自加速度,並執行draw方法 move:function(){ this.x+=this.speed.speedX; this.y+=this.speed.speedY; this.draw(); } } /* *創建一個Frame幀類,管理所有circles實例,實現畫布的渲染 */ var Frame=function(){ this.circles=[]; this.sint=null; } Frame.prototype={ //star開始定時器,循環調用渲染方法 star:function () { this.lastFrame=(new Date()).getTime(); this.sint=setInterval((function(progra){ return function(){progra.render();} })(this),30); }, //render渲染方法 render:function () { //清除上一幀 ctx.clearRect(0,0,canvas.width,canvas.height); imgdata=ctx.getImageData(0,0,canvas.width,canvas.height); data=imgdata.data; //實時輸出幀率 this.nowFrame=(new Date()).getTime(); this.ftp=1000/(this.nowFrame-this.lastFrame); this.lastFrame=this.nowFrame; console.log(this.ftp); //調用每個實例circle的運動方法,監聽circle坐標實現碰壁反彈效果 for (i in this.circles) { this.circles[i].move(); if(this.circles[i].x>canvas.width || this.circles[i].x<0){ this.circles[i].speed.speedX=-this.circles[i].speed.speedX; //delete this.circles[i];可以實現碰壁消失的效果,delete可刪除實例 } if(this.circles[i].y>canvas.height|| this.circles[i].y<0) this.circles[i].speed.speedY=-this.circles[i].speed.speedY; } ctx.putImageData(imgdata,0,0); } } /* *Main */ //創建一個幀實例fra var fra=new Frame(); //創建100個圓環實例circles【i】 for (var i=0; i<20000; i++) { //輸入speed屬性 var speed={ speedX:Math.floor(Math.random()*3), speedY:Math.floor(Math.random()*10+4) } //創建實例 var circle=new Circle(Math.floor(Math.random()*canvas.width/2),Math.floor(Math.random()*canvas.height/2),speed); fra.circles[i]=circle; } //開始渲染 fra.star(); </script> </html>