我是动画新手,但我最近使用setTimeout
创建了一个动画。 FPS太低了,所以我找到了一个使用requestAnimationFrame
的解决方案,如link中所述。
到目前为止,我的代码是:
//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);
})();
在第一帧期间停止。我在requestAnimFrame(animloop);
函数中有一个回调函数chopElement
。
此外,是否有更全面的指南来使用此API?
答案 0 :(得分:78)
警告!这个问题与填补 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
语句后面添加分号。这样做是因为它后跟换行符,下一行是有效的表达式。事实上它被翻译成:
return;
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function */ callback){
window.setTimeout(callback, 1000 / 60);
};
此代码返回undefined
并且从不执行return语句后面的代码。因此window.requestAnimFrame
是undefined
。当您在animloop
中调用它时,javascript会产生错误并停止执行。您可以通过将表达式括在括号中来解决问题。
我可以推荐Chrome开发者工具或firebug来检查javascript执行情况。使用这些工具,您会看到错误。您应该按照以下方式调试它(我假设Chrome):
未捕获的TypeError:对象[对象DOMWindow]的属性'requestAnimFrame'不是函数
window.requestAnimFrame
并按回车键,您会看到它是undefined
。到目前为止,您知道问题实际上与requestAnimationFrame
无关,您应该专注于代码的第一部分。另外,请注意this video编写javascript时的一些好习惯,他还提到了邪恶的自动分号插入。
答案 1 :(得分:8)
/*
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/
希望这有帮助!
答案 2 :(得分:0)
“智能限制,因此事件不会被触发的次数超过屏幕重绘更改的次数:
var requestFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
// polyfill - throttle fall-back for unsupported browsers
(function() {
var throttle = false,
FPS = 1000 / 60; // 60fps (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);
};
html, body{ height:300%; }
body::before{ content:'scroll here'; position:fixed; font:2em Arial; }