SVG SMIL Animations – Events
SVG-Animationen mit SMIL können durch Aktionen wie mouseover und click gestartet werden, das Ende einer Animation eine andere Animation starten. Animationen und Events triggern weitere Animation, um komplexe Abläufe zu synchronisieren.
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.