reklama

Budoucnost vektorové grafiky na webu, 2. část

Proč bychom měli kvůli vektorové grafice studovat hromadu nových nestandardních technik a postupů? Proč dělat věci dvojím způsobem? Proč ta schizofrenie, když nám stačí ty znalosti, které už máme dnes!

Skutečná síla spojení SVG+XHTML

Existuje standardní mechanismus, který dovoluje webdesignerům umístit do jednoho jediného XML souboru data v několika různých nářečích jazyka XML - jedná se o tzv. jmenné prostory XML ("name space").

Nepočítám-li Amayu, tak jsou Opera 9 a Mozilla Firefox 1.5 prvními dostupnými webovými prohlížeči, které dokážou kombinaci XHTML+SVG vykreslit.

Klepněte pro větší obrázek

Tento známý příklad pro Mozillu Firefox používá CSS pseudo-třídy ":hover" k vytvoření "roll-over" efektu (ukázka)

Aktualizováno: Demonstrační kód pocházel ve své originální podobě ze stránek Mozilla SVG. Původně jsem jej převzal, aniž by mne napadlo v něm hledat nějaké chyby. V tomto XML kódu se ale bohužel nacházelo několik věcí ne úplně splňujících podmínky normy SVG - a ty způsobily problémy prohlížeči Opera 9. Nyní je XHTML+SVG zcela ve shodě se standardem (a funkční v Opeře 9, Firefoxu 1.5, Safari 2 + SVG).

Nyní bych ctěné čtenáře rád upozornil speciálně na způsoby CSS formátování v ukázkách. Možnosti stylování grafických (!) prvků jsou velice rozsáhlé a přitom v podstatě identické (!) s postupy běžnými u textových dokumentů HTML.

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:svg="http://www.w3.org/2000/svg" >
<head>
  <style>
    circle:hover {fill-opacity:0.9;}
  </style>
</head>
<body>
  <svg:svg>
    <svg:g style="fill-opacity:0.7;">
      <svg:circle cx="6cm" cy="2cm" r="100"
        style="fill:red; stroke:black; stroke-width:0.1cm"
        transform="translate(0,50)" />
      <svg:circle cx="6cm" cy="2cm" r="100"
        style="fill:blue; stroke:black; stroke-width:0.1cm"
        transform="translate(70,150)" />
      <svg:circle cx="6cm" cy="2cm" r="100"
        style="fill:green; stroke:black; stroke-width:0.1cm"
        transform="translate(-70,150)"/>
    </svg:g>
  </svg:svg>
</body>
</html>

Prvek SVG se chová jako blokový prvek CSS. Vtipnou demonstraci reálných výhod standardní vektorové grafiky představuje i následující ukázka, ve které jsem nadefinoval rozměry SVG bloku s id="vector2" pomocí relativních CSS souřadnic "em". Pokud si v prohlížeči změníte měřítko zobrazení, změní se potom spolu s velikostí písma i rozměry takto vložených SVG grafik. A tyto obrázky budou v libovolném zvětšení absolutně ostré, nerozmazané, nekostičkované!

Klepněte pro větší obrázek

Měňte si velikost okna prohlížeče jak chcete, ale SVG písmo na pozadí bude stále vyplňovat celou plochu a stále bude stejně hladké. Červeno-modrý vektorový tvar se zvětšuje spolu s textem (ukázka)

Praktická poznámka: Vykreslování písem - zvláště ve FF - není zatím zcela přesné. Vývojová verze DeerPark v současnosti vykresluje písma v tomto příkladu zcela špatně - použijte proto FF 1.5. Obzvláště zde, na rozhraní mezi HTML a SVG, vývojáři kráčí nevyšlapanou cestičkou... Bude asi ještě chvíli trvat než se vše 100% odladí - definice velikosti SVG bloku není bohužel ještě zcela spolehlivá a stejně funkční ve všech SVG prohlížečích. Opera 9 ovšem jednoznačně vede.

Povšimněte si jak přirozeně můžete pomocí CSS třídy nastavit kupříkladu parametry SVG prvku stop, definujícího bod na přechodu barev (viz druhý SVG blok s id="vector1"):

<?xml version="1.0" encoding="utf-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>SVG + XHTML + CSS</title>
  <style>
    html,body {
      font-family:`Helvetica CE`,Helvetica,sans-serif;
      border:0; margin:0; padding:0;
      position:absolute; z-index:0; left:0%; top:0%; width:100%; height:100%;
    }
    h1,p {
      padding:0px 16px;
    }
    <!-- následují styly pro SVG elementy -->
    text.tx0 {
      font-family:`Helvetica CE`,Helvetica,sans-serif;
      font-size:55px; fill:blue; fill-opacity:.2
    }
    stop.begin { stop-color:#dff; }
    stop.end { stop-color:#7af; }
  </style>
</head>
<body>

<h1>Příklad SVG + XHTML + CSS</h1>
<p>Tento XML dokument obsahuje data ve formátech XHTML a SVG.</p>
<p>Pozadí je vektorové a definuje jej SVG element s id=`vector1`.</p>
<p>
  <svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="vector2"
    viewBox="0 0 100 100" width="3em" height="3em">
    <linearGradient id="gradient2">
      <stop stop-color="red" offset="0%"/>
      <stop stop-color="blue" offset="100%"/>
    </linearGradient>
    <polygon points="0,0 0,100 100,00"
             fill="url(#gradient2)"/>
    <circle cx="100" cy="100" r="71"
      fill="url(#gradient2)"
      transform="rotate(135,100,100)"/>
  </svg>
Na počátku tohoto odstavce je jako součást "tekoucího" textu vložen další SVG prvek s id=`vector2` a nastylován tak, aby se jeho velikost měnila spolu s textem.
</p>
<p>A to vše je jen jedna malá součást revoluce, kterou přináší nativní implementace SVG do světa webu!
</p>
  <svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="vector1"
    viewBox="0 0 100 100" preserveAspectRatio="none"
    style="position:absolute; top:0; left:0; width:100%; height:100%; z-index:-1;">
    <linearGradient id="gradient">
      <stop class="begin" offset="0%"/>
      <stop class="end" offset="100%"/>
    </linearGradient>
    <rect x="0" y="0" width="100" height="100" style="fill:url(#gradient)" />
    <text x="0" y="77" class="tx0" >SVG</text>
    <text x="9" y="66" class="tx0" >SVG</text>
    <text x="3" y="60" class="tx0" >SVG</text>
  </svg>
</body>
</html>

Kombinace různých druhů XML dat

SVG standard 1.1 vyžaduje od prohlížeče schopnost pracovat s prvky v cizím jmenném prostoru. Jinými slovy, pokud do SVG souboru vložíte data v jiném XML "name space", tato se stanou součástí objektového stromu DOM a je s nimi možno následně manipulovat využitím skriptovacího jazyka. Tím nám vypadává ze hry Opera 8, jelikož implementovaná SVG Tiny 1.1 neobsahuje podporu skriptování. Opera 9 za to už věc zvládá na jedničku.

Klepněte pro větší obrázek

Grafika vygenerovaná JavaScriptem z tabulkových dat vložených uvnitř SVG souboru (ukázka)

Obecná XML data vložená v SVG vypadají následovně:

 <data:polozka>
   <data:popis>výsledek</data:popis>
   <data:hodnota>7</data:hodnota>
 </data:polozka>

Tento příklad opět není v podstatě nikterak odlišný od "obyčejného" DHTML. Jen při hledání objektů navíc specifikujeme i konkrétní jmenný prostor ("name space"):

// ziska seznam s daty
seznamPopisu = doc.getElementsByTagNameNS(data_ns, "popis");
seznamHodnot = doc.getElementsByTagNameNS(data_ns, "hodnota");

To stejné při vytváření prvků pomocí funkcí DOM:

pathElement = doc.createElementNS(svg_ns, "path");

Jediné co je odlišné od HTML jsou jména prvků, se kterými pracujeme. Pro plné pochopení algoritmu je potřebné znát mj. význam atributu `d` v prvku path. (Zmíněný atribut obsahuje příkazy definující tvar křivek a čar.) V následující ukázce jsem odstranil některé méně zajímavé části:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" viewBox="0 0 1000 700" onload="onLoad(evt)">
<title>Generování SVG obrazu z dat v jiném XML "namespace"</title>

<defs>
<script type="text/ecmascript"><![CDATA[
var svg_ns = "http://www.w3.org/2000/svg";
var bd_ns = "http://example.org/Example";

function onLoad(evt){
  // ukazatel na objektovy model SVG dokumentu
  var svgElement = evt.target;
  var doc = svgElement.ownerDocument;

  // ukazatel na zdrojova XML data
  var resultsElement = doc.getElementById(`vysledky`);
  var gElement = doc.getElementById(`graf`);

  // spocita pocet polozek
  RegionNodeList = doc.getElementsByTagNameNS(bd_ns, "polozka");
  pocetPolozek = RegionNodeList.length;

  // ziska seznam s daty
  seznamPopisu = doc.getElementsByTagNameNS(bd_ns, "popis");
  seznamHodnot = doc.getElementsByTagNameNS(bd_ns, "hodnota");

  // zjisti maxHodn. hodnotu v grafu
  var maxHodn = 0, h;
  for (ix = 0; ix < pocetPolozek; ix++) {
    h = Number(seznamHodnot.item(ix).firstChild.nodeValue);
    if(h>maxHodn) maxHodn = h;
  }

  // generovani grafu
  for (ix = 0; ix < pocetPolozek; ix++) {
    popis = seznamPopisu.item(ix).firstChild.nodeValue;
    hodnota = Number(seznamHodnot.item(ix).firstChild.nodeValue);
    x = ix*1000/pocetPolozek + 70;
    y = 600 - hodnota*500/maxHodn;
    sirka = 1000/pocetPolozek/2.8;

    // textovy popis osy X
    textElement = doc.createElementNS(svg_ns, "text");
    textNode = doc.createTextNode(popis);
    textElement.appendChild(textNode);
    textElement.setAttributeNS(null, "x", x);
    textElement.setAttributeNS(null, "y", 640 );
    gElement.appendChild(textElement);

    ...

    // generovani elementu "path" pro sloupec
    pathElement = doc.createElementNS(svg_ns, "path");
    dAttribute = `M` + (x-sirka) + `,600 L`;
    dAttribute = dAttribute + (x-sirka) +  `,` + y + ` L`;
    dAttribute = dAttribute + (x+sirka) + `,` + y + ` L`;
    dAttribute = dAttribute + (x+sirka) + `,600 Z`;
    gray =  Math.round(Number(255 * (ix+2)) / (pocetPolozek+2));
    pathElement.setAttributeNS(null, "d", dAttribute);
    pathElement.setAttributeNS(null, "fill", "rgb("+gray+","+gray+","+gray+")");
    pathElement.setAttributeNS(null, "stroke", "black");
    pathElement.setAttributeNS(null, "stroke-width", "2");
    gElement.appendChild(pathElement);
  } /* ix */
} /* onLoad() */
]]></script>
</defs>

<g xmlns:data="http://example.org/Example">
<data:vysledky id="results">
 <data:polozka>
   <data:popis>výsledek</data:popis>
   <data:hodnota>7</data:hodnota>
 </data:polozka>
 <data:polozka>
   <data:popis>aa</data:popis>
   <data:hodnota>5</data:hodnota>
 </data:polozka>
 ...
</data:vysledky>
</g>

<text x="500" y="32" font-family="Helvetica" font-size="32" text-anchor="middle">
SVG graf automaticky vygenerovaný z obecných XML dat
</text>

<g id="graf" font-family="Helvetica" text-anchor="middle" font-size="24">
<desc>Na toto misto skript pripoji elementy grafu</desc>
</g>

<rect x="1" y="1" width="999" height="699" fill="none" stroke="blue"/>
</svg>

XSLT transformace

Další úžasné možnosti nativního SVG se otevírají při nasazení XSLT. Touto technologií můžeme konvertovat XML data do podoby vektorové grafiky jen za pomoci sofistikovaných stylopisů - bez jakýchkoli doplňkových programů či skriptů. Zdrojem může být databáze a cílem HTML nebo stejně tak dobře SVG.

V pokračování tohoto textu bych si rád posvítítil na použití XSLT transformací podrobněji tak, abyste je byli schopni sami použít např. k vytvoření grafu z číselných dat ve formátu XML (viz ukázka SVG grafiky o kousek níže).

Uvědomte si také, že navzdory poměrně malému využívání v současnosti - díky konzervativnímu přístupu dnešních webdesignerů - je XSLT velmi dobře zavedená technogie, která byla v prohlížečích IE a Mozilla Firefox implementována již před relativně dlouhou dobou a dnes tudíž už je spolehlivá a stabilní. Navíc současné verze zbývajících browserů Opera, Safari / Konqueror už její implementací disponují rovněž. (Nemluvě o existujících implementacích na straně serveru.) Takže: Zpět do budoucnosti!

Jdeme na věc, nastal čas

Nebojte se, buďte v pohodě. Vše co potřebujete je skutečně jen XML, skripty ponechte v minulosti! V následující ukázce vidíte útržek souboru ve standardním formátu tabulkového kalkulátoru Excel, vyexportovaný z Open Office verze 2:

<ss:Worksheet ss:Name="Tabulkový list 1">
  <Table ss:StyleID="ta1">
    <Column ss:StyleID="Default" ss:Span="1" ss:Width="64.2614"/>
    <Row ss:Height="12.8409">
      <Cell>
        <Data ss:Type="Number">
          0
        </Data>
      </Cell>
      <Cell ss:Formula="=SIN(RC[-1])*COS(RC[-1])">
        <Data ss:Type="Number">
          0
        </Data>
      </Cell>
    </Row>

  ...

  </Table>
  <x:WorksheetOptions/>
</ss:Worksheet>

Jediné co je třeba udělat pro získání regulérní webové stránky je přidání odkazu na transformační styl XSLT do hlavičky XML dat:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="table2svg.xsl" media="screen"?>

<?mso-application progid="Excel.Sheet"?>
<Workbook ...>
...
</Workbook>

Dotyčný XML soubor nyní můžete směle předhodit libovolnému modernímu prohlížeči (Mozilla Firefox 1.5, Opera 9, Safari 2 s SVG podporou) a voi-la - tak jednoduché to je!

Klepněte pro větší obrázek

Graf ve formátu SVG vygenerovaný automaticky mechanismem XSLT z tabulkových dat exportovaných z běžné aplikace typu Office (ukázka)

Webové služby atd.

A nakonec zmíním potenciální možnost využití pro vizualizaci (opět XML) dat získaných pomocí tzv. "webových služeb". Mozilla Firefox standardně obsahuje podporu pro SOAP i WSDL, takže v cestě nestojí absolutně nic.

Stručný přehled SVG standardu a jeho podpory v Mozille Firefoxu 1.5

  1. vektorové tvary - ANO
  2. jednobarevné výplně - ANO
  3. přechody barev - ANO
  4. textury - NE
  5. text + tspan - ANO
  6. tref (text odkazem) - NE
  7. text na křivce - NE
  8. SVG písma - NE
  9. transformace - ANO
  10. ořezávání (clipping) - ANO
  11. maskování (masking) - NE
  12. bitmapové filtry - NE
  13. animace SMIL - NE
  14. skriptování - ANO

Implementace SVG v Mozille Firefoxu 1.6 (DeerPark)

  1. vektorové tvary - ANO
  2. jednobarevné výplně - ANO
  3. přechody barev - ANO
  4. textury - ANO
  5. text + tspan - ANO
  6. tref (text odkazem) - NE
  7. text na křivce - ANO
  8. SVG písma - NE
  9. transformace - ANO
  10. ořezávání (clipping) - ANO
  11. maskování (masking) - NE
  12. bitmapové filtry - cca 25%
  13. animace SMIL - cca 15%
  14. skriptování - ANO

Témata článku: Software, Budoucnost, Programování, Opera, Firefox, Stop, Cell, Head, Translate, Transform, Gradient, Smile, FF, Pseudo

35 komentářů

Nejnovější komentáře

  • MaSlo, MaSlo 11. 5. 2006 10:29:36
    Wikipedia (http://cs.wikipedia.org/wiki/Pleonazmus):

    "Jako...
  • Antares 28. 4. 2006 12:47:26
    Co se na to podívat z jiné stránky. Právě SVG se může stát takovým...
  • MH 8. 3. 2006 12:34:25
    Používejte prosím Operu 9, dnes je to ve všech směrech nejlepší prohlížeč...
reklama
Určitě si přečtěte

Vybíráte herní periferii nebo hardware? Pak zapomeňte na nálepku Gaming

Vybíráte herní periferii nebo hardware? Pak zapomeňte na nálepku Gaming

** Herní hardware se od toho běžného často liší jen vzhledem ** Při výběru stále nezapomínejte na základní parametry ** Poradíme jak vybrat herní hardware i periferie

20.  2.  2017 | Stanislav Janů | 36

10 nejhorších produktů v historii Microsoftu

10 nejhorších produktů v historii Microsoftu

20.  2.  2017 | Karel Javůrek | 141

AMD oficiálně představilo procesory Ryzen. Známe i jejich české ceny

AMD oficiálně představilo procesory Ryzen. Známe i jejich české ceny

** AMD uvedlo první tři procesory Ryzen 7 ** Všechny budou pracovat s osmi jádry a šestnácti vlákny ** Na pulty obchodů se dostanou už za týden

22.  2.  2017 | Stanislav Janů | 133

EU se děsí Windows 10. Prý o nás vědí až příliš. Microsoft chystá změny

EU se děsí Windows 10. Prý o nás vědí až příliš. Microsoft chystá změny

** Evropští úředníci chtějí, aby byly Desítky transparentnější ** Microsoft od jara skutečně chystá změny ** Ochráncům soukromí to ale nestačí

21.  2.  2017 | Jakub Čížek | 218

Remix Singularity: Microsoft si na tom vylámal zuby. Jak dopadne Android?

Remix Singularity: Microsoft si na tom vylámal zuby. Jak dopadne Android?

** Microsoft do svých telefonů integroval desktopové prostředí ** Moc to ale nevyšlo, chyběl pořádný výkon ** Teď to zkoušejí ex-googleři s Remix Singularity

23.  2.  2017 | Jakub Čížek | 74


Aktuální číslo časopisu Computer

Supertéma o počítačové bezpečnosti

AMD Ryzen přichází

Velké testy kinoprojektorů a levných špuntových sluchátek

Příslušenství do USB-C

reklama
reklama