Matthias Scharwies: SVGs mit Vivus animieren? Ja!

Beitrag lesen

Neulich gab es im SELF-Forum eine Frage zu Vivus. Dies ist ein Tool, das SVGs so animiert, dass sie gezeichnet werden. Es gibt eine Vielzahl von verschiedenen Animationen sowie die Möglichkeit, ein benutzerdefiniertes Skript zu erstellen, um Ihr SVG auf beliebige Weise zu zeichnen.

Dieser hand-drawn-Effekt findet sich auf immer mehr Webseiten und wird auch in Explainity-Videos z.B. bei Simple-Show verwendet.

Zum schnellen Ausprobieren empfiehlt sich Vivus Instant . Dort kann kann man SVGs per Drag und Drop laden und verschiedene Parameter einstellen. Das fertige SVG enthält ein neues style-Element mit CSS-Animationen, die in allen Browsern außer dem obsoleten IE9-11 laufen.

Ich persönlich war etwas skeptisch, da ich nicht für jeden Effekt ein weiteres, externes JavaScript in meine Seiten einbinden wollte. Mit vivus Instant ist es jedoch möglich, fertige SVGs ohne eingebundenes JavaScript zu erstellen, die man als img in jede Webseite einbinden kann.

Funktionsweise

Wie funktioniert so etwas denn überhaupt? SVG ist ja eine Auszeichnungssprache, in der Grafiken Grundformen als Elemente enthalten. Diese Grundformen können Attribute wie z.B. die Füllfarbe (fill="red") oder eine Randlinie haben. Mit Vivus wird die Randlinie nun aus dem sichtbaren Bereich verschoben und als CSS-Animation eingeblendet.

Die Drag- und Drop-Funktion von Vivus verleitet uns nun, dies einmal mit einigen SVG-Grafiken auszuprobieren:

Beim linken Kreis wird keine Animation erstellt, beim rechten jedoch schon:

Wenn Sie die Grafik mit Rechtsklick in einem neuen Tab öffnen, können Sie erkennen, dass der linke Kreis keine Angaben zu Füllung und Randlinie hat. Deshalb wird als Defaultwert für die Füllfarbe schwarz verwendet. Ohne Angaben zur Randlinie wird keine gerendert und kann deshalb auch nicht animiert werden. Deshalb wurde im rechten Kreis ein style-Attribut hinzugefügt:


style="fill:none; stroke:gray; stroke-width:1"

Wenn Sie diesen Kreis nun per Drag und Drop in Vivus Instant ziehen, kann eine Animation erzeugt werden:

Vivus hat zwei Dinge geändert:

<path style="fill:none; stroke:gray; stroke-width:1" d="M-50,0A50,50 0,1,1 50,0A50,50 0,1,1 -50,0" class="nYCkRAFg_0"></path>
<style data-made-with="vivus-instant">
.nYCkRAFg_0{
	stroke-dasharray:315 317;
	stroke-dashoffset:316;
	animation:nYCkRAFg_draw 2000ms linear infinite 0ms forwards;
}

@keyframes nYCkRAFg_draw{
	100%{stroke-dashoffset:0;}
}

@keyframes nYCkRAFg_fade{0%{stroke-opacity:1;}94.44444444444444%{stroke-opacity:1;}100%{stroke-opacity:0;}}
  1. Es wurde ein style-Element mit einer CSS-Animation hinzugefügt. Unser Kreis wird über die ebenfalls hinzugefügte Klasse selektiert und erhält ein Strichmuster mit stroke-dasharray. Die Werte 315 und 317 entsprechen der Pfadlänge des Umfangs unseres Kreises (2r x pi → 100 x 3.14 = 314).
    Dieses Strichmuster wird mit stroke-dashoffset nun so verschoben, dass es ursprünglich nicht sichtbar ist. Mit einer CSS-Animation wird diese nun eingeschoben. (Um sie im Blog sichtbar zu lassen, habe ich den Wert ìnfinite hinzugefügt.) Die keyframes für den fade werden nicht benötigt und sind Ballast.

  2. Unser circle-Element wurde in einen Pfad umgewandelt, da ältere Browser die Pfadlänge nur für das SVGPathElement auslesen könnten. Mittlerweile gilt dies auch für die Pfadlänge von Grundformen (SVGGeometryElement-Objects).[1]

Füllung einer Zeichnung

Natürlich kann dem Zeichnen des Objekts auch die Füllfarbe nachträglich verändert werden.

Hier gibt es mehrere Ansätze. Eine Animation der fill-Eigenschaft von none auf red würde ja sprunghaft erscheinen. Um einen weichen Übergang zu erreichen, habe ich fill-opacity mit CSS animiert. Rechts gibt es zwei SMIL-Animationen, die ich eigentlich vermeiden wollte.

Kreis

(Um Animation zu wiederholen; Grafik mit Rechtsklick im neuen Tab laden!)

Fazit

Mit einem sauber gezeichneten SVG können Sie mit wenigen Handgriffen eine attraktive CSS-Animation erzeugen, die ohne JavaScript bequem als img in Ihre Webseiten eingebunden werden kann.

Allerdings wird diese Animation nur einmal begonnen, sodass sie entweder ganz oben positioniert oder als Dauerschleife laufen muss. Ein Pausieren, Rückwärts-Abspielen und erneutes Abspielen funktioniert nur mit der JavaScript-Variante.

Siehe auch


  1. caniuse: pathLength ↩︎