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

Canvas aneb grafika JavaScriptom

Možno ste si toho už všimli, možno ešte nie. HTML5 sa stáva štandardom, na ktorom vzniká čoraz viac aplikácií. Tejto novej technológii sa nevyhýbajú ani veľké spoločnosti, ako napríklad Google. Veľa ľudí si pod pojmom HTML5 predstavuje novú verziu HTML a je tomu naozaj tak. Avšak nejedná sa len o nové tagy, ktorých je tu veľa, ale aj o nové technológie. Jedným z mnohých nových prvkov je práve tag <canvas>. Canvas je plátno, na ktoré môžeme kresliť. Ako prvá ho uviedla firma Apple vo svojom OS a potom ho zabudovala aj do svojho prehliadača Safari. Postupom času sa canvas dostal aj do ďalších prehliadačov a dnes je už podporovaný všetkými modernými prehliadačmi.

Syntax, alebo ak chcete zápis, je veľmi podobný tagu <img />. Jediný rozdiel je v tom, že canvas je párový tag. Zápis by mohol vyzerať takto.

<canvas width="800" height="600" id="platno">
   Váš prohlížeč nepodporuje tag canvas.
</canvas>

Tento kód vytvorí prázdne plátno s veľkosťou 800x600 pixelov. Nastavíme mu atribút ID, aby sme na neho mohli kresliť JavaScriptom. Atribúty width a height nastaví výšku a šírku kontextu, na ktorý budeme kresliť. Tieto rozmery nie je možné nastaviť pomocou CSS, pretože by sme nastavili rozmery plátna, nie kontextu. Ak je však nenastavíte vôbec, budú automaticky nastavené na 300x150 pixelov.

Element je síce podporovaný modernými prehliadači, avšak v prehliadači Internet Explorer až od verzie 9.0. Aby sme upozornili užívateľa, môžeme použiť obsah tagu canvas. Tento obsah bude ignorovaný všetkými prehliadačmi, ktoré tag podporujú a zobrazí sa tak len tam, kde je ho potrebné.

2D vykresľovací kontext

Canvas podporuje zatiaľ len pár vykresľovacích kontextov. Jednak to je 2d, ktorý vie, ako už asi tušíte, kresliť 2D objekty a potom tiež WebGL (zatiaľ väčšinou len experimental-WebGL), ktorý vie vykresľovať aj 3D objekty. Nás však zatiaľ bude zaujímať ten 2D kontext.

Systém súradníc

Ešte než začneme kresliť, poviem niečo málo k systému súradníc. Systém je rovnaký ako je to v prípade CSS teda súradnice [0; 0] určujú ľavý horný roh plátna, nie stránky. Keďže tu funguje väčšinou absolútnu pozicovanie, všetky súradnice vychádzajú z bodu nula. Pozície sa udáva v pixeloch.

Kontext plátna

Ako som už spomenul, kreslíme na kontext plátna. Ten musíme získať z elementu canvas. Pre každé plátno je práve jeden kontext. Tu je ukážka, ako to urobiť v JavaScripte.

// Najdeme náš canvas element
var canvas = document.getElementById("platno");
// Získáme kontext plátna
var context = canvas.getContext("2d");

// Syntaxe v jQuery:
var canvas = $('#platno').get(0);
// Kontext
var context = canvas.getContext("2d");

Metóda getContext elementu Canvas získa kontext plátna s daným vykreslovacím režimom. U zápisu v jQuery si dajte pozor, aby ste metódu volali z objektu elementu Canvas a nie z objektu jQuery, preto .get(0).

Teraz môžeme kresliť. Pridať nasledujúci kód za definíciu premennej context.

context.fillRect(20, 20, 100, 100);

Výsledok bude vyzerať nejako takto:

Metóda fillRect v Canvas, - JavaScriptu zdrojákoviště - Základná konštrukcia jazyka
Teraz ste nakreslili váš prvý objekt na canvas. Je to jednoduché, nie?

Základné objekty a tvary

Základným objektom je obdĺžnik. Máme preddefinované tri metódy, ktorými môžeme obdĺžnik nakresliť. Sú nimi fillRect, strokeRect a clearRect. Všetky tri majú rovnaké argumenty a to x, y, výška a šírka. Funkcia fillRect odbélník vyplní, strokeRect vykreslí len jeho obrys a clearRect vymaže oblasť daného obdĺžnika.

// Vyplní čtverec o velikosti a = 100 na pozici 20, 20
context.fillRect(20, 20, 100, 100);
// Vymažeme vevnitř toho čtverce pole 80x80
context.clearRect(30, 30, 80, 80);
// A vykreslíme si tam obrys
context.strokeRect(40, 40, 60, 60);

výsledok:

JavaScriptu zdrojákoviště - Základná konštrukcia jazyka

Zhrnutie zápisu:
// Vyplní obdélník na x,y o velikostech width*height
context.fillRect(x, y, width, height);
// Vykreslí obrys obdélníku
context.strokeRect(x, y, width, height);
// Vymaže oblast obdélníku
context.clearRect(x, y, width, height);

Čiary

Čiary sa na plátno kreslí pomocou tzv. Ciest. Tieto cesty musíme (resp. Mali by sme) je začať a uzavrieť. Pre vytvorenie cesty použijeme funkciu beginPath (), pre uzatvorenie potom closePath (). Samotnú čiaru vykreslíme metódou Linette (x, y). Pozície sa odvíja od poslednej nastavenej polohy kurzora (sprvu 0; 0), ktorú nastavíme funkcií MOVETO (x, y). Táto funkcia nevykreslí nič, len presunie kurzor plátna na danú pozíciu. Cestu vykreslíme buď metódou fill (), ktorá vyplní celú cestu farbou (takto sa dajú kresliť vlastné tvary - preto je potrebné cesty uzatvárať), alebo funkciou stroke (), ktorá vykreslí len čiary z danej cesty. Jednoduchý príklad vykreslí čiaru z bodu 20; 20 do 20; 150.

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

Ďalší príklad kreslenie čiar je potrebné toto vykreslenie mriežky:

context.beginPath();
for(var x = 0; x < canvas.width; x += 40) {
    context.moveTo(0.5 + x, 0);
    context.lineTo(0.5 + x, canvas.width);
}
for(var y = 0; y < canvas.height; y += 40) {
    context.moveTo(0, 0.5 + y);
    context.lineTo(canvas.height, 0.5 + y);
}
context.closePath();
context.stroke();

Výsledok skriptu:

Mriežka – Canvas - JavaScriptu zdrojákoviště - Základná konštrukcia jazyka

Zhrnutie zápisu:
// Začne cestu
context.beginPath();
// Přesune kurzor na x, y
context.moveTo(x, y);
// Vykreslí čáru z kurzoru na x, y
context.lineTo(x, y);
// Uzavře cestu
context.closePath();
// Vykreslí cestu
context.stroke();
// Vyplní cestu
context.fill();

Kruhy, kružnice a výseky

Ďalšie, čo môžeme na plátno kresliť sú kruhy, kružnice a ich výseče. To všetko vie funkcie context.arc (), ktorej syntax je nasledovná:

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

Argumenty xay určujú opäť absolútnu pozíciu. Radius udáva polomer kružnice, pocatecniUhel je uhol, od ktorej sa má kružnice resp. výseč vykresliť. Je udaný v radiánoch. Z matematiky všetci samozrejme vieme, že obvod kružnice je 2 * PI a že stupňa sa prevedú na radiány (PI / 180) * stupňa. Posledný premenná je smer. Ide o logickú hodnotu (true / false), ktorá udáva, či sa bude kružnice vykresľovať v smere hodinových ručičiek alebo proti nemu. Základni je nastavené true, teda v smere hodinových ručičiek.

Kruh teda nakreslíme takto:

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

Odmenou za tak zložitý skript nám bude takýto kruh.

kruh - JavaScriptu zdrojákoviště - Základná konštrukcia jazyka

Štýly

Niekedy je potrebné, aby kresba nejako vyzerala. Na to sú tu štýly. Rozlišujeme štýly pre vyplnenie (fill) a vykreslenie obrysu (stroke). Štýly možno aplikovať na všetky objekty od obdĺžnikov po kruhy. Máme k dispozícii dve dve základné premenné, s ktorými počítajú metódy stroke () a fill (). Jednak je to fillStyle a potom tiež strokeStyle. Ako som už hovoril, sú to premenné a ich hodnoty sú zápisy farieb. Môžeme použiť klasický hexadecimálne zápisnica z CSS napr. #FFFFFF alebo rgb (255,255,255). Možno použiť aj RGBA (255,255,255,0.5), kde posledná hodnota je tzv. Alfa kanál (priehľadnosť) alebo HSL a hsla (rovnako ako v CSS3). Jednoduché štýlovanie objektov:

// 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);
JavaScriptu zdrojákoviště - Základná konštrukcia jazyka

Štýly čiar

Okrem farby vykreslenie môžeme stylovať aj iné veci. Napríklad pre štýly čiar sú dostupné premenné lineWidth - veľkosť vykreslených čiar, lineCap - zakončenie čiar. Hodnoty sú "butt", "round", "square".

Ukážka štýlovanie čiar:

// Nastavíme výchozí tloušťku čar
context.lineWidth = 10;

context.beginPath();
context.moveTo(10, 10);
context.lineTo(10, 50);
// Zakulacené zakončení
context.lineCap = "round";
context.stroke();

context.beginPath();
context.moveTo(40, 10);
context.lineTo(40, 50);
// Rovné zakončení
context.lineCap = "square";
context.stroke();

context.beginPath();
context.moveTo(70, 10);
context.lineTo(70, 50);
// Rovné zakončení bez přesahu
context.lineCap = "butt";
context.stroke();
Štýly zakončenie čiar - JavaScriptu zdrojákoviště - Základná konštrukcia jazyka
Všimnite si, že neuzatvárajú cestu metódou closePath (). Je to z dôvodov, že lineCap platí len pre jednotlivé čiary, nie pre komplexné cesty. Pre tých tu je premenná lineJoin, ktorá má opäť tri možné hodnoty a to: "round" - zaguľatené, "bevel" - bez presahu a "miter" - špicaté.

Externé obrázky

Okrem toho, že na plátno môžete kresliť, je tu tiež možnosť vykresliť aj nejaký externý obrázok. Len môžeme načítať z objektu Image (pokojne aj z tagu img). Najskôr sa ale musíme uistiť, že je obrázok načítaný a na to slúžia v DOM klasicky onload. Na plátno potom obrázok dostaneme metódou drawImage (obrazok, x, y).

Uvediem jednoduchý príklad. Treba na pozadí opakovať obrázky, ktoré sme si vytvorili. Použijeme preto metódu drawImage:

var obrazek = new Image();
obrazek.onload = function() {
    for(var x = 0; x < canvas.width; x++) {
        for(var y = 0; y < canvas.height; y++) {
            context.drawImage(this, x*this.width, y*this.height);
        }
    }
};
obrazek.src = "images/pixel.png";

A výsledok? obrázok typu JavaScriptu zdrojákoviště - Základná konštrukcia jazyka
sa nám bude opakovať cez celé plátno, pričom sme ho načítali len raz a len viackrát vykreslili.

Ďalej je možné obrázku meniť veľkosť. Iný spôsob zápisu funkcie drawImage je nasledovné:

context.drawImage(obrazek, x, y, vyska, sirka);

A komu by ani toto ešte nestačilo, posledný možný zápis je:

context.drawImage(obrazek, x1, y1, vyska1, sirka1, x2, y2, vyska2, sirka2);

Parametre x1, x2 určujú pozíciu výrezu obrázku. vysla1, sirka1 veľkosť výrezu. Ďalej x2, y2 pozíciu skutočného obrázka a výška2, sirka2 určujú rozmery opäť skutočného obrázka. To už je zložitejšie, avšak časom na to prídete.

Kreslenie textu

Okrem všakovakých tvarov môžeme na plátno vykresliť i text. To sa dá využiť napríklad ako watermark na obrázkoch vo vašej galérii, menovkami ku grafom alebo úplne inak, ako vám to len vaša fantázia dovolí :) Základné funkcie je fillText(text, x, y). Text tu zastupuje textový reťazec, ktorý chceme vypísať. X a Y sú absolútnou pozície. Jednoduchý text vykreslíme napríklad takto:

var text = "itnetwork.cz";
context.fillText(text, 10, 10);

Text bude ale bez štýlov a celkom malý. Preto máme k dispozícii premennú context.font, ktorú musíme ako trebárs fillStyle volať ešte pred vykreslením textu. Hodnoty premenné sú totožné so zápisom v CSS pri rovnomennej vlastnosti font. Nastavíme veľkosť textu treba na 30 pixelov a použijeme font sans-serif.

var text = "itnetwork.cz";
context.font = "30px sans-serif";
context.fillText(text, 5, 35);

A vložili sme na plátno text.

Text na plátne - JavaScriptu zdrojákoviště - Základná konštrukcia jazyka
Tým by som dnešný článok ukončil. Ak ste boli vytrvalí a dočítali ste sa až sem, mali by ste zvládať základné manipuláciu s prvkom canvas.

Tip na záver: Metóda canvas.toDataUrl(mimeType) vracia tzv. Dáta URL plátna. Jedná sa o zakódovaný reťazec hashom Base64 a možno ho použiť v img tagu miesto adresy obrázka alebo v CSS u backgrund-image. Dáta URL vyzerá potrebné:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAADFBMVEXx9vnw9fj+/v7///+vmeNIAAAAKklEQVQIHQXBAQEAAAjDoHn6dxaqrqpqAAWwMrZRs8EKAzWAshkUDIoZPCvPAOPf77MtAAAAAElFTkSuQmCC

Použitie v HTML napr .:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAADFBMVEXx9vnw9fj+/v7///+vmeNIAAAAKklEQVQIHQXBAQEAAAjDoHn6dxaqrqpqAAWwMrZRs8EKAzWAshkUDIoZPCvPAOPf77MtAAAAAElFTkSuQmCC" alt="Moje kresba" />

 

Všetky články v sekcii
JavaScriptu zdrojákoviště - Základná konštrukcia jazyka
Článok pre vás napísal Drahomír Hanák
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor v současné době studuje Informatiku. Zajímá se o programování, matematiku a grafiku.
Aktivity