JS:指定FPS帧频,requestAnimationFrame播放动画
来源:互联网 发布:淘宝店铺被投诉售假 编辑:程序博客网 时间:2024/05/18 00:57
/* 抄自: http://www.cnblogs.com/kenkofox/p/3849067.html 建议大家看原版 这样排版好*/
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(tick); 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(tick); 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(tick); 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(tick, interval);
draw(); }}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播放动画
- JS:指定FPS帧频,requestAnimationFrame播放动画
- 指定FPS帧频,requestAnimationFrame播放动画
- js requestanimationframe动画 时间控制
- 优化JS动画之requestAnimationFrame
- fps-动画以相同速度播放!
- 动画requestAnimationFrame
- Unity3D 设置帧频及显示FPS
- css vs js动画及requestAnimationFrame优化动画
- JS-requestAnimationFrame
- 性能更好的js动画实现方式——requestAnimationFrame
- 性能更好的js动画实现方式——requestAnimationFrame
- 性能更好的js动画实现方式——requestAnimationFrame
- 性能更好的js动画实现方式——requestAnimationFrame
- 性能更好的js动画实现方式——requestAnimationFrame
- 性能更好的js动画实现方式——requestAnimationFrame
- 新动画函数requestAnimationFrame
- 浏览器requestAnimationFrame动画
- 关于单元测试
- 关于ajax跨域问题
- 32. Longest Valid Parentheses
- 【Java基础】——JDBC
- C语言浮点数存储方式
- JS:指定FPS帧频,requestAnimationFrame播放动画
- SRIO学习(一)——外设数据流
- 【u030】扑克牌
- POJ 3904 Sky Code (容斥原理)
- 编译 pycaffe时报错:fatal error: numpy/arrayobject.h没有那个文件或目录
- JSP中的内容布局
- 【Java基础】——HTML隐藏域
- 学习书籍
- 7、PCIE总线-PCI、PCIE关系及信号定义