SVG SMIL Animations – Events

SVG animateMotion mit mpath

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.

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

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.

Die Animation beginnt mit dem Laden der Seite. Wenn sie abgelaufen ist, erscheint der rote Button – ein Klick leitet die Animation erneut ein.

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>
SVG SMIL Easing – langsam starten, langsam enden, beschleunigen, bremsen
SVG SMIL easing

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

SVG Filter animieren START
<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.

SVG SMIL combinations
SVG SMIL-Animationen kombinieren
<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.