Lepsze animacje za pomocą funkcji requestAnimationFrame w JavaScript

Autor podstrony: Krzysztof Zajączkowski

Stronę tą wyświetlono już: 3621 razy

Wstęp

Omawiane wcześniej metody setTimer i setInterval mają swoje wady, które przy programowaniu gier są szczególnie dotkliwe. Głównym problemem jest synchronizacja zdarzeń. Jeżeli podpięte zdarzenie np. onkeydown, które wykonuje się niezależnie od animacji a jest związane z przemieszczaniem jakiegoś obiektu w to problemem jest synchronizacja tego zdarzenia z animacją. I tu z odsieczą biegnie na ratunek funkcja requestAnimationFrame, którą obsługują jedynie najnowsze przeglądarki. Funkcja ta umożliwia podanie na jej wejście innej funkcji, która zostanie wywołana w odpowiedzi na odświeżenie okna przeglądarki. I tu trzeba powiedzieć sobie, że przeglądarki internetowe odświeżają swoje okna (odrysowują je) z częstotliwością 60 [Hz] (60 razy na sekundę). Dzięki tej funkcji można więc zsynchronizować animację wraz z zdarzeniami, które mają na nie wpływ.

Przykład praktycznego zastosowania funkcji requestAnimationFrame

Teoria teorią, ale czas zakasać rękawy i pokazać jak funkcja requestAnimationFrame działa. Oto przykładowy kod:

var lastTime = 0; // ostatnio odnotowany czas var dt = 0; // przyrost czasu var canvas = document.getElementById("drawing"); var ctx = canvas.getContext("2d"); var mousex = 0; // współrzędna x myszki nad canvas-em var mousey = 0; // współrzędna y myszki nad canvas-em function Ball(_x, _y){ // deklaracja klasy var x = _x; // współrzędna x obiektu var y = _y; // współrzędna y obiektu var ray = 20; // promień kulki this.draw = function(_x, _y, dt){ // rysowanie z przemieszczaniem kulki po czasie x = (x - _x) * dt / 1000 * 3 + x; // obliczanie nowej współrzędnej x y = (y - _y) * dt / 1000 * 3 + y; // obliczanie nowej współrzędnej y ctx.beginPath(); ctx.arc(x, y, ray, 0, Math.PI * 2); ctx.fillStyle="blue"; ctx.fill(); ctx.stroke(); } } var ball = new Ball(200, 200); // tworzenie obiektu kulki function draw(time){ // funkcja uruchamiana podczas odświeżania okna requestAnimationFrame(draw); // rekurencyjnie daję do zrozumienia, że funkcja draw ma się wykonywać przy każdym odświeżeniu okna przeglądarki dt = lastTime - time; // obliczanie interwału czasowego lastTime = time; // zapamiętywanie czasu ctx.fillStyle = "RGBA(255, 255, 255, 0.1)"; // kolor zamalowywania obszaru z przezroczystością co spowoduje powstanie efektu zostawiania śladu podczas ruch ctx.fillRect(0, 0, canvas.width, canvas.height); // wypełnienie obszaru wcześniej wybranym kolorem ball.draw(mousex, mousey, dt); } draw(0); // rozpoczęcie animacji canvas.onmousemove = function(event){ mousex = event.pageX - this.offsetLeft; // położenie kursora na osi x względem prawej krawędzi elementu mousey = event.pageY - this.offsetTop; // położenie kursora na osi y względem górnej krawędzi elementu }

Wynik działania powyższego skryptu widać poniżej (najedź kursorem myszki nad obszar canvas-u.

Propozycje książek