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.
Javascript | Alle Attribute | Aus Sicherheitsgründen nicht beim SVG in img-Element |
CSS | Alle style-Attribute, aber mit IE / älteren Versionen von EDGE: keine transform-Attribute | Animiert auch die externe SVG-Datei |
SVG SMIL | Alle Attribute mit animate, animateMotion, animateTransform | Animiert 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.
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:
- animate kann jedes skalierbare Attribut animieren.
- animateMotion bewegt ein Element auf einem Pfad,
- animateTransform animiert Größe, Lage und Rotation
- set setzt einen einfachen Wert – z.B. fill
Darüber können zwei Animationselemente bzw. Attribute verwendet werden.
- animateTransform
- 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 von einem Punkt zum nächsten Punkt. Ändert das Koordinatensystem des animierten Objekts. Im einfachsten Fall wird der Pfad im values-Attribut des animateMotion-Tags als Punktefolge angegeben.
<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)">.
<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.
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