JS:指定FPS帧频,requestAnimationFrame播放动画

Flash制作动画,最基础的概念就是帧,但在Flash中,帧频的控制比较简单,只需要编译前指定一下目标帧频就可以了。

实际运行时,不需要我们关心定时器的问题,flash player会定时触发EnterFrame消息,推动Movieclip播放。

在js这一侧,需要我们设定一个定时器,并推动相应的绘制逻辑执行。

最简单:

var FPS = 60;

setInterval(draw, 1000/FPS);

这个简单做法,如果draw带有大量逻辑计算,导致计算时间超过帧等待时间时,将会出现丢帧。除外,如果FPS太高,超过了当时浏览器的重绘频率,将会造成计算浪费,例如浏览器实际才重绘2帧,但却计算了3帧,那么有1帧的计算就浪费了。

成熟做法:

引入requestAnimationFrame,这个方法是用来在页面重绘之前,通知浏览器调用一个指定的函数,以满足开发者操作动画的需求。

这个函数类似setTimeout,只调用一次。

function draw() {
        requestAnimationFrame(draw);
        // ... Code for Drawing the Frame ...
}

递归调用,就可以实现定时器。

但是,这样完全跟浏览器帧频同步了,无法自定义动画的帧频,是无法满足需求的。

接下来需要考虑如何控制帧频。

简单做法:

var fps = 30;
function tick() {
  setTimeout(function() {
    requestAnimationFrame(draw);
    draw(); // ... Code for Drawing the Frame ...
  }, 1000 / fps);
}
tick();

这种做法,比较直观的可以发现,每一次setTimeout执行的时候,都还要再等到下一个requestAnimationFrame事件到达,累积下去会造成动画变慢。

自行控制时间跨度:

var fps = 30;
var now;
var then = Date.now();
var interval = 1000/fps;
var delta;

function tick() {
  requestAnimationFrame(draw);
  now = Date.now();
  delta = now - then;
  if (delta > interval) {
    // 这里不能简单then=now,否则还会出现上边简单做法的细微时间差问题。例如fps=10,每帧100ms,而现在每16ms(60fps)执行一次draw。16*7=112>100,需要7次才实际绘制一次。这个情况下,实际10帧需要112*10=1120ms>1000ms才绘制完成。
    then = now - (delta % interval);
    draw(); // ... Code for Drawing the Frame ...
  }
}
tick();

针对低版本浏览器再优化:

如果浏览器没有requestAnimationFrame函数,实际底层还只能用setTimeout模拟,上边做的都是无用功。那么可以再改进一下。

var fps = 30;
var now;
var then = Date.now();
var interval = 1000/fps;
var delta;
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;

function tick() {
  if(window.requestAnimationFrame)
   {
      requestAnimationFrame(draw);
      now = Date.now();
      delta = now - then;
      if (delta > interval) {
        // 这里不能简单then=now,否则还会出现上边简单做法的细微时间差问题。例如fps=10,每帧100ms,而现在每16ms(60fps)执行一次draw。16*7=112>100,需要7次才实际绘制一次。这个情况下,实际10帧需要112*10=1120ms>1000ms才绘制完成。
        then = now - (delta % interval);
        draw(); // ... Code for Drawing the Frame ...
      }
   }
   else
   {
       setTimeout(draw, interval);
   }
}
tick();
            


最后,还可以加上暂停。

var fps = 30;
var pause = false;
var now;
var then = Date.now();
var interval = 1000/fps;
var delta;
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;

function tick() {
     if(pause)
          return;
   if(window.requestAnimationFrame)
     {
    ...
     }
     else
     {
          ...
     }
}
tick();

JS:指定FPS帧频,requestAnimationFrame播放动画

时间: 2024-08-06 15:13:05

JS:指定FPS帧频,requestAnimationFrame播放动画的相关文章

系列博文-Three.js入门指南(张雯莉)-网格 setInterval方法 requestAnimationFrame方法 使用stat.js记录FPS

第6章 动画 在本章之前,所有画面都是静止的,本章将介绍如果使用Three.js进行动态画面的渲染.此外,将会介绍一个Three.js作者写的另外一个库,用来观测每秒帧数(FPS). CSS3动画那么强,requestAnimationFrame还有毛线用? window.requestAnimationFrame  MDN

Android PowerImageView实现,可以播放动画的强大ImageView

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11100315 我个人是比较喜欢逛贴吧的,贴吧里总是会有很多搞笑的动态图片,经常看一看就会感觉欢乐很多,可以释放掉不少平时的压力.确实,比起一张单调的图片,动态图片明显更加的有意思.一般动态图片都是GIF格式的,浏览器中可以直接将这种格式的图片播放成动画. 不过很可惜的是,Android的原生控件并不支持播放GIF格式的图片.我们都知道,在Android中如果想要显示一张图片,可以

Android PowerImageView实现,可以播放动画的强大ImageView[转]

我个人是比较喜欢逛贴吧的,贴吧里总是会有很多搞笑的动态图片,经常看一看就会感觉欢乐很多,可以释放掉不少平时的压力.确实,比起一张单调的图片,动态图片明显更加的有意思.一般动态图片都是GIF格式的,浏览器中可以直接将这种格式的图片播放成动画. 不过很可惜的是,Android的原生控件并不支持播放GIF格式的图片.我们都知道,在Android中如果想要显示一张图片,可以借助ImageView控件来完成,但是如果将一张GIF图片设置到ImageView里,它只会显示这张图片的第一帧,不会产生任何的动画

cocos2d-js 3.0 rc2 自定义UI控件组件 例子:能播放动画的MenuItem。MenuItemSprite的bug

其实总体自定义UI组件都比较简单,尤其是cocos2d-js是开源的,如果有什么不明白的直接看js代码或者C++代码即可.当然js代码基本就够了. 另外,js的ctor函数虽然说是构造函数,但毕竟不是flash或者c++的构造函数,这只是一个普通函数,也就是说可以不在第一行默认调用,这就给扩展带来了不少方便. 现在想做一个声音按钮,点一下能关闭音乐,再点一下又能打开.当然就是MenuItemToggle了. 但想做得再炫一点,有声音的时候,按钮的样子能有几个音波的变化.那么就需要用MenuIte

iOS控件——UIView与UIImageView播放动画的实现方法

1.UIView //初始状态 [UIView animateWithDuration:(int) animations:^{ //最终状态 }completion:^(BOOL finished){ //动画完成后需要做的事情 }]; 2.UIView //初始状态 [UIView startAnimation]; [UIView setAnimationDuration:(int)]; //最终状态 [UIView commitAnimation]; 3.UIImageView myImag

js指定时间之后跳转到指定页面代码实例

js指定时间之后跳转到指定页面代码实例:在某些场景下,需要网页在指定的时间后,网页能够自动跳转到指定页面,比如在无法找到指定网页的情况下,就会显示之前设置好的404页面,并且跳转到指定的页面,下面就是一段代码实现了此效果.代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="htt

开发进阶07_Segmented Control_播放动画

Segmented Control selectedSegmentIndex:返回当前选中的索引,序号从0开始 UIButton和UIImageView的区别 1.显示图片 ->UIImageView只能显示一张图片(图片默认会填充整个UIImageView)image\setImage ->UIButton能显示两张图片(一张是背景,一张是前景) 背景:(背景图片默认会填充整个UIButton)setBackgroundImage:forState 前景:(覆盖在背景上面的图片,按照原有的尺

qt程序启动播放动画

qt程序启动播放动画 编辑删除转载 2016-01-20 10:23:11 标签:qt启动动画 1.播放动画 1 QAxWidget *flash = new QAxWidget(0, 0); //QAxWidget使用的是ActiveX插件 2 3 flash->resize(800, 600); //设置该控件的初始大小 4 5 flash->setControl(QString::fromUtf8("{d27cdb6e-ae6d-11cf-96b8-444553540000}&

android帧切换播放动画

android动画的简单使用 这里通过不断切换图片,达成动画效果. 在布局中,定义一个ImageButton控件 并设置好其位置. //布局文件 //很简单,就一个控件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_wi