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 JavaScriptem

Možná jste si toho už všimli, možná ještě ne. HTML5 se stává standardem, na kterém vzniká stále více aplikací. Této nové technologii se nevyhýbají ani velké společnosti, jako třeba Google. Hodně lidí si pod pojmem HTML5 představuje novou verzi HTML a je tomu opravdu tak. Avšak nejedná se pouze o nové tagy, kterých je tu spousta, ale i o nové technologie. Jedním z mnoha nových prvků je právě tag <canvas>. Canvas je plátno, na které můžeme kreslit. Jako první ho uvedla firma Apple ve svém OS a poté ho zabudovala i do svého prohlížeče Safari. Postupem času se canvas dostal i do dalších prohlížečů a dnes je již podporován všemi moderními prohlížeči.

Syntaxe, nebo chcete-li zápis, je velmi podobný tagu <img />. Jediný rozdíl je v tom, že canvas je párový tag. Zápis by mohl vypadat takto.

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

Tento kód vytvoří prázdné plátno o velikosti 800x600 pixelů. Nastavíme mu atribut ID, abychom na něj mohli kreslit JavaScriptem. Atributy width a height nastaví výšku a šířku kontextu, na který budeme kreslit. Tyto rozměry nelze nastavit pomocí CSS, jelikož bychom nastavili rozměry plátna, nikoli kontextu. Pokud je ovšem nenastavíme vůbec, budou automaticky nastaveny na 300x150 pixelů.

Element je sice podporován moderními prohlížeči, avšak v prohlížeči Internet Explorer až od verze 9.0. Abychom upozornili uživatele, můžeme použít obsah tagu canvas. Tento obsah bude ignorován všemi prohlížeči, které tag podporují a zobrazí se tak jen tam, kde je ho potřeba.

2D vykreslovací kontext

Canvas podporuje zatím jen pár vykreslovacích kontextů. Jednak to je 2d, který umí, jak už asi tušíte, kreslit 2D objekty a pak také WebGL (zatím většinou jen experimental-WebGL), který umí vykreslovat i 3D objekty. Nás však zatím bude zajímat ten 2D kontext.

Systém souřadnic

Ještě než začneme kreslit, řeknu něco málo k systému souřadnic. Systém je stejný jako je to v případě CSS tedy souřadnice [0;0] určují levý horní roh plátna, nikoli stránky. Jelikož zde funguje většinou absolutní pozicování, všechny souřadnice vycházejí z bodu nula. Pozice se udává v pixelech.

Kontext plátna

Jak už jsem zmínil, kreslíme na kontext plátna. Ten musíme získat z elementu canvas. Pro každé plátno je právě jeden kontext. Tady je ukázka, jak to udělat v JavaScriptu.

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

Metoda getContext elementu Canvas získá kontext plátna s daným vykreslovacím režimem. U zápisu v jQuery si dejte pozor, abyste metodu volali z objektu elementu Canvas a ne z objektu jQuery, proto .get(0).

Nyní můžeme kreslit. Přidejte následující kód za definici proměnné context.

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

Výsledek bude vypadat nějak takto:

Metoda fillRect v Canvasu - JavaScript zdrojákoviště - Základní konstrukce jazyka

Teď jste nakreslili váš první objekt na canvas. Je to jednoduché, ne?

Základní objekty a tvary

Základním objektem je obdélník. Máme předdefinované tři metody, kterými můžeme obdélník nakreslit. Jsou jimi fillRect, strokeRect a clearRect. Všechny tři mají stejné argumenty a to x, y, výška a šířka. Funkce fillRect odbélník vyplní, strokeRect vykreslí pouze jeho obrys a clearRect vymaže oblast daného obdélníku.

// 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ýsledek:

JavaScript zdrojákoviště - Základní konstrukce jazyka

Shrnutí 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);

Čá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 20;150.

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

Další příklad kreslení čar je třeba toto vykreslení mříž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ýsledek skriptu:

Mřížka – Canvas - JavaScript zdrojákoviště - Základní konstrukce jazyka

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

Kruh - JavaScript zdrojákoviště - Základní konstrukce jazyka

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ě dvě základní proměnné, se kterými počítají metody stroke() a fill(). Jednak je to fillStyle a pak také strokeStyle. Jak už 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 CSS3). 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);
JavaScript zdrojákoviště - Základní konstrukce jazyka

Styly čar

Krom barvy vykreslení můžeme stylovat i jiné věci. Například pro styly čar jsou dostupné proměnné lineWidth - velikost vykreslených čar, lineCap - zakončení čar. Hodnoty jsou "butt", "round", "square".

Ukázka stylování čar:

// 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();
Styly zakončení čar - JavaScript zdrojákoviště - Základní konstrukce jazyka

Všimněte si, že neuzavírám cestu metodou closePath(). Je to z důvodů, že lineCap platí pouze pro jednotlivé čáry, nikoli pro komplexní cesty. Pro ty tu je proměnná lineJoin, která má opět tři možné hodnoty a to: "round" - zakulacené, "bevel" - bez přesahu a "miter" - špičaté.

Externí obrázky

Kromě toho, že na plátno můžete kreslit, je tu také možnost vykreslit i nějaký externí obrázek. Jen můžeme načíst z objektu Image (klidně i z tagu img). Nejdřív se ale musíme ujistit, že je obrázek načtený a na to slouží v DOM klasicky onload. Na plátno pak obrázek dostaneme metodou drawImage(obrazek, x, y).

Uvedu jednoduchý příklad. Je třeba na pozadí opakovat obrázky, které jsme si vytvořili. Použijeme proto metodu 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ýsledek? Obrázek typu JavaScript zdrojákoviště - Základní konstrukce jazyka se nám bude opakovat přes celé plátno, přičemž jsme ho načetli pouze jednou a jen vícekrát vykreslili.

Dále je možné obrázku měnit velikost. Jiný způsob zápisu funkce drawImage je následující:

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

A komu by ani tohle ještě nestačilo, poslední možný zápis je:

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

Parametry x1, x2 určují pozici výřezu obrázku. vysla1, sirka1 velikost výřezu. Dále x2, y2 pozici skutečného obrázku a vyska2, sirka2 určují rozměry opět skutečného obrázku. To už je složitější, avšak časem na to přijdete.

Kreslení textu

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:

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

Text bude ale bez stylů a celkem malý. Proto máme k dispozici proměnnou context.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.

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

A vložili jsme na plátno text.

Text na plátně - JavaScript zdrojákoviště - Základní konstrukce jazyka

Tím bych dnešní článek ukončil. Pokud jste byli vytrvalí a dočetli jste se až sem, měli byste zvládat základní manipulaci s prvkem canvas.

Tip na závěr: Metoda canvas.toDataUrl(mimeType) vrací tzv. data URL plátna. Jedná se o zakódovaný řetězec hashem Base64 a lze ho použít v img tagu místo adresy obrázku nebo v CSS u backgrund-image. Data URL vypadá třeba:

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

Použití v HTML např.:

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

 

Všechny články v sekci
JavaScript zdrojákoviště - Základní konstrukce jazyka
Článek pro vás napsal Drahomír Hanák
Avatar
Uživatelské hodnocení:
10 hlasů
Autor v současné době studuje Informatiku. Zajímá se o programování, matematiku a grafiku.
Aktivity