SMIL – Synchronisation
SMIL-Animationen (Synchronized Multimedia Integration Language) sind ein einfaches, aber ausgesprochen mächtig wucherndes Schema für die Animation von SVG-Elementen. SMIL ist ein Standard des W3C (ausgesprochen »smile«).
Als die Blink-Entwickler (Chrome und Opera) SMIL unter den Teppich kehrten und damit einen Standard versenkten, drohte SMIL zum aussterbenden Dinosaurier zu werden. Dabei haben die Blink-Entwickler den Intent to Deprecate – die Absicht, SMIL außer Kraft zu setzen – kurze Zeit später still und leise zurückgenommen.
Heute werden SMIL-Animationen von allen modernen Browsern unterstützt, auch von Microsoft EDGE, seitdem EDGE auf Chromium basiert.
SVG SMIL vs CSS-Keyframes-Animationen vs Javascript Web Animation
Gegenüber CSS-Keyframes-Animationen starten SMIL-Animationen in Abhängigkeit voneinander (z.B. begin="move1.end + 0.2s") und synchronisieren sich auf einer Timeline.
Wir können zwar SVG auch mit CSS animieren, aber CSS-Keyframes-Animationen haben enge Grenzen. CSS hat nur wenige Events, die eine Animation starten, pausieren oder stoppen können.
SVG-Animationen steuern
Die Liste der Attribute für das Steuern einer SVG-Animation ist lang. Da sich Animationen kombinieren und durch Events steuern lassen, bleibt die Timeline überschaubar.
Das ist die vereinfachte Variante des kleinen Schiffstransfers: Beim Laden der Seite rollt der Ball nach rechts (animateTransform id="one"), danach mit einer Verzögerung von 1s wieder zurück (animateTransform id="two").
<g id="beachball"> <animateTransform id="one" attributeName="transform" attributeType="XML" type="translate" from="0" to="500" begin="0s;animatFinished.end" dur="3s" calcMode="spline" keyTimes="0;1" keySplines="0.42 0 0.58 1" fill="freeze"/> <!-- Zurück bei at one.end + 1s --> <animateTransform id="two" attributeName="transform" attributeType="XML" type="translate" from="500" to="0" begin="one.end + 1s" dur="3s" calcMode="spline" keyTimes="0;1" keySplines="0.42 0 0.58 1" fill="freeze"/> … </g>
Der rote Button wird bei begin="two.end + 1s" sichtbar. Anstelle von one.end + 1s könnte der rote Button auch frühzeitig auftauchen: one.end - 1s.
animateTransform id="animatFinished" stößt bei einem Klick die den Lauf des Balls von links nach rechts erneut an.
<circle cx="300" cy="125" r="20" fill="red" opacity="0" style="cursor:pointer"> <animateTransform id="animatFinished" attributeName="transform" attributeType="XML" type="translate" from="0" to="0" begin="click" dur="1s" fill="freeze"/> <animate attributeName="opacity" begin="two.end + 1s" dur="1s" fill="freeze" values="0;1" /> </circle>
keySplines für ease, easeIn, easeOut, easeInOut
Den SMIL-Animationen (Synchronized Multimedia Integration Language) fehlen die eleganten Schlüsselwörter wie ease-in und ease-out für die Timing-Funktionen, aber einfache Spline-Animationen realiseren rasantes Beschleunigen und sanftes Auslaufen von Bewegungen und Transformationen.
calcMode="spline" erlaubt sanftes Beschleunigen und Abbremsen und realisiert Bewegungsmuster wie ease-in und ease-in-out mit CSS oder jQuery.
<circle r="20" fill="white" opacity="0.1"> <animateTransform attributeName="transform" repeatCount="1" begin="mouseover" type="scale" calcMode="spline" dur="2s" keyTimes="0;1" values="1;0.9" keySplines="0 0 0.58 1" /> <animate attributeName="opacity" repeatCount="1" begin="mouseover" calcMode="spline" dur="2s" keyTimes="0;1" values="1;0" keySplines="0 0 0.58 1" /> </circle>
Die Splines führen uns die Bewegungsmuster vor Augen: ease beginnt langsam, wird schneller und vor dem Ende wieder langsamer. Die meisten natürlichen Bewegungen verlaufen nach diesem Muster. ease-out hingegen beginnt wie eine Gewehrkugel schnell und wird dann langsmer.
P0 und P1 sind die x,y-Werte für die »Anfasser« einer Bezier-Kurve. Der x-Wert liegt sowohl in P0(x,y) als auch in P1(x,y) immer zwischen 0 und 1, der y-Wert kann größer als 1 oder kleiner als 0 werden.
SVG Filter animieren
elem.click | SVG Animation ohne Javascript starten
animation.end | Animation in Abhänigkeit einer anderen Animation starten
<defs> <animate id="slidein" attributeName="dx" from="500" to="0" begin="button.click+0s" dur="1s" fill="freeze" values=" 500; 0; -20; 10; 0" keyTimes=" 0; .8; .85; .9; 1" xlink:href="#slideEffect" /> <animate attributeName="stdDeviation" from="20,1" to="0,0" begin="slidein.end-0.2s" dur="0.2s" fill="freeze" xlink:href="#blur" /> <filter id="slide"> <feOffset id="slideEffect" dx="500" dy="0" /> <feGaussianBlur id="blur" stdDeviation="20,1" /> </filter> </defs> <text id="flyBlur" x="0" y="100" filter="url(#slide)">SVG Filter animieren</text> <circle id="button" cx="170" cy="170" r="30" fill="" style="cursor:pointer" />
Mehrere Animationen für ein Element
Für ein Element lassen sich mehrere Animationen kombinieren – z.B. animateMotion und animateTransform, um das Element gleichzeitig zu bewegen und zu skalieren.
<animateMotion begin="0s" dur="10s" rotate="auto" repeatCount="indefinite"> <mpath xlink:href="#just-another-8" /></animateMotion> <animateTransform type="scale" attributeName="transform" values="1; 0.9; 0.7; 0.4; 0.1; 0.4; 0.7; 0.9" dur="10s" repeatCount="indefinite" begin="10s"/>
- additive
replace | sum - Legt fest, ob eine Animation zum Attribut hinzugerechnet wird oder ob die Animation den Wert ersetzt
- acutate
user | auto - accumulate
none | sum - Legt fest, ob Iterationen kummulativ sind
- begin / end
0
mouseover
click |
load
focus
elem.endEvent+1s
sum
elem.begin + 1s
elem.end + 1s | wallclock()
indefinite
elem.repeat(2) - Zeit oder Event, bei der die Animation startet bzw. endet. Eine Animation kann zu einem Zeitpunkt beginnen oder durch ein Ereignis wie click oder durch den Anfang / das Ende einer anderen Animation
- dur
0s - Dauer der Animation
- fill
remove
freeze - Legt fest, ob die Animation am Ende stehen bleibt oder nicht
- min
0s - Minimale Dauer bzw. max. Dauer der Animation. Mit min muss die Animation end-Events ignorieren, bis der entsprechende Zeitpunkt erreicht ist.
- max
indefinite - Mit max endet die Animation.
- restart
always
whenNotActive
never - Legt fest, ob die Animation erneut gestartet werden kann.
- repeatCount
#
indefinite - Legt fest, wie oft die Animation wiederholt wird.
- repeatDur
Dauer
indefinite - die Gesamtdauer, über die eine Animation wiederholt wird.
- wallclock
- YYYY-MM-DD z.B. 2015-07-16T19:20+01:00 oder 08:00
- by
Dauer - wird zusammen mit addition verwendet und legt den Wert fest, der zum Animationswert hinzugerechnet wird, wenn die Animation beendet ist.
- calcMode
discrete
linear
paced
spline - bei paced werden keyTimes und keySplines ignoriert. Die Punkte eines Splines werden durch das keyTimes-Attribut festgelegt
- from / to
Startpunkt / Endpunkt - keyTimes
- Semikolon-getrennte Liste mit Werten zwischen 0 und 1.
Wenn keyPoints oder keySplines angegeben ist, muss keyTimes dieselbe Zahl von Elementen aufweisen wie keyPoints bzw. keySplines - 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 - keySplines
animateMotion
- path
- überschreibt andere Bewegungen wie from, to, by, values, ist absolut oder relativ
- calcMode
paced - bei paced werden keyTimes und keySplines ignoriert. Die Punkte eines Splines werden durch das keyTimes-Attribut festgelegt
- 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 - rotate
angle | auto | auto-reverse - Ob das Objekt entlang des Animationspfads rotiert wird: Bei auto liegt die x-Achse des Objekts parallel zum Pfad.
animateTransform
- type
scale
rotate
skew
translate - values
- Semikolon-getrennte Liste von Werten für ein Attribut
Alternativen zu SMIL-Animationen
Alternativen sind Velocity.js, motionPath, CSS und Javascript, Libraries wie GreenSocks und snap.svg
Velocity.js ist eine Animations-Library mit einem API, das an jQuery $.animate() angelehnt ist, aber sowohl mit als auch ohne jQuery genutzt werden kann. Velocity.js unterstützt auch SVG-Animationen.
Vivus ist eine kleine Library, die SVG path-Animationen umsetzt und die Grafik on the fly zeichnet. Vivus ist auf SVG-path-Animationen spezialisiert, ist unabhängig von anderen Librarys und bringt gerade mal 8KB Zusatzgewicht.