Javascript Animationen: setTimeout() / setInterval()

Die klassischen Javascript-Animationen werden mit setTimeout(), setInterval() oder requestAnimationFrame – mit Timern – in Gang gesetzt. Javascript Timer sind keine Events, aber fühlen sich wie Events an.

Animieren mit setTimeout: laufende Monster

Animations-Methoden in Javascript

Animationen können zum Verständnis der Benutzeroberfläche beitragen – z.B. durch das Verlangsamen der Reaktion auf Benutzeraktionen. Sie erzeugen einen Countdown oder bieten einfach Unterhaltung …

Für Animationen werden meist Libraries oder ganzen Frameworks eingesetzt, aber die Grundlagen von Animationen mit Javascript sind die Voraussetzung für das Verständnis der verzwickten Logik hinter Bewegungsabläufen und Reaktionen.

Javascript stellt drei Klassiker und eine modernere Technik für Animationen:

  1. setTimeout ()
  2. setInterval () wiederholt Anweisungen in einem Interval.
  3. Beim requestAnimationFrame () übernimmt der Browser die Schnittstelle und optimiert das Verfahren.
  4. Javascript Web Animation API ist die jüngste Option und lehnt sich eng an CSS-Animationen an.

Die Grundidee der Animation mit Javascript: Mach ein Element Bild für Bild in schneller Folge sichtbar oder unsichtbar, bewege es oder verändere sein Aussehen nach und nach. Dabei entsteht eine Sequenz von Einzelbildern oder Frames, die schnell genug aufeinander folgen, dass die Bewegung fließend und natürlich wirkt.

Ein Lemming läuft

Lemmings, das Computerspiel des Entwicklers DMA Design (1991)

setTimeout

Javascript window.setTimeout(action, timeout) gibt an, dass Anweisungen nach einer bestimmten Zeit timeout (angegeben in Millisekunden) ausgeführt werden.

     Zeit in Millisekunden bis  ──┐
     zum Aufruf der Anweisungen   │
                                  │
        Anweisung oder  ──┐       │
        Callback-Funktion │       │ 
                          ▼       ▼
let ani = setTimeout ( action, timeout );
     ▲
     |
     └--- optionale Referenz, mit der
          setTimeout abgebrochen werden kann

Javascript setTimeout() führt die Anweisungen exakt einmal aus (und der Timer ist nicht besonders exakt) und dann nie wieder.

clearTimeout()

Um die Anweisung wiederholt durchzuführen, muss das Skript wiederholt aufgerufen werden – z.B. rekursiv wie im Beispiel oder in einer Schleife.

Die Funktion setTimeout() gibt einen einfachen Wert zurück – einen Verweis auf den Timeout. Die Referenz auf setTimeout() wird benötigt, um den Timeout abzubrechen und die Ausführung der Anweisungen zu unterbinden.

Javascript clearTimeout() cancelt den Aufruf von setTimeout().

window.clearTimeout(ani);

setTimeout() wird eher selten für Animationen benutzt, sondern für einfache verzögerte Aktionen, da setTimeout() die Aktion nur einmal durchführt. Statt selber Schleifen oder rekursive Funktionen einzusetzen, greift man heute bei Animationen mit schrittweisen Änderungen bevorzugt zu requestAnimationFrame.

setTimeout ist »synchron«

Javascript arbeitet Anweisung für Anweisung ab wie die Knoten in einem Faden. Erst wenn eine Anweisung / Funktion beendet ist, kommt die nächste zum Zuge. Aber Javascript ist auch eine synchrone Programmiersprache: Funktionen wie setTimeout laufen quasi parallel

Synchron bedeutet, dass die Funktion sozusagen parallel zu den folgenden Anweisungen durchgeführt wird – die auf setTimeout folgenden Anweisungen also nicht blockiert.

Das Skript stopt nicht, um die Ausführung der Funktion abzuwarten, sondern läuft weiter. Das Skript wird Anweisung für Anweisung weiter abgearbeitet, während der Timer noch schläft und auf sein vorprogrammiertes Erwachen wartet.

const startCount = document.querySelector (".startCount");
const counter = document.querySelector (".count");

startCount.addEventListener ("click", function () {
	setTimeout (function () {
		const t = new Date ();
		console.log ("setTimeout", `${t.getHours()}:${t.getMinutes()}:${t.getSeconds()}`);
		counter.innerHTML = "5";
	}, 5000);
	counter.innerHTML = "1";
	const t = new Date ();
	console.log ("Zähler gestartet", `${t.getHours()}:${t.getMinutes()}:${t.getSeconds()}`);
});

In der Konsole wird deutlich, dass setTimeout die Ausführung nicht blockiert: Die Ausgabe »Global Scope« erscheint sofort.


Clicked Scope – "5:12:14"
setTimeout – "5:12:19"

setTimeout mit Parametern

Wenn die aufgerufene Funktion selber Parameter hat, könnten die Parameter auch in setTimeout übergeben werden. Diese Möglichkeit gab es immer schon, aber sie wurde nie von Internet Explorer unterstützt und geriet in Vergessenheit.

<div class="counterbox">
	<div class="circle">6</div>
	<button id="countStart">Start Countdown</button>
	<button id="countCancel">Cancel</button>
</div>
6
const countStart = document.querySelector ("#countStart");
const countCancel = document.querySelector ("#countCancel");

const circle = document.querySelector (".circle");

function countdown (time,hue) {
	time -= 1;
	hue += 60;

	circle.textContent = time;
	circle.setAttribute ("style", 
	    `border-color: hsl(${hue},85%,60%); 
	     color: hsl(${hue},85%,60%)`);
	let timer;
	if (time > 0) {
		timer = setTimeout( countdown, 1000, time, hue);
		
		countCancel.addEventListener ("click", 
		   function () { clearTimeout (timer) })
	}
}
   
countStart.addEventListener ("click", 
    function ( time, hue) { countdown(6, 30);
});

Anweisungen mit Verzögerung ausführen

Es gibt Situationen, in denen Anweisungen oder Funktionen erst nach einer Verzögerung ausgeführt werden sollen. Mit async await kann setTimeout als echte Verzögerung verwendet werden.

async function delay() {
   await setTimeout(5000);
   console.log("Ich warte 5 Sekunden");
}

delay();

console.log("Wartet nicht");

Der Aufruf await setTimeout() wirkt logisch und kann so verwendet werden, wie man es erwartet: Die folgende Anweisung wird erst nach Ablauf von 5 Sekunden ausgeführt.

Easing: natürliche Bewegungsabläufe

Easing hat Animationen mit Flash so elegant gemacht, Animationen mit jQuery liefern Easing, CSS beherrscht Easing mit transition und keyframes. Javascript musst all die Jahre ohne Easing auskommen, aber die meisten Javascript-Animationen verändern CSS-Eigenschaften – CSS transition und Keyframe-Animationen bringen Easing-Optionen mit.

Erst das Web Animation Api setzt Easing für natürliche Bewegungsabläufe ein: Easing – Beschleunigen und langsames Auslaufen von Bewegungen.

CSS transition statt Javascript

Die Kombination aus CSS3 transition, Keyframe-Animationen und Javascript vereinfacht heute Animationen und macht komplexe Abläufe möglich. Neue Javascript Methoden wie classList triggern 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.

Suchen auf mediaevent.de