Bildoben  
aptico-Home | AGB-(c) | SVG-Tutorial Inhalt
Schatten

SVG Tutorial

  svg tutorial index  |  Kapitel 13

13.7 Bewegung entlang eines Pfades - animateMotion

Um Objekte zu bewegen, können sie mit Hilfe von animate deren Koordinatenwerte verändern oder Sie können mittels animateTransform Verschiebungen animiert darstellen (siehe Kapitel 13.9).

Durch das Element animateMotion haben sie zusätzlich die Möglichkeit Objekte entlang eines Pfades zu bewegen.
Diesem Element stehen die Attribute aller Atttributgruppen für Animationen zur Verfügung, sowie zusätzlich die Attribute path und rotate. Außerdem kann animateMotion ein Kind-Element mpath zugeordnet werden.

Mittels path wird der Pfad festgelegt, an welchem das Objekt bewegt werden soll. Die Werte für path sind von der gleichen Art wie die Werte des d-Attributs im path-Element.

Mit rotate können Sie die Drehung des Objekts während der Bewegung entlang des Pfades einstellen. Dieses Attribut akzeptiert 3 mögliche Werte bzw. Wertangaben: auto, auto-reverse oder eine Winkelangabe.

  1. auto bewirkt, dass das Objekt dem Verlauf des Pfades entsprechend rotiert wird. Bei einem Wellenverlauf würde ein Objekt demnach immer entsprechend dem Verlauf gedreht.
  2. auto-reverse entspricht dem Wert auto bis auf den Umstand, das das Objekt "auf dem Kopf steht", also grundsätzlich erst um 180 Grad gedreht wird.
  3. Durch eine Winkelangabe legen Sie den Drehungswinkel definitiv fest, d.h. der Winkel wird während der gesamten Pfandwanderung nicht verändert. Wenn Sie den Wert 0 verwenden, bleibt das Objekt im Orginalzustand, während es am Pfad entlang bewegt wird.

Eine weitere Möglichkeit einen Pfad als Animationspfad festzulegen, bietet das leere Kind-Element mpath. Über das Attribut xlink:href können Sie hier ein vorher definierten Pfad über dessen ID referenzieren.
Sie sollten das Kind-Element mpath logischerweise nicht gemeinsam mit dem Attribut path in einem animateMotion-Element verwenden.

Beispiel Quellcode


   Grafische Darstellung:   SVG-Darstellung (nur SVG-fähige Browser!)    Screenshot JPG-Grafik
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="280"
  xmlns:xlink="http://www.w3.org/1999/xlink">
<title>das animateMotion-Element</title>
<desc>Bewegung entlang eines Pfades 1</desc>
  <defs>
    <style type="text/css">
    <![CDATA[
      text {font-family:Verdana,sans-serif; font-size:20px;
            fill:black;}
      rect {fill:limegreen; stroke:white; stroke-width:2px; opacity:.8}
      path {fill:none; stroke:black; stroke-width:2px;}
    ]]>
    </style>
    <linearGradient id="verlauf"
      x1="0" y1="0" x2="1" y2="1">
      <stop offset=".4" stop-color="white" />
      <stop offset=".6" stop-color="limegreen" />
    </linearGradient>
    <path id="p" d="M 30 80 c 50 -50 150 30 200 20 s 50 -30 100 -20" />
  </defs>

<!-- Hintergrund und Anzeige der Animationspfade  -->
  <rect x="1" y="1" width="398" height="298"
    style="fill:url(#verlauf); stroke:none; opacity:1;" />
  <use xlink:href="#p" />
  <use xlink:href="#p" transform="translate(0,60)" />
  <use xlink:href="#p" transform="translate(0,120)" />

<!-- die drei Animationen -->
  <rect id="re1" x="0" y="0" width="50" height="20"
    visibility="hidden" />
  <animateMotion xlink:href="#re1"
    begin="go.click" dur="6"
    rotate="auto"
    path="M 30 80 c 50 -50 150 30 200 20 s 50 -30 100 -20"
    fill="freeze" />
  <set xlink:href="#re1"
    attributeName="visibility"
    begin="go.click" dur="6"
    to="visible" />

  <rect id="re2" x="0" y="0" width="50" height="20"
    visibility="hidden" />
  <animateMotion xlink:href="#re2"
    begin="go.click" dur="6"
    rotate="auto-reverse"
    path="M 30 140 c 50 -50 150 30 200 20 s 50 -30 100 -20"
    fill="freeze"  />
  <set xlink:href="#re2"
    attributeName="visibility"
    begin="go.click" dur="6"
    to="visible" />

  <rect id="re3" x="0" y="0" width="50" height="20"
    visibility="hidden" />
  <animateMotion xlink:href="#re3"
    begin="go.click" dur="6"
    rotate="0"
    path="M 30 200 c 50 -50 150 30 200 20 s 50 -30 100 -20"
    fill="freeze"  />
  <set xlink:href="#re3"
    attributeName="visibility"
    begin="go.click" dur="6"
    to="visible" />

<!-- Text  -->
  <text x="20" y="60">rotate auto</text>
  <text x="20" y="120">rotate auto-reverse</text>
  <text x="20" y="180">rotate 0</text>
  <rect id="go" x="20" y="240" width="50" height="20"
    style="fill:limegreen; stroke:white; opacity:1;" />
  <text x="80" y="258" style="fill:white;">
    &lt;&lt; START
  </text>
</svg>
      

Beachten Sie: Der Startpunkt des Elements oder des Objekts, welches animiert wird, wird als relativ zum Startpunkt des Animationspfades interpretiert. Der Startpunkt der Animation ist somit immer:
x,y-Wert des Elements + x,y-Wert des Pfads = x,y-Wert des Elements beim Start der Animation.
Man kann diesen Umstand auch auf folgende Art beschreiben: Der eigentliche Nullpunkt des Koordinatensystems, in dem sich das zu animierenende Element befindet stimmt immer mit dem Anfangspunkt des Animationspfades überein.

Daher haben die animierten Rechtecke im obigen Beispiel ihren Anfangspunkt bei 0,0. Der Anfangspunkt der Animation fällt auf diese Weise mit dem Anfangspunkt des Animationspfades zusammen, welcher durch das Attribut path im jeweiligen animateMotion-Element festgelegt ist.

Die Ränder der Rechtecke wären normalerweise vor dem Start der Animation innerhalb der Grafik sichtbar. Und leider können die Elemente nicht im defs-Bereich definiert werden, da sie dann nicht direkt durch animateMotion verwendet werden können. Es muß hierfür zuerst eine Instanz des Elements mit use in die Grafik eingebunden werden, deren Ränder dann ebenfalls am Bildschirm zu sehen wären.

Im obigen Beispiel werden zur Lösung dieses Problems die zu animierenden Elemente nur während des Abspielzeitraums sichtbar gemacht. Dazu wird durch das Element set die Eigenschaft visibility in den jeweiligen Ziel-Rechtecken für die Dauer der Animation auf visible (sichtbar) eingestellt.

Eine weitere Möglichkeit zeigt das folgende Beispiel ..

Beispiel Quellcode


   Grafische Darstellung:   SVG-Darstellung (nur SVG-fähige Browser!)    Screenshot JPG-Grafik
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="220"
  xmlns:xlink="http://www.w3.org/1999/xlink">
<title>das animateMotion-Element</title>
<desc>Bewegung entlang eines Pfades 2</desc>
  <defs>
    <style type="text/css">
    <![CDATA[
      text {font-family:Verdana,sans-serif; font-size:14px;
            font-weight:bold; fill:black;}
      path {fill:none; stroke:black;}
      polygon {fill:seagreen; stroke:black;}
      circle {fill:black;}
    ]]>
    </style>
    <path id="welle1" d="M 0 0 q 50 -50, 100 0
                               t 100 0
                               t 100 0
                               t 100 0
                               t 100 0" />
    <g id="boot">
      <polygon points="0 0,
                       -20 0,
                       -30 -15,
                       -2 -15,
                       -2 -35,
                       -2 -35,
                       2 -15,
                       35 -15,
                       20 0" />
      <circle id="startpunkt" cx="0" cy="0" r="2" />
      <text x="-21" y="-2.8"
        style="font-size:14px;
               text-rendering:optimizeSpeed;
               fill:white;">
        sailor
      </text>
    </g>
  </defs>

<!-- Anzeige des Animationspfads -->
  <use xlink:href="#welle1" x="40" y="100" />

<!-- Animation -->
  <use id="go" xlink:href="#boot" x="40" y="100" />
  <animateMotion xlink:href="#boot"
    begin="go.click" dur="6"
    rotate="auto">
      <mpath xlink:href="#welle1" />
  </animateMotion>

<!-- Texte, Linie und Punkt -->
  <text x="35" y="210" style="fill:seagreen;">
    Klicken Sie zum Start der Animation auf das Boot.
  </text>
  <text x="10" y="30">Im defs-Bereich:</text>
  <text x="145" y="30">Anfangspunkt des Boots: 0,0
    <tspan x="145" dy="16">
      Anfangspunkt des Pfades: M 0,0
    </tspan>
  </text>
  <line x1="40" y1="100" x2="40" y2="150" stroke="black"/>
  <text x="35" y="170">Anfangspunkt der use-Instanz des Boots: 40,100
    <tspan x="35" dy="16">
      Anfangspunkt des Pfades: 40,100
    </tspan>
  </text>
  <circle cx="40" cy="100" r="2" />
</svg>
      

Im vorangegangenen Beispiel sind sowohl der Animationspfad, wie auch das zu animierende Objekt innerhalb des defs-Containers definiert. Sie werden also nicht direkt am Bildschirm angezeigt.

Der Punkt des Objekts, der genau auf dem Nullpunkt des Koordinatensystems liegt (quasi der Nullpunkt des Objekts), befindet sich genau in der Mitte der unteren Linie des Polygons (in der Grafik als kleiner, schwarzer Punkt gekennzeichnet). Der Startpunkt des Animationspfades ist mit 0,0 festgelegt, d.h. er bezieht sich in diesem Fall auf den Punkt ebenfalls auf den Nullpunkt des Koordinatensystems (0,0).

Das zu animierende Objekt "boot" wird innerhalb der Grafik durch das use-Element eingebunden. Dabei legen die Attribute x und y innerhalb dieses Elements die Platzierung dieser Instanz des Objekts innerhalb der Grafik fest (40,100).
Beachten Sie: Es handelt sich hier um eine Instanz des Objekts, die auch eine eingene ID "go" besitzt. Es ist also nicht das Objekt selbst.

Durch das Attribut xlink:href im animateMotion-Element wird das Objekt "boot" referenziert, und nicht (!) die Instanz "go". Dadurch wird zuerst die Animation berechnet und dann auf die Instanz angewandt, so dass das Objekt direkt am Animationspfad entlang verläuft.

Im folgenden und letzten Beispiel dieses Kapitels wird animateMotion nicht mit Hilfe eines Pfades definiert, sondern durch Attribute aus der Gruppe animValuesAttrs: from, to oder by und values.

Beispiel Quellcode


   Grafische Darstellung:   SVG-Darstellung (nur SVG-fähige Browser!)    Screenshot JPG-Grafik
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="220"
  xmlns:xlink="http://www.w3.org/1999/xlink">
<title>das animateMotion-Element</title>
<desc>Bewegung entlang eines Pfades 3</desc>
  <defs>
    <style type="text/css">
    <![CDATA[
      text {font-family:Verdana,sans-serif; font-size:14px;
            font-weight:bold; fill:black;}
      polyline {fill:none; stroke:blue; stroke-width:2px;
                stroke-dasharray:2,2;}
      circle {fill:red;}
      polygon {fill:seagreen; stroke:black;}
    ]]>
    </style>
    <g id="boot">
      <polygon points="0 0,
                       -20 0,
                       -30 -15,
                       -2 -15,
                       -2 -35,
                       -2 -35,
                       2 -15,
                       35 -15,
                       20 0" />
      <circle id="startpunkt" cx="0" cy="0" r="2" />
      <text x="-21" y="-2.8"
        style="font-size:14px;
               text-rendering:optimizeSpeed;
               fill:white;">
        sailor
      </text>
    </g>
  </defs>
<!-- Hilfslinien zur Anzeige der Animationspfade -->
  <polyline points="-60 60, 540 60" />
  <polyline points="-60 120,
                    140 120,
                    240 180,
                    340 120,
                    540 120" />
  <polyline points="-60 180,
                    140 180
                    240 120
                    340 180
                    500 180" />

<!-- Animationen mit animValueAttrs: from,to und values -->
  <use id="b1" xlink:href="#boot" x="40" y="60" />
  <animateMotion xlink:href="#b1"
    begin="0" dur="6"
    rotate="auto"
    from="-100,0" to="500,0"
    repeatCount="5" />

  <use id="b2" xlink:href="#boot" x="40" y="120" />
  <animateMotion xlink:href="#b2"
    begin="0" dur="6"
    rotate="0"
    values="-100,0;100,0;200,60;300,0;500,0"
    repeatCount="5" />

  <use id="b3" xlink:href="#boot" x="40" y="180" />
  <animateMotion xlink:href="#b3"
    begin="0" dur="3"
    rotate="0"
    values="-100,0;100,0;200,-60;300,0;500,0"
    repeatCount="10" />
</svg>
      

In der ersten Animation des obigen Beispiels wird der Animationspfad durch die Attribute from und to definiert. Beide Attribute erhalten als Wert jeweils eine x,y-Koordinate, die relativ zum animierenden Objekt interpretiert wird. Diese Koordinaten bestimmen den Start- und den Endpunkt einer Linie, die als Animationspfad verwendet wird.

Die beiden folgenden Animationen verwenden das Attribut values zur Definition des Animationspfades (in Form eine Polylinie). Der Wert von values ist bei der Verwendung mit animateMotion eine durch Semikolon getrennte Liste mit x,y-Koordinaten, die den Verlauf des Aninmationspfads festlegen.

Beachten Sie: das animateMotion-Element referenziert in diesem Beispiel die mit use erzeugten Instanzen des Objekts "b1", "b2" und "b3" und nicht, wie im zweiten Beispiel dieses Kapitels, das Objekt "boot" selbst. In diesem Fall würden sich die Anweisungen der drei animateMotion-Elemente nämlich auf das Objekt beziehen und somit gleichzeitig auf alle drei (!) Instanzen des Objekts.
.. und deshalb würden daraufhin nur die Anweisungen des zuletzt platzierten animateMotion-Elements auf alle (!) Instanzen des Objekts ausgeführt.




index  |  Kapitel 13  |  13.6  <<  | 13.7 |  >>  13.8   Animierte Farbveraenderungen - animateColor