Przewodnik po canvas:Proste animacje
z Mozilla Developer Center, polskiego centrum programistów Mozilli.
Spis treści |
UWAGA: Tłumaczenie tej strony nie zostało zakończone.
Może być ona niekompletna lub wymagać korekty.
Chcesz pomóc? | Dokończ tłumaczenie | Sprawdź ortografię | Więcej takich stron...
Odkąd używamy skryptów do kontroli elementów canvas, to w bardzo prosty sposób możemy utworzyć (interaktywne) animacje. Niestety element canvas nie był nigdy zaprojektowany w celu takiego użycia (w przeciwieństwie do technologi Flash), więc mamy nałożone pewne ograniczenia.
Prawdopodobnie największym ograniczeniem tego sposobu jest to, iż raz narysowany kształt pozostaje na elemencie canvas. Jeżeli będziemy chcieli go przemieścić to będziemy musieli przerysować zarówno ten kształt jak i wszystko co było narysowane przed nim. Dużo czasu zabierze ponowne narysowanie złożonych ramek i wydajność ściśle zależy od prędkości komputera na którym skrypt jest uruchomiony.
[edytuj] Prosta animacja - krok po kroku
Rysując ramki należy podjąć parę niezbędnych kroków.
- Wyczyść canvas
Jeżeli rysowany kształt nie wypełnia w całości canvas (np. umieszczenie obrazka w tle) należy przede wszystkim wyczyścić canvas i usunąć kształty uprzednio narysowane. Najprościej robi się to za pomocą metodyclearRect. - Zapamiętaj stan canvas
Jeśli zmienia się jakieś ustawienia (style, transformacje, itd.), które zmieniają stan canvas, należy zapamiętać jego stan aby zapewnić użycie oryginalnego stanu przy kolejnych próbach rysowania ramki. - Narysuj animowane kształty
Krok, w którym dokonujemy zasadniczej modyfikacji ramki. - Przywróć stan canvas
Jeśli zapamiętano stan, to przed narysowaniem aktualnej ramki należy ten stan przywrócić.
[edytuj] Kontrolowanie animacji
Kształty są rysowane w elemencie canvas przez użycie metod canvas lub wywołanie funkcji użytkownika. W normalnych warunkach zobaczymy tylko rezultaty widniejące w elemencie canvas po zakończeniu wykonywania skryptu. Przykładowo nie jest możliwa animacja z obrębu pętli for.
Potrzebujemy sposobu do wykonania naszych funkcji rysujących przez pewien okres czasu. Mamy dwa podobne sposoby na kontrolę animacji. Pierwszym są funkcje setInterval i setTimeout, które mogą być użyte do wywoływania określonej funkcji przez pewien ustalony okres czau.
setInterval('animateShape()',500);
setTimeout('animateShape()',500);
Jeżeli nie potrzebujemy żadnej interakcji z użytkownikiem najlepiej użyć funkcji setInterval, która wciąż na nowo wykonuje dostarczony kod. W przykładzie powyżej funkcja animateShape jest wykonywana co 500 milisekund (pół sekundy).
Funkcja setTimeout wykonywana jest tylko raz po ustawionej ilości czasu.
Drugą metodą, którą możemy użyć do kontroli animacji są dane wejściowe użytkownika. Jeżeli chcielibyśmy stworzyć grę moglibyśmy użyć zdarzeń klawiatury lub myszki do kontrolowania animacji. Przez ustawienie eventListeners wychwytujemy jakąś interakcję użytkownika i wykonujemy funkcje naszej animacji.
W przykładzie poniżej użyliśmy pierwszej metody do kontroli animacji. Na dole tej strony jest trochę odnośników do przykładów używających drugiego sposobu.
[edytuj] Przykład animacji 1
W tym przykładzie tworzymy animację mini symulacji naszego układu słonecznego.
var sun = new Image();
var moon = new Image();
var earth = new Image();
function init(){
sun.src = 'images/sun.png';
moon.src = 'images/moon.png';
earth.src = 'images/earth.png';
setInterval('draw()',100);
}
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
ctx.globalCompositeOperation = 'destination-over';
ctx.clearRect(0,0,300,300); // czyści canvas
ctx.fillStyle = 'rgba(0,0,0,0.4)';
ctx.strokeStyle = 'rgba(0,153,255,0.4)';
ctx.save();
ctx.translate(150,150);
// Ziemia
var time = new Date();
ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
ctx.translate(105,0);
ctx.fillRect(0,-12,50,24); // Cień
ctx.drawImage(earth,-12,-12);
// Księżyc
ctx.save();
ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
ctx.translate(0,28.5);
ctx.drawImage(moon,-3.5,-3.5);
ctx.restore();
ctx.restore();
ctx.beginPath();
ctx.arc(150,150,105,0,Math.PI*2,false); // orbita Ziemi
ctx.stroke();
ctx.drawImage(sun,0,0,300,300);
}
[edytuj] Przykład animacji 2
function init(){
clock();
setInterval('clock()',1000);
}
function clock(){
var now = new Date();
var ctx = document.getElementById('canvas').getContext('2d');
ctx.save();
ctx.clearRect(0,0,150,150);
ctx.translate(75,75);
ctx.scale(0.4,0.4);
ctx.rotate(-Math.PI/2);
ctx.strokeStyle = "black";
ctx.fillStyle = "white";
ctx.lineWidth = 8;
ctx.lineCap = "round";
// oznaczenie godziny
ctx.save();
ctx.beginPath();
for (i=0;i<12;i++){
ctx.rotate(Math.PI/6);
ctx.moveTo(100,0);
ctx.lineTo(120,0);
}
ctx.stroke();
ctx.restore();
// oznaczenie minut
ctx.save();
ctx.lineWidth = 5;
ctx.beginPath();
for (i=0;i<60;i++){
if (i%5!=0) {
ctx.moveTo(117,0);
ctx.lineTo(120,0);
}
ctx.rotate(Math.PI/30);
}
ctx.stroke();
ctx.restore();
var sec = now.getSeconds();
var min = now.getMinutes();
var hr = now.getHours();
hr = hr>=12 ? hr-12 : hr;
ctx.fillStyle = "black";
// wypisuje godzinę
ctx.save();
ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
ctx.lineWidth = 14;
ctx.beginPath();
ctx.moveTo(-20,0);
ctx.lineTo(80,0);
ctx.stroke();
ctx.restore();
// wypisuje minuty
ctx.save();
ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(-28,0);
ctx.lineTo(112,0);
ctx.stroke();
ctx.restore();
// wypisuje sekundy
ctx.save();
ctx.rotate(sec * Math.PI/30);
ctx.strokeStyle = "#D40000";
ctx.fillStyle = "#D40000";
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(-30,0);
ctx.lineTo(83,0);
ctx.stroke();
ctx.beginPath();
ctx.arc(0,0,10,0,Math.PI*2,true);
ctx.fill();
ctx.beginPath();
ctx.arc(95,0,10,0,Math.PI*2,true);
ctx.stroke();
ctx.fillStyle = "#555";
ctx.arc(0,0,3,0,Math.PI*2,true);
ctx.fill();
ctx.restore();
ctx.beginPath();
ctx.lineWidth = 14;
ctx.strokeStyle = '#325FA2';
ctx.arc(0,0,142,0,Math.PI*2,true);
ctx.stroke();
ctx.restore();
}
[edytuj] Inne przykłady
- Canvascape
Gra przygodowa 3D (kto pierwszy strzeli). - Prosty RayCaster
Dobry przykład jak robić animację używającą klawiszy do jej kontrolowania. - canvas adventure
Także miły przykład, w którym używamy klawiszy klawiatury do kontrolowania.


