17. diel - JS requestAnimationFrame - Za lepšie vykresľovanie
V predchádzajúcom kvíze, Kvíz - Pokročilé podmienky a cykly v JavaScripte, sme si overili nadobudnuté skúsenosti z predchádzajúcich lekcií.
V minulej lekcii, Kvíz - Pokročilé podmienky a cykly v JavaScripte , sme sa venovali animáciám. Spolu s HTML5 prišlo nové javascriptové API - requestAnimationFrame. Jedná sa o technológiu, ktorá nám umožňuje plynulejšie as vyšším výkonom vykresľovať animácie v prehliadači a my si ju v tomto tutoriálu predstavíme.
Ak ste niekedy skúšali napísať napr. Nejakú jednoduchú hru v prehliadači, iste vaše hlavné slučka vyzerala nejako takto.
setInterval(function() { posun(); vykresli(); }, 1000 / FPS);
Naše doterajšie animácie vyzerali veľmi podobne, len sme spojili posúvanie a vykresľovanie do jednej funkcie. Alternatívne vykresľovací slučka môže vyzerať aj napr. Nasledovne:
function smycka() { setTimeout(smycka, 1000 / FPS); posun(); vykresli(); } smycka();
Kód funguje, dokonca si môžeme aj obmedziť FPS. Čo je na ňom ale zle?
Plytvanie výkonom počítača
Problém vyššie uvedeného kódu je ten, že prehliadač ho vykonáva, aj keď sa užívateľ na danú stránku zrovna nepozerá (má překliknuto na inú záložku, prípadne je prehliadač minimalizovaný). Prehliadač Google Chrome tieto situácie rieši obmedzením takýchto slučiek iba na 1 FPS. To je ale iba jeho dobrovoľné správanie a v ostatných prehliadačoch to tak vôbec byť nemusí, takže na mobilných zariadeniach môže dochádzať zbytočne k poklesu výkonu a vybíjanie batérie.
RequestAnimationFrame to rieši!
S použitím funkcie requestAnimationFrame()
namiesto
setTimeout()
bude náš kód vyzerať veľmi podobne.
function smycka() { requestAnimationFrame(smycka); posun(); vykresli(); } smycka();
Túto funkciu vymyslela Mozilla a neskôr ju prevzal a vylepšil tím WebKite. Pomocou funkcie sa môže vykresľovať CSS, DOM elementy, WebGL alebo na canvas.
Výhody
requestAnimationFrame()
nám zaistí, že všetky naše
animácie sa budú vykresľovať naraz, s vyšším výkonom a nižšou
spotrebou batérie.
Ak v prehliadači prekliknite na inú stránku, alebo prehliadač minimalizujete, vykresľovanie sa zastaví, aby sa šetril výkon a bude sa pokračovať, hneď ako bude stránka opäť viditeľná.
Mohli ste si tiež všimnúť, že u použitie
requestAnimationFrame()
sme nikde nenastavovali počet FPS. Funkcia
v predvolenom nastavení používa 60 FPS, záleží ale na implementáciu v
prehliadači. Nemalo by sa to ale príliš líšiť a skôr záleží na výkone
PC, než na rozhodnutie výrobcu prehliadača. Tiež podpora v prehliadačoch je
pomerne dobrá.
Demo
Na záver si ukážeme jednoduchú aplikáciu, v ktorej sa štvorec pohybuje
po canvasu a implementujeme jej ako pomocou setInterval()
, tak
pomocou requestAnimationFrame()
. Plátno schválne tentoraz
nebudeme mazať, čím bude vidieť stopa štvorca.
Riešenie pomocou setInterval ()
window.onload = function() { let platno = document.querySelector("#platno"); let kontext = platno.getContext("2d"); let ctverec = { "x": 25, "y": 25, "smerX": -1, "smerY": 1, "rychlost": 2, "sirka": 50, "vyska": 50, "barva": "red" }; function smycka() { posun(); prekresli(); } setInterval(smycka, 1000 / 60); smycka(); function posun() { if (ctverec.x + ctverec.sirka + ctverec.rychlost * ctverec.smerX > platno.width) ctverec.smerX = -1; if (ctverec.x + ctverec.rychlost * ctverec.smerX < 0) ctverec.smerX = 1; if (ctverec.y + ctverec.vyska + ctverec.rychlost * ctverec.smerY > platno.height) ctverec.smerY = -1; if (ctverec.y + ctverec.rychlost * ctverec.smerY < 0) ctverec.smerY = 1; zmenBarvu(); ctverec.x += ctverec.rychlost * ctverec.smerX; ctverec.y += ctverec.rychlost * ctverec.smerY; } function prekresli() { kontext.fillStyle = ctverec.barva; kontext.fillRect(ctverec.x, ctverec.y, ctverec.sirka, ctverec.vyska); } function zmenBarvu() { barvy = ['green', 'blue', 'red', 'yellow']; ctverec.barva = barvy[Math.floor(Math.random() * barvy.length)]; } }
výsledok:
Riešenie pomocou requestAnimationFrame ()
window.onload = function() { let platno = document.querySelector("#platno"); let kontext = platno.getContext("2d"); let ctverec = { "x": 25, "y": 25, "smerX": -1, "smerY": 1, "rychlost": 2, "sirka": 50, "vyska": 50, "barva": "red" }; function smycka() { posun(); prekresli(); requestAnimationFrame(smycka); } smycka(); function posun() { if (ctverec.x + ctverec.sirka + ctverec.rychlost * ctverec.smerX > platno.width) ctverec.smerX = -1; if (ctverec.x + ctverec.rychlost * ctverec.smerX < 0) ctverec.smerX = 1; if (ctverec.y + ctverec.vyska + ctverec.rychlost * ctverec.smerY > platno.height) ctverec.smerY = -1; if (ctverec.y + ctverec.rychlost * ctverec.smerY < 0) ctverec.smerY = 1; zmenBarvu(); ctverec.x += ctverec.rychlost * ctverec.smerX; ctverec.y += ctverec.rychlost * ctverec.smerY; } function prekresli() { kontext.fillStyle = ctverec.barva; kontext.fillRect(ctverec.x, ctverec.y, ctverec.sirka, ctverec.vyska); } function zmenBarvu() { barvy = ['green', 'blue', 'red', 'yellow']; ctverec.barva = barvy[Math.floor(Math.random() * barvy.length)]; } }
výsledok:
Dúfam, že vám bola lekcie užitočná a že od teraz budete pre animácie
v prehliadači používať requestAnimationFrame()
V budúcej lekcii, Najčastejšie chyby JS začiatočníkov - Vieš pomenovať premenné? , si ukážeme najčastejšie chyby začiatočníkov v JavaScripte ohľadom pomenovanie premenných.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 516x (4.41 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript