Dav*_* M. 15 javascript canvas html5-canvas
所以,也许在这里总脑筋.语法setInterval()很清楚.每隔x毫秒做一些事情.如何最好地转换为使用requestAnimationFrame()?
我有大约300个对象,每个对象应该以一定的间隔(每8,6,2等秒)执行动画序列?我怎样才能最好地完成这个使用requestAnimationFrame()被称为每秒60次?可能有一个简单的答案,我只是,因为我的生活,无法弄明白.
Sim*_*ris 11
要强制requestAnimationFrame粘贴到特定的FPS,您可以同时使用它们!
var fps = 15;
function draw() {
setTimeout(function() {
requestAnimationFrame(draw);
// Drawing code goes here
}, 1000 / fps);
}
Run Code Online (Sandbox Code Playgroud)
有点奇怪,但不是世界上最混乱的事情.
您也可以使用requestAnimationFrame而不是FPS,但是使用已用时间来绘制需要根据自上次调用后的时间差更新的对象:
var time;
function draw() {
requestAnimationFrame(draw);
var now = new Date().getTime(),
dt = now - (time || now);
time = now;
// Drawing code goes here... for example updating an 'x' position:
this.x += 10 * dt; // Increase 'x' by 10 units per millisecond
}
Run Code Online (Sandbox Code Playgroud)
这两个片段来自这篇精美的文章,其中包含其他细节.
顺便说一句好问题!我不认为我已经看到过这个回答了(我在这里太过分了)
Mat*_*eer 10
requestAnimationFrame是非常低级别,它只是做你已经说过的:大致以60fps调用(假设浏览器可以跟上这个速度).所以通常你需要在那之上构建一些东西,就像一个有游戏循环的游戏引擎.
在我的游戏引擎中,我有这个(paraphased /简化):
window.requestAnimationFrame(this._doFrame);
...
_doFrame: function(timestamp) {
var delta = timestamp - (this._lastTimestamp || timestamp);
for(var i = 0, len = this.elements.length; i < len; ++i) {
this.elements[i].update(delta);
}
this._lastTimestamp = timestamp;
// I used underscore.js's 'bindAll' to make _doFrame always
// get called against my game engine object
window.requestAnimationFrame(this._doFrame);
}
Run Code Online (Sandbox Code Playgroud)
然后我的游戏引擎中的每个元素都知道如何更新自己.在您的情况下,每2,6,8秒应更新一次的每个元素需要跟踪已经过了多少时间并相应地更新:
update: function(delta) {
this.elapsed += delta;
// has 8 seconds passed?
if(this.elapsed >= 8000) {
this.elapsed -= 8000; // reset the elapsed counter
this.doMyUpdate(); // whatever it should be
}
}
Run Code Online (Sandbox Code Playgroud)
Canvas API和requestAnimationFrame它们的级别相当低,它们是动画和游戏引擎之类的构建块.如果可能的话,我会尝试使用像cocos2d-js这样的现有产品或者其他任何产品.