Animacja za pomocą requestAnimationFrame
Proszę tworzyć płynne animacje na canvasie.
Animacja za pomocą requestAnimationFrame to bezpłatna lekcja JavaScript Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej JavaScript Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs JavaScript Academy zawiera 4 lekcji w sumie.
Dlaczego requestAnimationFrame?
requestAnimationFrame(callback) planuje wykonanie funkcji rysującej przed ponownym odświeżeniem ekranu — zwykle 60 razy na sekundę. Wstrzymuje działanie w kartach działających w tle, oszczędzając procesor i baterię, w przeciwieństwie do setInterval.
function frame() {
// draw one frame
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);Podstawowa pętla
Pętla animacji czyści canvas, aktualizuje stan, rysuje, a następnie ponownie planuje własne wykonanie.
let x = 0;
function loop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(x, 50, 30, 30);
x += 2;
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);Czyszczenie każdej klatki
Bez clearRect poprzednia klatka pozostaje narysowana, przez co pojawiają się smugi. Na początku każdej klatki wyczyść cały bufor, aby narysować obraz od nowa.
ctx.clearRect(0, 0, canvas.width, canvas.height);Argument znacznika czasu
Funkcja callback otrzymuje znacznik czasu o wysokiej rozdzielczości (w milisekundach). Należy go użyć do obliczenia czasu, który upłynął między klatkami.
let last = 0;
function loop(now) {
const dt = now - last;
last = now;
// dt = ms since previous frame
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);Ruch niezależny od częstotliwości klatek
Należy pomnożyć prędkość przez czas delta, aby prędkość ruchu była stała niezależnie od częstotliwości klatek.
let x = 0;
const speed = 0.1; // px per ms
function loop(now) {
const dt = now - (loop.last || now);
loop.last = now;
x += speed * dt;
requestAnimationFrame(loop);
}Odbijanie piłki
Gdy obiekt uderzy w krawędź, należy odwrócić jego prędkość, aby się odbił.
let x = 50, vx = 3;
function loop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
x += vx;
if (x < 0 || x > canvas.width) vx = -vx;
ctx.beginPath();
ctx.arc(x, 75, 15, 0, Math.PI * 2);
ctx.fill();
requestAnimationFrame(loop);
}
loop();Zatrzymywanie pętli
requestAnimationFrame zwraca identyfikator. Należy przekazać go do cancelAnimationFrame, aby zatrzymać animację.
let id;
function loop() {
id = requestAnimationFrame(loop);
}
id = requestAnimationFrame(loop);
// later:
cancelAnimationFrame(id);Wstrzymywanie i wznawianie
Należy śledzić flagę określającą, czy animacja działa. Aby ją wznowić, należy zażądać nowej klatki; aby ją wstrzymać, wystarczy przestać żądać kolejnych klatek (lub anulować oczekującą klatkę).
let running = true;
function loop() {
if (!running) return;
// draw...
requestAnimationFrame(loop);
}
function pause() { running = false; }
function resume() { running = true; requestAnimationFrame(loop); }Animowanie wielu obiektów
Należy przechowywać obiekty w tablicy i aktualizować każdy z nich wewnątrz pętli.
const balls = [{ x: 10, vx: 2 }, { x: 80, vx: -3 }];
function loop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (const b of balls) {
b.x += b.vx;
ctx.fillRect(b.x, 60, 20, 20);
}
requestAnimationFrame(loop);
}
loop();Easing zapewniający płynny ruch
Należy interpolować w kierunku celu z użyciem funkcji easing, aby uzyskać naturalne wyhamowanie.
let x = 0;
const target = 200;
function loop() {
x += (target - x) * 0.1; // ease out
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(x, 50, 30, 30);
if (Math.abs(target - x) > 0.5) requestAnimationFrame(loop);
}
loop();Wskazówki dotyczące wydajności
Należy unikać tworzenia obiektów wewnątrz pętli, grupować wywołania rysowania i, gdy to możliwe, odświeżać tylko zmienione elementy. Praca wykonywana w każdej klatce powinna być niewielka, aby zmieścić się w budżecie około 16 ms dla 60 kl./s.
Szybki sprawdzian
Sprawdź swoją wiedzę na temat animacji.
Podsumowanie: animacja
Zbudowano pętle animacji za pomocą requestAnimationFrame, czyszczono każdą klatkę za pomocą clearRect, używano znacznika czasu, aby uniezależnić animację od częstotliwości klatek, animowano odbijające się piłki i wiele obiektów, zastosowano easing oraz nauczono się zatrzymywać i wstrzymywać animację za pomocą cancelAnimationFrame.
Często zadawane pytania
Czy lekcja „Animacja za pomocą requestAnimationFrame” jest bezpłatna?
Tak — pełny tekst „Animacja za pomocą requestAnimationFrame” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu JavaScript Academy, przejdź na CoddyKit PRO. Kurs JavaScript Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Animacja za pomocą requestAnimationFrame”?
Proszę tworzyć płynne animacje na canvasie. Ćwiczysz JavaScript Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć JavaScript Academy?
Nie wymagamy żadnego doświadczenia. JavaScript Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Animacja za pomocą requestAnimationFrame”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji JavaScript Academy?
Tak. Każda lekcja JavaScript Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Konfigurowanie kontekstu Canvas
- Rysowanie kształtów i ścieżek
- Praca z obrazami i tekstem
- Animacja za pomocą requestAnimationFrame