2016-01-01 10 views
5

Próbuję utworzyć animację na płótnie. Po raz pierwszy zadziałało dobrze, ale po dodaniu nowego elementu przez setTimeout, zwiększono prędkość wszystkich elementów. Czy ktoś może mi powiedzieć, dlaczego ta prędkość wzrasta? Fiddle LinkAnimacja płótna Html5 nie działa prawidłowo

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

Wywołujesz setInterval wewnątrz setInterval, zły pomysł ... Również w przypadku animacji użyj ['requestAnimationFrame()'] (https://developer.mozilla.org/en/docs/Web/API/window. requestAnimationFrame), setInterval naprawdę nie jest właściwą metodą, jeśli masz do czynienia z czymkolwiek w oparciu o czas. – Kaiido

+3

Musisz wywołać drugi setInterval poza pierwszym https://jsfiddle.net/v5eoeybe/5/ – jcubic

+0

@jcubic dzięki pracy teraz. –

Odpowiedz

0

postaram się wyjaśnić, dlaczego animacja jest przyspieszony. Za każdym razem, gdy wywoływana jest nazwa rendorBloonsetInterval, tworzony jest nowy setInterval. Kolejne etapy wyjaśnienia procesu:

1 - pierwszym uruchomieniu rendorBloonsetInterval (1 s):

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

2 - drugi bieg rendorBloonsetInterval (2 sekundy):

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

3 - Trzeci przebieg rendorBloonsetInterval (3 sekundy):

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

4 - ... trwa 10 razy

w każdym rendorBloon wykonania, nowy setInterval jest tworzony i każdy setInterval wykonuje metodę drawImage który porusza obraz 3 piksele powyżej. Po wyczyszczeniu setInterval rendorBloon będziesz miał 10 funkcji, próbując przenieść każde pole. Wynik: pola przesuwają się o 3 piksele z pierwszą iteracją, 6 pikseli z drugą, 9 pikseli z trzecią i kontynuują.

Utworzyłem nowy jsfiddle zmieniając kilka rzeczy:

1 - rozdzielenia dwóch setIntervals.

2 - Przenieś logikę animacji do funkcji animacji.

3 - Przenieś usunięcie pól do funkcji animacji.

4 - Utwórz metodę drawImage bezpośrednio w funkcji createBloon, unikając ustawienia prototype.

5 - Wyczyść animatesetInterval po zakończeniu animacji.

6 - Upewnij się, że wszystkie pola są narysowane w obszarze roboczym przy użyciu c_wdh - width of the boxes dla losowych wartości.

Tutaj masz nową jsfiddle.