Kurz SVG - DOM a JavaScript p°i programovßnφ animacφ
V tomto Φlßnku vßs Φekß prvnφ pomoc p°i programovßnφ (alias skriptovßnφ) v prost°edφ SVG. ZφskanΘ znalosti si hned vyzkouÜφme v n∞kolika zajφmav²ch praktick²ch p°φkladech. Myslφte si nap°φklad, ₧e znßte vÜechny v²hody, kterΘ majφ vektorovΘ mapy v SVG formßtu? Mo₧nß ano, ale i tak se vßs pokusφm p°esv∞dΦit, ₧e SVG mapy toho dovedou jeÜt∞ vφce, ne₧ jste Φekali.
Jeliko₧ ne vÜechny ·lohy lze zvlßdnout jen s animaΦnφmi prvky SVG specifikace, podφvßme se na mo₧nosti, kterΘ nßm nabφzφ skriptovßnφ. U₧ d°φve jsem v tomto kurzu n∞kolikrßte zmi≥oval, ₧e zvlßdßte-li techniku DHTML, jako byste ji₧ um∞li programovat i SVG. V nßsledujφcφm textu tΘto podobnosti tak trochu zneu₧iji a upozornφm vßs spφÜe na odliÜnosti a specifika SVG, ne₧ abych vysv∞tloval vÜe od zßkladu.
Pozor, nßsledujφcφ text p°edpoklßdß, ₧e s JavaScriptem ji₧ n∞jakΘ zkuÜenosti mßte a ₧e rovn∞₧ mßte p°edstavu o objektovΘ datovΘ struktu°e HTML (XML) strßnek. V p°φpad∞ pot°eby odkazuji na n∞kterΘ z nesΦetn²ch text∙ o DOM (Document Object Model) a DHTML, z nich₧ °ada je dostupnß i zde na Intervalu. V tomto textu nynφ zmφnφm jen n∞kterΘ zßkladnφ a nejΦast∞ji pou₧φvanΘ konstrukce. Detaily SVG-DOM bez problΘmu dohledßte v dokumentaci k ASV3.
Test aktivnφho SVG prohlφ₧eΦe
Hned ze zaΦßtku sΘrie text∙ o SVG jste se o Adobe SVG3 prohlφ₧eΦi mohli dozv∞d∞t, ₧e jednφm z hlavnφch rozdφl∙ oproti p°edchozφ verzi je implementace plnohodnotnΘho interpreteru JavaScriptu. Tato informace je pro nßs nynφ klφΦovß. Programßto°i firmy Adobe tφm v²razn∞ zv²Üili kompatibilitu prohlφ₧eΦe nap°φΦ vÜemi platformami a r∙zn²mi webov²mi prohlφ₧eΦi. Osobn∞ siln∞ doporuΦuji jako prvnφ krok p°i spouÜt∞nφ jak²chkoli skript∙ v SVG prost°edφ provΘst test verze prohlφ₧eΦe. Dovoluji si vßm nabφdnout svΘ odlad∞nΘ °eÜenφ:
<![CDATA[
function testAdobe() {
//created by Martin Hejral, 2003
//test if Adobe SVG Viewer 3 (ASV3) or greater is present
if(window.navigator)
if( (navigator.appName=="Adobe SVG Viewer")
&& (navigator.appVersion>="3.0") )
return true;
alert("PROSIM, nainstalujte novou verzi Adobe SVG prohlizece!!!");
return false;
}
]]>
</script>
A hned mohu dodat, ₧e zßpis k≤du uvnit° SVG souboru se °φdφ obecn²mi XML pravidly, proto je nutnΘ programovΘ k≤dy v₧dy uzav°φt do sekce CDATA, jak jste si vÜichni urΦit∞ povÜimli v p°edchßzejφcφm v²pisu.
Nejd∙le₧it∞jÜφ p°φkazy a postupy
Toto je notoricky znßmß konstrukce, kterou zaΦφnß tΘm∞° ka₧d² DHTML (a SVG) skript, kter² pracuje s DOM. Zjistφme takto ukazatel na objekt, se kter²m pot°ebujeme pracovat - a¥ u₧ Φφst jeho atributy, nebo n∞co modifikovat.
var obj = document.getElementById("nejake_id");
Adobe doporuΦuje ke stejnΘmu ·Φelu o n∞co slo₧it∞jÜφ postup. Ten vznikl p°edevÜφm k zamezenφ mo₧n²ch problΘm∙ v p°φpadech, kdy skript provßd∞l webov² prohlφ₧eΦ (v ASV2) a v HTML strßnce bylo souΦasn∞ vlo₧eno n∞kolik SVG prvk∙.
...
var svgDocument = null; //globalni promenna
function svgInitialize(evt)
{
svgDocument = evt.getTarget().getOwnerDocument();
var obj = svgDocument.getElementById("nejake_id");
...
}
...
Vidφte, ₧e namφsto toho, aby se vyu₧il standardnφ objekt document
, je zjiÜ¥ovßn objekt "vlastnφcφ" ty konkrΘtnφ SVG prvky, se kter²mi zrovna pot°ebujeme pracovat. (Abych byl zcela p°esn², hledßme vlastnφka objektu, kter² byl zdrojem udßlosti onload
, tedy prvku svg
.) Pro ka₧d² vlo₧en² SVG soubor se toti₧ vytvo°φ jeden dalÜφ objekt document
.
Pom∞rn∞ hojn∞ vyu₧φvanΘ jsou i nßsledujφcφ p°φkazy, rovn∞₧ znßmΘ z DHTML:
- window.status="text" - prom∞nnß
- window.alert("text") - funkce
V²znamnΘ usnadn∞nφ prßce p°i programovßnφ vßm poskytnou funkce zjednoduÜujφcφ prßci s atributy SVG element∙ - jejich slu₧eb vyu₧ijete p°i prßci s SVG velmi Φasto:
- obj.getAttribute( "transform" )
- obj.setAttribute( "transform", "translate(11,22)" )
Nßsledujφcφ v²pis ukazuje, jak modifikovat a Φφst obsah atributu style
. Prozatφm p°φliÜ nedoporuΦuji pou₧φvßnφ style
z d∙vod∙ kompatibility, jeliko₧ prohlφ₧eΦe mΘn∞ vysp∞lΘ ne₧ ASV2 v∞tÜinou CSS zatφm uspokojiv∞ nepodporujφ.
if (svgobj != null)
{
var svgstyle = svgobj.getStyle();
var fill = svgstyle.getPropertyValue("fill");
svgstyle.setProperty("stroke","#69F");
svgstyle.removeProperty("stroke-width");
}
K hodnotßm atribut∙ uvnit° struktury SVG-DOM se m∙₧eme dostat alternativn∞ takΘ nßsledujφcφm zßpisem:
- svgobj.attributes.getNamedItem("nazev_atr").value
ZvlßÜt∞ v p°φpad∞ animacφ jsou Φasto pou₧itelnΘ obecnΘ funkce JavaScriptu pro prßci s p°eruÜenφm a Φasovßnφm:
- var casovac = window.setTimeout("nejaka_funkce()", 50)
- window.clearTimeout(casovac)
Obsluha udßlostφ
DalÜφ oblφbenou Φinnostφ, kterou jist∞ budete chtφt provozovat takΘ, je obsluha udßlostφ u₧ivatelskΘho rozhranφ - tu velmi Φasto vyu₧ijete p°i vytvß°enφ interaktivnφch grafick²ch prezentacφ. Dovolφm si shrnout nejd∙le₧it∞jÜφ praktickΘ informace, kterΘ k tomu budete pot°ebovat.
SVG p°i obsluze udßlostφ pou₧φvß model shodn² s dob°e znßmou normou DOM2-Events, pou₧φvan² v prohlφ₧eΦφch Netscape a Mozilla (MSIE se trochu odchyluje). Ka₧dß obslu₧nß rutina toti₧ dostane jako parametr specißlnφ objekt event, kter² nese informace pot°ebnΘ k reakci na konkrΘtnφ udßlost. Pozor, zßvazn² nßzev tohoto specißlnφho objektu v ASV je evt
(na rozdφl od klasick²ch WWW browser∙)!
JednotlivΘ polo₧ky ve struktu°e objektu evt
pak jsou ji₧ shodnΘ. Ty nejzajφmav∞jÜφ si nynφ vyjmenujeme:
- target - zdrojov² objekt udßlosti
- currentTarget - aktußlnφ objekt, ke kterΘmu je p°ipojen obslu₧n² skript (event listener)
- screenX - X v sou°adnicovΘm systΘmu obrazovky
- screenY - Y v sou°adnicovΘm systΘmu obrazovky
- clientX - X relativn∞ vzhledem k oknu (rßmu) SVG grafiky
- clientY - Y relativn∞ vzhledem k oknu (rßmu) SVG grafiky
- ctrlKey
- shiftKey
- altKey
- metaKey
- button
- keyCode
- charCode
Animace s vyu₧itφm DOM a JavaScriptu
A vzh∙ru do praxe...
Fyzikßlnφ pokus - koule a pru₧iny
Nynφ si vyzkouÜφme realizaci znßmΘho fyzikßlnφho pokusu, kdy koule, zav∞Üenß na pru₧in∞, po jejφm napnutφ a uvoln∞nφ kmitß s klesajφcφ amplitudou okolo rovnovß₧nΘ polohy.
Fyzikßlnφ pokus - koule a pru₧iny (originßlnφ SVG, cca 5 kB)
V prvnφ fßzi jsem si v Illustratoru nakreslil jednoduchΘ ztvßrn∞nφ pru₧iny (skupina s id="spring") a koule (skupina s id="sphere"). Dovnit° ka₧dΘ skupiny jsem pak dodal animaΦnφ prvky. Musφ b²t dva, proto₧e v p°φpad∞ pru₧iny pot°ebujeme animovat smrÜ¥ovßnφ, naproti tomu koule jen m∞nφ polohu...
...
<!-- anim. pruziny -->
<animateTransform attributeName="transform"
type="scale" values="1 1;1 0.32;1 1" dur="10s"
additive="sum" repeatCount="indefinite" />
</g>
<g id="sphere">
...
<!-- anim. koule -->
<animateTransform attributeName="transform"
type="translate" values="0 0;0 -100;0 0" dur="10s"
additive="sum" repeatCount="indefinite" />
</g>
Definice pohybu pomocφ values
ovÜem ve v²chozφm (lineßrnφm) interpolaΦnφm re₧imu vede k fyzikßln∞ nesprßvnΘmu ΦasovΘmu °φzenφ animovan²ch hodnot. Abych dosßhl realistickΘ zm∞ny zrychlenφ, kterß p°i tomto fyzikßlnφm procesu probφhß, nastavil jsem v²poΦetnφ re₧im na calcMode="spline" a p°idal dv∞ °φdicφ k°ivky do atributu keySplines=".5 0 .5 1;.5 0 .5 1". Navφc byly v druhΘ fßzi koule a pru₧ina definovßny jako symboly, abychom je mohli "rozmno₧it":
<!-- anim. -->
<animateTransform
attributeName="transform" type="scale"
values="1 1;1 0.32;1 1" dur="10s"
keySplines=".5 0 .5 1;.5 0 .5 1" calcMode="spline"
additive="sum" repeatCount="indefinite" />
</use>
<use x="50" xlink:href="#sphere">
<!-- anim. -->
<animateTransform
attributeName="transform" type="translate"
values="0 0;0 -100;0 0" dur="10s"
keySplines=".5 0 .5 1;.5 0 .5 1" calcMode="spline"
additive="sum" repeatCount="indefinite" />
</use>
Stßle ale z∙stßvß opominut jeden fyzikßlnφ aspekt - v reßlnΘm sv∞t∞ bude v₧dy dochßzet ke ztrßt∞ energie kmitajφcφ soustavy a kmity se budou utlumovat. Mohli bychom to ud∞lat zp∙sobem, kter² pou₧il v podobnΘm p°φkladu s kostkami Antoine Quint, ale ten je nep°esn² a nßroΦn² na vypisovßnφ mno₧stvφ polohov²ch ·daj∙.
Proto si nynφ ukß₧eme p°φm² v²poΦet animaΦnφch fßzφ pomocφ JavaScriptu. Prosφm ct∞nΘ Φtenß°e, nekamenujte mne za nep°esnosti a zjednoduÜovßnφ ve fyzikßlnφ strßnce v∞ci, st°edem zßjmu stßle z∙stßvß vektorovß grafika:
var amp=50, scale=0.34, time=0, to=-1;
//perform fading animation
function fade() {
//get pointer to animated objects
var obj1 = document.getElementById('sphere1');
var obj2 = document.getElementById('spring1');
var s = y = Math.cos(time/1000);
//window.status="time = "+time/1000+" s";
//multiply COS t with amplitude
y *= amp;
//shift sphere to base position
y -= 50;
//scale spring
s *= scale;
//set base position
s += 0.34 + 0.32;
time += 50;
//amplitude and scale decay
amp = amp*999/1000;
scale = scale*999/1000;
//modify SVG graphics
obj1.setAttribute( "transform", "translate(0,"+y+")" );
obj2.setAttribute( "transform", "scale(1,"+s+")" );
//start timer
to = window.setTimeout("fade()", 50);
}
Uveden² k≤d vykonßvß zhruba nßsledujφcφ. Ihned potΘ, co zjistφ ukazatele na animovanΘ objekty, pou₧ije funkci cos()
k v²poΦtu animovan²ch hodnot: y - aktußlnφ poloha koule, s - aktußlnφ nata₧enφ pru₧iny. Jeliko₧ byla pru₧ina nakreslena v pln∞ nata₧enΘ poloze, byl jsem nßsledn∞ donucen do v²poΦtu p°idat mo₧nß pon∞kud zßhadnΘ konstanty (50, 0.34, 0.32). Pak se posuneme po ΦasovΘ ose zv²Üenφm prom∞nnΘ time, utlumφme amplitudu a aplikujeme vypoΦtenΘ hodnoty na SVG objekty (setAttribute
).
Nakonec nastavφme ΦasovaΦ, kter² rutinu fade()
spustφ znovu po 50 ms.
Äivot brouka
Tato animace op∞t vychßzφ z p°φkladu firmy Macromedia, ve kterΘm je beruÜka ovlßdßna virtußlnφm joystickem.
Op∞t jsem si trochu ulehΦil prßci, o°ezal jsem p°φklad a₧ na holΘ jßdro a vypustil n∞kterΘ vlastnosti originßlu. Pokud jste poctiv∞ doΦetli a₧ sem, mßte vÜechny pot°ebnΘ znalosti, kterΘ vßm umo₧nφ napsat JavaScriptovou rutinu kterß by nap°φklad stejn∞ jako v SWF p°edloze pohybovala °φdicφ pßkou (n∞co velmi podobnΘho obsahuje i p°φklad s animacφ masky obrßzku).
Äivot brouka (originßlnφ SVG, cca 18 kB)
Hned prvnφ varianta SVG p°φkladu naznaΦuje mo₧nosti °eÜenφ tΘto interaktivnφ animace bez pou₧itφ programovßnφ. Bohu₧el, ovlßdßnφ beruÜky pomocφ sm∞rovΘho k°φ₧e takto nelze stoprocentn∞ realizovat - neexistuje toti₧ mo₧nost, aby animaΦnφ prvek po ukonΦenφ a p°i novΘm startu p°iΦφtal rostoucφ hodnoty sou°adnic k poloze, ve kterΘ byla p°edtφm animace ukonΦena (beruÜka zastavena), proΦe₧ pohyb zaΦφnß v₧dy znovu od poΦßteΦnφch sou°adnic danΘho animaΦnφho prvku.
Prozatφm vßm nabφzφm °eÜenφ pomocφ JavaScriptu v druhΘ verzi p°φkladu. SVG k≤d je pro vaÜe pohodlφ pom∞rn∞ podrobn∞ okomentovßn.
Tento kousek SVG je zobrazenφm ovlßdacφho k°φ₧e s p°ipojenou rutinou onmouseover="beetleMania(evt)", kterß je potom aktivovßna kdykoli se ukazatel dostane nad zobrazenφ Üipek. P°i pozornΘm Φtenφ k≤du zjistφte, ₧e ve skuteΦnosti je kresba neviditelnß. D∙vod? P∙vodnφ sm∞rov² k°φ₧ byl toti₧ nakreslen jako jedna spojitß vektorovß cesta - to by ale neumo₧nilo jednoduchΘ rozpoznßnφ sm∞ru... Aby prvky v∙bec reagovaly na udßlosti, musφ b²t vykresleny, a jeliko₧ souΦasn∞ chceme vid∞t p∙vodnφ kresbu, nastavil jsem jim prost∞ stoprocentnφ pr∙hlednost pomocφ opacity="0".
<path id="n" d="M61,31.4V20.1h5.6L55,0L43.3,20.1h6v11.2"/>
<path id="nw" d="M41.5,34.8L33,26.2l2.8-2.8L19,18.9l4.4,16.9l2.8-2.8l8.7,8.7"/>
<path id="ne" d="M75,41.6l8.6-8.6l2.8,2.8L91,18.9l-16.9,4.5l2.8,2.8l-8.5,8.5"/>
<path id="e" d="M77.9,60.8h11.9v5.8l20.1-11.7L89.8,43.2V49H78.1"/>
<path id="w" d="M31.8,49H20.2v-5.8L0,54.9l20.2,11.7v-5.8h11.9"/>
<path id="se" d="M67.7,74.5l9.2,9.2l-2.8,2.8L91,90.9L86.5,74l-2.9,2.9l-9.1-9.1"/>
<path id="s" d="M49.2,77.5v12.3h-6L55,109.8l11.7-20.1H61V77.4"/>
<path id="sw" d="M35.3,67.8l-9.1,9.1l-2.8-2.8L19,91l16.9-4.5L33,83.7l9.2-9.3"/>
</g>
Podprogram beetleMania(evt) si snadno zjistφ id
prvku (evt.target.id), kter² spustil udßlost, a podle n∞j nastavφ sm∞r pohybu:
function beetleMania(evt) {
//get 'id' of control element to determine direction
var ctrl = evt.target.id;
switch(ctrl) {
case 'n': dx=0; dy=-1; mrot=0;
break;
case 'ne': dx=1; dy=-1; mrot=45;
break;
case 'e': dx=1; dy=0; mrot=90;
break;
case 'se': dx=1; dy=1; mrot=135;
break;
case 's': dx=0; dy=1; mrot=180;
break;
case 'sw': dx=-1; dy=1; mrot=-135;
break;
case 'w': dx=-1; dy=0; mrot=-90;
break;
case 'nw': dx=-1; dy=-1; mrot=-45;
break;
}
//stop event bubbling
evt.stopPropagation();
return false;
}
Pokud alespo≥ trochu vlßdnete JavaScriptem, jist∞ pro vßs nebude problΘmem cviΦn∞ naprogramovat druhou variantu pohybu, kdy se beruÜka otßΦφ plynule, nikoli skokov∞.
Vlastnφ pohyb (a modifikace SVG-DOM) zajiÜ¥uje rutina beetleMove()
, opakovan∞ spouÜt∞nß ΦasovaΦem:
//get pointer to animated object
var obj = document.getElementById('beetle');
mx += dx; my += dy;
if(mx < -128) mx = 128;
else if(mx > 128) mx = -128;
if(my < -128) my = 128;
else if(my > 128) my = -128;
obj.setAttribute("transform",
"translate("+mx+","+my+") rotate("+mrot+")");
to = window.setTimeout("beetleMove()", 22);
}
Interaktivnφ ₧elezniΦnφ mapa ╚R
V tomto p°φkladu si dovolφm troÜiΦku vylepÜit interaktivnφ SVG mapu ze serveru ╚esk²ch drah. Na okraj jeÜt∞ jednu poznßmku k ovlßdßnφ Adobe SVG prohlφ₧eΦe - zmenÜovßnφ Φi zv∞tÜovßnφ m∞°φtka lze provΘst i myÜφ, pokud podr₧φte klßvesu CTRL
, respektive CTRL+SHIFT
, a posuv mapy lze realizovat kombinacφ ALT+myÜ
, jak je sprßvn∞ uvedeno v map∞.
Interaktivnφ ₧elezniΦnφ mapa ╚R (velk² nßhled, cca 55 kB, originßlnφ SVG, cca 30 kB)
V rßmci naÜeho SVG kurzu jsem p°idal "roll-over" efekty (pomocφ animaΦnφch prvk∙ set
) a souΦasn∞ "kontextovou" nßpov∞du, kterß ukazuje velkΘ Φφslo trati (JavaScript).
K mod°e zbarven²m tratφm byl cviΦn∞ pomocφ animaΦnφho prvku set
dodßn zv²raz≥ovacφ efekt:
<set attributeName="stroke" to="magenta"
begin="mouseover" end="mouseout"/>
</path>
To byla hraΦka, zbytek u₧ bude troÜiΦku komplikovan∞jÜφ. Vyu₧il jsem toho, ₧e SVG ╚esk²ch drah obsahuje hyperlinky na jφzdnφ °ßdy, p°iΦem₧ Φφslo trati je v₧dy obsa₧eno v nßzvu odkazovanΘho dokumentu - prost∞ jsem je z atributu xlink:href
v objektovΘ struktu°e vyextrahoval:
V SVG jsem si p°edem vytvo°il textov² prvek s id="info", do kterΘho nφ₧e uvedenß rutina zapφÜe Φφslo trati a souΦasn∞ jej p°emφstφ na sprßvnΘ sou°adnice.
Program, kter² jsem vytvo°il, Üikovn∞ vyu₧φvß efektu zvanΘho event-bubbling - rutinu odchytßvajφcφ pohyb myÜi mi pak staΦilo umφstit do ko°ene objektovΘho stromu a poΦkat si, a₧ dotyΦnß udßlost probublß a₧ k nφ. Pak testuji, zda se jednß o prvek typu a
(hyperlink). M∙₧e se vßm zdßt divnΘ, proΦ netestuji zdrojov² objekt udßlosti (evt.target), nybr₧ jeho rodiΦe (evt.target.parentNode). Je to proto, ₧e udßlost onmouseover
m∙₧e spustit pouze viditeln² objekt - co₧ jsou Φßry znßzor≥ujφcφ jednotlivΘ trat∞, hyperlinky jsou jim v naÜem SVG souboru p°φmo nad°azeny:
<path class="fil0 str4" d="M-2472 1338l-294 -23">
<set attributeName="stroke" to="magenta"
begin="mouseover" end="mouseout"/>
</path>
</a>
DalÜφ velmi zajφmavou vlastnostφ, je₧ by rozhodn∞ nem∞la z∙stat nepovÜimnuta, je zjiÜt∞nφ aktußlnφho zv∞tÜenφ a posunutφ grafiky v SVG Vieweru (nezapome≥me - vektorovou grafiku lze neomezen∞ zv∞tÜovat bez ztrßty kvality) a nßsledn² p°epoΦet sou°adnic umis¥ovanΘho objektu.
function napoveda(evt) {
//evt = objekt 'event' s informacemi o udalosti
//zjisti ukazatel na textovy informacni objekt
var obj = document.getElementById('info');
//zjisti jmeno tagu zdrojoveho objektu
var tag = evt.target.parentNode.tagName.toLowerCase();
if(tag == "a") {
//extrahuje cislo trati z odkazu
//na PDF soubor s jizdnim radem
//a vlozi jej do text. prvku
//kontextove napovedy
obj.firstChild.nodeValue =
evt.target.parentNode.attributes.
getNamedItem("xlink:href").value.substring(4,7);
}
//nasledujici data potrebujeme abychom
//se prizpusobili aktualnimu zvetseni
//v prohlizeci SVG
meritko = document.rootElement.currentScale;
posun = document.rootElement.currentTranslate;
//nastavi polohu textu podle polohy mysi
obj.setAttribute("transform", "translate("
+ (evt.clientX-posun.x)/meritko + ","
+ (evt.clientY-posun.y)/meritko + ")");
//pripadne 'bublani' muze pokracovat
return evt;
}
To¥ vÜe. Jen za sebe dodßm, ₧e p°esn∞ zde je skrytß velkß sφla grafiky ve znaΦkovacφm jazyce SVG, zde se otevφrß spousta mo₧nostφ pro aplikace. Äiv∞ si p°edstavuji t°eba detailnφ mapu m∞sta, kde jsou vÜechny objekty podrobn∞ popsßny ve standardnφch prvcφch title
a desc
- skript velmi podobn² tomu zde p°edstavenΘmu pak dßvß u₧ivateli tΘto mapy mo₧nost velmi pohodln∞ tyto informace zφskat...
Kurz SVG - tvorba vektorovΘ grafiky v XML
Pokud u₧ mßte dost suchΘ teorie Scalable Vector Graphics, nenφ nic sna₧Üφho, ne₧ se vrhnout na praktickΘ testovßnφ jeho mo₧nostφ. Kurz SVG vßm usnadnφ osvojenφ zßkladnφch struktur a vlastnostφ tohoto jazyka pro prßci s vektorovou grafikou. Tato sΘrie Φlßnk∙ dosud nebyla ukonΦena!
- Kurz SVG - DOM a JavaScript p°i programovßnφ animacφ (prßv∞ Φtete)
- Kurz SVG - animace (praktickΘ ukßzky pro pokroΦilΘ)
- Kurz SVG - animace (dynamika zm∞ny hodnot)
- Kurz SVG - animace (praktickΘ ukßzky)
- Kurz SVG - animace (Φasovßnφ)
- Kurz SVG - nenφ to Flash a p°ece se toΦφ!
- Kurz SVG - transformace sou°adnic
- Kurz SVG - o°ezßvßnφ a maskovßnφ
- Kurz SVG - vypl≥ovßnφ II
- Kurz SVG - vypl≥ovßnφ I
- Kurz SVG - text
- Kurz SVG - grafickß primitiva
- Kurz SVG - struktura dokumentu, zobrazovacφ a vykreslovacφ model