Hlavní navigace

Grafický formát SVG a animace

Pavel Tišnovský

Animace a s ní související podpora skriptování, například s využitím populárního a rozšířeného JavaScriptu, dělají z grafického formátu SVG velmi flexibilní médium pro tvorbu vektorových animací. Ty se vyznačují poměrně malým objemem dat a vysokou vizuální kvalitou. V tomto ohledu se SVG vyrovná i známému Flashi.

Obsah

1. Transformace aplikované na jednotlivé objekty a jejich skupiny
2. První demonstrační příklad – rotovaný text
3. Úvod do tvorby animací
4. Druhý demonstrační příklad – animovaná úsečka
5. Opakování animace, vliv animace na stav objektu po jejím ukončení
6. Třetí demonstrační příklad – animovaný kruh
7. Literatura a odkazy na Internetu
8. Obsah dalšího pokračování tohoto seriálu

1. Transformace aplikované na jednotlivé objekty a jejich skupiny

V předchozí části tohoto seriálu jsme si ukázali způsob tvorby textových objektů. V principu se jedná o jednořádkové texty, u kterých je možné měnit jejich font, barvu obrysu, barvu a styl výplně, velikost a také pozici v rámci výkresového prostoru. Prozatím jsme si však neřekli, jak lze vykreslit různě natočené texty. Ve značce <text> totiž není možné rotaci (narozdíl od posunu, resp. počátečního bodu) zapsat pomocí nějakého specializovaného atributu – tuto možnost však nemáme ani u jiných geometrických objektů, například obdélníku. Je to z toho důvodu, že v SVG je možné zapsat libovolnou lineární transformaci, tj. kombinaci rotace, posunu, zkosení i změny měřítka, s využitím obecného atributu transform. Hodnotou tohoto atributu je požadovaná transformace specifikovaná klíčovým slovem translate, rotate, scale, skewX a skewY, za nímž se v závorkách uvedou potřebné hodnoty transformace.

V jednom atributu transform může být uvedeno více transformací, ty se potom skládají běžným způsobem, který jsme si popsali už u grafického formátu PostScript. Zápis transform=„tran­slate(10, 0)“ tedy znamená, že se daný objekt či skupina objektů má posunout o deset délkových jednotek doprava. Složitější je zápis transform=„tran­slate(100, 120), rotate(-30), translate(10,0)“, kterým je popsána složená transformace. Nejprve je grafický objekt posunut o deset délkových jednotek doprava, potom zrotován o 30° a následně posunut o vektor (100, 120) – vzhledem ke způsobu skládání transformací je tedy zápis posloupnosti transformací opačný než jejich provádění. Ve skutečnosti je samozřejmě celá transformace interně reprezentována pouze jednou transformační maticí. Transformace je možné skládat i jiným způsobem: pokud jsou do sebe vloženy značky <g> a v každé značce je uvedena nějaká transformace, jsou tyto transformace interně skládány tak, jako by byly zapsány za sebou v jednom atributu <transform>.

2. První demonstrační příklad – rotovaný text

V dnešním prvním demonstračním příkladu je ukázáno použití transformací při vykreslování natočených textových objektů. Všechny textové objekty jsou uzavřené do značky <g>, aby nebylo nutné u každého objektu zvlášť nastavovat font a velikost písma. Každý textový objekt je posunut o deset délkových jednotek doprava (zamezení překryvu znaků), otočen o násobek 30° a posléze posunut o vektor (100, 120), což je zhruba střed výkresu. Jedná se tedy o složenou transformaci – z tohoto důvodu mohou být souřadnice počátku objektu nastaveny na hodnotu [0, 0], protože vlastní posun objektu zajistí samotná lineární transformace. Také je změněna barva výplně. Poslední textový objekt je poloprůhledný, a je vykreslen oproti neměnnému pozadí. Zdrojový kód prvního demonstračního příkladu má tvar (zde je původní zdrojový kód):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400"
     height="400"
     viewBox="0 0 200 200"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">

     <!-- úsečky vykreslené implicitním stylem -->
     <g stroke="rgb(127, 127, 0)" stroke-width="0.5px">
         <line x1="0" y1="0"   x2="0"   y2="199" />
         <line x1="0" y1="20"  x2="20"  y2="199" />
         <line x1="0" y1="40"  x2="40"  y2="199" />
         <line x1="0" y1="60"  x2="60"  y2="199" />
         <line x1="0" y1="80"  x2="80"  y2="199" />
         <line x1="0" y1="100" x2="100" y2="199" />
         <line x1="0" y1="120" x2="120" y2="199" />
         <line x1="0" y1="140" x2="140" y2="199" />
         <line x1="0" y1="160" x2="160" y2="199" />
         <line x1="0" y1="180" x2="180" y2="199" />
         <line x1="0" y1="199" x2="200" y2="199" />
     </g>

     <!-- rotované textové objekty -->
     <g font-family="DejaVu Sans" font-size="28" font-weight="bold">

         <!-- text, který není rotován a posun je proveden atributy 'x' a 'y' -->
         <text x="100" y="120" font-family="DejaVu Sans" fill="#e80" transform="translate(10, 0)">
         hello!
         </text>

         <text x="0" y="0" font-family="DejaVu Sans" fill="#c82"
             transform="translate(100, 120), rotate(-30), translate(10,0)">
         hello!
         </text>

         <text x="0" y="0" font-family="DejaVu Sans" fill="#a84"
             transform="translate(100, 120), rotate(-60), translate(10,0)">
         hello!
         </text>

         <text x="0" y="0" font-family="DejaVu Sans" fill="#886"
             transform="translate(100, 120), rotate(-90), translate(10,0)">
         hello!
         </text>

         <text x="0" y="0" font-family="DejaVu Sans" fill="#688"
             transform="translate(100, 120), rotate(-120), translate(10,0)">
         hello!
         </text>

         <text x="0" y="0" font-family="DejaVu Sans" fill="#48a"
             transform="translate(100, 120), rotate(-150), translate(10,0)">
         hello!
         </text>

         <text x="0" y="0" font-family="DejaVu Sans" fill="#28c"
             transform="translate(100, 120), rotate(-180), translate(10,0)">
         hello!
         </text>

     </g>


     <!-- poloprůhledný textový objekt -->
     <text x="0" y="195" font-family="DejaVu Sans" font-size="28" font-weight="bold" fill="blue" fill-opacity="0.5">
     www.root.cz
     </text>
</svg> 

5501
Obrázek 1: Screenshot prvního demonstračního příkladu po zobrazení v prohlížeči SVG souborů

3. Úvod do tvorby animací

V perexu tohoto článku bylo napsáno, že ve formátu SVG lze vytvářet i animace. V podstatě je možné použít čtyři způsoby specifikace animace. Základní a také nejčastěji používaný způsob spočívá ve využití animačních elementů, druhý způsob ve využití DOM (Document Object Modelu), přes který je možné za pomoci skriptů měnit atributy objektů, třetí způsob je založen na použití jazyka SMIL (Synchronized Multimedia Integration Language) a čtvrtý způsob na integraci jazyka SMIL, SVG a libovolného dalšího formátu založeného na XML (ostatně moderní způsob práce s XML k tomuto obecnému řešení přímo vybízí). Dnes si ukážeme tvorbu animací založenou na postupné změně některých atributů objektů a v příští části tohoto seriálu bude ukázána tvorba složitějších animací s využitím spline křivek.

4. Druhý demonstrační příklad – animovaná úsečka

V dnešním druhém demonstračním příkladu, jehož zdrojový kód si můžete stáhnout zde, je ukázáno použití takzvaných animačních elementů. Vysvětleme si, jak animace pracuje. Nejprve je vytvořena úsečka s nastavenými vizuálními atributy (červená barva, tloušťka dva pixely), která začíná a končí na souřadnicích [0, 0] a [0, 200]. Ve všech předchozích příkladech jsme značku specifikující grafický objekt zapisovali jako nepárovou, tj. značka byla ukončena lomítkem:

<line x1="..." y1="..." ... /> 

V případě použití animačních elementů však zvolíme zápis párové značky, tj.:

<line x1="..." y1="..." ...>
...
</line> 

Tento zápis musí být použit z toho důvodu, že animační elementy se zapisují ve formě vložených značek, které leží uvnitř značky specifikující animovaný grafický objekt (úsečku, obdélník, text). Každý animační element je představován značkou <animate>, ve které je použito větší množství atributů s přesně daným významem. Hodnotou atributu attributeName je specifikováno, který atribut nadřízené značky bude při animaci měněn (nadřízenou značkou je v tomto případu myšlena značka specifikující úsečku, měněným atributem například x-ová souřadnice jejího počátku). Hodnotou atributu attributeType je možné nastavit, jaký zápis bude pro změnu atributu použitý – my se budeme držet XML formátu. Poté již následuje specifikace začátku animace (begin), délky trvání animace (dur) a počáteční i koncové hodnoty měněného atributu nadřazené značky (from, to). Po ukončení vlastní animace se může hodnota atributu změnit na počáteční hodnotu, či se zachová hodnota zadaná v atributu to (viz následující kapitolu).

V demonstračním příkladu jsou současně měněny atributy úsečky x1 a y2, první od nulové hodnoty do 200, druhý naopak od hodnoty 200 do nuly. Celá animace trvá deset sekund a po jejím ukončení je atribut x1 nastaven na hodnotu 200 a atribut y2 na nulovou hodnotu. Zdrojový kód tohoto demonstračního příkladu má tvar:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
    "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400"
     height="400"
     viewBox="0 0 200 200"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">

     <!-- animovaná úsečka, která má v prvním snímku animace -->
     <!-- nastaveny souřadnice [0, 0] - [0, 200] -->
     <line x1="0" y1="0" x2="0" y2="200" stroke="red" stroke-width="2">

         <!-- animovaná změna hodnoty atributu x1 -->
         <animate attributeName="x1" attributeType="XML"
             begin="0s" dur="10s" fill="freeze" from="0" to="200" />

         <!-- animovaná změna hodnoty atributu y2 -->
         <animate attributeName="y2" attributeType="XML"
             begin="0s" dur="10s" fill="freeze" from="200" to="0" />
     </line>
</svg> 

5502
Obrázek 2: Screenshot druhého demonstračního příkladu pořízený zhruba v polovině animace

5. Opakování animace, vliv animace na stav objektu po jejím ukončení

Ve druhém demonstračním příkladu jsme si ukázali animaci, která spočívala ve změně dvou atributů. Celá animace trvala deset sekund a oba atributy byly postupně měněny po celou tuto dobu. Ve skutečných animacích se však jednotlivé atributy mění různou rychlostí a i časování změn může být odlišné. Z tohoto důvodu je zápis změny každého atributu uveden v samostatné značce <animace>, aby bylo zajištěno, že změny atributů budou na sobě nezávislé. Animaci (resp. změnu některého atributu) je možné několikrát opakovat, což se nastavuje hodnotou repeatCount. Také jsme si již řekli, že po dokončení animace změny některého atributu (například souřadnice koncového bodu úsečky), je možné nastavit hodnotu tohoto atributu na počáteční stav nebo naopak ponechat stav, jaký je nastavený hodnotou to. Chování při ukončení animace je řízeno hodnotou atributu fill, konkrétní hodnoty, jichž může tento atribut nabývat, se jmenují freeze (zachovat stav platný při ukončení animace) a remove (nastavit počáteční hodnotu atributu).

6. Třetí demonstrační příklad – animovaný kruh

V dnešním třetím a současně i posledním demonstračním příkladu je ukázána tvorba animace kružnice. U této kružnice se v čase mění dva atributy – barva výplně a její poloměr. Pro změnu barvy je určen animační objekt představovaný značkou <animateColor>, poloměr je měněn nám již známým animačním objektem představovaným značkou <animate>. Pro nastavení počáteční a koncové hodnoty barvy je možné použít libovolnou specifikaci barevného odstínu, která je v SVG podporována, tj. jméno barvy, hexadecimální kód i trojici barvových složek RGB. V demonstračním příkladu je použita poslední zmíněná možnost.

Při animaci změny poloměru kružnice je nastavena doba trvání této části animace na dvě sekundy, poloměr se tedy mění pětkrát rychleji než barva výplně kružnice. To je však kompenzováno tím, že počet opakování změny poloměru je nastaven na hodnotu pět. Po ukončení animace, tj. po uběhnutí deseti sekund, je poloměr kružnice změněn na původní hodnotu, zatímco barva výplně kružnice zůstane stejná, jako ve chvíli ukončení celé animace.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400"
     height="400"
     viewBox="0 0 200 200"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">

     <!-- animovaná kružnice, která má v prvním snímku animace -->
     <!-- nastavenu barvu obrysu na černou a poloměr na 50 jednotek -->
     <circle cx="100" cy="100" r="50" stroke="black" stroke-width="2">
         <!-- animovaná změna barvy výplně -->
         <animateColor attributeName="fill" attributeType="XML" begin="0s" dur="10s" fill="freeze" from="rgb(255,255,0)" to="rgb(0,0,255)" />

         <!-- animovaná změna poloměru kružnice -->
         <animate attributeName="r" attributeType="XML" begin="0s" dur="2s" fill="remove" from="50" to="80" repeatCount="5" />
     </circle>
</svg> 

5503
Obrázek 3: Screenshot třetího demonstračního příkladu pořízený zhruba v polovině animace

7. Literatura a odkazy na Internetu

  1. Scalable Vector Graphics (SVG) 1.0 Specification,
    (W3C Recommendation)
  2. Scalable Vector Graphics (SVG),
    XML Graphics for the Web:
    http://www.w3­.org/Graphics/SVG//
  3. Cascading Style Sheets, level 2,
    B. Bos, H. W. Lie, C. Lilley, I. Jacobs, 12 May 1998.
  4. Document Object Model (DOM) Level 1 Specification,
    V. Apparao, S. Byrne, M. Champion, S. Isaacs, I. Jacobs, A. Le Hors, G. Nicol, J. Robie, R. Sutor, C. Wilson, L. Wood, editors, 1 October 1998.
  5. Document Object Model (DOM) Level 2 Core Specification,
    A. Le Hors, P. Le Hégaret, L. Wood, G. Nicol, J. Robie, M. Champion, S. Byrne, editors, 13 November, 2000.
  6. SMIL Animation,
    P. Schmitz, A. Cohen, editors, 31-July-2000.
  7. XML Linking Language (XLink),
    S. DeRose, E. Maler, D. Orchard, editors, 20 December 2000.
  8. Extensible Markup Language (XML) 1.0 (Second Edition),
    T. Bray, J. Paoli, C.M. Sperberg-McQueen, E. Maler, editors, 6 October 2000.
  9. XML Base,
    J. Marsh , editor, 20 December 2000.
  10. Namespaces in XML,
    T. Bray, D. Hollander, A. Layman, editors, 14 January 1999.
  11. Batik SVG Toolkit,
    http://xmlgrap­hics.apache.or­g/batik/
  12. SVG-Wiki,
    http://wiki.svg­.org/Main_Page
  13. Wikipedia EN: Scalable Vector Graphics,
    http://en.wiki­pedia.org/wiki/Sca­lable_Vector_Grap­hics
  14. Wikipedia CZ: Scalable Vector Graphics,
    http://cs.wiki­pedia.org/wiki/Sca­lable_Vector_Grap­hics
  15. Kurz SVG – tvorba vektorové grafiky v XML,
    http://interval­.cz/serialy/kurz-svg-tvorba-vektorove-grafiky-v-xml/

8. Obsah dalšího pokračování tohoto seriálu

V navazující části tohoto seriálu si řekneme, jakým způsobem je možné vytvářet složitější animace založené na pohybu objektů po zadaných spline křivkách. Také si ukážeme způsob tvorby animací přes DOM (Document Object Model) – s využitím této techniky lze animaci popsat programovým kódem.

Našli jste v článku chybu?

14. 9. 2007 21:59

J (neregistrovaný)
Prohlizec (FF) se presne dle specifikace rozhoduje primarne dle hlavicek, bud by to melo byt primo SVG, nebo aspon XML. Chapu ze autor to ovlivnit nemuze. Jinak dle pripony to samozrejme umi rozpoznat apache a poslat spravnou hlavicku, pokud je to na nem nastaveno.

14. 9. 2007 15:57

marek (neregistrovaný)
No, dobra zprava pro nektere z vas
Prvky animate velmi slusne podporuje i betaverze Batiku/Squiggle, ktery se da stahovat i jako JAR primo do kazdeho prohlizece, ktery ma funkcni podporu Java pluginu.

http://xmlgraphics.apache.org/batik/

Pro uzivatele Firefoxu, kteri si chteji vyzkouset jednoduzsi animace, slusne funguje i JS parser implementace. Ma mnoha omezeni a je pomala, ale na jednoduzsi veci se pouzit da - pouziti slozite je vzasade jen na prilinkovani JS knihovny do souboru, easy:

htt…






Vitalia.cz: Cena stejného léku se liší i o tisíce

Cena stejného léku se liší i o tisíce

Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

Vitalia.cz: „Připluly“ z Německa a možná obsahují jed

„Připluly“ z Německa a možná obsahují jed

120na80.cz: 5 nejčastějších mýtů o kondomech

5 nejčastějších mýtů o kondomech

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

DigiZone.cz: Rádio Šlágr má licenci pro digi vysílání

Rádio Šlágr má licenci pro digi vysílání

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Podnikatel.cz: Udávání a účtenková loterie, hloupá komedie

Udávání a účtenková loterie, hloupá komedie

Podnikatel.cz: Snížení DPH na 15 % se netýká všech

Snížení DPH na 15 % se netýká všech

Vitalia.cz: Pamlsková vyhláška bude platit jen na základkách

Pamlsková vyhláška bude platit jen na základkách

Měšec.cz: mBank cenzuruje, zrušila mFórum

mBank cenzuruje, zrušila mFórum

Měšec.cz: Air Bank zruší TOP3 garanci a zdražuje kurzy

Air Bank zruší TOP3 garanci a zdražuje kurzy

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

Podnikatel.cz: Udávání kvůli EET začalo

Udávání kvůli EET začalo

Vitalia.cz: Proč vás každý zubař posílá na dentální hygienu

Proč vás každý zubař posílá na dentální hygienu

Podnikatel.cz: Chaos u EET pokračuje. Jsou tu další návrhy

Chaos u EET pokračuje. Jsou tu další návrhy