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(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播放动画的更多相关文章
- 系列博文-Three.js入门指南(张雯莉)-网格 setInterval方法 requestAnimationFrame方法 使用stat.js记录FPS
第6章 动画 在本章之前,所有画面都是静止的,本章将介绍如果使用Three.js进行动态画面的渲染.此外,将会介绍一个Three.js作者写的另外一个库,用来观测每秒帧数(FPS). CSS3动画那么 ...
- Android PowerImageView实现,可以播放动画的强大ImageView
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11100315 我个人是比较喜欢逛贴吧的,贴吧里总是会有很多搞笑的动态图片,经常看一 ...
- [js高手之路]html5 canvas动画教程 - 边界判断与小球粒子模拟喷泉,散弹效果
备注:本文后面的代码,如果加载了ball.js,那么请使用这篇文章[js高手之路] html5 canvas动画教程 - 匀速运动的ball.js代码. 本文,我们要做点有意思的效果,首先,来一个简单 ...
- [js高手之路]html5 canvas动画教程 - 边界判断与反弹
备注:本文后面的代码,如果加载了ball.js,那么请使用这篇文章[js高手之路] html5 canvas动画教程 - 匀速运动的ball.js代码. 边界反弹: 当小球碰到canvas的四个方向的 ...
- requestAnimationFrame 持续动画效果
1. requestAnimationFrame 概述 requestAnimationFrame 是浏览器用于定时循环操作的一个API, 类似于setTimeout, 主要用途是按帧对网页进行重绘. ...
- requestAnimationFrame ---- 请求动画帧。
window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画.该方法需要传入一个回调函数作为参数,该回调函数会 ...
- JS实现文字转语音播放
JS实现文字转语音播放背景实现方式第一种:百度文字转语音开放API第二种:微软TTS语音引擎第三种:SpeechSynthesisUtterance总结背景在做项目的过程中,经常会遇到场景是客户要求播 ...
- [UWP]使用离散式关键帧播放动画
这篇文章介绍离散式关键帧,并使用它做些有趣的动画. 1. 什么是离散式关键帧 以DoubleAnimationUsingKeyFrames为例,它支持四种Double的关键帧,其中EasingDoub ...
- 使用requestAnimationFrame做动画效果二
3月是个好日子,渐渐地开始忙起来了,我做事还是不够细心,加上感冒,没精神,今天差点又出事了,做过的事情还是要检查一遍才行,哎呀. 使用requestAnimationFrame做动画,我做了很久,终于 ...
随机推荐
- ExtJS 4.2 教程-07:Ext.Direct
转载自起飞网,原文地址:http://www.qeefee.com/extjs-course-7-Ext-Direct ExtJS 4.2 教程-01:Hello ExtJS ExtJS 4.2 教程 ...
- SQLite中的增删改查
虽然android提供了sql查询的封装方法,但是理解起来还是麻烦,所以我这里用sql语句来完成工作. 首先是建立一个类,继承SQLiteOpenHelper 这里面会建立一个数据库,并且初始化一个表 ...
- 《OSPF和IS-IS详解》
<OSPF和IS-IS详解> 基本信息 作者: (美)Jeff Doyle 译者: 孙余强 出版社:人民邮电出版社 ISBN:9787115347886 上架时间:2014-4-25 出版 ...
- jquery的radio和checkbox的标签的操作集合
jquery的radio和checkbox的标签的操作集合: $("input[name='radio_name'][checked]").val(); //选择被选中Radio的 ...
- Netty端口被占用问题
问题: 最近发现Netty项目每次发布的时候Netty在重启时都会报端口被占用的异常, 需要过十几秒左右手动重启一遍, Netty才能恢复正常 目前猜测是由于Tomcat_restart的时候Ne ...
- SQL Server:使用 PIVOT 行转列和 UNPIVOT 列转行
ylbtech-SQL Server:使用 PIVOT 行转列和 UNPIVOT 列转行 可以使用 PIVOT 和 UNPIVOT 关系运算符将表值表达式更改为另一个表.PIVOT 通过将表达式某一列 ...
- 常用sql备份
统计数据库中表格数据行数所占空间和索引情况 set nocount on exec sp_MSForEachTable @precommand=N' create table ##( id int i ...
- Spring Boot 直接用jar运行项目
概述 在Spring Boot 开篇-创建和运行一文中,介绍了如何创建一个Sprint Boot项目并且运行起来.但是运行的方式是在IDEA中直接Run起来的.还有另一中方式可以可以把Spring B ...
- vue使用watch 观察路由变化,重新获取内容
watch: { $route(to) { console.log(to) if (to.path.indexOf('index') != -1) { //路由变化后重新获取帖子列表 this.$ht ...
- Android -- 获取视频第一帧缩略图
干货 从API 8开始,新增了一个类: android.media.ThumbnailUtils这个类提供了3个静态方法一个用来获取视频第一帧得到的Bitmap,2个对图片进行缩略处理. public ...