更好的逐帧动画函数 — requestAnimationFrame 简介
本文将会简单讲讲 requestAnimationFrame 函数的用法,与 setTimeout/setInterval 的区别和联系,以及当标签页隐藏时 requestAnimationFrame、setTimeout 各自的后续渲染。
requestAnimationFrame
说到 requestAnimationFrame,不得不提到 canvas 动画,而说到 canvas 动画,又不得不说到 setTimeout/setInterval。
canvas 动画是基于逐帧重绘的,我们可以用 setTimeout 或者 setInterval 函数,设置定时器,每过一定时间,完成数据更新,继而重绘到画布上。但是这样做有个缺点,可能会有卡顿。举个简单的例子,假设浏览器一秒刷新 10 次(正常的浏览器都在 60 fps 左右),重绘的时间点为 0ms,100ms,200ms,300ms .. 1000ms,用 setInterval 来做动画,间隔设置为 60ms,也就是每 60ms 更新数据,那么数据更新点为 60ms,120ms,180ms,240ms ... ,100ms 的时候实际更新了一次数据,200ms的时候实际已经更新了三次数据,恩,理论上会出现不流畅的情况(如果没有听懂,可以参考下张鑫旭大神的文章 CSS3动画那么强,requestAnimationFrame还有毛线用?有个很好的比喻)。what'more,setTimeout/setInterval 的时间间隔并不是像传的参数那般准确,事实上,setTimeout 间隔通常会大于所传的数,而 setInterval 可能会因为丢失回调而小于所定数字,具体可以看下 从setTimeout谈JavaScript运行机制。
这时候,我们设想,如果浏览器在重绘前,通知客户端数据更新,那就太棒了!requestAnimationFrame 函数闪亮登场!requestAnimationFrame 是浏览器用于定时循环操作的一个接口,类似于 setTimeout,主要用途是按帧对网页进行重绘。设置这个 API 的目的是为了让各种网页动画效果(DOM 动画、Canvas 动画、SVG 动画、WebGL 动画)能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。代码中使用这个 API,就是告诉浏览器希望执行一个动画,让浏览器在下一个动画帧安排一次网页重绘。
使用方式非常简单,现代浏览器已经支持无前缀的 API,低版本的现代浏览器可以用带前缀的 API 回退,低版本 ie 可以用 setTimeout 回退(具体兼容性可以参考 http://caniuse.com/#search=requestAnimationFrame):
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
};
})();
一个简单的使用:
// 调用 相当于setTimeout里的callback
function animationLoop(){
// logic
document.body.innerHTML = currentnumber++;
// 循环
requestID = requestAnimFrame(animationLoop);
}
// start
requestID = requestAnimFrame(animationLoop);
跟 setTimeout 一样,RAF 也可以取消掉。非常简单,以上面代码为例,将 requestID 传入 cancelAnimationFrame 函数即可:
window.cancelAnimationFrame(requestID);
事实上,我还是比较习惯用一个变量来表示是否继续重绘:
// 调用 相当于setTimeout里的callback
function animationLoop(){
// logic
document.body.innerHTML = currentnumber++;
// 循环
if (flag) // 继续重绘直到 flag === false
requestID = requestAnimFrame(animationLoop);
}
有一个完整的 polyfill,可以参考下谷歌大神的这篇文章 requestAnimationFrame for Smart Animating
标签页隐藏时
RAF 宣称,使用这个 API,一旦页面不处于浏览器的当前标签,重绘频率则会大大降低。大大降低到底是降低到什么程度?出于好奇,我决定进一步探索下。
做法非常简单,将标签页隐藏,然后看看刷新频率,输出前后两个刷新的间隔时间。
chrome,当标签页隐藏时,不再继续刷新。firefox 中,间隔时间如下:
1017
1997
3998
7999
15993
32000
63994
127999
很明显的指数型增长趋势。
setTimeout/setInterval 呢?当标签页被隐藏时还是一样工作吗?经测试(仅在 firefox & chrome 下测试),当时间间隔大于 1000ms 时,如果标签页被隐藏,还是按照设定的时间执行回调;如果时间间隔小于 1000ms,当标签页被隐藏时,时间间隔会被延迟到 1000ms 执行回调。
Read More:
- requestAnimationFrame 阮一峰
- window.requestAnimationFrame MDN
- requestAnimationFrame for Smart Animating
更好的逐帧动画函数 — requestAnimationFrame 简介的更多相关文章
- window.requestAnimationFrame() ,做逐帧动画,你值得拥有
window.requestAnimationFrame() 方法告诉浏览器您希望执行动画,并请求浏览器调用指定的函数在下一次重绘之前更新动画.该方法使用一个回调函数作为参数,这个回调函数会在浏览器重 ...
- 过渡与动画 - 逐帧动画&steps调速函数
写在前面 上一篇中我们熟悉五种内置的缓动曲线和(三次)贝塞尔曲线,并且基于此完成了缓动效果. 但是如果我们想要实现逐帧动画,基于贝塞尔曲线的调速函数就显得有些无能为力了,因为我们并不需要帧与帧之间的过 ...
- css3 实现逐帧动画
css3 实现逐帧动画 实现逐帧动画需要使用到的是Animation动画,该CSS3的Animation有八个属性:分别是如下:1: animation-name2: animation-durati ...
- Esfog_UnityShader教程_逐帧动画
有段日子没出这个系列的新文章了,今天就拿一个比较常见也比较基础的利用改变Shader来改变不断调整UV实现播放逐帧动画的小功能.很久没写了就当练练手了.在新版本的Unity中早就已经集成了Sprite ...
- animation中的steps()逐帧动画
在我们平时做宽高确定,需要背景图片切换的效果时,我如果用的是一张大的png图片.而且恰好是所有小图都是从左向右排列的,那么 我们只需测量出某一个小图距左侧有多少像素(x),然后我们banckgroun ...
- 利用css3-animation来制作逐帧动画
前言 趁着还没有元旦之前先码一篇文章,不然到时候估计又被各种虐了,所以趁现在还有力气先来一篇.今天来聊聊css3中的动画属性animation,对这个属性懵懂是在很早的时候有前辈用这个 animati ...
- css3逐帧动画
写css3动画的时候,我们经常用到animation来实现,默认情况下,animation是属于连贯性的ease动画.我们熟悉的animation动画有ease.ease-in.ease-out.li ...
- Android动画效果之Frame Animation(逐帧动画)
前言: 上一篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画),今天来总结下Android的另外一种动画Frame ...
- Android 逐帧动画
原理: 逐帧动画是最简单的一种动画.原理就是把几张图片连续显示出来,以达到动画的效果.就相当于下面这种手绘翻页动画啦~ 实现: 1.需要建立一个animation-list来设置静态图片资源.持续时间 ...
随机推荐
- Android中的单例模式
定义: 单例模式:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 使用场景: 确保某一个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有且只有一 ...
- [Linux 性能检测工具]IOSTAT
IOSTAT NAME: Iostat, 报告CPU的统计,和 I/O的统计. 语法: iostat [ -c ] [ -d ] [ -N ] [ -n ] [ -h ] [ -k ...
- NGINX高性能Web服务器详解(读书笔记)
原文地址:NGINX高性能Web服务器详解(读书笔记) 作者:夏寥寥 第4章 Nginx服务器的高级配置 4.1 针对IPv4的内核7个参数的配置优化 说明:我们可以将这些内核参数的值追加到Linu ...
- 玉渊潭赏樱花有感:从无到有写一个jQuery开源插件
“玉渊潭公园樱花节”是每年樱花绽放时,都会在玉渊潭公园樱举办樱花节,游客前往玉渊潭公园,可以欣赏到20个品种2000株樱花.2016玉渊潭樱花节时间:3月中旬-4月中旬观赏最佳,2016年3月23日开 ...
- 不同Framework下StringBuilder和String的性能对比,及不同Framework性能比(附Demo)
本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 阅读目录 介绍 环境搭建 测试用例 MSDN说明 ...
- DataTable转换为Json格式
private string DataTableToJson(DataTable dt) { string Json = ""; Json = Json + "[&quo ...
- SQL Server:查看SQL日志文件大小命令:dbcc sqlperf(logspace)
SQL Server:查看SQL日志文件大小命令:dbcc sqlperf(logspace) DBA 日常管理工作中,很重要一项工作就是监视数据库文件大小,及日志文件大小.如果你管理数据库的有很 ...
- SQLServer中比较末尾带有空格的字符串遇到的坑
最近发现SQLServer中比较字符串的时候 如果字符串末尾是空格 那么SQLServer会无视那些空格直接进行比较 这和程序中平时的字符串判断逻辑不统一 );set @a=N'happycat198 ...
- Superpixel Based RGB-D Image Segmentation Using Markov Random Field——阅读笔记
1.基本信息 题目:使用马尔科夫场实现基于超像素的RGB-D图像分割: 作者所属:Ferdowsi University of Mashhad(Iron) 发表:2015 International ...
- Caffe源码解析1:Blob
转载请注明出处,楼燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/ 首先看到的是Blob这个类,Blob是作为Caffe中数据流通的 ...