requestAnimationFrame 的实验性实践
记得当 requestAnimationFrame 出现时我立马就石更了,就跟初次玩耍 transition 时一样,欣喜若狂...
然后,然后特么的就懵逼了,这明明就是口挖不通的深井呀(如果是我傻,那我认了...)
一. 简介
随着页面上动画的使用越来越频繁,为了避免过多的定时器带来额外系统开销,一般的动画组件都会采用“统一帧管理”:只使用一个定时器,在每一动画帧依次调用所有注册的动画事件。
后来,一些浏览器推出各自私有Api提供动画管理,W3C也出了一份 WindowAnimationTiming interface 规范,也就是 requestAnimationFrame。
动画四要素: 时长(dur),即动画播放的时间总长。 进度(per),播放的进度,在区间 [0,1] 之内。 帧间隔时间(frameTime),即多长时间播放一帧。 动画函数(animFun),它是每一帧的渲染函数。
对动画优化而言,最需考虑的就是帧间隔时间 frameTime。
原生实现里的 frameTime 被设计为可根据 CPU 使用率、window 是否被最小化、元素是否被隐藏等因素进行动态调整。
浏览器可根据实际情况降低 fps 甚至停止动画。这比以前的 setTimeout 和 setInterval 不知道好到哪里去了。
二. 实践
简单点来讲:
注册动画使用 requestAnimactionFrame 函数,接受动画函数callback作为参数,并返回动画ID;
移除动画使用 cancelRequestAnimationFrame 函数,参数是动画ID;
动画函数执行时,会传入当前系统时间戳。
function timeout(dur, animFun, callback) {
var nowTime, Timer, duration;
function _run() {
var per = Math.min(1.0, (Date.now() - nowTime) / duration);
if (per >= 1) {
_stop();
if (callback) callback.call(this, duration);
} else {
if (animFun) animFun.call(this, per, duration);
Timer = window.requestAnimationFrame(_run);
}
}
function _start() {
_go(dur); return this;
}
function _go(dur) {
duration = dur, nowTime = Date.now(), _run(); return this;
}
function _stop() {
window.cancelAnimationFrame(Timer); return this;
}
return {
start: _start, stop: _stop, go: _go,
};
}
var start = Date.now();
timeout(1000, function(per, dur){
var offset = 500 * per + 0;
if (per < 1) console.log('方块将从 0 移动' + offset + 'px 到 500');
}, function() {
console.log(Date.now() - start);
}).start();
三. 遗留的问题
在进行每一秒运行一次的倒计时会误差很严重,并不是标准的一秒。
这源于 requestAnimactionFrame 的智能,会根据现有性能进行的速率调整....虽然很好,但好尴尬呀...
上文说到,“动画函数执行时,会传入当前系统时间戳”,这句话并不可信,
因为 webkitRequestAnimationFrame 是可以的,但 requestAnimactionFrame 不对。
其次, firefox 里有 mozRequestAnimationFrame,却没有对应的 mozCancelRequestAnimationFrame,非常坑爹...
所以得这样 window.removeEventListener('MozBeforePaint', animFun, false);
开始还跟同事说它很牛逼牛逼呀,现在啪啪打脸,还得保持微笑,因为它是如此的令人期待...
requestAnimationFrame 的实验性实践的更多相关文章
- Canvas 最佳实践(性能篇)
Canvas 想必前端同学们都不陌生,它是 HTML5 新增的「画布」元素,允许我们使用 JavaScript 来绘制图形.目前,所有的主流浏览器都支持 Canvas. Canvas 最常见的用途是渲 ...
- MySQL5.6 GTID新特性实践
MySQL5.6 GTID新特性实践 GTID简介 搭建 实验一:如果slave所需要事务对应的GTID在master上已经被purge了 实验二:忽略purged的部分,强行同步 本文将简单介绍基于 ...
- 高性能javascript学习笔记系列(5) -快速响应的用户界面和编程实践
参考高性能javascript 理解浏览器UI线程 用于执行javascript和更新用户界面的进程通常被称为浏览器UI线程 UI线程的工作机制可以理解为一个简单的队列系统,队列中的任务按顺序执行 ...
- 大熊君学习html5系列之------requestAnimationFrame(实现动画的另一种方案)
一,开篇分析 Hi,大家好!大熊君又和大家见面了,(*^__^*) 嘻嘻……,这系列文章主要是学习Html5相关的知识点,以学习API知识点为入口,由浅入深的引入实例, 让大家一步一步的体会" ...
- requestAnimationFrame与setInterval,setTimeout
自打学习canvas动画以来,都说requestAnimationFrame好,就一直用,也没觉得有什么太过于特殊的地方,直到刚才,在写完前面的"小球碰撞墙壁----干掉误差"之后 ...
- 记一次动画的优化--requestAnimationFrame、webp
需要写一个类似帧动画的东西,但是每一帧是一张全屏的图,而且量特别大,600都张,而且存在跳帧的问题,只有把速度调的很快还可以看着不跳帧.但是只用谷歌还真正常播放. 其实优化起来两个方面.一个是用req ...
- ReactNative学习实践--Navigator实践
离上次写RN笔记有一段时间了,期间参与了一个新项目,只在最近的空余时间继续学习实践,因此进度比较缓慢,不过这并不代表没有新进展,其实这个小东西离上次发文时已经有了相当大的变化了,其中影响最大的变化就是 ...
- ReactNative学习实践--动画初探之加载动画
学习和实践react已经有一段时间了,在经历了从最初的彷徨到解决痛点时的兴奋,再到不断实践后遭遇问题时的苦闷,确实被这一种新的思维方式和开发模式所折服,react不是万能的,在很多场景下滥用反而会适得 ...
- 移动端 transition动画函数的封装(仿Zepto)以及 requestAnimationFrame动画函数封装(仿jQuery)
移动端 css3 transition 动画 ,requestAnimationFrame 动画 对于性能的要求,h5优先考虑: 移动端 单页有时候 制作只用到简单的css3动画即可,我们封装一下, ...
随机推荐
- Java基础07 包(转载)
包(package)的目的就是为了更好的组织Java程序. 包的建立 包的建立非常简单.我们只用在Java程序的开始加入package就可以了.我们以Human类为例,将它放入包中: packag ...
- 本地调试远程api tag
当你在本地开发js且需要跨域调用远程接口的时候.可按照下列步骤设置你的chrome. 1.创建chrome快捷方式. 2.右键属性新的快捷方式,在目标一栏后面追加 "--args ...
- 怎样利用kettle官方社区查找关于carte服务的设置
原创作品,出自 "深蓝的blog" 博客,转载时请务必注明出处.否则有权追究版权法律责任. 深蓝的blog:http://blog.csdn.net/huangyanlong/ar ...
- day8笔记
一.上节回顾 1,id() 内存地址2, == 比较的是值 is 比较的是内存地址 数字,字符串,有小数据池, #内存地址一样的 int -5--256 str:1,不能有空格. 2,长度不能超过20 ...
- 【spring boot logback】spring boot中logback日志乱码问题
在初次使用logback的自定义配置文件完整的控制spring boot日志后,发现了一个无法忍受的问题,就是日志乱码. 控制台看到打印日志乱码如下: 而日志文件打开: 记事本打开 sublime打开 ...
- 不通过AppStore,在iOS设备上直接安装应用程序的原理
本文转载至 http://mobile.51cto.com/hot-439095.htm 通过itms-services协议,可以通过safari浏览器直接在iOS设备上安装应用程序.利用这种方式, ...
- hdu 5452(树链刨分)
看到题目,想了挺长时间,发现不会,然后看着样子像是树上成段操作,所以查了下树链刨分,结果真的就是这个东西... Minimum Cut Time Limit: 3000/2000 MS (Java/O ...
- 【网络编程】之十三、ping程序实现
使用原始套接字:SOCK_RAW 需要ICMP 代码如下: #include<iostream> #include<WinSock2.h> using namespace st ...
- Coursera课程《Machine Learning》学习笔记(week2)
1 特征 1-1 什么是特征? 我的理解就是,用于描述某个样本点,以哪几个指标来评定,这些个指标就是特征.比方说对于一只鸟,我们评定的指标就可以是:(a)鸟的翅膀大还是小?(b)鸟喙长还是短?(c)鸟 ...
- 关于angularjs的ng-repeat指令
(如果有说的不对,欢迎指教,更欢迎大家一起交流.) 关于angularjs的ng-repeat指令,想必每个学习angularjs的初学者都很有映像.那我也总结一下我使用ng-repeat的时候经验, ...