2016-01-01 11 views
5

Sto provando a creare un'animazione su tela. La prima volta ha funzionato bene, ma quando un nuovo elemento è stato aggiunto attraverso setTimeout, tutta la velocità degli elementi è aumentata. Qualcuno può dirmi perché questa velocità è in aumento. Fiddle LinkL'animazione tela HTML5 non funziona correttamente

var canvas = $("#canvas")[0], 
    context = canvas.getContext("2d"), 
    bloons = {}, 
    bloonIndex = 0; 

var c_wdh = 360, 
    c_hgt = 540; 


function createBloon(x, y) { 
    this.x = x; 
    this.y = y; 
    this.vx = 1, 
    this.vy = 3; 
    bloonIndex++; 
    bloons[bloonIndex] = this; 
    this.id = bloonIndex; 
} 

createBloon.prototype.drawImage = function() { 
    this.y -= this.vy; 
    context.fillStyle = "#FF0000"; 
    context.fillRect(this.x, this.y, 50, 50); 
    if(this.y <= -120){ 
     delete bloons[this.id]; 
    } 
}; 


var nob = 0; 
var i = 1; 
var rendorBloon = setInterval(function(){ 
    bloons[i] = new createBloon(Math.random() * c_wdh, c_hgt); 
    var animate = setInterval(function() { 
     context.clearRect(0, 0, c_wdh, c_hgt);   
     for (var i in bloons){ 
     bloons[i].drawImage(); 
     } 
    }, 30); 

    i++; 
    nob++; 
    if(nob >= 10){ 
     clearInterval(rendorBloon); 
    }  
}, 1000); 
+3

si sta chiamando setInterval all'interno di un setInterval, idea sbagliata ... Inoltre, per l'animazione, utilizzare ['requestAnimationFrame()'] (https://developer.mozilla.org/en/docs/Web/API/window. requestAnimationFrame), setInterval non è davvero il metodo giusto se si ha a che fare con qualsiasi cosa in base al tempo. – Kaiido

+3

È necessario chiamare il secondo setInterval al di fuori del primo https://jsfiddle.net/v5eoeybe/5/ – jcubic

+0

@jcubic grazie ora. –

risposta

0

Cercherò di spiegarvi perché l'animazione è accelerato. Ogni volta che lo rendorBloonsetInterval viene chiamato un nuovo setInterval viene creato. I passi successivi spiegano il processo:

1 - Prima esecuzione di rendorBloonsetInterval (1 secondo):

1 setInterval is created. 1 setInterval is running, it will run every 30 milliseconds 

2 - Seconda manche di rendorBloonsetInterval (due secondi):

1 setInterval is created. 2 setInterval are running, they will run every 30 milliseconds 

3 - Terza serie di rendorBloonsetInterval (3 secondi):

1 setInterval is created. 3 setInterval are running, they will run every 30 milliseconds 

4 - ... Continua 10 volte

In ogni rendorBloon esecuzione, viene creata una nuova setInterval e ogni setInterval esegue il metodo drawImage che sposta l'immagine 3 pixel sopra. Quando si cancella il setInterval rendorBloon, si avranno 10 funzioni che cercano di spostare ciascuna casella. Il risultato: le caselle si muovono di 3 pixel con la prima iterazione, 6 pixel con la seconda, 9 pixel con la terza e continuano.

Ho creato un nuovo jsfiddle cambiare alcune cose:

1 - Separare le due setIntervals.

2 - Spostare la logica dell'animazione sulla funzione di animazione.

3 - Spostare la cancellazione delle caselle nella funzione di animazione.

4 - Creare il metodo drawImage direttamente nella funzione createBloon evitando lo prototype.

5 - Cancellare animatesetInterval quando l'animazione è terminata.

6 - Assicurarsi che tutte le caselle siano disegnate all'interno dell'area di disegno utilizzando c_wdh - width of the boxes per i valori casuali.

Qui avete il nuovo jsfiddle.