Stejně jako jakákoliv podobná technologie dokáže být SVG pěkně složité, ale podobně jako (skoro :-) vždy základy zas tak hrozné nejsou. Vlastně jsou úplně jednoduché, ale prostým rozhlédnutím po webu to není moc poznat. V dalším se pokusím to nejzákladnější ukázat.
PS: SVG je samozřejmě plnohodnotný vektorový obrazový formát (jen je to prostě dialekt XML), takže kromě webu ho najdete i v programech na úpravu vektorových obrázků či přímo SVG-dedikovaných editorech (viz např. Inkscape). Nicméně nás zde bude nejvíc zajímat jako plnohodnotná součást webové stránky.
Ať už je SVG ve stránce zobrazeno jakkoli, jedná se v principu o obdélníček, ovšem se zajímavou vlastností – jako byste nějakým okénkem koukali na obraz a mohli si vybrat, jaké zvětšení použijete a tím pádem i jakou část obrazu uvidíte. Přitom:
<svg>
;
@viewBox="x y width height"
, taktéž na kořenovém elementu <svg>
.
Souřadnice jsou přitom klasické počítačové, tzn. bod (0, 0) je v levém horním rohu a souřadnice y roste směrem dolů (a x standardně doprava). viewBox tedy vlastně určuje počátek a velikost soustavy souřadné zobrazené části obrázku – x a y jsou její počátek z hlediska soustavy souřadné celého viewportu, width a height pak velikost vlastního výřezu od tohoto počátku.
@preserveAspectRatio
na kořenovém elementu.
PS: V rámci větší švandy může používat samotné okénko i libovolný objekt uvnitř něj souřadnice v úplně jiných jednotkách. (A pokud není u čísla žádná zapsaná, myslí se tím pixely.)
Obrázek je vidět celý:
viewBox="0 0 200 200"
Z obrázku je vidět (zvětšený) levý horní kvadrant:
Z obrázku je vidět (zvětšený) levý spodní kvadrant:
Vynecháte-li určení velikosti viewportu, pravděpodobně se dočkáte překvapení – chování totiž není definováno. Respektive velmi dlouhou dobu nebylo, takže se může stát v podstatě cokoliv.
Když budete mít štěstí, roztáhne se SVG-obrázek do celé dostupné šířky, čímž příslušně naškáluje vnitřní souřadnice viewBoxu. Když natrefíte na modernější implementaci, dostane SVG-element standardní velikost 300×150 pixelů, jako ostatní inline-objekty bez určené velikosti. A když budete mít hodně smůlu, neuvidíte nic, protože velikost SVG-obrázku ve stránce bude 0×0 nebo něco podobně absurdního. Ostatně posuďte sami:
Pokud byste chtěli použít SVG na kreslení grafů nebo si prostě jenom pro jisté úlohy usnadnit výpočet souřadnic, můžete s výhodou posunout levý horní roh dostatečně „do mínusu“ ^_~
Podobně jako elementy v HTML mají rámeček a vnitřní a vnější okraj, jejichž vlastnosti se nastavují samostatně nezávisle na sobě (border, padding, margin), mají základní elementy SVG zase svůj okraj (tah, stroke) a vnitřek (výplň, fill), které se také nastavují zvlášť. A jelikož se jedná o obrázky zapsané pomocí XML, nepřekvapivě jsou tyto reprezentovány příslušnými atributy:
Šířka tahu se přičítá:
S tahem (stroke), který reprezentuje něco jako dosud nevystínovanou kresbu, se dá v SVG docela dost vyřádit:
stroke-dasharray definuje vzor přerušované čáry stylem délka tahu, délka mezery, délka tahu, …
. Je-li čísel lichý počet, pro určení vzoru se spojí dvakrát za sebou. stroke-dashoffset pak udává posun začátku vzoru od začátku tahu:
Průhlednost se dá buď nastavit pro celý element najednou atributem @opacity
..
..nebo zvlášť pro výplň i tah za použití výběru barvy rgba()
:
Plus se to dá samozřejmě smíchat dohromady, ale hodnoty průhlednosti se pak skládají (násobením)!
Pokud podobných elementů bude hodně, nastavování jejich vzhledu pomocí atributů začne být stejně nepřehledné a otravné jako používání atributu @style
na HTML-elementech. Naštěstí se totéž dá nastavit i přes CSS:
Jak jste si již zajisté z příkladů asi všimli, později se ve zdrojovém dokumentu vyskytující element překreslí elementy dříve se vyskytující, pokud je alespoň částečně překrývá. Pořadí ve zdroji tudíž přirozeně definuje tzv. stacking order, který o uvedeném rozhoduje.
A protože v SVG žádný z-index
jako v HTML není a v dohledné době – pokud vůbec někdy! – ani nebude, jediná pořádná možnost, jak změnit pořadí vykeslování objektů, je změnit jejich pořadí ve zdroji. Klidně i JavaScriptem.
TranslateZ()
.
Nemůžete-li z nejrůznějších důvodů předchozí použít, ještě pořád tu je čistě XML-možnost – nejdříve elementy bez vykreslení pouze nadefinujte v jejich přirozeném pořadí pomocí elementu <defs>
a následně je v požadovaném pořadí vykreslete pomocí elementů <use>:
<def>
kupodivu funguje také ^_~
@href
už je nativní součástí SVG a nemusíme si ho již půjčovat ze standardu XLink.
Popravdě element <defs>
ani používat nemusíte, <use>
zpřehází stacking order i tak. Ale už na první pohled je to s ním čistší řešení – původní elementy ve „špatném“ pořadí se vůbec nevykreslí.
SVG nabízí možnost provést něco podobného jako v předchozím příkladu i pro skupinu více elementů, které patří k sobě – element <symbol> seskupí dohromady celý svůj podstrom, takže je možné ho odkazovat (a pracovat s ním) jako jeden objekt, aniž by ho zobrazil.
@viewBox
a @preserveAspectRatio
, takže je to nejen přehlednější, ale i univerzálnější.
Změna barvy jednotlivých kopií je možná pouze proto, že v definici je barva nenastavena! Jinak by všechny kopie měly stejnou barvu (či jiné přednastavené vlastnosti).
Element <g>
slouží k tomu, abyste mohli větší skupinu SVG-elementů používat jako jeden objekt. A narozdíl od <symbol>
u se jeho obsah ihned vykreslí (a nemá tolik možností nastavení zobrazení).
Výhoda – jak je vidět – je v tom, že na celou skupinu najednou můžete aplikovat nejen CSS-styly, případně JavaScripty, ale třebas právě i SVG-animace.
Jelikož elementy v SVG se v podstatě skládají ze tří samostatných částí, nepřekvapí, že i pořadí jejich vykreslení ovlivňuje výsledný vzhled. Standardní pořadí jest následující:
fill (vnitřek) → stroke (rámeček) → markers (označení konců cest)
Naštěstí se dá změnit pomocí CSS-pravidla paint-order
, protože zvláště u textu dokáže být rozdíl až neuvěřitelný:
Jak jsme viděli, oddělení vykreslení rámečku (vector-effect: non-scaling-stroke;
: