Navigace

Hlavnφ menu

 

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φ:

   Pr' = (1 - Ea) x Pr + Er
   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
<g>
   <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.

<?xml version="1.0" encoding="UTF-8"?>
<!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
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).

<g>
   <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.

<?xml version="1.0" standalone="no"?>
<!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
Zobrazenφ maskovßnφ v SVG (originßlnφ SVG, cca 1 kB)
Hejral, Martin (11. 8. 2004)