博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
动画优化之window.requestAnimationFrame()
阅读量:4323 次
发布时间:2019-06-06

本文共 2190 字,大约阅读时间需要 7 分钟。

requestAnimationFrame解决了浏览器不知道javascript动画什么时候开始、不知道最佳循环间隔时间的问题。

编写动画循环的关键,是要知道延迟时间多长合适。一方面,循环时间必须足够短,这样才能保证动画效果更平滑流畅;另一方面,循环还要足够长,这样才能保证浏览器有能力渲染产生的变化。大多数显示器的刷新频率是60Hz,相当于每秒钟重绘60次。大多数浏览器都会对重绘操作加以限制,不超过显示器的重绘频率,因为即使超过了这个频率,用户体验也不会有提升。

因此最平滑动画的最佳循环间隔是1000ms/60,约等于17ms。以这个循环间隔重绘的动画是平滑的,因为这个速度最接近浏览器的最高限速。为了适应17ms的循环间隔,多重动画可能需要加以节制,以便不会完成得太快。

虽然与使用多组setTimeout()相比,使用setInterval()的动画循环效率更高。但是无论setTimeout()还是setInterval()都不十分精确。为它们传入的第二个参数,实际上只是指定了把动画代码添加到浏览器UI线程队列以等待执行的时间。如果队列前面已经加入了其他任务,那动画代码就要等前面的任务执行完成后再执行。如果UI线程繁忙,比如忙于处理用户操作,那么即使把代码加入队列也不会立即执行。

requestAnimationFrame的速度是由浏览器决定的,不同浏览器会自行决定最佳的帧效率。

    window.requestFrame    

  以上是requestAnimationFrame的运行代码,但是有的浏览器不支持requestAnimationFrame,所以兼容写法如下:

if(!window.requestAnimationFrame) { window.requestAnimationFrame = (window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {  var self = this, start, finish;  return window.setTimeout(function() {   start = +new Date();   callback(start);   finish = +new Date();   self.timeout = 1000/60 - (finish - start);  }, self.timeout); });}

这段代码先检查了window.requestAnimationFrame函数的定义是否存在。如果不存在,就遍历已知的各种浏览器实现并替代该函数。如果还是找不到一个与浏览器相关的实现,它最终会采用基于JavaScript定时器的动画以每秒60帧的间隔调用setTimeout函数。

更加优雅的requestAnimationFrame兼容封装代码:

(function() { var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {  window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];  window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; }  if (!window.requestAnimationFrame)  window.requestAnimationFrame = function(callback, element) {   var currTime = new Date().getTime();   var timeToCall = Math.max(0, 16 - (currTime - lastTime));   var id = window.setTimeout(function() { callback(currTime + timeToCall); },     timeToCall);   lastTime = currTime + timeToCall;   return id;  };  if (!window.cancelAnimationFrame)  window.cancelAnimationFrame = function(id) {   clearTimeout(id);  };}());

 

转载于:https://www.cnblogs.com/H5C3XXN/p/7358012.html

你可能感兴趣的文章
ABAP CDS ON HANA-(10)項目結合して一つ項目として表示
查看>>
网站地址信息
查看>>
产品经理 - 登录 注册
查看>>
小白的python进阶历程------05.占位符
查看>>
CF414BMashmokh and ACMDP
查看>>
Notepad++ 通过g++编译
查看>>
JAVA基础2——类初始化相关执行顺序
查看>>
转:Zend Framework 重定向方法(render, forward, redirect)
查看>>
Linux下查看磁盘与目录的容量——df、du
查看>>
关于日记app的思考
查看>>
使用sencha的cmd创建项目时提示找不到\Sencha\Cmd\repo\.sencha\codegen.json
查看>>
如何快速启动一个Java Web编程框架
查看>>
MSP430单片机存储器结构总结
查看>>
文本框过滤特殊符号
查看>>
教育行业安全无线网络解决方案
查看>>
7个杀手级的开源监测工具
查看>>
软件架构学习小结
查看>>
C语言实现UrlEncode编码/UrlDecode解码
查看>>
返回用户提交的图像工具类
查看>>
树链剖分 BZOJ3589 动态树
查看>>