2012-11-05 12 views
6

http://updates.html5rocks.com/2012/05/requestAnimationFrame-API-now-with-sub-millisecond-precision erzählt mir, dass vor kurzem (Chrome 20) requestAnimationFrame eine neue unter-Millisekunde Präzisions-Timer gewonnen hat, und dass ich meinen Code aktualisieren muss, um es zu unterstützen.Aktuelle Polyfill für AnfrageAnimationFrame

Wenn man sich die verschiedenen Polyfüllungen anschaut, scheinen sie alle dieses Update vorwegzunehmen. Sind sie irgendwie funktional (ich glaube nicht), oder gibt es einfach kein aktuelles? Sollte ich nur das Timing selbst machen (scheint ein wenig verschwenderisch).

+0

Ich glaube nicht, dass es möglich ist, einen Sub-Millisekunden-Timer ohne die neuen APIs zu bekommen. – Bergi

+0

Wir planen, diese Änderung in Chrome 21 auszuweiten, also wenn Sie diesen Callback-Parameter bereits nutzen sicher, deinen Code zu aktualisieren! - Nicht Chrome 20, Sie haben noch Zeit. – nycynik

Antwort

2

Die Änderung für die Hi-Res-Zeit beeinflusst nur den Parameter für den Rückruf. Ich glaube nicht, dass Polyfills explizit auf den Parameter verweisen, es hängt nur davon ab, wie Sie es verwenden. Die Polyfills müssen also nicht aktualisiert werden und sollten schon gut funktionieren - seien Sie vorsichtig, wie Sie den Parameter für den RAF-Callback verwenden, und wenn nicht, müssen Sie sich keine Sorgen machen!

+0

Während die Polyfills gut funktionieren, wenn ich den Parameter ignoriere, würde ich es lieber verwenden, wo sonst, warum also den neuen Parameter einführen? –

-2

Paul Irish hat eine Polyfill dafür vorgeschlagen.

window.requestAminFrame = (function(){ 
    return window.requestAminFrame || window.webkitRequestAnimFrame || window.mozRequestAnimFrame || window.msRequestAnimFrame || window.oRequestAnimFrame || function(func){return setTimeout(func,1/60);}; 
})(); 
+0

Es gibt kein 'window.requestAminFrame'. Es ist 'window.requestAnimationFrame' – cpburnz

1

das könnte funktionieren. diesem GIST

modifizierte

https://gist.github.com/1579671

(function() { 
    var lastTime = 0; 
    var startTime = Date().getTime(); 
    var vendors = ['ms', 'moz', 'webkit', 'o']; 
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 
     window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; 
     window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] 
            || window[vendors[x]+'CancelRequestAnimationFrame']; 
    } 

    if (!window.requestAnimationFrame) 
     window.requestAnimationFrame = function(callback, element) { 
      var currTime = new Date().getTime(); 
      var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 
      var id = window.setTimeout(function() { callback(currTime - startTime); }, 
       timeToCall); 
      lastTime = currTime + timeToCall; 
      return id; 
     }; 

    if (!window.cancelAnimationFrame) 
     window.cancelAnimationFrame = function(id) { 
      clearTimeout(id); 
     }; 
}()); 

den Zeitstempel erhalten, wenn der Verschluss führt zuerst (Seite Last), dann in den Rückruf zwischen dem aktuellen Zeitstempel und den ursprünglichen, den Unterschied bestehen. Sollte Ihnen ein ganzzahliges Äquivalent der neuen Methode geben. Nicht so präzise, ​​aber besser als ein ganz anderer Wert.

+0

Danke dafür. Leider habe ich nicht die Möglichkeit, dies im Moment sorgfältig zu testen, aber das sieht gut aus! –

3

Ich hatte gerade diesen Artikel gelesen und war neugierig, das selbst zu versuchen. In Browsern, die keine hochauflösenden Timer unterstützen, habe ich versucht, einen Wrapper zum rAF-Callback hinzuzufügen. Es nutzt Paul Irish ursprünglichen polyfill mit den folgenden hinzugefügten Zeilen:

var hasPerformance = !!(window.performance && window.performance.now); 

// Add new wrapper for browsers that don't have performance 
if (!hasPerformance) { 
    // Store reference to existing rAF and initial startTime 
    var rAF = window.requestAnimationFrame, 
     startTime = +new Date; 

    // Override window rAF to include wrapped callback 
    window.requestAnimationFrame = function (callback, element) { 
     // Wrap the given callback to pass in performance timestamp 
     var wrapped = function (timestamp) { 
      // Get performance-style timestamp 
      var performanceTimestamp = (timestamp < 1e12) 
       ? timestamp 
       : timestamp - startTime; 

      return callback(performanceTimestamp); 
     }; 

     // Call original rAF with wrapped callback 
     rAF(wrapped, element); 
    }   
} 

Hier ist ein Kern des Ganzen miteinander kombiniert und ein aktualisiertes Beispiel mit dem neuen Code:

https://gist.github.com/4078614

http://jsfiddle.net/timhall/XQpzU/4351/

Dieser Ansatz zielt darauf ab, den Parameter, der an die Callback-Funktion übergeben wird, an das hochauflösende Zeitgeberformat zu normalisieren. Sie könnten einen ähnlichen Ansatz verwenden, genau umgekehrt, um den hochauflösenden Timer in das alte Format zu konvertieren, wenn Sie bereits Code erwarten, aber ich sehe das als eine Regression.

Ich werde es in einem meiner Projekte ausprobieren, an denen ich gerade arbeite, und werde das Wesentliche aktualisieren, wenn ich irgendwelche Probleme/Verbesserungen finde.