Kaadrivahetus Javascriptiga
setTimeout | regAnimFrame |
Selles loengus esitatakse:
Kanvaal liikuva objekti saamiseks kõige lihtsam meetod on:
pall.vx = 4; pall.vy = -2;
function render(){ ctx.clearRect(0, 0, w0,h0-hf); for(var i=0;i < balls.length; i++){ var pall=balls[i]; pall.move(); pall.draw(); } }
function animate(){ render(); setTimeout(animate,1000/30); };
Seega objekti liikumise kiirus kanvaal sõltub kahest tegurist:
nihetest dx,dy
kaadrivahetuse kiirusest (ülalesitatud näites - 30 ms)
Funktsiooni setTimeout (käivitatakse kaadrivahetusfunktsioonist animate iga kord uuesti) asemel võib kasutada ka funktsiooni setInterval(animate,30) - see on pidevalt toimiv taimer, mis käivitab funktsiooni animate iga 30 ms järel kuni see taimer peatatakse funktsiooniga clearInterval.
Kahjuks brauserid sageli ei soorita kaadrivahetust konstantse kiirusega - näiteks teeb Javaskripti interpretaator aegajalt prahikogumist (garbage collection - see on Javascriptis automaatne ja pole kontrollitav) ja kuna Javascriptis pole protsesside paralleelset (samaaegset) käivitamist, aeglustab see kohe koodi täitmist (vaata numbreid kanvaa all).
Konstantse kiirusega kaadrivahetuse tagab funktsioon requestAnimationFrame, mis käivitab kaadrivahetuse siis kui brauseril on vaba hetk. Selle kasutamine on analoogiline taimeri kasutamisega:function animate(30) { pall.x += pall.vx; pall.y += pall.vy; window.requestAnimationFrame(animate); } window.requestAnimationFrame = (function(){ //käivitamiseks return window.requestAnimationFrame || function(callback, fps){ //Fallback function window.setTimeout(callback, 1000/60);} //ca 33 FPS })(); //anonüümne (nimeta) funktsioon käivitatakse selle kirjeldusega kohe!
Praegu töötab see meetod enamuse brauserite viimastes versioonides: Firefox 15, IE9, Chome 21, Chromium, Opera 12, Comodo Dragon 21 (testitud selle lehega 19.09.2012)
NB! Kui IE ei näita HTML5 dokumenti standartsel viisil (IE9 standards), tuleb dokumendi päisesse lisada rida
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
then = Date.now(); animate();
Funktsioonis animate salvestatakse praegune ajahetk uues muutujas now , arvutatakse vahepeal kulunud aeg, s.t. kaadrivahetuse kiirus (millissekundites, s.t. sekundi tuhandikes), see näidatakse dokumendi osas (div) 'inf' ja saadetakse järgmise mõõtmise jaoks praegune ajahetk muutujasse then::
var now = Date.now(); var delta = now - then; inf.innerHTML = "FPS: "+Math.floor(1000/delta); then = now;