我正在跟随this书来了解html5画布动画,我想知道,在这段代码中:
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var x = 0;
function drawIt() {
window.requestAnimFrame(drawIt);
var canvas = document.getElementById('canvas');
var c = canvas.getContext('2d');
c.fillStyle = "red";
c.fillRect(x,100,200,100);
x+=5;
}
window.requestAnimFrame(drawIt);
为什么要在drawIt函数的外部和内部调用window.requestAnimFrame(drawIt)
?
答案 0 :(得分:0)
详细说明大多数已在评论中说明的内容(附加一些提示) -
requestAnimationFrame
对作为参数传入的函数进行单个异步调用。这意味着需要连续调用该方法来创建动画循环。
调用更新下一帧的调用的逻辑位置来自循环本身。但是,循环只是一个函数,也需要调用,因此需要初始调用以启动"循环。 (因此,考虑一种破坏循环的机制也是明智的。)
另一种技术可能是使用自我调用的调用。在这种情况下,代码看起来就像这样,没有初始调用:
(function drawIt() {
window.requestAnimFrame(drawIt);
var canvas = document.getElementById('canvas');
var c = canvas.getContext('2d');
c.fillStyle = "red";
c.fillRect(x,100,200,100);
x+=5;
})();
评估第一对括号内的函数,而第二对将调用任何被评估的函数,即。功能。如果你选择了这个,或者原件或多或少是个人品味的问题(第一帧不会更新,直到第一个下一个可用的显示器刷新,所以你不会在第一次做手动更新时有任何故障)。
另一件值得注意的事情是:获取对canvas和context的引用通常永远不会在 inside 循环中完成,因为它们是相对昂贵的操作。尝试始终获取循环外的那些,只有一次:
var canvas = document.getElementById('canvas');
var c = canvas.getContext('2d');
(function drawIt() {
window.requestAnimFrame(drawIt);
c.fillStyle = "red"; // also a potential candidate for optimizing
c.fillRect(x,100,200,100);
x+=5;
})();
如果您只设置一次颜色,也可以将其移动到循环外(即。fillStyle
,strokeStyle
等)。这些在动画方面也很昂贵。