SVG animieren – drei Techniken
Auch wenn SVG mit SMIL ein eigenes Animationsmodell hat – SMIL-Animationen wurden von IE in allen Versionen nicht unterstützt. Seit der Ankündigung der Entwickler, dass Chrome SMIL nicht länger unterstützen wolle, sitzen SVG-Animationen auf einem Ersatzteillager.
CSS kann SVG ebenfalls animieren, wobei SVG-Geometrie-Attribute wie x, y, width, height, r, rx, ry und SVG transform allerdings außen vor bleiben. Sie lassen sich nicht im style-Attribut zusammenfassen. An diesen Stellen muss Javascript eingreifen.
CSS-Animationen
Nur Eigenschaften, die als CSS notiert werden können
Wird in externen SVG-Dateien ausgeführt
Javascript-Animationen
Alle Eigenschaften und alle Geometrie-Attribute.
Wird in externen SVG-Dateien nicht ausgeführt.
SMIL-Animationen
Alle Eigenschaften und alle Geometrie-Attribute
Wird in externen SVG-Dateien ausgeführt
Allerdings haben SVG-Animationen mit Javascript einen Haken: Sie funktionieren nicht wie SMIL-Animationen in externen SVG-Dateien. SVG-Animationen mit Javascript müssen inline ins HTML oder mit einem HTML iframe bzw. object in die Webseite geladen werden, damit Animationen mit Javascript ausgeführt werden.
Die SVG-Grafik wird zwar angezeigt, aber Javascript wird nicht ausgeführt, die Animation springt nicht an.
CSS Transform auf SVG
CSS Transformationen arbeiten auf SVG- genauso wie auf HTML-Elementen: Beispiel.
Hier animiert CSS in der SVG-Datei ein schlichtes transform: rotate().
Der Trick bei der Rotation mit CSS Keyframes liegt im Ursprung der Transformation. Quelle Rotating a SVG path using CSS3 around its own center auf stackoverflow.com
#dolphin { animation: turning 5s infinite linear; transform-origin: 170 170; } @keyframes turning { from {transform: rotate(0)} to {transform: rotate(-360deg) } }
transform-origin und transform-box
SVG-Elemente mit CSS zu rotieren ist ein Hexenkessel. CSS transform:rotate (xdeg) rotiert ein Element im Uhrzeigersinn um seinen Mittelpunkt, SVG-Elemente rotieren um den Nullpunkt der ViewBox oben links.
.rocket { transform-origin: 50% 50%;
transform-origin: 75% 120%;
transform-box: fill-box;
animation: rocket 3s linear infinite; } @keyframes rocket { to { transform: rotate(359deg)} }
CSS transform-origin: 75% 120%;
CSS transform-box: fill-box;
CSS transform-origin: 50% 50%; oder transform-origin: center; setzt den Mittelpunkt der Rotation auf den Mittelpunkt der ViewBox. 50% oder center sind relative Werte. Absolute Werte wie transform-origin: 200px 121px würden in einem responsiven SVG, dessen Abmessungen vom Viewport des Browsers abhängen, immer wieder daneben liegen.
Damit die Rakete um den Mond kreist, braucht sie nur die relativen Koordinaten des Mittelpunkts des Monds: transform-origin: 75% 120%; (denn der Mittelpunkt des Monds liegt außerhalb der Viewbox der Grafik).
Werte für CSS transform-box für SVG-Elemente
- transform-box: fill-box
- Die Object Bounding Box des Elements
- transform-box: stroke-box
- Die Stroke Bounding Box des Elements
- transform-box: view-box
- Der SVG-Viewport – default-Wert
SVG mit SMIL animieren
Auch wenn SMIL zwischenzeitlich todgesagt wurde – SMIL wird heute wieder von allen modernen Browsern unterstützt. Das SVG-eigene Animationsmodell SMIL hat eine leichte Ähnlichkeit mit CSS-Keyframes, aber anstelle von CSS-Stilen verwendet SMIL spezielle SVG-Elemente wie <animateTransform … />.
<div class="turtle"> <div class="crossing"> … </div> </div>
SVG-Lineart mit CSS
Selbst Lineart-Animationen lassen sich mit CSS-Keyframes umsetzen.
<style>
#boot {
stroke: hsl(200,50%,50%);
stroke-dasharray: 0;
animation: dashdraw 3s 2s linear reverse forwards;
}
@keyframes dashdraw {
from {stroke-dashoffset: 0; stroke: #fff }
to {stroke-dashoffset: 396; stroke: hsl(200,50%,50%) }
}
</style>
<path id="boot" d="m 356.2,140.6 … …"
style="stroke-dasharray: 225px, 225px; stroke-dashoffset: 0px;"/>
Ähnlich wie CSS border hat SVG ein Attribut stroke-dasharray, mit dem der Stroke gestrichelt wird, und das als CSS-Eigenschaft geschrieben werden kann. Was als style notiert werden kann, läßt sich mit CSS animieren.
Die Grafik-Datei ist Javascript-frei. Allerdings müssen vor dem Speichern der SVG-Datei ein paar Zeilen Javascript die Länge des animierten Pfads berechnen.
let draw = document.querySelector('#boot'); console.log (draw.getTotalLength());
Die Länge des Pfads in der Console auslesen und in das style-Attribut übernehmen (mehr zu SVG-Pfad-Animationen).
Alternativ: Vivus von maxwellito auf Github ist eine bezaubernde kleine Library, die SVG Lineart-Animationen umsetzt und die Grafik on the fly zeichnet. Vivus ist auf SVG-line-Animationen spezialisiert, ist unabhängig von anderen Librarys und bringt gerade mal 11 KB Zusatzgewicht.
SVG mit Velocity.js
Velocity.js ist eine Library für Animationen mit Javascript, die auf jQuery aufsetzt, aber auch ohne jQuery agiert. Auch wenn Velocity ohne jQuery $.animate() benutzt wird, bleibt die Syntax fast gleich und verschiebt nur alle Argumente um eins nach rechts, um dem animierten Element Platz zu machen.
Velocity (circle[0], {fill: "#efefef", opacity: 1, r: 35}, {delay: 1000, duration: 2000, easing: "swing"});
Warum nicht mit CSS Keyframes? CSS Keyframes-Animationen haben keine einfache Möglichkeit, die Keyframes der vier Blöcke miteinander zu synchronisieren. CSS animation-delay könnte zwar einspringen, aber dann fehlt immer noch das Animation Reset und Neustart in CSS.
Wie wäre es mit dem Web Animation API für Javascript? Javascript animate() lehnt sich eng an CSS Keyframes-Animation an.