setInterval vs setTimeout
Während setTimeout (action,timeout) Anweisungen nach einer Verzögerung von timeout Millisekunden einmal ausführt, wiederholt Javascript Anweisungen mit setInterval ( action, i) in einem Intervall von i Millisekunden.
Für eine fließende Animation wie der Farbroller muss setTimeout rekursiv ausgeführt werden, aber dann gibt es immer noch einen kleinen Unterschied:
- setInterval führt die Anweisungen sofort und dann alle 1000 / 2000 … Millisekunden durch
- setTimeout wartet 1000 / 2000 … Millisekunden, führt die Funktion aus (und braucht dafür ein paar Millisekunden) und wartet dann auf den nächsten Timeout. Die Zeitspanne zwischen zwei Frames ist also einen Tick größer als 1000 / 2000 … Millisekunden.
+-- Referenz für den Aufruf von cancelInterval | | Verzögerung / Delay --+ | | var ref = window.setInterval( animate, 1000); | +-- callback function animate() { // Anweisungen der Animation }
setInterval mit closures
Alternativ kann setInterval ( action , delay) mit einer anonymen Funktion aufgerufen werden. Das hält den Scriptcode besser zusammen als var interval = window.setInterval (code, delay) und ersetzt auch eine externe Funktion.
const timerId = setInterval ( function tick() { let counter = parseInt(document.getElementById("counter").textContent); if (counter < 1) { clearInterval(timerId) } else document.getElementById("counter").textContent = counter - 1; }, 1000);
clearInterval
clearInterval(action,interval) regelt oder cancelt eine Funktion, die wiederholt mit einer Verzögerung aufgeweckt wird.
setInterval mit Parametern
Wenn die aufgerufene Funktion selber Parameter hat, könnten die Parameter auch in setInterval übergeben werden.
const monsters = document.querySelectorAll ('.monster'); let numMonsters = monsters.length; let left = [0, -40, -80]; function moveMonster (obj,j) { let repeater = setInterval (function () { j += 1; obj.setAttribute ('style','left: ' + j + 'px'); if (j>width) { clearInterval(repeater); obj.setAttribute ('style','left: 0px'); } },10); } for (let i=0; i<numMonsters; i++) { moveMonster (monsters[i], left[i]); }
Die Funktion könnte mitsamt Parametern in Hochkommas an setInterval übergeben werden. Dann wird die Funktion – auf gleiche Weise wie eine einzelne Anweisung – evaluiert.
let reference = setInterval("slideshow(opt1,opt2)",500);
Das gilt als ausgesprochen unschicklich und unsicher (genauso wie eval).
CSS transition statt Javascript
Heute vereinfacht die Kombination aus CSS3 transition, CSS Keyframe-Animationen und Javascript Animationen und macht komplexe Abläufe möglich. Javascript classList triggert Aktionen, denn CSS hat nur wenige Events, die eine Animation auslösen.
Der Ruf, dass reine CSS Animationen und Transformationen performanter als Javascript wären, rührt aus jQuery-Animationen: jQuery war nicht für Animationen gedacht.
Easing
Erst Easing – Beschleunigen und langsames Auslaufen von Bewegungen kommt ein natürlicher Bewegungsablauf zustande. Easing hat Animationen mit Flash so elegant gemacht, Animationen mit jQuery liefern Easing ebenfalls mit und CSS macht es mit transition und keyframes. Aber in Javascript fehlte Easing, bevor das Web Animation Api die Bühne betrat.
Wenn Easing-Funktionen wie easeIn, easeInOut oder easeInOutQuart nicht via CSS oder jQuery eingebracht werden, gibt es eine Portierung des Urvaters der Easing-Funktionen (Robert Penner) von Kirupa Chinnathambi.
easeIn(currentIteration, begin, change, duration);
change = finish - begin
Javascript Animation API
Erst das Web Animation API bringt die Animation von DOM-Elementen mit Timing / Easing und entwickelt sich zu einem leistungsstarken Konzept für Animation. Das Web Animation API verschiebt CSS-Animation direkt ins Javascript und eröffnet sich Webdesignern mit CSS-Erfahrung im Handumdrehen.
Starten mit Mausklick oder Tap auf dem mobilen Gerät
const blueTurtle = document.getElementById("turtle"); let maxWidth = blueTurtle.closest (".water").getBoundingClientRect().width; const turtleSwimKeyframes = new KeyframeEffect( blueTurtle, [ { transform: "translateX(0)" }, { transform: "translateX(" + maxWidth + "px)" } ], { duration: 15000, fill: "forwards", easing: "ease" } ); var turtleCrossing = new Animation(turtleSwimKeyframes, document.timeline); // Bei mousedown und touchStart blueTurtle.addEventListener("mousedown", turtleGo, false); blueTurtle.addEventListener("touchstart", turtleGo, false); function turtleGo(event) { blueTurtle.removeEventListener("mousedown", turtleGo, false); blueTurtle.removeEventListener("touchstart", turtleGo, false); turtleCrossing.play(); }