如何使用requestAnimationFrame?

我是新来的animation,但我最近使用setTimeout创build了一个animation。 FPS太低,所以我find了一个解决scheme,使用requestAnimationFrame ,在这个链接中描述。

到目前为止,我的代码是:

 //shim layer with setTimeout fallback window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(/* function */ callback){ window.setTimeout(callback, 1000 / 60); }; })(); (function animloop(){ //Get metrics var leftCurveEndX = finalLeft - initialLeft; var leftCurveEndY = finalTop + finalHeight - initialTop; var rightCurveEndX = finalLeft + finalWidth - initialLeft - initialWidth; var rightCurveEndY = leftCurveEndY; chopElement(0, 0, 0, 0, leftCurveEndX, leftCurveEndY, rightCurveEndX, rightCurveEndY);//Creates a new frame requestAnimFrame(animloop); })(); 

这在第一帧停止。 我有一个callback函数requestAnimFrame(animloop);chopElement函数中。

另外,有没有更彻底的使用这个API的指导?

警告! 这个问题不是关于填充 requestAnimFrame 的最佳方法 如果您正在寻找,请转到此页面上的任何其他答案。


你被自动分号插入欺骗了。 尝试这个:

 window.requestAnimFrame = function(){ return ( window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(/* function */ callback){ window.setTimeout(callback, 1000 / 60); } ); }(); 

javascript会自动在你的return语句后面加一个分号。 它这样做是因为它后面跟着一个换行符,下一行是一个有效的expression式。 事实上,它被翻译成:

 return; window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(/* function */ callback){ window.setTimeout(callback, 1000 / 60); }; 

此代码返回undefined ,从不执行返回语句后面的代码。 所以window.requestAnimFrameundefined 。 当你在animloop调用它时,javascript会产生一个错误并停止执行。 您可以通过将expression式括在括号中来解决问题。

我可以推荐Chrome开发人员工具或萤火虫来检查JavaScript执行。 有了这些工具,你会看到错误。 你应该去debugging它,如下(我假设铬):

  1. 执行代码(它会产生意想不到的结果)
  2. 打开开发者工具(右键点击 – > Inspect Element)在右边的状态栏中会看到一个红色的x(这意味着在执行过程中有错误)
  3. 打开控制台选项卡
  4. 你会看见

    Uncaught TypeError:object [object DOMWindow]的属性'requestAnimFrame'不是一个函数

  5. input控制台: window.requestAnimFrame并按下回车键,你会看到它是undefined 。 现在你知道这个问题实际上与requestAnimationFrame无关,你应该把精力集中在你的代码的第一部分。
  6. 现在是把代码缩小到它返回的地步。 这是一个困难的部分,如果你现在还没有find它,你可能想转向互联网寻求更多的帮助。

另外,看这个video的一些好的做法,在写javascript,他也提​​到了邪恶的自动分号插入。

  /* Provides requestAnimationFrame in a cross browser way. http://paulirish.com/2011/requestanimationframe-for-smart-animating/ */ if (!window.requestAnimationFrame) { window.requestAnimationFrame = (function() { return window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || // comment out if FF4 is slow (it caps framerate at ~30fps: https://bugzilla.mozilla.org/show_bug.cgi?id=630127) window.oRequestAnimationFrame || window.msRequestAnimationFrame || function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element) { window.setTimeout(callback, 1000 / 60); }; })(); } animate(); function animate() { requestAnimationFrame(animate); draw(); } function draw() { // Put your code here } 

看看下面的jsfiddle示例; 它清楚地说明了我的意思;

http://jsfiddle.net/XQpzU/4358/light/

希望这可以帮助!

使用智能调节,使事件不会被触发多次,屏幕可以重新绘制变化:

 var requestFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || // throttle fall-back for unsupported browsers (function(){ var throttle = false, FPS = 60 / 1000; // time in ms return function(CB) { if( throttle ) return; throttle = true; setTimeout(function(){ throttle = false; }, FPS); CB(); // do your thing } })(); // use case: function doSomething(){ console.log('fired'); } window.onscroll = function(){ requestFrame(doSomething); };