IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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 - requestAnimati­onFrame. 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.

RequestAnimati­onFrame 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:

Animácie pomocou setInterval
localhost

Riešenie pomocou requestAnimati­onFrame ()

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:

Animácie pomocou requestAnimati­onFrame
localhost

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é 511x (4.41 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript

 

Predchádzajúci článok
Kvíz - Pokročilé podmienky a cykly v JavaScripte
Všetky články v sekcii
Základné konštrukcie jazyka JavaScript
Preskočiť článok
(neodporúčame)
Najčastejšie chyby JS začiatočníkov - Vieš pomenovať premenné?
Článok pre vás napísal Neaktivní uživatel
Avatar
Užívateľské hodnotenie:
2 hlasov
Tento uživatelský účet již není aktivní na základě žádosti jeho majitele.
Aktivity