CSS, HTML und Javascript mit {stil}

Javascript Animationen mit requestAnimationFrame

requestAnimationFrame

Mit requestAnimationFrame anstelle von setInterval oder setTimeout für Animationen übernimmt der Browser die Schnittstelle und optimiert das Verfahren, so dass Animationen weicher ablaufen.

Wenn der Benutzer zu einem anderen Tab wechselt, kann der Browser die Animation pausieren, um die CPU weniger zu belasten. Schön für unsere mobilen Geräte …

Für Animationen mit Javascript wird setInterval() noch einige Zeit die sicherste Methode sein. Zwar unterstützen die modernen Browser requestAnimationFrame, aber IE ist erst ab Version 10 dabei.

setInterval() erwartet zwei Parameter oder Argumente: die Funktion, die bei jedem Animationsschritt aufgerufen wird, und das Zeitinterval, in dem die Funktion für die Animation aufgerufen wird.

Aber setInterval() ist ineffizient. Wenn der Benutzer ein anderes Tab im Browser öffnet, läuft die Animation weiter. requestAnimationFrame ist effizienter.

12 1 2 3 4 5 6 7 8 9 10 11 00 13 14 15 16 17 18 19 20 21 22 23 5 10 15 20 25 30 35 40 45 50 55 60 CORPS OF ENGINEERS CALLBACK CALLBACK

Timing control for script-based animations

Frame-Rate

Bei Animationen mit setTimeout oder setInterval kann das Script die aktuelle Frequenz der Frames nicht feststellen. requestAnimationFrame wird per Vorgabe 60 mal pro Sekunde aufgerufen – mehr ist selten nötig (oder besser: möglich), denn 60 Hz ist die Refresh-Rate der meisten Browser (oder Zeitrahmen von 16.7ms).

In Animationen mit requestAnimationFrame kann die Browser die Refresh-Rate reduzieren, wenn die Animation in einem Hintergrund-Tab läuft, um den Energieaufwand zu senken.

requestAnimationFrame agiert anders als setInterval. Statt einen Timeout mit einer Verzögerung von 16.7ms in einer Schleife immer wieder aufzurufen, feuern die Browser ein Event, sobald das System wieder einen Frame rendern kann.

Die Syntax von requestAnimationFrame() gleich mehr der Syntax von setTimeout(), da requestAnimationFrame wiederholt aufgerufen wird. Nur ein Timeout oder Interval wird nicht benötigt.

window.requestAnimationFrame(callbackFunction);
var iterationCount = 0;
var repeater;

function runlock () {
   easing = easeInQuad(iterationCount, 0, width, 300);
   lok.setAttribute ('style','left: ' + easing + 'px');
   iterationCount++;

   if (iterationCount > 250) {
      cancelAnimationFrame(repeater);
   } else {
      repeater = requestAnimationFrame(runlock);
   }
}

runlock();

Die Lok läuft langsam an und wird schneller: Easing für Javascript Animationen – Robert Penners Original-Gleichungen, von Kipura für Javascript portiert.

requestAnimationFrame mit Parametern

requestAnimationFrame wird mit einer callbackFunction aufgerufen. Wenn Parameter übergeben werden, kann die callbackFunction auch eine anonyme Funktion sein, die wiederum die benötigten Parameter enthält.

function moveCurtain (curt, height) {
    easing = easeInOutQuart(step, height, -300, 90);
    step++;

    if (easing < 1) {
        cancelAnimationFrame (repeater);
        step = 0;
    } else {
        curt.setAttribute('height',easing);
        repeater = requestAnimationFrame (function () {
            moveCurtain (curt, easing);
        });
    }
}

requestAnimationFrame mit Browser-Präfix

IE9 ist der letzte Microsoft-Browser, der requestAnimationFrame nicht unterstützt. Am 12.1.2016 hat Microsoft den Support für IE9 für die meisten Betriebssysteme eingestellt.

IE10, Safari ab Version 9, Chrome ab V45, Firefox ab 43, Opera ab 34 unterstützen requestAnimationFrame bereits.

Trotzdem wird es für viele Anwendungen sicherer sein, den Browser-Präfix oder das Polyfill von Paul Irisch zu benutzen.

if (window.requestAnimationFrame) window.requestAnimationFrame(func);
    else if (window.msRequestAnimationFrame) 
        window.msRequestAnimationFrame(func);
    else if (window.mozRequestAnimationFrame)
        window.mozRequestAnimationFrame(func);
    else if (window.webkitRequestAnimationFrame) 
        window.webkitRequestAnimationFrame(func);