12. díl - Obrázky a kreslení na canvas v JavaScriptu

JavaScript Základní konstrukce Obrázky a kreslení na canvas v JavaScriptu

Vítám vás u dalšího dílu o tvorbě webových stránek a aplikací v JavaScriptu. V tomto díle se podíváme na zub obrázkům.

Na webu existují dva typy obrázků – statické a dynamické. Statické obrázky již znáte a moc se s nimi nedá kouzlit. Jsou to obyčejné obrázky (tag <img>), se kterými můžete provádět jen několik málo základních operací. Povětšinou s nimi manipulujeme jen jako s prvkem DOMu. Dynamické obrázky již mohou být v dokumentu HTML znázorněny 2 značkami – SVG a Canvas. Přičemž první jmenovaná sice není striktně statická, ale vesměs v JavaScriptu s ní toho moc nenaděláme (zatím). Canvas již je o trochu zajímavější a zároveň jediný, jehož obsah nelze definovat jinak než JavaScriptem. Projdeme si to postupně.

Statické obrázky

Jak jsem již zmínil v úvodu, jedná se o klasický obrázek, který v HTML definujeme tagem <img>. Můžeme mu samozřejmě obsluhovat různé události jako je kliknutí a to úplně stejným způsobem jako třeba na tlačítko. V JavaScriptu ho můžeme vytvořit buďto klasicky jako prvek DOM

var img = document.createElement("img");

Nebo můžeme vytvořit nový objekt Image, což je zkrácená varianta tvorby prvku DOM.

var img = new Image();

Načtení obrázku

Velkým problémem je načítání obrázku (ostatně jako načítání čehokoliv v JavaScriptu). Než s obrázkem začneme pracovat, musí se načíst. Pokud máme obrázek v HTML a JavaScript spouštíme v obsluze události load, není žádný problém. Prohlížeč zajistí, že obsluha se zavolá až po načtení všeho (i obrázku).

V případě, že si obrázky zpracováváme až v JavaScriptu, musíme na načtení počkat. Poslouží nám k tomu událost load na daném obrázku.

var img = new Image();
img.src = "cesta/k/obrazku.jpg";

img.onload = function () {
        // tady víme, že je obrázek načtený
}

Příklad: Přepínač

Vytvoříme si přepínač. Jistě znáte přepínač ON-OFF. Obrázky si stáhněte níže a ideálně pojmenujte switch0.png a switch1.png.

Vytvořme stránku, kde bude obrázek s ID prepinac a jako výchozí cestu mu dáme k obrázku prepinac0.png.

<img src="switch0.png" id="prepinac" />

Vytvoříme si skript, kde deklarujeme proměnnou prepinac a po načtení stránky do ní dosadíme náš obrázek přepínače. Dále si vytvoříme funkci Prepni() a nastavíme ji jako obsluhu události pro kliknutí na obrázek.

var prepinac;
window.onload = function () {
        prepinac = document.getElementById("prepinac");
        prepinac.onclick = Prepni;
}

Img.src × img.getAttribu­te("src")

Teď již je to jen o podmínce a změně src, ale... objekt obrázku (u OOP zjistíte, že se jmenuje HTMLImageElement) má vlastnost src. Nabízí se tedy možnosti změnit hodnotu jeho atributu nebo ji dosadit rovnou do této vlastnosti. Jenže... Tyto dvě možnosti se v některých prohlížečích chovají trochu odlišně. Zatímco metoda getAttribute() vrátí přesně tu hodnotu, co je v parametru, src vrátí absolutní cestu. Pokud tedy budeme porovnávat, tak až na pár výjimek budeme porovnávat s hodnotou v atributu. Na vyzkoušení si hodnoty změníme již přes vlastnost src.

function Prepni() {
        if (prepinac.getAttribute("src") == "switch0.png") {
                prepinac.src = "switch1.png"
        } else {
                prepinac.src = "switch0.png"
        }
}

Stránku si otevřete a vyzkoušejte, přepínač by měl fungovat. Všimněte si, že vůbec nemusíme ošetřovat, kdy se obrázek načte, protože nás to nezajímá. Uživatel bude čekat tak či tak, ale my jsme od toho odstínění, pokud s obrázkem dále nepracujeme.

Nyní se přesuneme k dynamickým obrázkům.

Dynamické obrázky

Dynamické obrázky se kreslí na plátno, což je tag <canvas>. Tento element MUSÍ mít atributy width a height. Pokud je neuvedeme nebo je nastavíme třeba v CSS, některé prohlížeče to nepochopí a plátno rozmažou. Na tento samotný element však ještě kreslit nemůžeme, musíme si získat jeho kontext. Možná si říkáte k čemu je to dobré, ten kontext? Ono je totiž rozdíl, když na plátno kreslíte 3D hru a 2D stromeček. 3D se v současnosti teprve prosazuje jako standard WebGL a tím se teď zabývat nebudeme, nás bude zajímat jen kontext 2D. Více jich v současnosti neexistuje.

Získání kontextu plátna

Kontext plátna získáme voláním metody getContext() a jako parametr ji předáme formou textového řetězce typ požadovaného kontextu. V našem případě 2d.

var context = canvas.getContext("2d");

Na tento kontext již můžeme volat různé metody pro vykreslení na plátno.

Čtverce a obdélníky

Základním objektem je obdélník. Máme předdefinované dvě základní metody, kterými můžeme obdélník nakreslit. Jsou jimi fillRect() a strokeRect(). Obě mají stejné argumenty a to x, y, výška a šířka. Funkce fillRect() odbélník vyplní, strokeRect() vykreslí pouze jeho obrys.

context.fillRect(50, 50, 100, 100)
context.strokeRect(200, 50, 100, 100);
Kreslení obdélníků na plátno v JavaScriptu

Čáry

Čáry se na plátno kreslí pomocí tzv. cest. Tyto cesty musíme (resp. měli bychom) je začít a uzavřít. Pro vytvoření cesty použijeme funkci beginPath(), pro uzavření pak closePath(). Samotnou čáru vykreslíme metodou lineTo(x, y). Pozice se odvíjí od poslední nastavené pozice kurzoru (zprvu 0;0), kterou nastavíme funkcí moveTo(x, y). Tato funkce nevykreslí nic, pouze přesune kurzor plátna na danou pozici. Cestu vykreslíme buďto metodou fill(), která vyplní celou cestu barvou (takto se dají kreslit vlastní tvary - proto je třeba cesty uzavírat), nebo funkcí stroke(), která vykreslí pouze čáry z dané cesty. Jednoduchý příklad vykreslí čáru z bodu 20;20 do 40;150.

context.beginPath();
context.moveTo(20, 20);
context.lineTo(40, 150);
context.closePath();
context.stroke();
Kreslení čar na canvas v JavaScriptu

Kruhy, kružnice a výseče

Další, co můžeme na plátno kreslit, jsou kruhy, kružnice a jejich výseče. To vše umí funkce context.arc(), jejíž syntaxe je následovná:

context.arc(x, y, radius, pocatecniUhel, konecnyUhel, smer);

Argumenty x a y určují opět absolutní pozici. Radius udává poloměr kružnice, pocatecniUhel je úhel, od které se má kružnice resp. výseč vykreslit. Je udán v radiánech. Z matematiky všichni samozřejmě víme, že obvod kružnice je 2*PI a že stupně se převedou na radiány (PI/180)*stupně. Poslední proměnná je smer. Jedná se o logickou hodnotu (true/false), která udává, jestli se bude kružnice vykreslovat ve směru hodinových ručiček nebo proti němu. Základně je nastaveno true, tedy ve směru hodinových ručiček.

Kruh tedy nakreslíme takto:

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

Odměnou za tak složitý skript nám bude takovýto kruh.

Kreslení kruhů na canvas v JavaScriptu

Styly

Někdy je třeba, aby kresba nějak vypadala. Na to jsou tu styly. Rozlišujeme styly pro vyplnění (fill) a vykreslení obrysu (stroke). Styly lze aplikovat na všechny objekty od obdélníků po kruhy. Máme k dispozici dvě základní proměnné, se kterými počítají metody stroke() a fill(). Jednak je to fillStyle a pak také strokeStyle. Jak již jsem říkal, jsou to proměnné a jejich hodnoty jsou zápisy barev. Můžeme použít klasický hexadecimální zápis z CSS např. #ffffff nebo rgb(255,255,255). Lze použít také rgba(255,255,­255,0.5), kde poslední hodnota je tzv. alfa kanál (průhlednost) nebo hsl a hsla (stejně jako v CSS 3). A poslední možností je pokud má barva svůj název, uvést ten (např. green).

Ukažme si jednoduché stylování objektů:

// Styly musí být vždy před samotným vykreslením (zavoláním metody fill, stroke nebo samovykreslovacích metod, jako jsou fillRect, strokeRect ...)

context.fillStyle = "#a8c101";
context.fillRect(10, 10, 50, 50);
Stylování canvasu v JavaScriptu

Externí obrázky

Můžeme na plátno samozřejmě vykreslovat i existující obrázky, musíte je však mít načtené, jinak se nevykreslí. Vykreslení obrázku docílíme jednoduše metodou drawImage(), které jako první parametr předáme obrázek a druhý a třetí jsou pozice X a Y kam se obrázek vykreslí. Existují ještě metody s parametry pro zvětšení/zmenšení a ořezání obrázků.

Vykreslení obrázku na canvas v JavaScriptu

Text

Kromě všelijakých tvarů můžeme na plátno vykreslit i text. To se dá využít třeba jako watermark na obrázcích ve vaší galerii, popisky ke grafům nebo úplně jinak, jak vám to jen vaše fantazie dovolí. Základní funkce je fillText(text, x, y). Text zde zastupuje textový řetězec, který chceme vypsat. X a Y jsou absolutní pozice. Jednoduchý text vykreslíme třeba takto:

context.fillText("itnetwork.cz", 50, 50);

Text bude ale bez stylů a celkem malý. Proto máme k dispozici proměnnou con­text.font, kterou musíme jako třeba fillStyle volat ještě před vykreslením textu. Hodnoty proměnné jsou totožné se zápisem v CSS u stejnojmenné vlastnosti font. Nastavíme velikost textu třeba na 30 pixelů a použijeme font sans-serif.

context.font = "30px sans-serif"
context.fillText("itnetwork.cz", 50, 50);
Vypsání textu na canvas v JavaScriptu

To by na úvod stačilo. V příštím díle se podíváme na plátno ještě podrobněji.


 

Stáhnout

Staženo 229x (106.96 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

  Aktivity (3)

Článek pro vás napsal Michal Žůrek (misaz)
Avatar
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.

Jak se ti líbí článek?
Celkem (11 hlasů) :
4.909094.909094.909094.909094.90909


 


Miniatura
Předchozí článek
Cvičení k 11. lekci JavaScriptu
Miniatura
Všechny články v sekci
Základní konstrukce jazyka JavaScript
Miniatura
Následující článek
2D kontext plátna v JavaScriptu

 

 

Komentáře

Avatar
Lukáš Legas Selichar:

Hoj, neni tam chyba? Jednoduchý příklad vykreslí čáru z bodu 20;20 do 20;150. Nemá tam být do 40;150?

 
Odpovědět  +1 30. března 13:01
Avatar
Odpovídá na Lukáš Legas Selichar
Lukáš Legas Selichar:
  • obcas se uvadi promenna context a nekdy kontext, může to mást :)
 
Odpovědět 30. března 14:14
Avatar
Odpovědět 31. března 7:00
Nesnáším {}, proto se jim vyhýbám.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 3 zpráv z 3.