2

2D キャンバスで煙のシミュレーションを作成する必要があります。スクリプトを作成しましたが、クロムとサファリでは見た目も動作も問題ありませんが、Firefox ではフレームレートが許容範囲を超えており、他にコードを最適化する方法がわかりません。また、Windows 7 と Chrome の最新バージョンでは何も表示されない (コンソール エラーも表示されない) と言う人もいます。これが私のコードです:

http://jsfiddle.net/jonigiuro/mwdqb/

/** MY PARTICLES **/

// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();


var Particles = function() {
    this.oPoint = {
        x: 0,
        y:0
    }
this.addPuffs = false;
this.maxParticles = 200;
this.imageSrc = "http://people.csail.mit.edu/acornejo/Projects/images/smoke_particle.png"
this.canvas = null;
this.ctx = null;
this.windX = .5;
this.windY = -5;
this.alphaDecrease = .006;
this.growingSpeed = 2.9;
this.jitterX = 2;
this.jitterY = 1;
this.speedXJitter = 4;
this.speedYJitter = 10;
this.puffs = [];
this.maxLife = 200;
this.cWidth = screen.width;
this.cHeight = screen.height;
this.img = new Image();
this.img.src = this.imageSrc;
this.alphaDie = .05;
this.bornSize = 10;

this.init = function() {
    var self = this;
    document.onmousemove = function(e) {
        self.oPoint.x = e.clientX;
        self.oPoint.y = e.clientY;
    }

    document.onmousedown = function() {
        self.addPuffs = true;
    }

    document.onmouseup = function() {
        self.addPuffs = false;
    }
    //CREATE THE CANVAS
    this.canvas = document.createElement('canvas');
    this.canvas.id = 'canvas';

    document.body.appendChild(this.canvas);
    document.getElementsByTagName('body')[0].appendChild(canvas);

    this.canvas.width = this.cWidth;
    this.canvas.height = this.cHeight;

    this.applyStyles(canvas);

    this.ctx = canvas.getContext("2d");

    (function animloop(){
        requestAnimFrame(animloop);
        self.tick();
    })();
}

this.applyStyles = function( element ) {
    element.style.position = "absolute";
    element.style.top = 0;
    element.style.left = 0
}

//STEP DONE EACH FRAME
this.tick = function() {

    var self = this;
    var puffLength = this.puffs.length;

    //ONLY ADD PUFFS WHEN NEEDED
    if ( this.addPuffs && ( puffLength < this.maxParticles )) {
        this.puffs.push(this.newPuff());
    }

    this.ctx.clearRect(0,0,this.cWidth,this.cHeight)

    //ANIMATE PUFFS PROPERTIES
    for(var i = 0; i < puffLength ; i++) {
        var currentPuff = this.puffs[i];
        if( currentPuff ) {

            //REMOVE THE CURRENPUFF IF IT HAS GONE INVISIBLE OR IF IT LIVED LONG ENOUGH
            if(currentPuff.age == this.maxLife || currentPuff.alpha <= .05) {
                this.puffs.splice(0, 1);
            } else {
                currentPuff.posX = currentPuff.posX + (this.windX + currentPuff.speedX);
                currentPuff.posY = currentPuff.posY + this.windY;
                currentPuff.scale += this.growingSpeed;
                currentPuff.age++;
                currentPuff.alpha -= this.alphaDecrease;
                this.render( currentPuff );

            }

        }

    }

}

this.newPuff = function() {
    return {
            posX: this.oPoint.x + Math.random() * this.jitterX - (this.jitterX / 2),
            posY: this.oPoint.y + Math.random() * this.jitterY - (this.jitterY / 2),
            speedX: Math.random() * this.speedXJitter,
            speedY: Math.random() * this.speedYJitter,
            scale: this.bornSize - 80,
            age: 0,
            alpha: .7,
        }
}


this.render = function( currentPuff ) {
    var puffLength = this.puffs.length;

    this.ctx.globalAlpha = currentPuff.alpha;
    this.ctx.drawImage(this.img, currentPuff.posX, currentPuff.posY, currentPuff.scale + 80, currentPuff.scale + 80);


}

this.init();
}


var particles = new Particles();

PS: 動作を確認するには、結果ウィンドウでクリック アンド ドラッグします。

4

0 に答える 0