SVG mit CSS und Javascript animieren

SVG mit CSS-Keyframes AnimationSVG Animation

CSS animiert SVG in gleicher Weise wie HTML-Elemente: alle Eigenschaften, die in einem style-Attribut stehen können, können mit CSS animiert werden. Wo CSS an die Grenzen stößt, hilft Javascript nach.

SVG unterstützt CSS und kann im style-Attribut dekorative Eigenschaften wie fill, opacity, stroke, stroke-width und font-family zusammenfassen.

Diese Eigenschaften können entweder als fill="#fff" oder style="fill:#fff" geschrieben werden und lassen sich mit CSS animieren.

Auch wenn SVG mit SMIL ein eigenes Animationsmodell hat – SMIL-Animationen werden von IE in allen Versionen und von Microsoft Edge nicht unterstützt. Seit der Ankündigung, dass Chrome SMIL nicht länger unterstützen wolle (aber die Drohung leise wieder zurücknahm), sitzen SVG-Animationen auf einem Ersatzteillager aus CSS und Javascript.

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.

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 die Animation springt nicht an.

SVG mit einfachen CSS-Animationen

CSS-Keyframes-Animationen funktionieren wie bei HTML-Elementen.

Die aufsteigenden Seifenblasen sind SVG-circle-Elemente. Der Wechsel der Farben wird von einer CSS-Keyframes-Animation gesteuert.

@keyframes blub {
  from {fill: hsla(0,60%,50%,0.5)}
  to { fill: hsla(250,60%,50%,0.1)}
}

.blub {
  animation-duration: 5s;
  animation-name: blub;
  animation-iteration-count: infinite;
}

Position und Aufsteigen der Seifenblasen sind Geometrie-Attribute. Da muss eine Javascript-Animation – z.B. mit requestAnimationFrame – eingreifen.

In IE und Microsoft Edge funktionieren nur die Javascript-Animationen, aber nicht die CSS Keyframe-Animationen (der Farbwechsel der Seifenblasen).

SVG mit CSS Keyframe-Animation

Die kleine Rakete im Seitenkopf umkreist dem Mond mit einer einfachen CSS-Keyframes-Animation.

<style>
.littlerocket {
	animation-name: looping;
    animation-duration: 5s;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
}

@keyframes looping {
	from { transform:rotate(0deg); transform-origin: 280% 150% }
    to   { transform:rotate(359deg); transform-origin: 280% 150% }
}
</style>

Microsoft unterstützt CSS-Keyframes-Animationen auf SVG-Elementen nicht. Alternativ mit Javascript requestAnimationFrame-Animation:

(function() {
var rocket = document.querySelector("#littlerocket");
var angle = 0;
function loop () {
   rocket.setAttribute("transform","rotate(" + angle + " 747 890)");
   angle = angle + 1;
   repeater = requestAnimationFrame(loop);
}
loop();
} () );

CSS-Animationen wirken auch in externen SVG-Dateien, die mit einem img-Tag eingebunden sind.

<img src="svg-keyframes-animation.svg">

SVG mit CSS und Javascript animieren

Es gibt nur wenige CSS-Events, die eine CSS-Animation starten (so wie in diesem einfachen Beispiel ein Hovern mit der Maus über die Seifenblasen).

Ein kleines Javascript hilft der Animation von SVG-Elementen auf die Beine:

Die Beine der Schildkröte sind mit Javascript und requestAnimationFrame animiert.

function rotateLegs() {
   legft.setAttribute("transform", "rotate(" + angle + " 204 78)");
   legtfb.setAttribute("transform", "rotate(" + -angle + " 204 160)");
   legbt.setAttribute("transform", "rotate(" + -angle + " 78 78)");
   legbb.setAttribute("transform", "rotate(" + angle + " 78 160 )");

   if (angle > -20 && forth === true) {
      angle = angle - 0.3;
   } else if (angle < 0) {
      forth = false;
      angle = angle + 0.6;
   } else {
      angle = 0;
      forth = true;
   }
   repeater = requestAnimationFrame(rotateLegs);
}

Die einfache SVG-Rotation mit transform = rotate () kann drei Parameter aufnehmen: den Rotationswinkel und den Punkt, um den sich ein Element oder eine Gruppe von Elementen dreht.

Die Animation startet, wenn die Grafik in den Viewport kommt – im Browserfenster sichtbar wird.

function isScrolledIntoView(el) {
   var elemTop = el.getBoundingClientRect().top;
   var elemBottom = el.getBoundingClientRect().bottom;
   var isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight);
   return isVisible;
}

getBoundingClientRect gibt in allen modernen Browsern vier Werte zurück: Abstand vom oberen / linken und zum rechten / unteren Rand des Browserfensters.

CSS Transform auf SVG

CSS Transformationen arbeiten auf SVG- genauso wie auf HTML-Elementen: Beispiel.

Hier animieren CSS und Javascript nur ein schlichtes transform: rotate(). Das funktioniert auch in Internet Explorer und in Edge, die SVG-Animationen mit SMIL nicht unterstützen.

<script>
<![CDATA[
(function() {
   var d1 = document.getElementById('dolphin');
   var y = 0;
   d1.setAttribute('transform','translate(180,190) rotate(0)');
   var dolphin = setInterval (function () {
      d1.setAttribute('transform', 'translate(180,190) rotate(' + y + ')');
                                              ^
                                              |
                                              +-- Setzt den Pivotpunkt,
                                                  damit sich der Delphin 
                                                  um den Mittelpunkt dreht
      y = y-3;
   },60);
} () );
]]>
</script>

Wenn Javascript in die SVG-Datei gesetzt wird (z.B. um es in einem HTML-iframe aufzurufen), muss es in <![CDATA[ … ]]> gewickelt werden.

SVG-Line-Animationen mit Vivus

Vivus ist eine bezaubernde kleine Library, die SVG Line-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.

Jedes SVG path hat zwei zusätzliche data-Attribute: data-start und data-duration, die eine Timeline defininieren.

<path id="boot" data-start="75" data-duration="50" d="" />
<path id="welle" data-start="70" data-duration="50" d="" />
<path id="welle2" data-start="60" data-duration="50" d="" />
<path data-start="40" data-duration="50" d="" />
<path data-start="0" data-duration="50" d="" />

Nur noch die Animation starten:

boot = new Vivus('boot', {type: 'scenario', duration: 100});

Vivus von maxwellito auf Github

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.

RESTART
Velocity (circle[0], 
           {fill: "#efefef", opacity: 1, r: 35}, 
           {delay: 1000, duration: 2000, easing: "swing"});
SVG mit CSS-Keyframes Animation SVG Animation