SVG und JavaScript/Animation

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Animationen mit JavaScript haben den Vorteil, dass sie anders als reine CSS-animation durch Interaktion mit dem Benutzer gesteuert werden können und dieser so immer die Kontrolle über die Webseite behält.

SMIL, das jetzt von allen Browsern unterstützt wird, kann dies mit Einschränkungen auch, „vermüllt“ aber das SVG-Markup durch seine Kindelemente und ist so nicht mehrfach verwendbar.

In diesem Kapitel werden einige Anwendungsbeispiele gezeigt, die ohne JavaScript so nicht möglich wären.

Animationen mit WAAPI

Mit der Web Animations API können Sie Präsentationseigenschaften schnell und komfortabel animieren und diese Animationen auch steuern. Leider ist sie aber eben auf diese beschränkt, sodass z. B. Shape-Morphing mittels Animation des d-Attributs oder Kamerafahrten, bei denen das viewBox-Attribut animiert wird, nicht möglich sind.[1]

Ladebalken

Das erste Beispiel aus dem Einstieg in Web Animations-Tutorial kann auch in SVG realisiert werden:

Beispiel ansehen …
function animiere() { 
  var ladebalken = document.getElementById('ladebalken');
  ladebalken.animate(
    [
      {
        width: '20px',
        fill: 'green'
      }, {
        width: '200px',  
        fill: 'lime'
      }
    ], {
      duration: 2000,
      iterations: 1,
      fill: 'forwards'
    })
  };

In diesem Beispiel wird in einem script-Bereich eine Funktion (animiere) definiert. Diese Funktion legt sich eine Referenz auf das betreffende SVG-Element mit der id ladebalken in einer Variablen ab, um bequem darauf zurückgreifen zu können.

Beim Auslösen der Funktion werden die Breite und Farbe des rect-Elements, das diese id enthält, animiert.

Neben den keyframes der Animation werden mit duration: 2000 eine Dauer von 2 Sekunden (in Millisekunden) und mit iterations: 1 eine einmalige Durchführung festgelegt. fill: 'forwards' legt fest, dass das animierte Objekt im Endzustand der Animation bleibt und nicht zum Ausgangspunkt mit 1em Breite zurückspringt.

Pie Timer mit SVG

Kreis mit gestricheltem Rand, der doppelt so breit wie der Radius des Kreises ist.

Häufig soll eine Timer-Funktion auch grafisch visualisiert werden. Im Netz gibt es dazu unter dem Begriff pie timer mehrere meist mit canvas realisierte Beispiele. Da das Zeichnen von kreisförmigen Pfaden weder in canvas noch in SVG intuitiv zu nennen ist (David Gilbertson hat die diversen mathematischen Hürden in seinem Artikel A simple pie chart in SVG humorvoll aufs Korn genommen), wollen wir Ihnen einen alternativen Ansatz von Lea Verou vorstellen.[2]

Ein pie timer ist ja ein Kreisdiagramm, das auch durch ein circle-Element realisiert werden kann. Anstelle des Vollkreises soll aber nur ein (sich stetig vergrößerndes) Segment dargestellt werden.

Die durchgezogene Randlinie kann über stroke-dasharray gestrichelt werden. Wenn Sie den Intervall nun an die benötigte Länge (Kreisumfang U = 2r * π => 314.2) anpassen und die stroke-width auf den doppelten Radius erhöhen, erhalten Sie ein Kreissegment.

Kreis mit gestricheltem Rand ansehen …
        <circle r="100" fill="white" />
        <circle r="50" fill="var(--yellow)"
          stroke="var(--accent)"
          stroke-width="100"
          stroke-dasharray="52 52" />
Beachten Sie, dass die Strichelung an der 3-Uhr-Position beginnt - der Kreis wird deshalb im nächsten Beispiel um -90° gedreht.

Selbst die Animation des schrittweisen Füllens kann mit CSS erreicht werden; der Einsatz von JavaScript beschränkt sich auf das Steuern der Animation. Die Berechnung der einzelnen Schritte ist denkbar einfach: Startpunkt ist ein Strich von 0 und eine Lücke von 314 – am Endpunkt beträgt die Strichlänge 314 und die Lücke 0 – die Einteilung in 60 Schritte übernimmt CSS!

Pie Timer mit CSS-Animation ansehen …
#timer {
 fill: none;
 stroke: var(--accent);
 stroke-width: 100;
 stroke-dasharray: 0 314; 
 transform: rotate(-90deg);
 animation: timer 60s steps(60) forwards;
}

@keyframes timer {
 from {
 stroke-dasharray: 0 314;
 }
 to {
 stroke-dasharray: 314 0;
 }
}
Beachten Sie: Im Tutorial von SparkBox werden die Kreissegmente gestaltet, indem die Werte für stroke-dasharray mit der calc()-Funktion berechnet werden. Dies funktioniert in den Chromium-Browsern; nicht jedoch im Firefox.[3]

In der Großansicht wird das Kreissegment teilweise nicht gerade gezeichnet (Firefox und Windows 10 auf Microsoft Surface; auch die png-Vorschau oben); in den meisten Browsern sieht es gut aus. In der kleineren Ansicht sind diese Fehler nicht mehr zu erkennen.

Animation mit der Web Animations API

Jede Animation sollte immer durch den Benutzer gesteuert werden können. Ein Timer soll gestartet, aber auch unter- oder abgebrochen werden können. Deshalb übertragen wir unsere CSS-Animation nun ins JavaScript:

Pie Timer - Animation durch JavaScript ansehen …
  ...
  var timer = document.querySelector( '#timer' );
	 
  // animate timer
	var anim = timer.animate([{
		 strokeDasharray: '0 314'
        }, {
		 strokeDasharray: '314 0'
	    }
        ], {
         duration: 60*1000,
         direction: 'normal',
         iterations: Infinity,
         easing: 'steps(60)',
         playbackRate : 1
     });

Das Script entspricht weitgehend der CSS-Animation. Ausnahmen sind …

  • stroke-dasharray wird, da in JavaScript keine Bindestriche erlaubt sind, zu strokeDasharray in CamelCase-Schreibweise
  • steps(60) wird in der easing-TimingOption notiert und erhält, da es ein String ist, Anführungszeichen

Die Kontroll-Buttons erhalten Eventlistener, die je eine Funktion PlayPause-Toggle und ein Abbruch der Animation veranlassen:

Pie Timer - Steuerung durch JavaScript ansehen …
  document.querySelector('#play').addEventListener('click', togglePlayPause);
  document.querySelector('#stop').addEventListener('click', stopAnim);   
  var timer = document.querySelector( '#timer' );
	 
  // animate timer
 ...

  function togglePlayPause () {
    document.querySelector('output').innerText = ' togglePlayPause';
	if (document.querySelector('#play').textContent == '❙❙') {
		document.querySelector('#play').textContent = '►';
		anim.pause();
	} else {
		document.querySelector('#play').textContent = '❙❙';
		anim.play();		
		anim.playbackRate = 1;				
	}
  }    

  function stopAnim () { 
	anim.playbackRate = 0;
	anim.cancel();
  }


Quellen

  1. sarasoueidan: Art-Directing SVG Images With The viewBox Attribute How-To, Notes, Tips and Why We Need A viewBox Property in CSS
  2. smashingmagazine: Designing A Flexible, Maintainable CSS Pie Chart With SVG von Lea Verou (28.07.2015)
  3. Sparkbox: How to Create an SVG Pie Chart—Code Along with Kasey (Video)

Weblinks

Line-Animation

Convert Text to Path in Inkscape