Skrypty i SVG

Teraz zajmiemy się nieco bardziej uniwersalną techniką tworzenia animacji w SVG poprzez skrypty JavaScript. Wzajemne oddziaływanie obiektów możemy osiągnąć za pomocą obsługi zdarzeń. Obiekty mogą odpowiadać na zdarzenia związane z kliknięciem myszką (onclick, onmousedown, onmouseup), poruszaniem myszką (onmouseover, onmouseout, onmousemove), stopniem załadowania (onload) oraz związane z wciskaniem klawiszy na klawiaturze (onkeyup, onkeydown). Każde zdarzenie posiada pewne właściwości i metody. Są to: getTarget() – zwraca odnośnik do obiektu, który to zdarzenie wywołał, getClientX() i getClientY() zwracają współrzędne x i y wskaźnika myszy w momencie, w którym zdarzenie nastąpiło.

Zmiana atrybutów pojedynczego obiektu

Najprostszym sposobem wykorzystania zdarzenia do pracy z SVG jest zmiana wartości określonego atrybutu po jego wystąpieniu. Spójrzmy na poniższy przykład.
<?xml version="1.0"?>
<!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">
<script type="text/javascript">
<![CDATA[
function powieksz(evt)
{
    			var circle = evt.getTarget();
    			circle.setAttribute("r", 50);
}
function zmniejsz(evt)
{
    			var circle = evt.getTarget();
    			circle.setAttribute("r", 25);
}
// ]]>
</script>
<circle cx="150" cy="100" r="25" fill="green"
    onmouseover="powieksz(evt)"
    onmouseout="zmniejsz(evt)"/>

<text x="150" y="175" style="text-anchor: middle;">
    Najedz kursorem na obiekt.
</text>
</svg>
Treść skryptu znajduje się pomiędzy znacznikami <script></script>, a atrybut type określa język, w którym będzie pisany skrypt (u nas JavaScript). Następnie umieszczamy sekcję CDATA. Jest ona pomocna jeśli w skrypcie chcielibyśmy zawrzeć następujące znaki: <, >, &, które nie powinny być interpretowane jako znaczniki. Następnie definiujemy dwie funkcje: powieksz(evt) i zmniejsz(evt), odpowiadające za animację naszego obiektu. Evt przechwytuje zdarzenie. Kolejnym krokiem jest przypisanie do zmiennej circle odnośnik (obiekt), który to zdarzenie wywołał (evt.getTarget()). U nas będzie to oczywiście nasze koło. Ustawiamy atrybut r za pomocą metody setAttribute(). W funkcji powieksz() na 50, a w zmniejsz() na 25. Na koniec przypisujemy do znacznika <circle> zdarzenia onmouseover (kiedy wskaźnik myszki znajdzie się nad obiektem) i onmouseout (wskaźnik myszki opuszcza obiekt). Efektem animacji będzie powiększenia koła po najechaniu na nie myszką i powrót do pierwotnej wielkości kiedy wskaźnik opuści obiekt.
Przerobimy teraz trochę powyższy skrypt. Dodamy efekt zmiany koloru na pomarańczowy po najechaniu myszką oraz powrót do zielonego po jej zwolnieniu. Zrobimy to za pomocą setAttribute("fill", "orange"). Cały kod przedstawiam poniżej.
<?xml version="1.0"?>
<!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">
<script type="text/javascript">
<![CDATA[
function powieksz(evt)
{
    var circle = evt.getTarget();
    circle.setAttribute("r", 50);
    circle.setAttribute("fill", "orange");
}
function zmniejsz(evt)
{
    var circle = evt.getTarget();
    circle.setAttribute("r", 25);
    circle.setAttribute("fill", "green");
}
// ]]>
</script>
<circle cx="150" cy="100" r="25" fill="green"
    onmouseover="powieksz(evt)"
    onmouseout="zmniejsz(evt)"/>

<text x="150" y="175" style="text-anchor: middle;">
    Najedz kursorem na obiekt.
</text>
</svg>

Animacja przesuwającego się tekstu po ekranie

Zajmiemy się teraz kolejnym skryptem. Mianowicie zbudujemy przesuwający się tekst od lewej do prawej. Listing tego przykładu znajduje się poniżej.
<?xml version="1.0" standalone="yes" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="100%" height="100%" onload="animuj(evt)"
     xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
  <script type="text/javascript"><![CDATA[

var rect;
        var x = 0;
        var speed = 60;
function animuj(evt) {
    if ( window.svgDocument == null )
        svgDocument = evt.target.ownerDocument;

    rect = svgDocument.getElementById("rect");

    setTimeout("advance()", speed);
}

function advance() {
    if ( ++x > 450 ) x = 0;

    rect.setAttribute("x", x);

    setTimeout("advance()", speed);
}


]]></script>
<a xlink:href="http://www.zvon.org" xlink:type="simple">
  <text  y="150" id="rect" font-family="Verdana" font-size="26" font-weight="bold" fill="green">
    Witaj na mojej stronie
  </text>
 </a>
</svg>
Zauważmy, że znacznik <svg> ma atrybut onload="animuj(evt)", co oznacza, że funkcja animuj(evt) zostanie uruchomiona po załadowaniu strony. Deklarujemy zmienne globalne rect (będzie odnośnikiem do naszego tekstu), x (atrybut x – położenie tekstu) i speed (szybkość animacji). Następnie zaczynamy definiować funkcję animuj. Polecenie evt.target.ownerDocument zwraca nasz document SVG. Przypisujemy do zmiennej rect nasz tekst (korzystamy z metody getElementById). Za pomocą setTimeout uruchamiamy funkcję advance() z opóźnieniem równym speed. Kolejnym krokiem jest określenie funkcji advance(). Jest ona odpowiedzialna za przesuwanie tekstu w prawo, aż do momentu osiągnięcia wartości 450. Wtedy zmiennej x przypisywana jest wartość 0 i animacja zaczyna się od początku.
Oczywiście tematykę zastosowań skryptów w SVG można dużo bardziej rozbudować. Jednak skupiliśmy się tutaj na podstawach.