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í.

Navrhujeme doplnok webu v JavaScripte

V predchádzajúcom cvičení, Riešené úlohy k 20.-22. lekciu OOP v JavaScripte, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.

V tomto článku si skúsime naprogramovať doplnok pre interaktívne stránky v JavaScripte. Náš doplnok bude fungovať plne automaticky, tvoriť budeme guľatý progress bar. K vykresľovanie použijeme canvas s data- * atribúty. V tomto článku to nebudem uvádzať step-by-step postupom, ako ste asi zvyknutí, ale vždy vás iba nakopnem (snáď) správnym smerom. Rovnako článok počíta s tým, že ste študijné typy a dokážete použiť google. Aj keby ste nechceli tvoriť celý komplet, tak si môžete stiahnuť priložený zdrojový kód (dole pod článkom) a upraviť ho tak, aby bol lepší a dokonalejší.

Niekde sa začať musí

Väčšina ľudí začína tým, že si predstaví výsledok. To je síce fajn, ale keď potom začínajú písať, stále majú tú predstavu. Začnite inak, predstavte si svoj výsledok, keď ste ho orezal na minimum. Toto sa vám bude robiť oveľa lepšie a tej prvej predstavy dosiahnete oveľa rýchlejšie. Rovnako tak je dobré začať práve tým základom. Ak začnete vykresľovaním textu doprostred, pri dorábanie samotného progress baru zistíte, že to nie je až zas tak jednoduché a pritom je.

Začneme samotným skriptom, ktorý bude obsluhovať každý canvas s atribútom data-percent. K tomuto účelu nám dobre poslúži metóda document.query­SelectorAll (), ktorá v parametri dostáva CSS selektor a vráti nám polia elementov, ktoré by ovplyvnil tento selektor. Pre vybranie všetkých Canvas s atribútom data-percent použijeme volič canvas [data-percent], po načítaní stránky teda prejdeme pomocou querySelectorAll ( "canvas [data-percent]"), ktorý nám vráti presne tie canvas čo potrebujeme.

Teraz si vytvoríme objekt, ktorý bude zastupovať náš guľatý progress bar. Objekty sú v JavaScripte jeden veľký kameň úrazu. Definujú sa totiž konštruktor, čo je jednak už od pohľadu divné, zle sa v tom orientuje a tým sa nám občas aj zmení celkom jasné premenné aj napučí pomocný kód. Avšak sa na objekty v JavaScripte pozrime z tej druhej stránky, akonáhle by sa naše progressbar rozrástli, projekt by sa automaticky stal natoľko zložitý, že bez dobrého návrhu by sme sa skôr alebo neskôr dostali do bodu, kedy sme na doterajšom projekte viacmenej len stratili čas. Hoci teda s objekty zo začiatku budeme zápasiť, nebudeme sa im za žiadnu cenu vyhýbať.

Objekt v JavaScriptu definujeme vo funkcii, tam načítame všetky vlastnosti. Metódy sa definujú cez prototype tejto triedy. Vlastnosti ukladáme cez kľúčové slovo this. Ako jednoduchú ukážku kódu použijeme triedu pre osoby, na ktoré to možno všetko celkom pekne vidieť.

function Clovek(jmeno, vek) {
    this.jmeno = jmeno;
    this.vek = vek;

    Clovek.prototype.Pozdrav = function () {
        alert("Jmenuji se " + this.jmeno + " a je mi " + this.vek + " let.");
    }
}

var karel = new Clovek("Karel", 34)
karel.Pozdrav();

Tu vytvárame 34 ročného Karla a necháme ho, aby nás pozdravil. V našom doplnku nám bude stačiť len jeden objekt, ten bude reprezentovať práve náš progressbar. Objekt by mohol mať metódy pre aktualizáciu stavu a vykreslenie, prípadne by mohol obsahovať metódy pre vykresľovanie jednotlivých častí, čím sa kód sprehľadní. Jednotlivé metódy a celkový kód nezabudnite zdokumentovať, veľmi vám to pomôže vyznať sa v už tak dosť neprehľadných objektoch. Pre dokumentáciu môžete použiť napríklad nejakú syntax, je ich veľa, môžete použiť napríklad JSdoc. Zápis JS doc sa príliš nelíši od dokumentácie používané v Jave, našu metódu Pozdrav v človekovi by sme mohli zdokumentovať nasledovne:

/**
 * @author Misaz
 * Představí člověka
*/
Clovek.prototype.Pozdrav = function () {
    alert("Jmenuji se " + this.jmeno + " a je mi " + this.vek + " let.");
}

Vykresľovanie

Vykresľovanie na plátno je sprostredkované kontextom, na ktorom sa volajú jednotlivé metódy pre vykresľovanie. Budú vám bohato stačiť metóda arc (), ktorá berie rôzne parametre a vykreslí časť kruhu. Pozor si dávajte na to, že všetky uhly nie sú v stupňoch, ale v radiánoch. Vzorec pre prevod stupňov na radiány je

Radiany = PI / 180 * stupně

Ak prevod budete používať častejšie, vložte si to do funkcie niekde mimo. Veľmi zaujímavé je si tú funkciu vložiť priamo do interných Math. V JavaScriptu je to ľahké, jednoducho priradíte do požadovaného názvu v Math (vytvoríte si nový, nič neprepíšu) onú funkciu. Týmto zakomponujete vašu funkciu do už existujúcich a čistota kódu je zachovaná.

Math.deg2rad = function (degrades) {
    return Math.PI / 180 * degrades
}

Aby metóda arc () fungovala podľa vašich potrieb, je potrebné si pohrať s cestami. Cestu otvorte metódou beginPath (), ukončíte closePath () a vykreslíte cez fill (). Tá vyplní uzavretú cestu a stroke vykreslí len obrys.

Animácie

Aby ste docielili efektu animácie, musíte v určitom intervale volať vykresľovanie a aktualizáciu stavu. K tomu môžete použiť dve varianty. Môžete nastaviť interval alebo odpočet s tým, že odpočet by ste potom museli v každom kroku nastaviť nový. Na prvý pohľad sa môže zdať, že interval je teda lepšie, ale opak je pravdou. Interval beží stále, aj keď nie je potreba - animácie predsa nebude nekonečná. Toto síce na bežnom modernom počítači s obvykle 2 a viac jadrovým procesorom nejde spoznať, ale na mobile sa to výrazne negatívne prejaví na výdrži batérie (v dnešnej dobe veľký problém) au niektorých telefónov aj prehrievaniu (ale toho sa väčšinou nevyhnete tak či tak). Osobne vám teda vzhľadom ku koncovému užívateľovi odporúčam metódu odpočtu, nastavíte ju metódou setTimeout (). Ak ste sa aj napriek tomu rozhodli pre interval, tak ten nastavíte cez metódu setInterval (). Aj pre interval je tu ešte jedna možnosť, ktorá by riešila problém zbytočných aktualizácií a to návratovú hodnotu si niekam uložiť a v okamihu konca animácie zavolať clearIterval (), do parametra predáte práve premennú. Vo výsledku to môže vyjsť na rovnaké a je len na vás, ktorá varianta sa vám viac páči.

Ak ste animácie v JavaScripte nikdy nerobili a nie ste v tom zbehlí, tak sa vám možno budú na úvod hodiť jednoduché tipy pre ich tvorbu. Ak by sa mal progressbar animovať, tak sa bude hodnota väčšinu času pohybovať niekde vo vnútri. Najprv to bude 0, potom 1, 2, 3 a nakoniec to bude treba 75 uložených v Attribut data-percent (ten ktorý sme overovali selektorom). K zaradenie tejto pohybujúce sa premenné do aplikácie máte opäť dva varianty. Prvý variant je tá, že to budete celý čas animácie odovzdávať v parametri, tá druhá, že si vytvoríte pomocnú premennú (osobne je pre prehľadnosť označujem tým, že začínajú podčiarknikom). Druhá mi osobne príde o trochu lepšie, pretože robili by ste animáciu, ktorá môže pribúdať alebo ubúdať (možno si hovoríte na čo ubúdanie, to preto, že akonáhle implementuje obsluhu udalosti pre zmenu parametra, tak užívateľ môže zadať hodnotu menšiu ako je doterajší), tak musíte použiť buď inkrementácia, alebo dekrementace, hoci to ide urobiť všetko aj v parametri príde mi krajší variant pracovať s vlastnosťou.

DOMsubtreeModified

Aby sme mohli nejako za behu kontrolovať zmeny parametrov, tak máme (ako už asi už tradične) dve možnosti. Tá prvá je, že budeme v určitom časovom intervale kontrolovať každú hodnotu alebo si odchytíme udalosť DOMsubtreeModified. Tá sa vyvolá vždy v okamihu, keď sa čokoľvek zmení v stromu DOM. Hoci by túto udalosť mali správne spracovať všetky prehliadače, zistil som, že v Google Chrome nefunguje. Neustála kontrola atribútov je jednak asi mierne zložitejšie, kód je menej prehľadnejšie, pretože tam je okolo toho veľa pomocného kódu a ako už som spomínal v odseku o animáciách, pre mobilné zariadenia to nie je to pravé orechové. Preto si odchyt DOMsubtreeModified a obslúžte si to podľa ľubovôle.

Možná vylepšenia

Týmto by ste mali mať progreessbary hotové a môžete sa pustiť do implementácie ďalších vylepšení, dbajte vždy na dobrý návrh, premýšľajte a verte, že prepisovať kód na päťkrát je úplne normálne, niekedy si to ani neuvedomujete. Nakoniec vám výpisy, čo by ste mohli doimplementovat.

  • Voliteľné animácie, dajte možnosť i neanimované verzie, môžete použiť attrbtu data- *
  • Možnosť nastavovania rôznych farieb pre pozadie aj samotný progress
  • Umožniť nastavenie štartového uhla, u niektorých aplikácií sa hodí viac keď pregress začína napríklad v 3/5.
  • Podpora rôzne výšky šírky. Môžete treba vycentrovať obsah, k tomu sa dobre hodí možnosť posunutia kontextu u plátna.

Dúfam že sa vám tento článok páčil, niečo ste sa naučili, ale hlavne dúfam že bol pre vás prínosný a vaše nadchádzajúce výsledky v JavaScripte budú zase o trochu lepší.

Objektovo orientované programovanie v JavaScriptu
Odporúčam sa skúšať zapájať do tunajších minisoutěží Machr na JavaScript. Trénujete nielen JavaScrit, ale aj schopnosť riešiť určitú úlohu rýchlo a celý projekt stihnúť dokončiť do deadline. V machri na JS sa nehodnotí len výsledok, ale aj zdrojový kód. A práve tento článok vás mal naviesť správnou cestou a dať vám niektoré tipy k správnemu návrhu a písanie pekného a dobre čitateľného kódu. Práve guľatý progressbar je úloha jedného predchádzajúceho odborníka. :)

V nasledujúcom cvičení, Riešené úlohy k 23. lekcii OOP v JavaScripte, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 534x (2.36 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript

 

Predchádzajúci článok
Riešené úlohy k 20.-22. lekciu OOP v JavaScripte
Všetky články v sekcii
Objektovo orientované programovanie v JavaScriptu
Preskočiť článok
(neodporúčame)
Riešené úlohy k 23. lekcii OOP v JavaScripte
Článok pre vás napísal Michal Žůrek - misaz
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje tvorbě aplikací pro počítače, mobilní telefony, mikroprocesory a tvorbě webových stránek a webových aplikací. Nejraději programuje ve Visual Basicu a TypeScript. Ovládá HTML, CSS, JavaScript, TypeScript, C# a Visual Basic.
Aktivity