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.
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.
<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).