SVG, nebo Canvas? Vyberte si
Pro vložení grafiky do stránky měli weboví vývojáři až donedávna v podstatě jen dvě možnosti – buď statický obrázek, nebo využít plugin (Flash, VML apod.) V poslední době doznal značného rozšíření ale vektorový formát SVG a bitmapový HTML5 canvas. Jaké jsou jejich vlastnosti a v čem se liší?
Úvod
Nové webové technologie jsou stále dostupnější ve všech prohlížečích, a pro ty, které je zatím neimplementují, existují náhradní řešení, jako např. Raphaёl pro SVG a ExCanvas pro Canvas. A když i Internet Explorer začal koketovat se SVG (a IE9 beta potvrdila, že to Microsoft myslí s podporou vážně), můžeme se v budoucnu těšit na větší podporu. Což ale způsobí další problém, který budeme muset řešit – totiž rozhodnout se, kterou technologii použít.
HTML5 Canvas i SVG jsou technologie, které umožňují vložit do HTML stránek nějakou pokročilejší grafiku, ale jsou od základu rozdílné. V tomto článku si popíšeme rozdíly a znalosti, které vám pomůžou používat SVG a Canvas efektivně a hlavně na správném místě.
Pokud si chcete vyzkoušet zde uvedené kódy, můžete si stáhnout soubor s příklady z článku.
Scalable Vector Graphics
SVG je vektorový grafický formát založený na XML. Obsah může být statický, dynamický, interaktivní či animovaný – SVG je velmi flexibilní. Navíc můžete stylovat SVG pomocí CSS a dynamicky s ním pracovat SVG DOM. A vzhledem k tomu, že text v SVG je zapsán jako text, splňuje tak do jisté míry i požadavky na přístupnost. SVG můžete zapsat přímo do (X)HTML stránky pomocí elementu object.
Zde je ukázka kruhu nakresleného pomocí SVG — obsahuje barevný přechod a jednoduchou animaci:
<svg version="1.1"
width="320" height="320"
xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="circleGrad">
<stop offset="0%" stop-color="rgb(255, 255, 0)" />
<stop offset="100%" stop-color="rgb( 0, 255, 0)" />
</radialGradient>
</defs>
<ellipse fill="url(#circleGrad)" stroke="#000" cx="50%"
cy="50%" rx="50%" ry="50%">
<animate attributeName="rx" values="0%;50%;0%" dur="2s"
repeatCount="indefinite" />
<animate attributeName="ry" values="0%;50%;0%" dur="2s"
repeatCount="indefinite" />
</ellipse>
</svg>
Animace funguje pouze v Opeře a v prohlížečích s jádrem WebKit.
Se SVG dokážete udělat mnohem víc než jednoduchou vektorovou grafiku a animace. Můžete vytvořit velmi interaktivní webovou aplikaci se skriptováním, animovanými efekty, filtry a téměř čímkoli, čeho si zamanete. Pokud se chcete o SVG dozvědět víc, přečtěte si seriál SVG: Evolution, Not Revolution na webu Opery.
HTML5 Canvas
Specifikace HTML5 Canvas je v podstatě jednoduché JavaScriptové API, které umožňuje kreslit programově. Canvas sám umožňuje definovat objekt canvas (zapsaný jako element <canvas> do HTML stránky), do kterého se pak kreslí. Samotné kreslení probíhá pomocí tzv. kontextů:
První je známější a je dostupný ve všech moderních prohlížečích (v IE od verze 9), ten druhý je zatím na počátku specifikace a je zatím nemnoho experimentálních implementací.
V článku se budeme věnovat 2D kontextu, protože je široce podporovaný. Tento kontext nabízí jednoduché, ale poměrně mocné API, pomocí něhož kreslíte do 2D bitmapového „plátna“. Nemá specifikovaný „formát souboru“ a lze kreslit jen skripty. Není tu žádný DOM pro nakreslené tvary, vše je pouze v bitmapě, jako pixely. To znamená, že budete-li kreslit další a další čáry, křivky, objekty, …, nebude se nikde v paměti vytvářet stále složitější objektový model.
Zde je ukázka stejného animovaného kruhu s Canvasem:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Canvas animation example</title>
<script type="text/javascript"><!--
window.addEventListener('load', function () {
// Získáme canvas element.
var canvas = document.getElementById('myCanvas'),
w = 4,
h = 4,
zoompx = 6,
step = 'zoomin';
if (!canvas || !canvas.getContext) {
return;
}
// Získáme 2d kontext.
var ctx = canvas.getContext('2d');
if (!ctx) {
return;
}
var K = 4*((Math.SQRT2-1)/3);
setInterval(function () {
if (step == 'zoomin') {
w += zoompx;
h += zoompx;
} else if (step == 'zoomout') {
w -= zoompx;
h -= zoompx;
}
if (w > canvas.width) {
w = canvas.width;
step = 'zoomout';
} else if (w < 4) {
w = 4;
step = 'zoomin';
}
if (h > canvas.height) {
h = canvas.height;
step = 'zoomout';
} else if (h < 4) {
h = 4;
step = 'zoomin';
}
// Vytvoření kruhového gradientu: x0, y0, r0, x1, y1, r1.
// Uveden je střed počátečního kruhu (x0,y0) a poloměr r0,
// následovaný souřadnicemi (x1,y1) a poloměrem r1 vnějšího kruhu.
var gradient = ctx.createRadialGradient(
Math.round(w/2), Math.round(h/2), 0, Math.round(w/2), Math.round(h/2),
Math.round(Math.min(w, h)/2));
gradient.addColorStop(0, "#ff0");
gradient.addColorStop(1, "#0f0");
// nastavíme gradient pro fillStyle.
ctx.fillStyle = gradient;
// Poloměr a souřadnice kružnice
var cx = w/2,
cy = h/2,
rx = cx*K,
ry = cy*K;
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.setTransform(1, 0, 0, 1, Math.round((canvas.width - w) / 2),
Math.round((canvas.height - h) / 2));
ctx.beginPath();
// startX, startY
ctx.moveTo(cx, 0);
// Řídicí body: cp1x, cp1y, cp2x, cp2y, destx, desty
ctx.bezierCurveTo(cx + rx, 0, w, cy - ry, w, cy);
ctx.bezierCurveTo(w, cy + ry, cx + rx, h, cx, h);
ctx.bezierCurveTo(cx - rx, h, 0, cy + ry, 0, cy);
ctx.bezierCurveTo(0, cy - ry, cx - rx, 0, cx, 0);
ctx.fill();
ctx.stroke();
ctx.closePath();
}, 20);
}, false);
// --></script>
</head>
<body>
<p><canvas id="myCanvas" width="320" height="320">Your browser does not have
support for Canvas.</p>
</body>
</html>
2D kontext nemá žádné funkce pro animování – provádí jen kreslící operace, které mu zadáte a když mu je zadáte. V tomto případě je tedy kruh kreslen ve funkci, která je volána každou milisekundu.
V canvasu můžete provádět operace s jednotlivými pixely, jako jsou třeba různé obrazové filtry. Můžete vložit bitmapové obrázky jako jsou PNG a JPG či jakékoli, které umí prohlížeč zobrazit, a můžete obsah plátna exportovat či ukládat jako obrázky.
Příklad použití canvasu, který jsme si zde uvedli, není příliš vhodný pro canvas – téhož výsledku dosáhnete s mnohem menším SVG, jak jsme si ukázali výše. Navíc bude SVG čitelnější a snáze udržovatelné. Pokud chceme pomocí canvasu udělat animaci, musíme ji obsloužit pomocí časovačů, které budou vyvolávat překreslení snímek po snímku, zatímco se SVG dosáhneme téhož mnohem snáz, protože podporu animací obsahuje.
Mnohem lepší příklad použití je zobrazování dynamických informací, jako jsou interkativní grafy či analýza obrazu. Ukažme si jako příklad demo, které spočítá a zobrazí barevný histogram pomocí API pro 2D kontext:
Ukázkový kód načte obrázek do elementu img a projde všechny pixely v obrázku pomocí funkce 2D kontextu. Pixely jsou počítány pro jednotlivé kanály dle výběru barevného prostoru (RGB, HSV nebo CMYK). Když je histogram spočítán, je vykreslen do druhého canvasu.
K čemu je tedy 3D kontext? S 3D kontextem můžete kreslit trojrozměrné objekty, textury, stínování. Můžete do něj zapracovat i animace. Můžete vytvořit 3D hry a 3D modelovací nástroje. Prohlížeč takový obsah vykreslí pomocí HW akcelerace, pokud je k dispozici.
Porovnání SVG a Canvasu
Následující tabulky ukáží rozdíly mezi SVG a canvasem, jejich výhody a nevýhody.
Výhody
| Canvas | SVG |
|---|---|
|
|
Nevýhody
| Canvas | SVG |
|---|---|
|
|
Pokud je důležité, aby aplikace byla přístupná, bude pravděpodobně vhodnější HTML než SVG, protože pro HTML existuje víc testovacích nástrojů. Na každý pád můžete přidat atributy ARIA k HTML/SVG kódu a zlepšit tak přístupnost celé aplikace.
Který formát vybrat?
Každá technologie má oblasti, v nichž je vhodné ji použít – není to tak, že byste opustili Canvas a přešli na SVG či obráceně.
Canvas použijete např. při:
- Interaktivních úpravách obrázku: ořezy, změna velikosti, filtry (sépia, odstranění červených očí, odbarvení apod.)
- Generování rastrové grafiky: Vizualizace dat, vykreslování fraktálů, …
- Analýza obrázku: čtení obrazových dat pro histogramy, využití barev a další.
- Vykreslování grafiky v hrách, jako jsou sprity či pozadí.
SVG byste měli použít v:
- Uživatelských rozhraních webových aplikací v případech, kdy nechcete řešit rozlišení.
- Interaktivní animovaná uživatelská rozhraní
- Grafy a náčrtky.
- Editování vektorových obrázků
Ve zkratce – používejte obě technologie. V hrách můžete chtít použít vykreslení rastrové grafiky pomocí canvasu, a pak animovat SVG. V aplikaci typu obrázkového editoru můžete chtít použít obojí, jak vektorovou, tak rastrovou grafiku.
Kde byste tyto technologie neměli používat? Existují čistě HTML+CSS řešení pro věci jako jsou kulaté rohy, přechody, stíny a průsvitnost. Můžete použít i knihovny jako jQuery UI. Zamyslete se, zda opravdu potřebujete SVG nebo Canvas, zda nedokážete totéž s HTML + CSS. I když je SVG převážně značkovací jazyk, budete odborníky na SVG shánět mnohem obtížněji než zkušené HTML kodéry. HTML je známější, široce podporované a má bohatší sémantické možnosti. Zvolit SVG namísto HTML + CSS čistě pro prezentační účely nebude asi nejlepší volba.
Shrnutí
V článku jsme si ukázali rozdíly mezi dvěma, na první pohled podobnými, webovými technologiemi, SVG a Canvasem. Každá technologie má své slabé i silné stránky, proto byste měli konkrétní využití dobře zvážit. Často může vhodná kombinace obou technik vést k dobrým výsledkům.
Hodně štěstí při vývoji další killer aplikace!
Další článek na téma rozdílů mezi Canvasem a HTML je např. A Bit of SVG and Canvas, jehož autorem je Divya Manian.
Tento článek je volným překladem článku SVG or Canvas? Сhoosing between the two, vydaného na Dev.Opera. Autorem původního textu je Mihai Sucan. Překlad vychází s laskavým svolením Opera Software.
Školení: Návrh a používání MySQL databáze

Naučte se používat jednu z nejrozšířenějších databází. Dozvíte se vše potřebné od návrhu až po samotné využití MySQL v projektech.
Školení pro všechny, kteří se chtějí naučit efektivně pracovat s MySQL nebo se v práci s touto databází zlepšit.
Přihláška a podrobné informace
Přehled názorů
Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

