SVG Animationen: CSS, Javascript und SMIL

Luftballons schweben entlang eines SVG-Pfads, animiert mit SMIL

SVG kann mit Javascript und CSS animiert werden und hat darüber hinaus ein eigenes Animationsmodell: SMIL (Synchronized Multimedia Integration Language). Der Vorteil von SMIL gegenüber Javascript-Animationen: SMIL-Animationen bewegen SVG auch in img-Tags.

23-02-02 SITEMAP CSS HTML JS Basis JS Web Tutorial SVG

Leben, Sterben und Wiederauferstehung der SMIL-Animationen

SMIL hat eine bewegte Geschichte hinter sich: Kaum dass SVG auf breiter Basis von den Browsern unterstützt wurde, verkündeten die Blink-Entwickler (die hinter Chrome sitzen), dass sie SMIL als deprecated (veraltet und unerwünscht) ansahen und die Unterstützung irgendwann einstellen würden. Von Chrome in Version 45 den CSS-Animationen zuliebe als deprecated (veraltet) gekennzeichnet und – schwupps – abgesetzt, sind SMIL-Animationen in Chrome wieder an Bord. Die Blink-Entwickler sind lautlos vom deprecated zurückgerudert.

Heute setzt Microsoft Edge auf Chromium auf und SVG SMIL-Animationen wirken in Firefox, Safari, Chrome, Opera und EDGE. Somit sind SMIL-Animationen mit der Unterstützung aller modernen Browser zurück.

SVG ist ein spezielles DOM-Element mit einer ähnlichen Syntax wie HTML: SVG-Elemente bestehen aus Tags, Attributen und Verhalten. Sie können mit CSS animiert werden – wenn auch mit den Einschränkungen, denen CSS-Animationen unterliegen.

JavascriptAlle AttributeAus Sicherheitsgründen nicht beim SVG in img-Element
CSSAlle style-Attribute, aber mit IE / älteren Versionen von EDGE: keine transform-AttributeAnimiert auch die externe SVG-Datei
SVG SMILAlle Attribute mit animate, animateMotion, animateTransformAnimiert auch die externe SVG-Datei

SVG Animationen mit SMIL

SMIL hat neben einer überwältigenden Menge an Optionen einen Pluspunkt: SMIL ist »All in One«. Ein externes animiertes SVG enthält alle erforderlichen Elemente und Animationen und kommt mit einem einfachen img-Tag aus.

SVG animate with SMIL
Download Download cityscape-animiert.svg
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Bei einfachen SVG-Animationen springt CSS ein. Dort fehlt es allerdings an einer einfachen Umsetzung der Timeline oder Chaining, denn SMIL-Animationen setzen durch ein einfaches begin="move1.end + 0.4s" Animationen in Abhängigkeit von anderen Animationen und auch zu Events wie click.

Für Effekte und Animationen, die mit CSS und Javascript zu aufwändig sind, springen Libraries wie Vivus und Velocity (klein und leicht) oder den großen Libraries à la Snap.svg und GreenSocks ein.

SVG animate

Um ein SVG-Element zu animieren, wird ein animate-Tag zwischen das öffnende und schließende Tag des Elements gesetzt. Das animate-Tag kommt in vier Variationen:

  1. animate kann jedes skalierbare Attribut animieren.
  2. animateMotion bewegt ein Element auf einem Pfad,
  3. animateTransform animiert Größe, Lage und Rotation
  4. set setzt einen einfachen Wert – z.B. fill

Darüber können zwei Animationselemente bzw. Attribute verwendet werden.

  1. animateTransform
  2. mpath
animateMotion
<rect x="" y="" … >
    <animateMotion values="-200,0; 2500,0"  …/>
</rect>

<rect x="" y="" … >
    <animateMotion …>
        <mpath xlink:href="#p1" />
    </animateMotion>
</rect>
animateTransform (translate | scale | rotate | skewX | skewY)
<rect x="" y="" … >
    <animateTransform type="rotate"  …/>
</rect>
animate Attribute
<rect x="" y="" … >
    <animate attributeName="x"  …/>
</rect>
Set – einfaches Toggeln
<rect x="" y="" … >
    <set  …/>
</rect>

animateMotion

Bewegung entlang eines Pfades. Ändert das Koordinatensystem des animierten Objekts. Im einfachsten Fall wird der Pfad im values-Attribut des animateMotion-Tags als Punktefolge angegeben.

SVG SMIL animate transform
<circle cx="50" cy="50" r="50" fill="ivory">
   <animateMotion dur="10s" 
      values="0,0; 450,0; 200,150; 0,0" 
      repeatCount="indefinite" />
</circle>
path
überschreibt andere Bewegungen wie from, to, by, values, ist absolut oder relativ
calcMode
paced ignoriert keyTimes und keySplines. Die Punkte eines Splines werden durch das keyTimes-Attribut festgelegt
linear einfache Interpolation zwischen den Werten
discrete springt in diskreten Schritten von einem Wert zum nächsten
spline interpoliert zwischen den Werten anhand eines Cubic-Bezier-Splines
keyPoints
Semikolon-getrennte Liste mit Werten zwischen 0 und 1
Die Zahl der keyPoints kann von der Zahl der Knoten auf dem Animationspfad (value) abweichen und die keyPoints können in beliebiger Reihenfolge stehen, um vorwärts- / rückwärts-Bewegungen zu erzeugen
repeatCount
# | indefinite (tatsächlich indefinite, nicht infinite wie in CSS und nicht Infinity wie mit Javascript) Legt fest, wie oft die Animation wiederholt wird.
freeze
friert die Bewegung am Ende ein
rotate
angle | auto | auto-reverse
Ob das Objekt entlang des Animationspfads rotiert wird. Bei auto liegt die x-Achse des Objekts parallel zum Pfad.
values
Semikolon-getrennte Liste von Werten für ein Attribut

Ein komplexer Animationspfad kann auch in ein defs-Element gesetzt werden. animateMotion muss dann einen Link auf den Animationspfad setzen.

<svg xmlns:xlink="http://www.w3.org/1999/xlink" … >
</svg>
<defs>
    <path id="p1"  d="…" />
</defs>
<path d="…" style="fill:#666">
    <animateMotion dur="50" repeatCount="indefinite">
        <mpath xlink:href="#p1"/>
    </animateMotion>
</path>

Wenn die SVG-Grafik nicht inline im HTML-Dokument liegt, braucht das svg-Element eine Referenz auf den xlink-Namespace.

animateTransform

type
translate | scale | rotate | skewX | skew>
Legt fest, welche Transformation animiert wird

Der Nullpunkt des SVG-Koordinatensystems liegt oben links. Um ein Element um seinen Pivotpunkt (Mittelpunkt) zu rotieren, braucht das Element – in diesem Beispiel ein Viereck – ein eigenes Koordinatensystem durch <g transform="translate( 250,125)">.

SVG SMIL animate transform
<g transform="translate( 250,125)">
   <rect x="-75" y="-75" width="150" height="150" fill="ivory">
   <animateTransform repeatCount="indefinite"
      attributeName="transform" type="rotate"
      from="0" to="90" begin="0" dur="5s" />
   </rect>
</g>

Statt das Element mit transform="translate()" zu versetzen, kann der Rotationspunkt (Pivotpunkt) auch in animateTransform angegeben werden.

<rect x="175" y="50" width="150" height="150" rx="5" ry="5">
   <animateTransform 
      repeatCount="indefinite"
      attributeName="transform" type="rotate"
      from="0 250 125" to="360 250 125" begin="0" dur="5s" />
</rect>

Mehrere Werte können auch als Semikolon-getrennte Liste angegeben werden. Dann kommt eine Animation vorwärts und rückwärts (forth and back) mit einer Anweisung aus.

SVG SMIL Animation rotate

Jedes Bein der Schildkröte braucht nur ein animationTransform-Element.

<g>
    <path fill="#5a852c" d="…"/>
    <path fill="#496c24" d="…"/>
    <animateTransform repeatCount="indefinite" 
                         attributeName="transform"        +---+ Mittelpunkt der Rotation
                         type="rotate"                    |   |
                         values="0 204 78; -20 204 78; 0 204 78" dur="8s" />
                                 |          |          |
                          0° ----+        -20°         +--- 0°
</g>

set

set ist eine Kurzschrift für animate und erzeugt eine Animation mit einer Dauer von 0s. Ein dur-Attribut mit einem anderen Wert als 0 hat keine Wirkung. Der neue Wert wird sofort zugewiesen, wenn die Animation durch ein Event ausgelöst wird.

Kurz: set toggelt zwischen zwei Zuständen.

<rect id="box" width="10" height="10">
	<set attributeName="opacity" to="0.5" begin="box.click" dur="15s" />
</rect>

set ist nützlich, um nichtnumerische Attribute wie visibility zu verändern oder ein CSS class einzusetzen.

Alternativen zu SVG SMIL-Animationen

Alternativen sind CSS und Javascript, Javascript animate(), motionPath, Libraries wie GreenSocks und snap.svg