Kurz SVG – vyplňování 1.

28. července 2004

Máte před sebou další článek, týkající se kreslení – jde o úvod do vybarvování a vyplňování vektorových tvarů, které jsme se naučili vytvářet v předchozích článcích. Tentokrát se budeme zabývat například hodnotami typu „výplň“, vyplňováním ploch, ovládáním viditelnosti, značkami a parametry vykreslování.

Jak už jsem naznačil, z hlediska vyplňování jsou výplně i tahy vektorových objektů zcela ekvivalentní. Zdůrazňuji tento fakt i proto, že spousta reálných grafických programů má všelijaká omezení – zejména při vytváření obrysů. SVG prohlížeč dodržující normu „bez mrknutí oka“ vyplní tah jakéhokoliv vektorového objektu vámi vytvořenou texturou nebo vystínuje text kruhovým přechodem barev (přičemž každý definiční bod na přechodu může mít navíc jinou průhlednost).

Elementy path, polyline, polygon a line mohou mít navíc na místě kotevních bodů vykresleny takzvané značky (marker symbols). Proto prvek „marker“ patří právě spíše do článku o vybarvování než-li do textu o kreslení, jak byste snad mohli očekávat.

Hodnota typu „výplň“ (paint)

Podporovány jsou následující typy vyplňování, použitelné pro výplně i tahy:

  • plné barvy (s různými průhlednostmi)
  • přechody barev lineární a kruhové
  • vzorky (textury)

Pro všechny uvedené způsoby vyplňování používá někdy norma společný obecný výraz paint server – česky bychom snad mohli říkat vyplňovací stroj. Řečeno obecnou, abstraktní terminologii normy se při definování vybarvení obbjektů v atributech „fill“ a „stroke“ odkazujeme lokální referencí URI právě na žádaný „vyplňovací stroj“. Zdá se to poněkud překombinované, zato ale získáme velkou flexibilitu. Jak uvidíte o kousíček níže, při nejběžnější variantě – vybarvování plnou barvou – se zde uvedená konstrukce redukuje na zápis shodný s CSS/HTML.

Podle uvedených údajů mohou tedy atributy „fill“ a „stroke“ nabývat následující hodnoty typu „výplň“:

  • none – nic
  • currentColor – pro barvu se použije atribut „color“ (tento mechanismus byl použit pro bezproblémové sdílení barev definovaných například v nadřazené rodičovské HTML struktuře – kde je „color“ barva textu – v případě SVG kódu vnořeného uvnitř HTML)
  • #rgb – přímo uvedená barva podle pravidel CSS (lze uvádět i jména barev nebo, pokud prohlížeč podporuje správu barev, také ICC barvy)
  • URI – lokální odkaz, například na definici textury nebo přechodu
  • inherit – zděděná hodnota (mimochodem, s touto hodnotou se budeme setkávat téměř u všech atributů a už ji nadále nebudu ani popisovat)

Atributy definující vyplňování ploch

  • fill – barva, viz výše (hodnota typu „výplň“); výchozí hodnota: „black“
  • fill-opacity – průhlednost výplně, může nabývat hodnot od 0.0 (plně průhledná) do 1.0 (zcela neprůhledná); výchozí hodnota: „1“
  • fill-rule – jak jsme probírali v článku o grafických primitivech, vektorové prvky path se mohou skládat z více než jedné plochy, proto potřebujeme tento parametr, abychom určili, co se stane, pokud se budou takové plochy překrývat; výchozí hodnota: „nonzero“;

Jak jsme se už také zmínili, nejčastější praktické použití atributu „fill-rule“ bude vytváření průhledných otvorů v ploše elementu path – a i když to tak možná na první pohled nevypadá, jedná se o velmi pokročilou a velmi silnou vlastnost s obrovským kreativním potenciálem, jak naznačují i následující ukázky.

Hodnota fill-rule=“evenodd“

<?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“ height=“160px“ viewBox=“0 0 1200 400″
     xmlns=“http://www.w3.org/2000/svg“
     xmlns:xlink=“http://www.w3.org/1999/xlink“>
  <title>5.2 Demonstrace atributu ‚fill-rule:evenodd'</title>
  <desc>
    Priklad ukazuje take v prvnim clanku probirane
    prvky ‚defs‘ a ‚use‘ pro vicenasobne
    zobrazeni sipek ukazujicich smer
    vektorovych cest. V tomto jednoduchem
    priklade lze vynechat prvek ‚symbol‘.
    Transformacni atrib. vysvetlime pozdeji.
  </desc>
  <defs>
    <!– popis ‚path‘ viz kap. 3.7 –>
    <path id=“Triangle“ d=“M 16,0 L -8,9 v-18 z“
          fill=“black“ stroke=“none“ />
  </defs>
  <!– nastaveni pravidla vyplnovani –>
  <g fill-rule=“evenodd“ fill=“red“ stroke=“black“ stroke-width=“3″ >
    <path d=“M 250,75 L 323,301 131,161 369,161 177,301 z“ />
    <use xlink:href=“#Triangle“
         transform=“translate(306.21 249) rotate(72)“ />
    <use xlink:href=“#Triangle“
         transform=“translate(175.16,193.2) rotate(216)“ />
    <use xlink:href=“#Triangle“
         transform=“translate(314.26,161) rotate(0)“ />
    <use xlink:href=“#Triangle“
         transform=“translate(221.16,268.8) rotate(144)“ />
    <use xlink:href=“#Triangle“
         transform=“translate(233.21,126.98) rotate(288)“ />
    <path d=“M 600,81 A 107,107 0 0,1 600,295 A 107,107 0 0,1 600,81 z 
             M 600,139 A 49,49 0 0,1 600,237 A 49,49 0 0,1 600,139 z“ />
    <g transform=“translate(600,188)“>
    <use xlink:href=“#Triangle“
         transform=“rotate(  0) translate(107,0) rotate(90)“ />
    <use xlink:href=“#Triangle“
         transform=“rotate(120) translate(107,0) rotate(90)“ />
    <use xlink:href=“#Triangle“
         transform=“rotate(240) translate(107,0) rotate(90)“ />
    <use xlink:href=“#Triangle“
         transform=“rotate( 60) translate(49,0) rotate(90)“ />
    <use xlink:href=“#Triangle“
         transform=“rotate(180) translate(49,0) rotate(90)“ />
    <use xlink:href=“#Triangle“
         transform=“rotate(300) translate(49,0) rotate(90)“ />
    </g>
    <path d=“M 950,81 A 107,107 0 0,1 950,295 A 107,107 0 0,1 950,81 z 
             M 950,139 A 49,49 0 0,0 950,237 A 49,49 0 0,0 950,139 z“ />
    <g transform=“translate(950,188)“>
    <use xlink:href=“#Triangle“
         transform=“rotate(  0) translate(107,0) rotate(90)“ />
    <use xlink:href=“#Triangle“
         transform=“rotate(120) translate(107,0) rotate(90)“ />
    <use xlink:href=“#Triangle“
         transform=“rotate(240) translate(107,0) rotate(90)“ />
    <use xlink:href=“#Triangle“
         transform=“rotate( 60) translate(49,0) rotate(-90)“ />
    <use xlink:href=“#Triangle“
         transform=“rotate(180) translate(49,0) rotate(-90)“ />
    <use xlink:href=“#Triangle“
         transform=“rotate(300) translate(49,0) rotate(-90)“ />
    </g>
  </g>
  <!– obrys platna –>
  <rect x=“1″ y=“1″ width=“1198″ height=“398″
        fill=“none“ stroke=“blue“ />
</svg>

Demonstrace atributu "fill-rule:evenodd"
Demonstrace atributu „fill-rule:evenodd“ (originální SVG, cca 3 kB)

Hodnota fill-rule=“nonzero“

Kromě hodnoty fill-rule="nonzero" je zdrojový kód této ukázky shodný s předchazejícím.

Demonstrace atributu "fill-rule:nonzero"
Demonstrace atributu „fill-rule:nonzero“ (originální SVG, cca 3 kB)

Parametry tahů

  • stroke – barva, viz výše (hodnota typu „výplň“); výchozí hodnota: „black“
  • stroke-width – šířka tahu; výchozí hodnota: „1“
  • stroke-linecap – tvar konců čar, nabývá jednu z hodnot: butt (useknutý kolmo na tah), round (zaoblený/kulatý), square (čtvercový); výchozí hodnota: „butt“
  • stroke-linejoin – typ napojení a rohů čar: miter (špičatý), round (kulatý), bevel (useknutý); výchozí hodnota: „miter“
  • stroke-miterlimit – omezení „špičatosti“ – čím je úhel svíraný dvěma spojenými čarami menší, tím delší je průřez „špičky“ ve spojovacím bodě; hodnota (n) omezí průřez v bodě spojení na (n)násobek šířky tahu; výchozí hodnota: „4“
  • stroke-dasharray – slouží pro snadnou výrobu libovolně čárkovaných, čerchovaných nebo tečkovaných čar; hodnotou tohoto atributu je libovolně dlouhá posloupnost čísel, kde zapsané hodnoty určují postupně délku plného tahu a poté délku přerušení – mezery (pokud byste zadali lichý počet čísel, bude taková posloupnost při interpretaci zduplikována tak, aby se dosáhl kýžený sudý počet hodnot: například z posloupnosti 5,3,2 vznikne při vykreslování 5,3,2,5,3,2); hodnota „none“ znamená plnou čáru; výchozí hodnota: „none“
  • stroke-dashoffset – definuje posun vzoru čárkování vůči počátečnímu bodu vektorové cesty; výchozí hodnota: „0“
  • stroke-opacity – průhlednost tahu; výchozí hodnota: „1“

Ovládání viditelnosti

Existují dva významově velmi odlišné atributy (opět převzaté z CSS):

  • display – nastavení na „none“ způsobí absolutní vyřazení prvku a jeho dětí ze zobrazování; výchozí hodnota: „inline“
  • visibility – nastavení na „hidden“ skryje prvek a všechny jeho případné potomky; všechny prvky ale zůstanou v objektovém stromu vykreslovaných objektů. V případě skupiny se stále například mohou její děti zviditelnit opětovnou změnou visibility na „visible“.

Značky (marker)

Značka neboli marker je uživatelsky definovaná grafická značka libovolného tvaru (může být dokonce i pohyblivá), přiřazená k nějakým bodům vektorových objektů typů path, line, polyline a polygon. Typicky se používá k výrobě šipek nebo označování bodů ve kresbě.

Definice značek v probíhá pomocí prvku marker, jehož význam a chování je velmi blízké SVG elementu symbol. Vykreslovány jsou tak, že jejich referenční bod (atributy „refX“ a „refY“) je umístěn na zadaný vrchol vektorové cesty.

Atributy značek

  • markerUnits – definuje souřadnicový systém značky; výchozí hodnota „strokeWidth“ je vhodná právě pro vykreslování šipek a podobně (1 jednotka = šířka tahu), druhá povolená hodnota je „userSpaceOnUse“ (v tom případě se použije aktuální souřadnicový systém objektu – tedy konkrétní vektorové cesty)
  • refX, refY – nastaví referenční bod značky, tedy bod, který bude při vykreslení „přiložen“ na konkrétní vrchol značkované cesty; výchozí hodnoty: „0“
  • markerWidth, markerHeight – šířka a výška značky; výchozí hodnoty: „3“
  • orient – orientace, tedy natočení značky; výchozí hodnota „auto“ způsobí natáčení značky ve směru tečny aktuálně značkované křivky; lze též číselně zapsat úhel, vztahující se k aktuálnímu souřadnicovému systému objektu – pak budou všechny značky natočeny stejně

Atributy pro značkování čar

  • marker-start – atribut definuje značku, která se vykreslí na prvním bodě vektorové cesty či vektorového objektu typu rect a podobně
  • marker-end – analogicky definuje značku pro poslední bod cesty
  • marker-mid – značky vykreslující se nad vnitřními body cesty

V případě složených cest se poměrně logicky značky vykreslují pro každou subcestu samostatně.

<?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“ height=“160px“
     viewBox=“0 0 4000 2000″ version=“1.1″
     xmlns=“http://www.w3.org/2000/svg“>
   <title>5.5.2 Vytvoreni sipky</title>
   <desc>
      Element ‚marker‘ je pouzit k vykresleni
      trojuhelniku na konci cary. Povsimnete si
      ze souradnicovy system je nastaven
      relativne k sirce cary – velikost sipky
      se bude automaticky prizpusobovat
      skutecne sirce cary!
   </desc>
   <defs>
      <!– povsimnete si pouziti ‚defs‘ –>
      <marker id=“Triangle“
        viewBox=“0 0 10 10″ refX=“0″ refY=“5″
        markerUnits=“strokeWidth“
        markerWidth=“4″ markerHeight=“3″
        orient=“auto“>
        <!– viz kap. 3.7 –>
        <path d=“M 0 0 L 10 5 L 0 10 z“ />
      </marker>
   </defs>
   <path d=“M 1000 750 L 2000 750 L 2500 1250″
           fill=“none“ stroke=“black“ stroke-width=“100″
           marker-end=“url(#Triangle)“ />
   <!– obrys platna –>
   <rect x=“10″ y=“10″ width=“3980″ height=“1980″
         fill=“none“ stroke=“blue“ stroke-width=“10″ />
</svg>

Element "marker" je použit k vykreslení trojúhelníku na konci čáry
Element „marker“ je použit k vykreslení trojúhelníku na konci čáry (originální SVG, cca 1 kB)

Parametry vykreslování

Interpolace barev

Následující dva atributy se uplatní v těchto případech:

  • color-interpolation – způsob přechodu mezi dvěma barvami v gradientech a také při animacích nebo výpočtech průhledností
  • color-interpolation-filters – výpočty filtrů

Barevné prostory:

  • linearRGB – lineární světelná energie (lineární průběh všech barevných kanálů bez gama korekce)
  • sRGB – nelineární prostor s křivkou gama korekce 2.2

Možné hodnoty atributů

Povšimněte si, že má každý atribut jinou výchozí hodnotu:

  • color-interpolation – auto, sRGB, linearRGB, inherit; výchozí: „sRGB“
  • color-interpolation-filters – auto, sRGB, linearRGB, inherit; výchozí: „linearRGB“

Následující příklad krásně demonstruje, jak může interpolace barev silně ovlivnit vykreslení přechodu barev. Jen ještě poznamenávám že tato vlastnost patří mezi ty implementačně náročnější a osobně jsem se setkal s prohlížeči, které zvládají pouze jeden typ a uvedené atributy vesele ignorují.

<?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>5.6.1 Interpolace barev</title>
  <desc>
    Vykresli se 3 stejne linearni gradienty
    s ruznymi interpolacemi barev. Vysvetleni
    prechodu viz. kap. 5.9.2 a transformacni
    atributy najdete v kap. 7.
  </desc>                  
  <!– nejdrive prechody nadefinujeme –>
  <defs>
    <linearGradient id=“gradient“>
      <stop offset=“0″ stop-color=“white“ />
      <stop offset=“.33″ stop-color=“blue“ />
      <stop offset=“.66″ stop-color=“red“ />
      <stop offset=“1″ stop-color=“yellow“ />
    </linearGradient>
    <!– Zde v prohlizeci ASV3 objevite –>
    <!– jednu z minima chyb jinak vyborneho –>
    <!– prohlizece – ignorace atributu ‚href‘. –>
    <linearGradient id=“gradientSRGB“
      color-interpolation=“sRGB“ xlink:href=“url(#gradient)“ >
    </linearGradient>
    <linearGradient id=“gradientLRGB“
      color-interpolation=“linearRGB“ xlink:href=“url(#gradient)“ >
    </linearGradient>
  </defs>
  <!– nasleduje vykresleni preddefinovanych vyplni –>
  <g transform=“translate(40, 80)“>
    <rect width=“300″ height=“40″ stroke=“black“
          fill=“url(#gradient)“ />
    <text x=“310″ y=“20″ font-size=“16″>
      vychozi (sRGB)
    </text>
  </g>
  <g transform=“translate(40, 160)“>
    <rect width=“300″ height=“40″ stroke=“black“
          fill=“url(#gradientSRGB)“ />
    <text x=“310″ y=“20″ font-size=“16″ >
      sRGB
    </text>
  </g>
  <g transform=“translate(40, 240)“>
    <rect width=“300″ height=“40″ stroke=“black“
          fill=“url(#gradientLRGB)“ />
    <text x=“310″ y=“20″ font-size=“16″ >
      linearRGB
    </text>
  </g>
  <!– obrys platna –>
  <rect x=“1″ y=“1″ width=“478″ height=“358″ fill=“none“ stroke=“blue“/>
</svg>

Vykreslí se tři stejné lineární gradienty s různými interpolacemi barev
Vykreslí se tři stejné lineární gradienty s různými interpolacemi barev (originální SVG, cca 1 kB)

Rychlost versus kvalita zobrazení

Následující čtyři atributy umožňují změnit kvalitu vykreslování grafických prvků na úkor rychlosti a naopak. Tím si můžeme přizpůsobit například obrázek, od kterého budeme očekávat zobrazení pohybu a podobně. Větší kvalita se v SVG prohlížečích obvykle projeví zapnutím vyhlazování, případně zvětšením přesnosti výpočtů.

  • color-rendering – kvalita výpočtu barev; hodnoty: auto, optimizeSpeed, optimizeQuality, inherit
  • shape-rendering – preferuje buď rychlost, ostré „čitelné“ hrany nebo přesnost grafických tvarů; hodnoty: auto, optimizeSpeed, crispEdges, geometricPrecision, inherit
  • text-rendering – kvalita vykreslení textu; hodnoty: auto, optimizeSpeed, optimizeLegibility, geometricPrecision, inherit
  • image-rendering – kvalita resamplingu bitmap; hodnoty: auto, optimizeSpeed, optimizeQuality, inherit
Předchozí článek gb.cz
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *