2016-01-16 17 views
0

所以我做了這個代碼(在教程的幫助下),我想在任何地方點擊都能創建效果。如何在一個addEventListener('click')上的SetInterval中乘以一個函數;

該代碼做了它的工作,但每次我再次單擊並調用drawParticle函數時,該過程都會加速並顯示更少的粒子。 我想這是因爲我一次調用多個setIntervals而JavaScript是單線程的。但我該如何解決它?

var canvas, 
     c, 
     particles, 
     particleIndex, 
     particleNum, 
     w, 
     h; 

window.onload =function(){ 

    canvas = document.createElement("canvas"); 
    c = canvas.getContext("2d"); 
    particles = {}; 
    particleIndex = 0; 
    particleNum = 3; 
    w = window.innerWidth; 
    h = window.innerHeight; 

    canvas.width = w; 
    canvas.height = h; 

    document.body.appendChild(canvas); 

    c.fillStyle ="black"; 
    c.fillRect(0,0,canvas.width,canvas.height); 

    canvas.addEventListener('click', drawParticle, false); 
}; 

function drawParticle(e){ 

    function Particle(){ 
     this.x = e.clientX; 
     this.y = e.clientY; 
     this.vx = Math.random() * 10 - 5; 
     this.vy = Math.random() * 10 - 5; 
     this.gravity = 0.2; 
     particleIndex++; 
     particles[particleIndex] = this; 
     this.id = particleIndex; 
     this.life = 0; 
     this.maxLife = Math.random() * 30 + 50; 
     this.color = "rgb("+parseInt(Math.random()*255,10)+",0,0)"; 

     } 

    Particle.prototype.draw = function(){ 

     this.x += this.vx; 
     this.y += this.vy; 

     if(Math.random() < 0.1){ 
      this.vx = Math.random() * 10 - 5; 
      this.vy = Math.random() * 10 - 5; 

     } 


     //this.vy += this.gravity; 
     this.life++; 

     if(this.life >= this.maxLife){ 
     delete particles[this.id]; 
     } 

     c.fillStyle = this.color; 
     c.fillRect(this.x,this.y,10,10); 
     }; 

    interval = setInterval(function(){ 
     //c.globalCompositeOperation ="source-over"; 
     c.fillStyle ="rgba(0,0,0,0.3)"; 
     c.fillRect(0,0,canvas.width,canvas.height); 

     for (var i = 0; i < particleNum; i++){ 
     new Particle(); 
     } 
     //c.globalCompositeOperation ="lighter"; 
     for (var i in particles){ 

      particles[i].draw(); 
     } 
    },30); 

}; 

回答

0

我認爲你對這個間隔是正確的。我不確定這是否是您想要的反應,但如果您在重繪之前清除間隔,則事情不會加快。嘗試是這樣的:

var interval = null; 
function drawParticle(e){ 

    if (interval) { 
    clearInterval(interval) 
    } 

    function Particle(){ 
    ... 

有一個在這裏codepen http://codepen.io/bunnymatic/pen/BjwVBM

UPDATE:

我已經改變了代碼筆包括包含下面的新代碼。主要變化是創建一個對象,該對象將保存爲每次點擊繪製的粒子集。通過移動這個粒子集合,它們似乎解決了這個問題。我懷疑將每個元素添加到全局particles列表中有什麼奇怪的。現在,Particles實例只管理與該組關聯的粒子。

我也拿出了particleId,因爲它似乎沒有必要,儘管如果它對這段代碼的其他內容有用的話可能需要重新寫回。

這裏是我更新的代碼:

var canvas, 
c, 
particleNum, 
w, 
h; 

window.onload =function(){ 

    canvas = document.createElement("canvas"); 
    c = canvas.getContext("2d"); 
    particleNum = 3; 
    w = window.innerWidth; 
    h = window.innerHeight; 

    canvas.width = w; 
    canvas.height = h; 

    document.body.appendChild(canvas); 

    c.fillStyle ="black"; 
    c.fillRect(0,0,canvas.width,canvas.height); 

    canvas.addEventListener('click', drawParticles, false); 
}; 

function Particles() { 
    this.particles = {}; 
    this.particleIndex = 0; 
} 

Particles.prototype.addParticle = function(particle) { 
    this.particles[++this.particleIndex] = particle; 
} 

Particles.prototype.killDeadParticles = function() { 
    for (var i in this.particles) { 
    var particle = this.particles[i]; 
    if (particle.isDead()) { 
     delete this.particles[i] 
    } 
    } 
} 

Particles.prototype.draw = function() { 
    // draw particles 
    for (var i in this.particles){ 
    this.particles[i].draw(); 
    } 
    this.killDeadParticles(); 
} 


function Particle(e){ 
    this.x = e.clientX; 
    this.y = e.clientY; 
    this.vx = Math.random() * 10 - 5; 
    this.vy = Math.random() * 10 - 5; 
    this.gravity = 0.2; 
    this.life = 0; 
    this.maxLife = Math.random() * 30 + 50; 
    this.color = "rgb("+parseInt(Math.random()*255,10)+",0,0)"; 
    // console.log('new particle', particleIndex); 
} 

Particle.prototype.isDead = function() { 
    return (this.life >= this.maxLife); 
} 

Particle.prototype.draw = function(){ 

    this.x += this.vx; 
    this.y += this.vy; 

    if(Math.random() < 0.1){ 
    this.vx = Math.random() * 10 - 5; 
    this.vy = Math.random() * 10 - 5; 

    } 

    //this.vy += this.gravity; 
    this.life++; 

    c.fillStyle = this.color; 
    c.fillRect(this.x,this.y,10,10); 
}; 

function drawParticles(e){ 

    var particles = new Particles(e); 

    setInterval(function(){ 
    //c.globalCompositeOperation ="source-over"; 
    c.fillStyle ="rgba(0,0,0,0.3)"; 
    c.fillRect(0,0,canvas.width,canvas.height); 

    for (var i = 0; i < particleNum; i++){ 
     var particle = new Particle(e); 
     particles.addParticle(particle); 
    } 
    //c.globalCompositeOperation ="lighter"; 
    particles.draw(); 
    },30); 

}; 
+0

這是朝正確方向的一步,但也可把每點擊運行的每一個區間的可能性?這樣粒子不斷被吸引? –

+0

我會再試一次。所以你希望它能像你的初始代碼一樣工作,除了每次點擊都不會加快,對吧? –

相關問題