IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

25. diel - Obrázky a kreslenie na canvas v JavaScripte

V minulej lekcii, Práca s číslami a knižnica Math v JavaScripte, sme si predstavili si knižnicu Math pre prácu s číslami.

V dnešnom tutoriáli sa začneme venovať ďalšej väčšej kapitole, práci s grafikou v JavaScripte. Ukážeme si, ako je možné z kódu vkladať do stránky obrázky reprezentované tagom <img> a predstavíme si tag <canvas> (v preklade plátno). Na plátno sa potom naučíme nakresliť jednoduché geometrické tvary.

Práca s obrázkami

Klasický obrázok v HTML definujeme tagom <img>. Môžeme mu samozrejme nastaviť obsluhu udalostí, ako je kliknutie, a to úplne rovnakým spôsobom ako napríklad pri tlačidle.

V JavaScripte obrázok vytvoríme ako akýkoľvek iný element DOM zápisom:

let image = document.createElement("img");

Rovnaký výsledok dosiahneme aj zápisom:

let image = new Image();

Tento variant zároveň umožňuje nastaviť obrázku rozmery. Požadovanú šírku a výšku obrázku v pixeloch zadáme ako parametre v zátvorke:

let image = new Image(100, 200); // 100 is the width and 200 is the height

Načítanie obrázku

Než s obrázkom začneme pracovať, musí sa načítať. Ak máme obrázok v HTML a JavaScript spúšťame v obsluhe udalosti onload, nie je žiadny problém. Prehliadač zaistí, že sa náš kód zavolá, až bude načítaná celá stránka.

V prípade, že si obrázky vytvárame až v JavaScripte, musíme na načítanie počkať. Použijeme teda udalosť onload na danom obrázku:

let image = new Image();
image.src = "path/to/image.jpg";

image.onload = function () {
    // Here we know that the image is loaded
}

Ďalšou dôležitou udalosťou pri práci s obrázkami je udalosť onerror, ktorá je aktivovaná, keď dôjde k chybe pri načítaní obrázku. Ku kódu vyššie doplníme:

image.onerror = function() {
    console.error("Error while loading image: " + image.src);
    // Additional code
};

V tomto príklade sa v prípade chyby pri načítaní obrázka zobrazí v konzole uvedený text. Obsluhu chyby je však možné upraviť aj rozšíriť o ďalšie akcie, ako je nastavenie náhradného obrázku alebo výpis informácie o chybe na stránke.

Ukážme si rovnaký kód s obsluhou udalostí pomocou metódy addEventListener():

let image = new Image();
image.src = "path/to/image.jpg";

image.addEventListener('load', function() {
    // Here we know that the image is loaded
});

image.addEventListener('error', function() {
    console.error("Error while loading image: " + image.src);
    // Additional code
});

Všimnime si, že sme udalosť načítania nenastavili ako DOMContentLoaded, ale ako load. Takto overíme, že boli načítané aj externé zdroje (ako napríklad obrázky) a nie iba štruktúra HTML stránky, teda všetky tagy DOM elementov.

Prepínanie obrázkov

Poďme si ukázať jednoduchý príklad, v ktorom budeme meniť obrázok na stránke. Vytvoríme si prepínač. Po kliknutí na obrázok so zapnutým prepínačom vložíme do stránky obrázok s vypnutým prepínačom a naopak. Obrázky sú na stiahnutie nižšie, pomenujeme ich shunt0.png a shunt1.png a uložíme ich do zložky nového projektu:

Prepinac - Základné konštrukcie jazyka JavaScript Prepinac - Základné konštrukcie jazyka JavaScript

Teraz vytvorme stránku, kde bude v <body> obrázok s id shunt. Ako východiskový obrázok nastavíme shunt0.png:

<img src="shunt0.png" id="shunt" alt="Shunt" />

Doplníme skript, v ktorom deklarujeme premennú shunt a po načítaní stránky do nej dosadíme náš element obrázku prepínača. Obrázku nastavíme obsluhu udalosti kliknutia, v ktorej zavoláme funkciu switchIt(), ktorú vzápätí doplníme.

let shunt;

window.onload = function() {
    shunt = document.getElementById("shunt");
    shunt.onclick = switchIt;
}

Zmena atribútu src

Vo funkcii switchIt() budeme potrebovať zistiť a zmeniť aktuálnu hodnotu atribútu src elementu <img>. Tento atribút získame pomocou metódy getAttribute(), ktorá vracia presnú hodnotu zapísanú v atribúte. V podmienke ju potom porovnáme s názvom jedného z obrázkov a potom nastavíme opačný obrázok:

function switchIt() {
    if (shunt.getAttribute("src") == "shunt0.png") {
        shunt.src = "shunt1.png";
    } else {
        shunt.src = "shunt0.png";
    }
}

Keby sme v prvej časti podmienky namiesto metódy getAttribute("src") použili vlastnosť src a zapísali shunt.src, získame absolútnu cestu k súboru s obrázkom, napríklad https://www.example.com/images/my-image.jpg.

Stránku si otvoríme a prepínač vyskúšame:

Switch
localhost

Plátno

Teraz si predstavíme plátno a ukážeme si, ako naň kresliť. Plátno je vhodné použiť pre prípady, keď potrebujeme vytvárať obrázky dynamicky, pretože jeho obsah musíme definovať programovo v JavaScripte.

Plátno je reprezentované párovým tagom <canvas>. Tento element musí mať nastavené atribúty width a height priamo v tagu <canvas>. Ak ich nezadáme alebo ich definujeme iba v CSS, môže to viesť k nežiaducim výsledkom. Zatiaľ čo CSS mení veľkosť zobrazenia plátna, neprispôsobuje jeho vnútorné rozlíšenie, čo môže viesť k rozmazanému alebo skreslenému obsahu v niektorých prehliadačoch.

Do tela novej HTML stránky teda vložíme plátno takto:

<canvas width="500" height="500" id="canvas"></canvas>

Získanie kontextu plátna

Aby sme mohli na plátno začať kresliť, musíme si získať jeho kontext. Kontext určuje, aký typ obsahu budeme vytvárať. Existujú rôzne typy kontextov, my sa zameriame na 2D kontext, ktorý je ideálny pre väčšinu grafických úloh.

Pre prácu s 3D grafikou poskytuje JavaScript knižnicu WebGL (Web Graphics Library). My si ju však v tomto kurze základov predstavovať nebudeme a zameriame sa iba na prácu s 2D kontextom.

Kontext plátna získame volaním metódy getContext(). Ako parameter jej odovzdáme formou textového reťazca typ požadovaného kontextu. V našom prípade je to 2d:

let canvas;
let context;

window.onload = function () {
    canvas = document.getElementById("canvas");
    context = canvas.getContext("2d");

    // Here will be the code for rendering individual geometric shapes
}

Na tomto kontexte už môžeme volať rôzne metódy na kreslenie.

Obdĺžniky

Základným objektom je obdĺžnik. Obdĺžnik nakreslíme pomocou metódy fillRect() alebo strokeRect(). Obe prijímajú rovnaké argumenty. V prvých dvoch zadáme súradnice ľavého horného rohu obdĺžnika (x a y). Pomocou ďalších dvoch argumentov nastavujeme výšku a šírku (width a height) obdĺžnika. Metóda fillRect() obdĺžnik vyplní, metóda strokeRect() vykreslí iba jeho obrys.

Kód vyššie doplníme a nakreslíme dva rovnako veľké štvorce:

let canvas;
let context;

window.onload = function () {
    canvas = document.getElementById("canvas");
    context = canvas.getContext("2d");

    context.fillRect(50, 50, 100, 100);
    context.strokeRect(200, 50, 100, 100);
}

Plnému štvorcu sme nastavili súradnice x a y na hodnotu 50, výšku a šírku sme nastavili na 100. Obrys štvorca má rovnaké hodnoty, iba os x je posunutá na pozíciu 200.

Výsledok:

Canvas
localhost

Čiary a trojuholníky

Čiary sa na plátno kreslia pomocou tzv. ciest. Tieto cesty musíme začať a uzavrieť. Najprv teda voláme metódu beginPath(), ktorá vytvorí novú cestu a prerušuje predchádzajúcu, pokiaľ kreslíme viac nezávislých obrazcov. Na uzavretie cesty zavoláme metódu closePath().

Samotnú čiaru vykreslíme metódou lineTo(). Čiara sa v predvolenom nastavení pozície kurzora vykreslí z pozície [0;0]. Túto pozíciu môžeme zmeniť metódou moveTo(). Metóda nevykreslí nič, iba presunie kurzor plátna na danú pozíciu. Obe uvedené metódy prijímajú parameter x a y. Samotnú čiaru potom vykreslíme metódou stroke().

Aj v ďalších príkladoch musíme najskôr počkať na načítanie dokumentu, potom získať element plátna z HTML súboru a nastaviť mu kontext. V ukážkach však už budeme uvádzať iba kód na kresbu jednotlivých geometrických tvarov.

Jednoduchý príklad nižšie vykreslí čiaru z bodu [20;20] do [40;150]:

context.beginPath();
context.moveTo(20, 20);
context.lineTo(40, 150);
context.closePath();
context.stroke();

Pridaním druhej čiary potom vytvoríme obrázok trojuholníka. Je to preto, že pri zatvorení cesty dochádza k prepojeniu východiskového bodu s konečným bodom:

context.beginPath();
context.moveTo(120, 20);
context.lineTo(140, 150);
context.lineTo(200, 100);
context.closePath();
context.stroke();

Teraz môžeme použiť aj metódu fill(), ktorá vyplní vnútro cesty farbou a vykreslí vyplnený trojuholník:

context.beginPath();
context.moveTo(270, 20);
context.lineTo(290, 150);
context.lineTo(350, 100);
context.closePath();
context.fill();

Výsledok:

Canvas
localhost

Kruhy, kružnice a výseče

Ďalšou metódou na kreslenie na plátno kresliť je metóda arc(). Tá vie nakresliť kruh, kružnicu a ich výseče. Jej syntax je nasledovná:

context.arc(x, y, radius, initialAngle, finalAngle, direction);

Parametre x a y určujú pozíciu stredu kruhu, ďalej uvádzame jeho radius (polomer). Nasledujú parametre initialAngle a finalAngle, tu volíme, či vykresliť celú kružnicu alebo jej výseč.

Každý uhol udávame v radiánoch. Plný uhol je 2 * PI, stupne sa prevedú na radiány ako (PI / 180) * stupně.

Kružnica sa v predvolenom nastavení vykresľuje v smere hodinových ručičiek. Toto nastavenie zmeníme doplnením voliteľného parametra direction s hodnotu true. Metódu arc() musíme používať vo vnútri cesty.

Kruh teda nakreslíme takto:

context.beginPath();
context.arc(100, 100, 80, 0, Math.PI * 2);
context.closePath();
context.fill();

Pridajme si k existujúcemu príkladu ešte ukážku na vykreslenie kružnice:

context.beginPath();
context.arc(300, 100, 80, 0, Math.PI * 2);
context.closePath();
context.stroke();

V prehliadači sa zobrazí:

Canvas
localhost

Na záver si ukážme, ako nakresliť výseč. Takto si nakreslíme nevyplnený polkruh:

context.beginPath();
context.arc(100, 100, 80, 0, Math.PI);
context.closePath();
context.stroke();

Potom vykreslíme plný polkruh a v metóde arc() pridaním voliteľného parametra určíme smer vykresľovania proti smeru hodinových ručičiek:

context.beginPath();
context.arc(300, 100, 80, 0, Math.PI, true);
context.closePath();
context.fill();

Výsledok:

Canvas
localhost

Dnes sme si ukázali kreslenie základných geometrických tvarov. Plátno ponúka oveľa viac ďalších možností, ktoré si ukážeme nabudúce.

V budúcej lekcii, Štylovanie obrázkov a vloženie textu na plátno v JavaScripte, budeme pokračovať v práci s obrázkami, naučíme sa zmeniť ich farbu, šírku čiary alebo doplniť na canvas text.


 

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

 

Predchádzajúci článok
Práca s číslami a knižnica Math v JavaScripte
Všetky články v sekcii
Základné konštrukcie jazyka JavaScript
Preskočiť článok
(neodporúčame)
Štylovanie obrázkov a vloženie textu na plátno v JavaScripte
Článok pre vás napísal Michal Žůrek - misaz
Avatar
Užívateľské hodnotenie:
5 hlasov
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