What’s the best way to use requestAnimationFrame and fixed frame rates

I recently got into using the HTML5-requestAnimationFrame-API a lot on animation-heavy websites, especially after seeing the Jank Busters talk. This seems to work pretty well and really improve performance in many cases.

Yet one question still persists for me: When wanting to use an animation that is NOT entirely calculated (think spritesheets for example) you will have to aim for a fixed frame rate. Of course one could go back to use setInterval again, but maybe there are other ways to tackle this.

The two ways I could think of using requestAnimationFrame with a fixed frame rate are:

var fps = 25; //frames per second

function animate(){

   //actual drawing goes here
   setTimeout(function(){
      requestAnimationFrame(animate);
   }, 1000 / fps)

}

animate();

or

var fps = 25; //frames per second

var lastExecution = new Date().getTime();

function animate(){

    var now = new Date().getTime();

    if ((now - lastExecution) > (1000 / fps)){
        //do actual drawing
        lastExecution = new Date().getTime();
    }

    requestAnimationFrame(animate);

}

animate();

Personally, I’d opt for the second option (the first one feels like cheating), yet it seems to be more buggy in certain situations.

Is this approach really worth it (especially at low frame rates like 12.5)? Are there things to be improved? Is there another way to tackle this?

1

Your animation should be calculated even if that calculation is entirely a function of time. And at any given time you should be able to draw() an [animated] image and know that you’re getting the right frame. You want something like this, but not necessarily this:

// whatever your "attributes" looks like, the point is you've given enough
// information to the constructor to find ordered frames in the image and know
// the framerate
function SpriteAnimation(image, attributes) {

  // you probably want a SpriteFrame "class" to populate here, based on whatever
  // existing code you use to extract frames from the sprite
  this.frames = [ SpriteFrame, SpriteFrame, ... ];
                         // ... getFramesFromImageAndAttributes(image, attributes)

  // if the animation is running, this is the time it started
  this.startTime = 0;

  // whatever your framerate is ... 
  this.fps = 25;         // getFPSFromAttributes(frame_attributes)

  // whether the animation loops infinitely
  this.loop = true;      // getLoopFlagFromAttributes(frame_attributes)

  // for canceling the animationframe request, if necessary
  this.animationFrameRequestId = null;

  // draw whichever frame should be visible *right now*
  this.draw = function() {

    // unconditionally show the first frame if the animation isn't running
    if (this.startTime == 0) {
      this.frames[0].draw();
      return;
    }

    // there may be a better and more accurate way to compute this ...
    var frame_duration = 1000 / this.fps;
    var now = (new Date()).getTime();
    var elapsed_time = now - this.startTime;
    var visible_frame = Math.floor(elapsed_time / frame_duration);

    if (visible_frame_number > frames.length) {
      if (!this.loop) {
        // we're past the end of the animation and we're not looping.
        // stop the animation.
        this.startTime = 0;
        visible_frame = 0;
      }
    }

    this.frames[visible_frame % frames.length].draw();

    if (this.startTime != 0) {
      var _t = this;
      requestAnimationFrame(_t.draw);
    }

  }

  this.animate = function() {
    this.startTime = (new Date()).getTime();
    var _t = this;
    requestAnimationFrame(_t.draw);
  }

  this.stop = function() {
    this.startTime = 0;
    if (this.animationFrameRequestId) {
      cancelAnimationFrame(this.animationFrameRequestId);
    }
  }

}

var a = new SpriteAnimation("/path/to/image.jpeg", {
  fps: 25,
  frame_width: 100,
  frame_height: 100,
  image_width: 1000,
  image_height: 10000
});
a.animate();

… Or whatever.

0

For seamless animations, even sprite based use the second option, with Date.now(). Dont forget about

Return value

requestID is a long integer value that uniquely identifies the entry
in the callback list. This is a non-zero value, but you may not make
any other assumptions about its value. You can pass this value to
window.cancelAnimationFrame() to cancel the refresh callback request.

(from MDN )

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật