Přejít k navigační liště

Zdroják » JavaScript » Začínáme s HTML5 canvasem

Začínáme s HTML5 canvasem

Články JavaScript, Různé

Canvas je pravděpodobně jednou z nejrevolučnějších značek HTML5. V dnešním článku si tuto značku představíme a naučíme se její základní použití. Ukážeme, jak pomocí ní kreslit základní geometrické útvary přímo do webové stránky.

Tento článek je překladem anglického originálu vydaného na Dev.Opera. Autorem původního textu je Mihai Sucan.

Úvod

Specifikace HTML5 obsahuje řadu nových vlastností, jednou z nich je značka canvas . HTML 5  canvas vám nabízí snadnou možnost kreslení grafiky pomocí JavaScriptu. V každé značce canvas můžete použít „context“, jehož javascriptové metody nakreslí cokoliv chcete. Prohlížeče mohou implementovat více contextů s rozličnými API.

Většina prohlížečů implementovala 2D context canvasu – Opera, Firefox, Chrome a Safari (IE canvas nepodporuje, ale většina API canvasu je v něm snadno emulovatelná pomocí VML – pozn. překl.). Existuje také experimentální build Opery s implementací 3D contextu a rozšíření, které přidá podporu 3D contextu do Firefoxu:

Tento článek vás provede základy 2D contextu canvasu, používáním základních funkcí včetně čar, tvarů, obrázků, textu a dalších. Budeme předpokládat, že znáte základy JavaScriptu.

Můžete si také stáhnout zdrojový kód příkladů z článku.

Základy používání canvasu

Použití canvasu na vaší stránce je velmi jednoduché, stačí přidat značku <canvas> do vašeho HTML, např.:

<canvas id="myCanvas" width="300" height="150">
  Fallback content (náhradní obsah) pro prohlížeče, které canvas nepodporují.
</canvas> 

Definovali jsme id elementu, abychom se na něj mohli snadno odkazovat z JavaScriptu a také jsme definovali jeho šířku a výšku. Tím jsme si vytvořili kreslící plochu. Pojďte si něco nakreslit.

Pro kreslení do canvasu budeme potřebovat JavaScript. Nejprve vytvoříme referenci na náš canvas pomocí getElementById a následně inicializujeme požadovaný context. Pak už můžeme začít kreslit do canvasu pomocí rozhraní contextu, který jsme inicializovali. Následující skript (živá ukázka) do našeho canvasu nakreslí jednoduchý obdélník:

// Odkaz na canvas
var elem = document.getElementById('myCanvas');

// Vždy kontrolujte dostupnost vlastností a metod, to aby skript skript
// v nějakém prohlížeči "nehavaroval".
if (elem && elem.getContext) {
  // získáme 2d context.
  // Zapamatujte si: pro jednu značku canvas můžete inicializovat jen 1 context.
  var context = elem.getContext('2d');
  if (context) {
    // Nyní nakreslíme obdélník.
    // Zadáme souřadnice x,y následované šířkou a výškou.
    context.fillRect(0, 0, 150, 100);
  }
} 

Skript můžete vložit ho hlavičky vašeho dokumentu nebo do externího souboru, to je na vás.

API 2D contextu

Nyní, když jsme si vytvořili náš první příklad, se můžeme podívat na API 2D contextu hlouběji, ať vidíme, co máme k dispozici.

Kreslení čar

Pokud jste si prostudovali příklad výše, je pro vás jednoduché nakreslit obdélník jakékoliv barvy.

Pomocí vlastností fillStyle a strokeStyle snadno nastavíte, jaká barva bude použita pro vyplnění a jaká pro obrys. Můžete používat stejné hodnoty barev jako v kaskádových stylech: šestnáctkové kódy, rgb(), rgba() and dokonce hsla() pokud to prohlížeč podporuje (např. Opera 10 a Firefox 3).

Metoda fillRect nakreslí vyplněný obdélník, metoda strokeRect nakreslí obdélník bez výplně obsahující pouze obrysy. Pokud chcete vyčistit část canvasy, můžete použít metodu clearRect. Všechny tyto tři metody používají stejné argumenty: x, y, width, height. První dva argumenty jsou souřadnice x, y, další dva argumenty jsou šířka a výška obdélníku.

Tloušťku pak nastavíme vlastností lineWidth. Podívejme se na příklad používající metody fillRect, strokeRectclearRect :

context.fillStyle   = '#00f'; // modrá
context.strokeStyle = '#f00'; // červená
context.lineWidth   = 4;

// Nakreslíme obdélníky.
context.fillRect  (0,   0, 150, 50);
context.strokeRect(0,  60, 150, 50);
context.clearRect (30, 25,  90, 60);
context.strokeRect(30, 25,  90, 60); 

Výstup tohoto příkladu najdete na obrázku 1.

Ukázka použití fillRect, strokeRect a clearRect.

Obr. 1: Ukázka použití fillRect, strokeRect a clearRect.

Cesty (paths)

Cesty vám umožní kreslit libovolné tvary. Napřed vyznačíte obrys, ten pak můžete vyplnit a nakreslit obrysovou čáru, pokud chcete. Vytvoření tvaru je jednoduché – na začátku zavoláte beginPath(), následně nakreslíte cestu pomocí čar a dalších metod. Jakmile jste hotovi, zavoláte fill a stroke  – pokud chcete tvar vyplnit nebo vykreslit obrysovou čáru. Na konci zavoláte metodu  closePath().

Následuje příklad – tento kód nakreslí trojúhelník:

// Nastavení stylu
context.fillStyle   = '#00f';
context.strokeStyle = '#f00';
context.lineWidth   = 4;

context.beginPath();
// Začíná se v levém horním rohu
context.moveTo(10, 10); // souřadnice (x,y)
context.lineTo(100, 10);
context.lineTo(10, 100);
context.lineTo(10, 10);

// Hotovo. Nyní tvar vyplníme a nakreslíme obrys.
// Pozn.: vyznačený tvar nebude viditelný, dokud nezavoláte jednu z těchto dvou metod.
context.fill();
context.stroke();
context.closePath(); 

Výsledek bude stejný jako na obrázku 2.

Triangle

Obr. 2: Trojúhelník.

Připravil jsem pro vás i komplikovanější cesty kombinující čáry, křivky a oblouky – jen se podívejte.

Vkládání obrázků

Metoda drawImage vám dovolí vložit do vašeho canvasu obrázek (ze značek img nebo canvas). V Opeře můžete do canvasu nakreslit i SVG obrázky. (Metoda drawImage je jednou z metod, kterou není možné emulovat v Internet Exploreru – pozn. překl.) Jedná se o komplikovanou metodu, která používá tři, pět nebo devět argumentů:

  • Tři argumenty: základní použití drawImage obsahuje argument odkazující na vkládaný obrázek a dvě souřadnice obsahující místo vložení do vašeho contextu v canvasu.
  • Pět argumentů: o něco komplikovanější varianta drawImage obsahuje předchozí tři argumenty a navíc šířku a výšku vkládaného obrázku (pro případ, že chcete změnit jeho velikost).
  • Devět argumentů: nejkomplikovanější použití drawImage obsahuje předchozích pět argumentů a navíc dvě souřadnice uvnitř vkládaného obrázku a také šířku a výšku. Tuto variantu použijete, pokud chcete obrázek dynamicky oříznout před jeho vložením do canvasu.

Následující kód ukazuje všechny tři způsoby použití  drawImage :

// Tři argumenty: element, cílové souřadnice (x,y).
context.drawImage(img_elem, dx, dy);

// Pět argumentů: element, cílové souřadnice (x,y)
// a cílová šířka s výškou.
context.drawImage(img_elem, dx, dy, dw, dh);

// Devět argumentů: element, zdrojové souřadnice (x,y), šířka a výška pro oříznutí,
// cílové souřadnice a cílová šířka s výškou (pro změnu velikosti).
context.drawImage(img_elem, sx, sy, sw, sh, dx, dy, dw, dh); 

Výsledek bude vypadat jako na obrázku 3.

Ukázka kreslení metodou drawImage.

Obr. 3: Příklad použití drawImage .

Pokračování příště

To není všechno. Příště vás seznámíme s dalšími možnostmi canvasu, jakou je práce s pixely, textem a používání gradientů.

Tento článek je překladem textu HTML 5 canvas – the basics, jehož autorem je Mihai Sucan a je zde zveřejněn s laskavým svolením Opera Software.

Použili jeste někdy canvas?

Komentáře

Subscribe
Upozornit na
guest
46 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
Anonymní

"Začínáme z HTML5 canvasem"

s kým čím?
(po opravě smažte)

ares952

Taky me to hned bouchlo do oci :-)

MD

super

JanJanuska

Myslíte, že bude mať canvas niekedy praktické využitie?
Mňa zatiaľ nič nenapadlo, možno nejaké vykresľovanie grafov a podobne, ale veď to už sa dá aj inak

JanJanuska

To s tým "inak" som myslel tak, že aké výhody (oproti iným technológiám) so sebou prináša canvas?
Prostredníctvom canvasu nie je možná interakcia užívateľa (ak sa nemýlim), predstavujem si ho ako vygenerovaý obrázok.

MD
JanJanuska

Skvelé! Presne niečo takéto som potreboval vidieť, ďakujem :)
"Tuším", že som sa s tou interakciou mýlil, teraz pre mňa canvas naberá úplne iný rozmer

xurpha

Tak nevim, ale proc to neudelat radeji pomoci SVG?

karf

No s tím skriptováním měl ovšem kolega výše tak trochu pravdu. Interakce je dost omezená a veškeré události myši musí člověk počítat ručně. Např. mapka s hovery nad jednotlivými oblastmi se canvasem dělá dost neohrabaně. V tomto je lepší SVG (pokud není potřeba zrovna vysoký výkon).

karf

To je pravda. Ale dneska je canvas hrozně módní a mám pocit, že hype kolem canvasu trochu zastiňuje SVG, které se na mnohé aplikace hodí lépe. Pak se dostáváme k paradoxním situacím, kdy emulujeme interakce myši nad cavasem pomocí javascriptu, přičemž canvas v IE emulujeme pomocí ExCanvasu, který vnitřně používá VML, které vlastně tyto události umí nativně :) V tomto případě mi přijde vhodnější např. i zde na zdrojáku popisovaná knihovna Raphael. Samozřejmě je možné, že u nativního canvasu a rychlého JS se i u té emulace dostaneme i na vyšší rychlost, než u nativního SVG. Vždycky je dobré zvážit, co je pro daný účel vhodnější.

karf

Dosud jsem se vůbec nepřel, ale nyní asi začnu. Canvas i SVG mají dnes prakticky stejnou podporu – obě technologie naráží na nepodporu v IE, kde jsou obě omezené na emulaci pomocí SVG. Nejde tedy o žádné teoretizování – jak canvas, tak SVG jsem již několikrát použil na reálných webech – vždy pomocí podpůrných knihoven pro IE. Není pravda, že skryté procesy nikoho nezajímají. Naopak, v praxi člověk obvykle narazí na bugy nebo omezení z těchto emulací vyplývající a musí je nějakým způsobem řešit. Ovšem canvas a SVG si navzájem nekonkurují, naopak se můžou dobře doplňovat – a to jsem se snažil v předchozích příspěvcích sdělit.

karf

Mělo tam být samozřejmě "emulací pomocí VML"…

karf

Ano, pomocí Raphaël, ale stejný princip používá již déle např. dojo.gfx.

Anonymní

Na jednej strane je to pekné, na druhej strane nevidím veľké využitie takéhoto grafu. Normálne v grafe ukazujem výsledky, ku ktorým som došiel, neprezentujem graf, aby si ho každý mohol pohýbať. Dokonca aj pre výukové účely je často lepšia nejaká animácia (stačí aj GIF) alebo priloženie viacerých obrázkov ilustrujúcich mnou zvolené situácie.
Toto sa mi zdá vhodné len na nejaké srandičky, ako nosič informácie si to predstaviť stále nedokážem.

Anonymní

Ja sa len snažím nejaké využitie nájsť. :-)
Je možné pomocou canvas vytvoriť aj taký graf, ktorý by sa prekresľoval tým, že by som menil vstupné dáta, alebo naopak, hýbaním krivky by sa mi zobrazovali vstupné dáta? Ale to by zas bolo využiteľné len pre výukové účely. Možno na to hľadím nesprávne, ale som zvyknutý publikovať trebárs vedecké články, a tam väčšinou presne viem, čo chcem čitateľovi ukázať a nebýva toho ani tak veľa, že by to nešlo obrázkami – tie zosnímam trebárs ako screenshoty zo štatistického programu alebo z grafického programu. Možno byt bolo výhodné, ak by som tvrdil, že som objavil nejakú rovnicu, ktorá sa dá využiť v praxi a užívateľ by si mohol skúšať rôzne kombinácie dát, či ma nenachytá…

MD

> možno nejaké vykresľovanie grafov a podobne, ale veď to už sa dá aj inak

A jak?

mofo

řekl bych, že svět existoval i před canvasem, ne?

MD

Ano, treba generovani obrazku/grafu na serveru. Prijde vam to jako srovnatelne reseni? Canvas urcite sve uplatneni najde

snoblucha

Asi byly míněny grafy sloupcové pomocí pozicování. Pro čáry mě čistě HTML řešení nenapadá a to je dle mého mínění prostor pro canvas. Ikdyž jestli není lepší na takové věci potom využít spíše Flash(to asi je míněno tím jinak).

Anonymní

Proč by mělo být lepší místo Canvasu použít Flash?

snoblucha

Výhodu flashe spatřuji v tom, že je vektorový, a je k dispozici na 98% prohlížečích. Tudíž se na tvorbu grafů hodí o něco lépe(jednoduchý zoom a posun po ose). A co si budem nalhávat, vzhled grafu tam jde daleko více kontrolovat.

Osobně se ale nebráním Canvasu, protože to je přesně element který v HTML chyběl, pro jednoduché grafy ideální a kdo ví kam se dostane. Specifikace vypadá velmi dobře(a ten posun a zoom by měl umět nakonec taky).

http://www.whatwg.org/specs/web-apps/current-work/#canvas

snoblucha

To jsem ani netvrdil, že by něco ve Flashi šlo a v canvasu ne. Šlo mi o komfort. Práce s nimi je dost odlišná. Jde o to, že Flash je ze své podstaty vektorový, zatímco canvas je bitmapa, ke které jsou funkce, které dokáží vektorové chování napodobit, bohužel současná implementace není z nejideálnějších.

Také jde o to, že zatímco flash je zde již delší dobu a má lepší podporu v prohlížečích tak canvas je novinka, která se snaží vyplnit místo, která byla pro čisté (x)HTML nepřístupná, a za to jsem vděčen.

Bohužel, jistý majoritní prohlížeč se ani nesnaží zabudovat řádnou podporu do svého kódu. Je zde podobná situace, jako okolo SVG obrázků, keré by hravě dokázály canvas nahradit, alsepoň z hlediska již známých dat. Jak by to bylo hezké mít podporu pro tento formát, přičemž JScipt funkce by byly téměř identické. Bohužel si nelze dovolit si na tento luxus spoléhat.

xurpha

Mělo by to tu výhodu, že to bude fungovat i bez javascriptu :)

xurpha

A canvas jako půjde použít? Ha ha ha, you are on the way to destruction…

xurpha

MSIE canvas „neumí“…

Makovec

pochopitelne bylo…. jenomze je posledni dobou modou znovuvynalezat kola (a delat je pritom sisata, protoze je to tak nejak kool)…

Anonymní

Neříkete, SVG umí interaktivitu bez Javascriptu? Totiž něco na způsob tohohle?

Anonymní

Ve vývojové verzi gnuplotu (4.3) byl nedávno implementován terminál canvas, "set term canvas", který generuje HTML5 kód pro vykreslení grafu, a to včetně některých myšoidních možností (zoom, popis bodů). Demo viz např. zde: http://skuld.bmsc.washington.edu/~merritt/gnuplot/canvas_demos/

Anonymní

Muzete si prelozit vyvojovou verzi gnuplotu podle techto instrukci:
http://gnuplot.sourceforge.net/development/index.html#DownloadCVS
nebo si stahnout prelozenou binarku pro Wokna:
http://gnuplot.sourceforge.net/development/binaries/
http://www.tatsuromatsuoka.com/gnuplot/Eng/winbin/

asida

chyti rybar morskou pannu, chvili na ni cumi a pak ji hodi zpatky, druhy se ho pta: Proc ??, prvni odpovi: Jak ??

toz asyk tak s tim canvasem…

A.

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.