SVG und Javascript

Javascript für SVG

SVG wird mit Javascript genauso gescriptet wie HTML: Elemente einfügen, Attribute und Stile ändern und SVG animieren, denn SVG wird durch das DOM dargestellt. Scripte können direkt in der SVG-Datei sitzen, bei Inline-SVG in HTML-Seiten innerhalb des SVG-Elements oder im HTML der Seite.

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

SVG mit Javascript animieren

Javascript-Librarys für SVG gibt es in jeder Größenordnung – von SnapSVG über Velocity.js bis hin zu kleinen spezialisieren Librarys wie Vivus (Line-Animationen).

SVG wird genauso wie HTML durch das DOM (Document Object Model) beschrieben – wer HTML mit Javascript manipulieren kann, kann auch SVG mit Javascript ändern und anpassen.

SVG mit Javascript animiert
const f1 = document.getElementById('fluegel1');
f1.setAttribute('transform','translate(210,120) rotate(0)');
const f2 = document.getElementById('fluegel2');
f2.setAttribute('transform','translate(240,120) rotate(0)');

Da SVG durch das DOM dargestellt wird, erreicht Javascript die Elemente durch ihre ID. Der Slider ist ein HTML-range-Slider und bestimmt die Frequenz des Flügelschlags.

let flybird = setInterval (function () {
   let y = Math.sin(20*speed) * 10;
   f1.setAttribute('transform', 'translate(210,120) rotate(' + y + ')');
   f2.setAttribute('transform', 'translate(240,120) rotate(' + -y + ')');
   speed = speed - dyna;
},60);

SVG kann auch mit CSS animiert werden: CSS transition und CSS-Keyframes-Animationen wirken auf alle SVG-Attribute, die auch in einem style-Attribut stehen können.

Die schöne Seite der CSS-Animationen für SVG-Elemente: Die SVG-Datei kann dann mit einem HTML-img-Tag direkt eingebunden werden.

Javascript in externer SVG-Datei

Wenn SVG in einer externen SVG-Datei gespeichert wird, muss das Script in die SVG-Datei, damit Javascript Elemente ansprechen kann. Die SVG-Datei wiederum muss mit einem iframe oder object-Element in die Seite eingebunden werden, denn die Browser führen Javascript in externen SVG-Dateien nicht aus.

Die Script-Anweisungen müssen in CDATA-Tags liegen, sonst kommt es zu Kollisionen zwischen SVG und Script.

This page contains the following errors:
error on line 51 at column 9: StartTag: invalid element name
Below is a rendering of the page up to the first error.
<script>
<![CDATA[
   …
   document.querySelector('#shadow').setAttribute('transform','translate(' + x + ',' + y+ ')');
   …
]]>
</script>

Die ganz normalen Anweisungen des DOMs funktionieren mit SVG: createAttribute, setAttribute, …

Die SVG-Datei muss mit einem object- oder iframe-Tag geladen werden. Mit einem HTML img-Tag zeigen die Browser die reine SVG-Grafik an, aber führen das Script nicht aus.

<iframe src="farbraum-interaktiv.svg"></iframe>

Quelle Grafik Farbraum-Vergleich: Farbe auf Wisotop

Animierter SVG-Spinner mit iframe

Warterädchen oder Spinner als Symbol, dass die Seite auf das Laden eines Bildes wartet, sind meist kleine GIF-Animationen, also Bitmaps. Ihre Farbe und ihre Größe sind fest in Pixel eingebrannt.

SVG-Spinner hingegen sind beliebig skalierbar, responsive und sie wechseln die Farbe wie ein Chamäleon.

<svg height="100%" width="100%" viewBox="0 0 250 250">
   <g id="wheel" transform="rotate(125 125)">
      <path d="M 125,25 A 100 100 0 0 0 125,225" 
         fill="none" stroke="hsla(0,0%,50%,0.5)" stroke-width="50"/>
      <path d="M 125,75 A 25 25 0 0 0 125,175" 
         fill="hsla(0,0%,50%,0.5)" />
   </g>
</svg>

<script>
const wheel = document.querySelector("#wheel");
let angle = 0;
function animate(time){        // Animieren mit requestAnimationFrame
   angle += 2;
   wheel.setAttribute("transform", "rotate(" + angle + " 125 125)")
   requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
</script>

Damit der Schwall von SVG-Tag und Javascript nicht in den HTML-Quelltext schwappt, sitzen SVG und Script in einem iframe-Tag (geladen als img-Tag würde das Javascript nicht ausgeführt).

<iframe src="svg-spinner.html" width="100" height="100"></iframe>

SVG mit Javascript in HTML-Seiten

Javascript funktioniert selbstverständlich auch, wenn SVG in die HTML-Seite eingebettet ist und muss nicht als <![CDATA[-Sektion ausgewiesen werden. Ebensogut kann das Skript aus dem SVG-Tag herausgenommen und auch in eine externe Javascript gesteckt werden.

So weit so gut. Wenn SVG erst auf der HTML-Seite durch ein Script erzeugt wird, dann kommt der Namespace zum Einsatz.

createElementNS (namespaceURI, qualifiedName)
createAttributeNS (namespaceURI, qualifiedName)

So wird ein SVG-Element on the fly mit Javascript erzeugt:

const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute('viewBox','0 0 200 200');
svg.setAttribute('width','240');
svg.setAttribute('height','240');
const svguse = document.createElementNS("http://www.w3.org/2000/svg",'use');
svguse.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href", "#koenig");
svg.appendChild (svguse);
document.querySelector('.picto').append(svg);

und erzeugt ein SVG-Element mit einem use – eine Referenz auf ein anderes Element (einen »Klon«).

Am Rande: Wer IE11 noch mitziehen muss, nutzt appendChild() anstelle von append(elem).