如何使用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.requestAnimFrame
是undefined
。 当你在animloop
调用它时,javascript会产生一个错误并停止执行。 您可以通过将expression式括在括号中来解决问题。
我可以推荐Chrome开发人员工具或萤火虫来检查JavaScript执行。 有了这些工具,你会看到错误。 你应该去debugging它,如下(我假设铬):
- 执行代码(它会产生意想不到的结果)
- 打开开发者工具(右键点击 – > Inspect Element)在右边的状态栏中会看到一个红色的x(这意味着在执行过程中有错误)
- 打开控制台选项卡
- 你会看见
Uncaught TypeError:object [object DOMWindow]的属性'requestAnimFrame'不是一个函数
- input控制台:
window.requestAnimFrame
并按下回车键,你会看到它是undefined
。 现在你知道这个问题实际上与requestAnimationFrame
无关,你应该把精力集中在你的代码的第一部分。 - 现在是把代码缩小到它返回的地步。 这是一个困难的部分,如果你现在还没有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); };