不断产生粒子并使它们遵循相同的路径

时间:2013-11-12 13:17:54

标签: javascript jquery html html5 html5-canvas

我正在尝试生成一个对象(像粒子一样)并使其遵循特定的路径。我已经创建了一个粒子并使其遵循我想要的路径。我的问题是我无法按照相同的路径连续创建粒子。

这是我想要遵循的路径和代码:

var requestAnimationFrame = window.mozRequestAnimationFrame    ||
             window.webkitRequestAnimationFrame ||
               window.msRequestAnimationFrame     ||
              window.oRequestAnimationFrame
            ;  
var pathArray=[];
pathArray.push({x:490,y:290});
pathArray.push({x:330,y:380});
pathArray.push({x:110,y:300});
//pathArray.push({x:570,y:40});
//pathArray.push({x:570,y:175});
var polypoints = makePolyPoints(pathArray);

var width = 10;
var height = 10;
var position = 0;
var speed = 2;
//var rotation = 0;
//var rotationSpeed = 0.1;
var TimeInterval;

function anim() {

  TimeInterval=setTimeout(function () {
           requestId=requestAnimationFrame(anim);

        // calc new position
        position += speed;
        if (position > polypoints.length) {
            return;
        }
        var pt = polypoints[position];

        //rotation += rotationSpeed;

        // draw
        ctx2.clearRect(0, 0, layer1.width,layer1.height);
        ctx2.save();
        ctx2.beginPath();
        ctx2.translate(pt.x, pt.y);
        //ctx2.rotate(rotation);
        ctx2.rect(-width / 2, -height / 2, 10, 10);
        ctx2.fill();
        ctx2.stroke();
        ctx2.restore();

    }, 100);
}

function makePolyPoints(pathArray) {

    var points = [];

    for (var i = 1; i < pathArray.length; i++) {
        var startPt = pathArray[i - 1];
        var endPt = pathArray[i];
        var dx = endPt.x - startPt.x;
        var dy = endPt.y - startPt.y;
        for (var n = 0; n <= 90; n++) {
            var x = startPt.x + dx * n / 90;
            var y = startPt.y + dy * n / 90;
            points.push({
                x: x,
                y: y
            });
        }
    }
    return (points);
}

用于生成粒子的代码:

var packets={}; 
var packetIndex=0;
var packetNum=5;
ctx.clearRect(0,0,canvas.width,canvas.height);

function packet(){
this.x1=670;
this.y1=350;
this.vx1= Math.random()*5;
//this.vy1=Math.random()*10-5;
packetIndex++;
packets[packetIndex] = this;
this.id = packetIndex;
this.life=0;
this.maxLife=1000;
}
packet.prototype.draw=function(){
this.x1 -=this.vx1;
//this.y +=this.vy;
this.life++;
if(this.life>=this.maxLife){
delete packets[this.id];
}
ctx.fillStyle="black";
ctx.fillRect(this.x1,this.y1,10,10);
};

setInterval(function(){ 
//ctx.fillStyle="white";
ctx.clearRect(0,0,canvas.width,canvas.height);
for (var i1=0; i1<0.018; i1++){
new packet();
}
for(var i1 in packets){
packets[i1].draw();
}
},40);
};

请提出一个想法,以便我可以将两者结合起来。

提前致谢..

1 个答案:

答案 0 :(得分:0)

如果您允许进行一些重构......

演示:http://jsfiddle.net/m1erickson/TXa82/

您的每个数据包都需要知道:

  • #steps已沿您的固定折线路径完成,
  • 其速度,旋转角度和旋转速度。

所以Packet类的属性可能定义如下:

function Packet(){
    this.currentStep=0;
    this.velocity=parseInt(Math.random()*4)+1;
    this.rotation=0;
    this.rotationSpeed=Math.PI/180*Math.random()*10;
    this.width=15;
    this.height=10;
    this.fill=randomColor();
    this.isActive=true;
}

您的每个数据包都需要移动并自行绘制。

所以Packet类的方法可能定义如下:

//
Packet.prototype.move=function(){
    this.currentStep+=this.velocity;
    this.rotation+=this.rotationSpeed;
    if(this.currentStep>polypoints.length-1){
        this.isActive=false;
    }
}
//
Packet.prototype.draw=function(){
    if(!this.isActive){ return; }
    var point=polypoints[this.currentStep];
    // draw
    ctx.save();
    ctx.beginPath();
    ctx.translate(point.x,point.y);
    ctx.rotate(this.rotation);
    ctx.rect(-this.width/2,-this.height/2,10,20);
    ctx.fillStyle=this.fill;
    ctx.fill();
    ctx.stroke();        
    ctx.restore();
}

然后你的动画循环只是要求每个数据包移动并自行绘制。

所以你的动画循环可能如下所示:

function animate() {

        // request another loop if the animation is not done

        if(isAnimationDone){return;}
        requestAnimFrame(animate);

        // set the isAnimationDone flag 

        isAnimationDone=true;

        // clear the canvas

        ctx.clearRect(0,0,canvas.width,canvas.height);

        // ask all packets to move and draw themselves

        for(var i=0;i<packets.length;i++){
            var packet=packets[i];

            // if this packet has completed the trip, don't process it

            if(!packet.isActive){continue;}


            // tell this packet to move and draw

            packet.move();
            packet.draw();

            // clear the isAnimationDone flag so we get another loop next time

            isAnimationDone=false;
        }

}