Kurz SVG - o°ezßvßnφ a maskovßnφ
Standard SVG obsahuje kompletnφ sadu grafick²ch nßstroj∙ a nenφ mu cizφ ₧ßdn² postup vyu₧φvan² profesionßly. Rozdφl mezi formßtem SVG a zbytkem sv∞ta, lidov∞ °eΦno, se podobß rozdφlu mezi Mercedesem a Trabantem. V tomto Φlßnku si tedy probereme o°ezßvßnφ a maskovßnφ, co₧ jsou velmi silnΘ grafickΘ nßstroje, umo₧≥ujφcφ podstatn∞ m∞nit vzhled dokumentu.
Maskovßnφ a o°ezßvßnφ jsou sice podobnΘ grafickΘ operace, ale s pom∞rn∞ velk²m kvalitativnφm rozdφlem:
- O°ezovΘ cesty (clipping paths) - dobrß p°edstava je takovß, jako by o°ezßvan² objekt byl podle obrysu tΘto vektorovΘ cesty vyst°i₧en z papφru n∙₧kami. Slovy modernφ poΦφtaΦovΘ grafiky, o°ezov² obrys p°edstavuje jednobitovou masku, pod kterou jsou maskovanΘ objekty vykresleny, zatφmco vn∞ nikoli.
- Masky (masks) - na rozdφl od prostΘho o°ezu m∙₧e mφt ka₧d² bod v masce r∙zn² stupe≥ pr∙hlednosti (typicky bude maska osmibitovß = 256 ·rovnφ pr∙hlednosti), v tomto p°φpad∞ tedy masku netvo°φ obrys maskovacφch objekt∙, ale jas jejich v²pln∞. Uv∞domte si i vyÜÜφ v²poΦetnφ nßroΦnost prßce s maskami, to je pravd∞podobn∞ dalÜφ d∙vod, proΦ jsme Φekali na podobnΘ funkce tak dlouho.
Pro lepÜφ p°edstavu mohu vzφt p°φklad z oblasti profesionßlnφ grafiky. O°ezovΘ cesty, historicky samoz°ejm∞ starÜφ, p°edstavuje nap°φklad (dodnes dosti rozÜφ°en² zp∙sob) vklßdßnφ obrßzk∙ EPS s nastavenou o°ezovou cestou do sßzecφho programu QuarkXpress. Maskovßnφ na osobnφ poΦφtaΦe pravd∞podobn∞ p°inesl jako prvnφ slavn² Adobe Photoshop - sice ji₧ pom∞rn∞ brzy (od verze 3), ale vklßdßnφ do strßnek se zachovßnφm pr∙hlednosti dovolujφ a₧ nov∞jÜφ programy. Mßte-li zpr∙hledn∞nou obrazovou vrstvu s maskou v souboru formßtu PSD, m∙₧ete takov² soubor umφstit kup°φkladu do InDesignu od verze 2 nebo Corelu (tuÜφm od verze 9), kde bude maskovan² obraz stejn∞ pr∙hledn² jako v bitmapovΘm editoru.
SluΦovßnφ maskovanΘho objektu s pozadφm
TakzvanΘ sluΦovßnφ (simple alpha compositing) je d∙le₧it² termφn, kter² p°edstavuje postup, jak se maskovanΘ objekty vykreslujφ do ji₧ existujφcφho pozadφ. Maskovan² objekt je slouΦen (smφchßn) s existujφcφm pozadφm podle nßsledujφcφho vzorce, kter² ukazuje, jak se spoΦφtß v²slednß hodnota bodu pozadφ p°i slouΦenφ s bodem vykreslovanΘho elementu, jen₧ je ovlivn∞n maskou Φi pr∙hlednostφ:
Pg' = (1 - Ea) x Pg + Eg
Pb' = (1 - Ea) x Pb + Eb
Pa' = 1 - (1 - Ea) x (1 - Pa)
- Er, Eg, Eb - barva Elementu x Ea
- Ea - pr∙hlednost Elementu
- Pr, Pg, Pb - barva Pozadφ x Pa
- Pa - pr∙hlednost Pozadφ
- Pr', Pg', Pb' - barva Pozadφ po slouΦenφ x Pa'
- Pa' - pr∙hlednost Pozadφ po slouΦenφ
Pozor, aby se dosßhlo elegantnφho zßpisu, hodnoty barev jsou psßny jako p°ednßsobenΘ (premultiplied) hodnotou pr∙hlednosti (alpha).
Co je "viewport"
Na ·vod problematiky si budeme muset zavΘst jeden teoretick² pojem. V jakΘmkoli bod∞ kresby lze vytvo°it takzvan² viewport, co₧ je rßm, kter² Φinφ do n∞ho vlo₧enou grafiku do urΦitΘ mφry nezßvislou na nad°azenΘm obsahu. Aby n∞jak² prvek mohl vytvo°it viewport, musφ mφt atributy "x", "y", "width" a "height".
P°edevÜφm se uvnit° viewportu automaticky vytvo°φ nov² sou°adnicov² systΘm, kter² bude shodn² se systΘmem aktußlnφm v mφst∞ vlo₧enφ s tφm rozdφlem, ₧e se zm∞nφ poΦßtek sou°adnic - posune se na bod "x", "y" - m∞°eno v systΘmu aktußlnφm v mφst∞ vlo₧enφ. Dßle se logicky zm∞nφ v²znam procentnφch jednotek, tak₧e 100 % bude odpovφdat plnΘ Üφ°ce Φi v²Üce novΘho boxu. Sou°adnicov² systΘm lze navφc p°edefinovat nepovinn²m atributem "viewBox = (x y Üφ°ka v²Üka)" (viz tΘ₧ p°ehled atribut∙ elementu svg
). Dßle se na takov² prvek aplikujφ atributy "overflow" a "clip", popsanΘ nφ₧e.
Nov² viewport vytvß°ejφ nßsledujφcφ prvky svg
, symbol
(kdekoliv je vyvolßn prvkem use
), image
, pattern
, marker
a foreignObject
(vklßdßnφ obsahu v jinΘm XML jazyce).
O°ezßvßnφ
O°ezßvßnφ je starÜφ a jednoduÜÜφ metodou vykreslovßnφ Φßsti dokumentu urΦenΘ pomocφ hraniΦnφ k°ivky.
Atributy "overflow" a "clip"
P°esahuje-li obsah sv∙j rodiΦovsk² rßmec, podporuje SVG jako₧to W3C standard i CSS2 atributy "overflow" a "clip", ovliv≥ujφcφ p°etΘkßnφ a o°ezßvßnφ obsahu. Pravidla bylo nutno pro grafiku samoz°ejm∞ lehce rozÜφ°it, ale veÜkerß rozÜφ°enφ jsou velmi logickß a znalci pravidel CSS2 si budou p°ipadat jako doma. Oba atributy lze pou₧φt na vÜechny prvky, kterΘ vytvß°φ nov² "viewport". Musφme si takΘ uv∞domit, ₧e ka₧d² grafick² prvek bude v terminologii CSS v₧dy typu block-level box.
- overflow - definuje, jak a kdy bude vnit°nφ rßm (grafick² prvek) o°φznut podle hranic rßmu, ve kterΘm je obsa₧en. Mo₧nΘ hodnoty atributu jsou: visible, hidden, scroll, auto, inherit.
- clip - specifikuje velikost a tvar o°ezanΘ oblasti (masky) nßsledujφcφm zp∙sobem:
style="clip: rect(shora, zprava, zdola, zleva);"
. Hodnoty uvnit° zßvorek p°edstavujφ p°φsluÜnΘ vzdßlenostφ m∞°enΘ od okraj∙ vn∞jÜφho rßmu. CSS2 p°itom povoluje pouze pravo·hl² o°ez. Vidφme, ₧e se poΦφtß s budoucφ mo₧nostφ o°ezßvat i jin²mi tvary ne₧ obdΘlnφkem, pou₧it² zßpis je ale bohu₧el s SVG nekompatibilnφ.
Vytvo°enφ o°ezovΘ cesty
O°ezovß cesta se definuje uvnit° prvku clipPath
. Pou₧φvß se odkazovßnφm pomocφ lokßlnφ URI v atributu "clip-path", kter² p°idßme k prvk∙m, je₧ chceme o°φznout. Lze provßd∞t dokonce takovΘ kejkle, jako nap°φklad aplikovat o°ez v atributu
"clip-path" na jin² element clipPath
.
Element clipPath
m∙₧e obsahovat vektorovΘ prvky path
a text
, zßkladnφ tvary typu circle
a knihovnφ objekty use
(odkazujφ-li pouze na prvky uveden²ch povolen²ch typ∙). Sßm o sob∞ se nevykreslφ.
Atributy prvku clipPath
Prvek clipPath
m∙₧e nΘst nßsledujφcφ atributy:
- id - standardnφ identifikßtor objektu
- clipPathUnits - (nepovinn²) vybere jeden ze dvou mo₧n²ch sou°adnicov²ch systΘm∙ pro grafickΘ prvky masky; mo₧nΘ hodnoty: userSpaceOnUse (v²chozφ), objectBoundingBox. V p°φpad∞ tohoto atributu opakovan∞ doporuΦuji v∞novat extra pozornost nßsledujφcφm hodnotßm. Existuje toti₧ mnoho p°φpad∙, kdy z hlediska p°ehlednosti a elegance zßpisu je v²hodnΘ pou₧φvat sou°adnice relativnφ v∙Φi velikosti aktußln∞ zpracovßvanΘho objektu - jako auto°i dokumentu pak nap°φklad nemusφte m∞nit velikost Üipek na konci Φar, kdy₧ se zm∞nφ Üφ°ka dotyΦnΘ Φßry.
- "userSpaceOnUse" - pou₧ije se aktußlnφ systΘm sou°adnic ve kter²ch je souΦasn² zpracovßvan² objekt definovßn Φi kreslen.
- "objectBoundingBox" - tato hodnota aktivuje sou°adnicov² systΘm orientovan² uvnit° rßmeΦku ohraniΦujφcφho konkrΘtnφ prßv∞ zpracovßvan² objekt - sou°adnice (0,0), respektive (0%,0%), jsou v levΘm hornφm rohu a (1,1), respektive (100%,100%), v pravΘm spodnφm rohu ohraniΦenφ objektu; jin²mi slovy - tento sou°adnicov² systΘm se p°izp∙sobuje velikosti naÜeho objektu
- clip-rule - (nepovinn²) je nutno aplikovat na vektorovΘ objekty uvnit°
clipPath
; mß identick² v²znam s "fill-rule" (viz atributy definujφcφ vypl≥ovßnφ ploch); mo₧nΘ hodnoty: nonzero (v²chozφ), evenodd, inherit
<clipPath id="orez_cesta">
<path d="..." clip-rule="evenodd" />
</clipPath>
<rect clip-path="url(#orez_cesta)" ... />
</g>
Aplikace o°ezu
Vlastnφ pou₧itφ o°ezovΘ cesty je po vÜech definicφch u₧ hraΦkou - o°ezßvan² objekt (skupina objekt∙) pouze dostane navφc atribut clip-path="url(#orez_cesta)" odkazujφcφ na n∞jakΘ lokßlnφ URI.
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="320px" viewBox="0 0 480 360">
<title>6.3.3 Orezova cesta</title>
<defs>
<!-- bude se orezavat nasledujicim napisem -->
<clipPath id="orez" clipPathUnits="userSpaceOnUse">
<text x="40" y="270"
font-size="100" font-family="Helvetica">
Clip Test
</text>
</clipPath>
</defs>
<!-- nejdrive zrojove objekty pro lepsi predstavu -->
<image xlink:href="checker.png" x="40" y="20"
width="400px" height="128px" />
<text x="40" y="120" font-size="100"
font-family="Helvetica" fill="yellow">
Clip Test
</text>
<!-- oriznuty obraz -->
<image xlink:href="checker.png" x="40" y="170"
width="400px" height="128px" clip-path="url(#orez)"/>
<!-- obrys platna -->
<rect x="1" y="1" width="478" height="358"
fill="none" stroke="blue"/>
</svg>
Zobrazenφ o°ezßvßnφ v SVG (originßlnφ SVG, cca 1 kB)
Maskovßnφ
Maskovßnφ v norm∞ SVG znamenß, ₧e libovoln² grafick² objekt nebo skupina m∙₧e b²t pou₧ita jako takzvanß maska pr∙hlednosti (alpha mask) na jak²koli jin² objekt Φi skupinu p°i jejφm sluΦovßnφ s ji₧ vykreslen²m pozadφm.
Na rozdφl od prostΘho o°ezu m∙₧e mφt ka₧d² bod v masce r∙zn² stupe≥ pr∙hlednosti (typicky bude maska osmibitovß = 256 ·rovnφ pr∙hlednosti) - masku netvo°φ obrys maskovacφch objekt∙, ale jejich kresba, tedy p°esn∞ji jas jejich v²pln∞.
Vytvo°enφ masky
Masku definujeme pomocφ prvku mask
. PotΘ je aplikovßna na grafiku p°ipojenφm odkazu v atributu "mask", vlo₧enΘho do konkrΘtnφho objektu Φi skupiny. Pokud jste ji₧ prostudovali o°ezßvßnφ pomocφ cesty, urΦit∞ vidφte formßlnφ shodnost maskovßnφ s o°ezßvacφ operacφ (clipPath = mask, clip-path = mask).
<mask id="maska">
<path d="..." />
</mask>
<rect mask="url(#maska)" ... />
</g>
Element mask
ji₧ m∙₧e obsahovat prvky libovolnΘho typu - vΦetn∞ image
, kter² nebyl v p°edchozφm p°φpad∞ povolen - a sßm o sob∞ se mask
rovn∞₧ nevykreslφ. Praktickß realizace bude vypadat tak, ₧e se maskovacφ objekty vykreslφ do pomocnΘho alfa kanßlu (inicializovanΘho na "pr∙hlednou" Φernou) a nßsledn∞ se maskovan² objekt nebo skupina, po svΘm kompletnφm vykreslenφ, slouΦφ s pozadφm se zapoΦtenφm hodnot z p°ipravenΘho alfa kanßlu.
Atributy prvku mask
Prvek clipPath
m∙₧e nΘst nßsledujφcφ atributy:
- id - standardnφ identifikßtor objektu
- maskUnits - (nepovinn²) typ sou°adnicovΘho systΘmu pro urΦenφ velikosti alfa kanßlu masky; mo₧nΘ hodnoty: userSpaceOnUse, objectBoundingBox (v²chozφ)
- maskContentUnits - (nepovinn²) typ sou°adnicovΘho systΘmu pro obsah masky; mo₧nΘ hodnoty: userSpaceOnUse (v²chozφ), objectBoundingBox
- x, y - (nepovinn²) lev² hornφ roh alfa bufferu; v²chozφ hodnoty: -10%
- width, height - (nepovinnß) Üφ°ka a v²Üka alfa bufferu; v²chozφ hodnoty: 120%
Aplikovßnφ masky
Pou₧itφ masky je ji₧ naprosto trivißlnφ - maskovan² objekt (skupina objekt∙) pouze dostane navφc atribut mask="url(#maska)" s lokßlnφm URI odkazem na vytvo°enou masku.
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="320px" viewBox="0 0 800 300" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>6.4.2 Maska</title>
<desc>
Modry text na fialovem pozadi maskovany gradientem
(opet zduraznuji spravne pouziti 'defs').
</desc>
<defs>
<linearGradient id="Gradient" gradientUnits="userSpaceOnUse"
x1="0" y1="0" x2="800" y2="0">
<stop offset="0" stop-color="white" stop-opacity="0" />
<stop offset="1" stop-color="white" stop-opacity="1" />
</linearGradient>
<mask id="Mask" maskUnits="userSpaceOnUse"
x="0" y="0" width="800" height="300">
<rect x="0" y="0" width="800" height="300"
fill="url(#Gradient)" />
</mask>
</defs>
<!-- fialove pozadi -->
<rect x="0" y="0" width="800" height="300" fill="plum" />
<text x="400" y="200" text-anchor="middle"
font-family="Helvetica" font-size="100"
fill="blue" mask="url(#Mask)" >
Maskovany text
</text>
<!-- nakresli pouze cerny obrys textu -->
<text x="400" y="200" text-anchor="middle"
font-family="Helvetica" font-size="100"
fill="none" stroke="black" >
Maskovany text
</text>
</svg>
Zobrazenφ maskovßnφ v SVG (originßlnφ SVG, cca 1 kB)