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:
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:
// 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:
// 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.
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);
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();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
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.
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" />