Raphaël: vektorová grafika pro web

Raphael logo

Javascriptová knihovna Raphaël zapouzdřuje a sjednocuje práci s vektorovou grafikou v různých prohlížečích. Dokáže využít SVG tam, kde je podporováno; kde není, pracuje s VML. Pomocí této knihovny lze snadno vytvářet přenositelné a interaktivní aplikace založené na vektorové grafice. Ukážeme si, jak s ní pracovat.

Seriál: Grafické knihovny (2 díly)

  1. Raphaël: vektorová grafika pro web 1.11.2010
  2. Artisan: kreslíme v JavaScriptu 26.11.2010

Knihovna Raphaël slouží k jednoduchému vytváření interaktivní vektorové grafiky, a to pomocí SVG či (pokud SVG není dostupné) VML. Není nijakým nováčkem, na Zdrojáku jsme se o ní už zmiňovali, v současnosti je aktuální verze 1.5.2. Na této šikovné knihovně je založena řada aplikací. Pojďme se tedy podívat, jak ji můžeme využít i my.

Vektory? Vždyť sexy je canvas!

Pokud se hovoří o grafice v HTML5, lidé nejčastěji zmiňují element canvas, SVG a vektorová grafika jako by byla lehce opomíjena. Ostatně vektory nejsou tak cool a sexy jako bitmapové efekty s canvasem, ale to neznamená, že canvas je lepší. To je ostatně častý omyl – ptát se „která technologie je lepší?“ a nedodat pro jaký účel. Mezi SVG a canvasem je základní rozdíl dán tím, že jedno je vektorová grafika a druhé bitmapová.

Pravděpodobně není mezi čtenáři Zdrojáku žádný, kdo by rozdíl neznal, ale pro jistotu: Bitmapová grafika přistupuje k obrázku jako k matici barevných bodů, hodí se tak např. pro fotografie a video. Vektorová grafika namísto toho pracuje s grafickými objekty jako je úsečka, křivka, ohraničená plocha atd., s jejich transformacemi (zvětšení, natočení, zkosení) a vlastnostmi (barva obrysu, barva výplně), je tedy vhodná pro výkresy, schémata, ale i např. reklamní grafiku. Její velkou předností je, že výsledek lze libovolně zvětšit či zmenšit bez ztráty kvality. Rozdíly z hlediska použití na webu shrnuje článek SVG, nebo Canvas? Vyberte si, v němž najdete detaily k technickým možnostem obou technologií.

Knihovna Raphaël slouží k tvorbě vektorové grafiky. Pracuje tedy, jak jsme si řekli, s grafickými objekty, nikoli s barevnými body. Tyto objekty mají svou reprezentaci v DOM stromu stránky, lze tedy s nimi nakládat jako s jinými elementy ve stránce – např. přiřadit jim obsluhu událostí nebo dynamicky měnit jejich vlastnosti. Nevýhodou je, že složitější grafika s mnoha elementy představuje velké zatížení DOM a možné zpomalení práce.

Začínáme s Raphaëlem

Vlastní práce s knihovnou Raphaël je snadná podobně jako u většiny obdobných knihoven: vložíme tag SCRIPT:

<script src="raphael.js"></script>

Pro produkční použití doporučuji využít minifikovanou verzi raphael.min.js, která zabírá 60 kB, při využití gzip komprese pak pouhých 20.

Na začátku práce si řekneme o prostor k malování, v terminologii dokumentace k Raphaëlu zvaný prostě papír, na který budeme malovat. Můžeme požadovat buď prostor o daných rozměrech na daných souřadnicích

var paper = Raphael(10, 20, 320, 200); //prostor 320x200px na souřadnicích [10,20]

nebo prostor v HTML elementu:

var paper = Raphael(document.getElementById("prostor"), 320, 200); //320x200px v elementu s ID "prostor"

či zjednodušeně:

var paper = Raphael("prostor", 320, 200); //totéž, jen s jednodušším zápisem

Jakmile máme papír, na který budeme kreslit, můžeme začít s vlastním malováním.

Grafické prvky

Kruh

Nejjednodušším prvkem vektorové grafiky je kruh – je definován pouhými třemi parametry, totiž souřadnicemi středu a poloměrem. (Opět pro detailisty dodám, že jde vlastně o kružnici, ale pro naše potřeby budeme brát kružnici jako speciální případ kruhu bez výplně.) Nakreslíme si jeden neinvenční kruh: doprostřed papíru a co největší.

var circle = paper.circle(160, 100, 100);

Všimněte si, že elementy vytváříme voláním metod objektu paper (záměrně zjednodušeně řečeno) a že dostáváme objekt, pomocí něhož budeme k elementu přistupovat. Samosebou nám nic nebrání návratovou hodnotu zahodit,

paper.circle(160, 100, 100);

ale pak s nakresleným kruhem už nic neuděláme. Co třeba? Například nezměníme barvu výplně:

circle.attr("fill", "#f00");

Atributy

Elementy totiž mají metodu attr, která slouží ke změně atributů či k získání jejich hodnoty. Použitelné atributy naleznete v dokumentaci – od atributů, udávajících vlastnosti výplně, přes vlastnosti obrysu až po transformace a ořezové oblasti. Například:

var circle = paper.circle(160, 100, 90);
circle.attr("fill", "45-#000-#00f");
circle.attr("stroke", "#f00");
circle.attr("stroke-width", "5");
circle.attr("stroke-dasharray", "-..");

Lehce jsme náš kruh vyšperkovali – výplní je lineární přechod, obrys je červený, pět pixelů tlustý a je kreslen čerchovaně. To je on:

Obdélník

Druhý nejjednodušší objekt je dán opět jednou souřadnicí (levého horního rohu) a rozměry (výškou a šířkou). Nepřekvapí, že volání je opět velmi podobné

var rect = paper.rect(10, 10, 90, 90); //x, y, šířka a výška

Pokud přidáte ještě pátý parametr, dostanete základ celého webu 2.0 – totiž obdélník s kulatými rohy, kde pátý parametr udává poloměr zakulacení (demo):

var rect = paper.rect(10, 10, 90, 100, 5);
rect.attr("fill","45-#000-#00f");
rect.attr("stroke", "#f00");
rect.attr("stroke-width", "5");

Elipsa

Elipsa je definována souřadnicemi středu a délkou poloos. Víc asi netřeba dodávat, jen volání funkce:

paper.ellipse(50, 50, 40, 20);

Křivka

Zatímco předchozí grafické prvky byly triviální, křivka je o něco složitější – ti, co kdy pracovali s vektorovým grafickým editorem a/nebo s želví grafikou (jazyk Logo např.) budou mít situaci jednodušší. Křivka se totiž kreslí voláním metody path, která má jediný parametr. Tím je řetězec, který křivku popisuje. Popis je dán standardem SVG PathData a jeho vysvětlení přesahuje rámec tohoto článku. Jen jako příklad uvedeme:

paper.path("M10 10L90 90C90 150,160 0,150 50");

Řetězec obsahuje příkazy pro přesun „kreslicího pera“ do pozice [10, 10] (M), pro nakreslení lineární čáry do pozice [90, 90] (L) a pro nakreslení Bézierovy křivky do bodu [150, 50] s řídicími body [90, 150] a [160,0]. Kromě čar a kubických Béziérových křivek lze kreslit i křivky kvadratické či eliptické oblouky.

Ke křivkám se vztahují některé zajímavé metody, které si nebudeme popisovat podrobněji, jen je zmíníme. Metoda getTotalLength, která vrátí délku celé křivky v pixelech. Metodou getPointAtLength získáme souřadnice bodu na křivce v dané vzdálenosti od začátku a úhel tečny. Metoda getSubpath() vrátí řetězec, pomocí něhož lze nakreslit část křivky, danou počáteční a koncovou vzdáleností v pixelech.

Text

Pomocí metody text() můžeme do obrázku vložit řetězec – parametry jsou v tomto případě souřadnice oblasti, do které se píše, a řetězec (odřádkování lze zajistit metaznakem  n).

I psaní textu nabízí některé pomocné metody – lze použít vlastní font (podobně jako v CSS3) či vykreslit text po jednotlivých znacích metodou print()  – tato metoda vrátí pole objektů, kde každá položka představuje jeden znak, což umožňuje pracovat s jednotlivými písmeny a měnit jejich parametry.

Operace s grafikou

Představili jsme si základní grafické elementy – nejsou všechny, chybí množina (set) a obrázek (image) – zájemce opět najde podrobnosti v dokumentaci. Pojďme se podívat na další operace, které můžeme s nakreslenými objekty dělat.

Každý vytvořený vektorový grafický prvek obsahuje vlastnost node, která odkazuje na DOM element pro daný prvek. Můžeme tak snadno např. obsloužit událost a oživit první příklad:

circle.node.onclick = function () {
    circle.attr("fill", "yellow");
};

Prvky obsahují i vlastnost paper, která odkazuje na papír, v němž bylo kresleno. Užitečné to může být pro různé pluginy.

Trojice metod remove(), hide() a show() dělá přesně to, co názvy napovídají – odstraní prvek, skryje jej a ukáže jej.

Metoda rotate() může mít jeden parametr – pak jím je úhel, o který má být element otočen, vyjádřený ve stupních. Pokud má dva parametry, je druhým parametrem příznak, zda natočení je absolutní (true) nebo relativní (false) k předchozím natočením. Pokud má tři parametry, je prvním opět úhel a další dva udávají střed otáčení.

Metoda translate() má dva parametry, které udávají vzdálenost v osách X a Y, o jakou má být objekt posunut.

Metoda scale() má dva povinné parametry – změna velikosti v ose X a v ose Y, udávaná jako násobek, tj. 1 znamená beze změny, 2 je dvojnásobné zvětšení a 0.5 je zmenšení na polovinu. Může mít i dva další, nepovinné parametry, které určují střed, od něhož se změna velikosti počítá.

Pomocí metody getBBox získáme tzv. „bounding box“, neboli rozměry obdélníku, v němž je objekt vykreslen.

Další metody (přesouvání do popředí, do pozadí, vkládání před či za konkrétní objekty) naleznete i s popisem v dokumentaci.

Animace

Všechny výše popsané změny, včetně změn atributů, lze poměrně důkladně animovat. Od jednoduchých přechodů (např. změna pozice X a poloměru během dvou sekund)

circle.node.onclick = function () {
    circle.animate({cx: 20, r: 20}, 2000);
};

po komplexní animace, např. pohybu po křivce (viz demonstrace):

var p = paper.path("M100,100c0,50 100-50 100,0c0,50 -100-50 -100,0z").attr({stroke: "#ddd"}),
    e = paper.ellipse(104, 100, 4, 4).attr({stroke: "none", fill: "#f00"}),
    b = paper.rect(0, 0, 620, 400).attr({stroke: "none", fill: "#000", opacity: 0}).click(function () {
        e.attr({rx: 5, ry: 3}).animateAlong(p, 4000, true, function () {
            e.attr({rx: 4, ry: 4});
        });
    });

Animacím lze určit i easing, tedy „plynulost“ pohybu (opět viz demo). Téma animací je opět velmi obsáhlé; ve stručném představení možností knihovny Raphaël, o něž v článku jde, není na podrobný popis místo – zájemce tak opět odkazuji na ukázku možností a na dokumentaci.

A to ještě není všechno…

Raphaël umožňuje vytvářet vlastní metody objektu paper, vlastní metody pro jednotlivé elementy či vlastní atributy. Lze tak vytvářet pluginy a rozšiřovat možnosti této knihovny.

Velmi slušná je podpora událostí – lze obsluhovat širokou škálu událostí uživatelského rozhraní, včetně techniky drag-n-drop.

A v neposlední řadě nabízí Raphaël řadu užitečných funkcí, které se mohou hodit – od přepočtu úhlových jednotek přes zjišťování úhlu, který svírají dvě přímky po funkce k převodu barev. 

Knihovna Raphaël představuje velmi komplexní, jednoduché a zároveň přenositelné řešení pro práci s vektorovou grafikou. Podporovány jsou prohlížeče Firefox 3.0+, Safari 3.0+, Chrome 5.0+, Opera 9.5+ a Internet Explorer 6.0+. Pokud nepotřebujete možnosti, které nabízí SVG, pokud potřebujete přenositelnost nebo je vám prostě procedurální přístup bližší, určitě s Raphaëlem nešlápnete vedle.

Začal programovat v roce 1984 s programovatelnou kalkulačkou. Pokračoval k BASICu, assembleru Z80, Forthu, Pascalu, Céčku, dalším assemblerům, před časem v PHP a teď je rád, že neprogramuje…

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Zdroj: http://www.zdrojak.cz/?p=3355