最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - HTML Canvas Interval vs RequestAnimationFrame - Stack Overflow

programmeradmin1浏览0评论

So, maybe total brainfart here. The syntax for setInterval() is pretty clear. Do something every x miliseconds. How is this best translated to using the requestAnimationFrame() ?

I have about 300 objects and each is supposed to perform an animation sequence at a certain interval (every 8, 6, 2, etc seconds)? How can I best accomplish this using requestAnimationFrame() which gets called ~60 times a second? There is probably an easy answer, I just, for the life of me, can't figure it out.

So, maybe total brainfart here. The syntax for setInterval() is pretty clear. Do something every x miliseconds. How is this best translated to using the requestAnimationFrame() ?

I have about 300 objects and each is supposed to perform an animation sequence at a certain interval (every 8, 6, 2, etc seconds)? How can I best accomplish this using requestAnimationFrame() which gets called ~60 times a second? There is probably an easy answer, I just, for the life of me, can't figure it out.

Share Improve this question edited Feb 13, 2014 at 4:45 alex 490k204 gold badges889 silver badges991 bronze badges asked Aug 13, 2012 at 22:17 David M.David M. 7734 silver badges13 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 11

To force requestAnimationFrame to stick to a specific FPS you can use both at once!

var fps = 15;
function draw() {
    setTimeout(function() {
        requestAnimationFrame(draw);
        // Drawing code goes here
    }, 1000 / fps);
}

A little weird, but noth the most confusing thing in the world.

You can also use requestAnimationFrame not with FPS but with elapsed time in order to draw objects that need to be updated based on the time difference since the last call:

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
}

These two snippets are from this fine article, which contains additional details.

Good question by the way! I don't think I've seen this answered on SO either (and I'm here way too much)

requestAnimationFrame is pretty low level, it just does what you already said: roughly gets called at 60fps (assuming the browser can keep up with that pace). So typically you would need to build something on top of that, much like a game engine that has a game loop.

In my game engine, I have this (paraphased/simplified here):

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);
 }

Then each element in my game engine knows how to update themselves. In your case each element that should update every 2, 6, 8 seconds needs to keep track of how much time has passed and update accordingly:

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
     }
 }

The Canvas API along with requestAnimationFrame are rather low level, they are the building blocks for things like animation and game engines. If possible I'd try to use an existing one like cocos2d-js or whatever else is out there these days.

发布评论

评论列表(0)

  1. 暂无评论