requestAnimationFrame,Web中写动画的另一种选择
HTML5/CSS3时代,我们要在web里做动画选择其实已经很多了:
你可以用CSS3的animattion+keyframes;
你也可以用css3的transition;
你还可以用通过在canvas上作图来实现动画,也可以借助jQuery动画相关的API方便地实现;
当然最原始的你还可以使用window.setTimout()或者window.setInterval()通过不断更新元素的状态位置等来实现动画,前提是画面的更新频率要达到每秒60次才能让肉眼看到流畅的动画效果。
现在又多了一种实现动画的方案,那就是还在草案当中的window.requestAnimationFrame()方法。
初识requestAnimationFrame
来看MDN上对其给出的诠释:
The window.requestAnimationFrame() method tells the browser that you wish to perform an animation and requests that the browser call a specified function to update an animation before the next repaint. The method takes as an argument a callback to be invoked before the repaint.
window.requestAnimationFrame() 将告知浏览器你马上要开始动画效果了,后者需要在下次动画前调用相应方法来更新画面。这个方法就是传递给window.requestAnimationFrame()的回调函数。
也可这个方法原理其实也就跟setTimeout/setInterval差不多,通过递归调用同一方法来不断更新画面以达到动起来的效果,但它优于setTimeout/setInterval的地方在于它是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销。
基本语法
可以直接调用,也可以通过window来调用,接收一个函数作为回调,返回一个ID值,通过把这个ID值传给window.cancelAnimationFrame()可以取消该次动画。
requestAnimationFrame(callback)//callback为回调函数
一个简单的例子
模拟一个进度条动画,初始div宽度为1px,在step函数中将进度加1然后再更新到div宽度上,在进度达到100之前,一直重复这一过程。
为了演示方便加了一个运行按钮(看不到例子请刷新)。
<div id="test" style="width:1px;height:17px;background:#0f0;">0%</div> <input type="button" value="Run" id="run"/>
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; var start = null; var ele = document.getElementById("test"); var progress = 0;function step(timestamp) {progress += 1;ele.style.width = progress + "%";ele.innerHTML=progress + "%";if (progress < 100) {requestAnimationFrame(step);} } requestAnimationFrame(step); document.getElementById("run").addEventListener("click", function() {ele.style.width = "1px";progress = 0;requestAnimationFrame(step); }, false);
浏览器支持情况
既然还是草案状态下引入的一个功能,在使用全我们就需要关心一下各浏览器对它的支持情况了。就目前来说,主流现代浏览器都对它提供了支持,请看下图:
31+ |
26+ |
10+ |
19+ |
6+ |
更为具体的浏览器兼容性可以在这里看到。
Polyfill
Polyfill就是垫片,按发明这个词的人的原话来说,它就是一段这样的代码,让浏览器原生地支持我们期望使用的一些API。
就比如这里的requestAnimationFrame,在看到了上面的浏览器支持情况后,你就知道了比上面列出的浏览器版本老的就不支持该方法,但为了让代码能够有更好的浏览器兼容性在老机器上也能运行不报错,我们可以写一些代码让浏览器在不支持requestAnimationFrame的情况下使用window.setTimeout(),这是一种回退(fallback)到过去的方法。
这样一来,就可以通俗一点的理解polyfill了,它就是备胎。
下面是由Paul Irish及其他贡献者放在GitHub Gist上的代码片段,用于在浏览器不支持requestAnimationFrame情况下的回退,回退到使用setTmeout的情况。当然,如果你确定代码是工作在现代浏览器中,下面的代码是不必的。
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/ // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel // MIT license (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);}; }());
上面代码作用有二,一是把各浏览器前缀进行统一,二是在浏览器没有requestAnimationFrame方法时将其指向setTimeout方法。
提到备胎代码呢,这里多说一句,在CSS代码中,我们也经常使用这种回退的技巧,即对同一条CSS规则,编写多条以不同浏览器前缀开头代码,或者编写一条备用样式。
下面是一个CSS中的备胎代码的例子:
div {background: rgb(0, 0, 0); /* fallback */background: rgba(0, 0, 0, 0.5); }
代码中设置div背景为黑色带50%的透明度,但IE9-的浏览器是不支持rbga格式的颜色的,所以浏览器会回退到上一条CSS规则应用rgb颜色。
转载于:https://www.cnblogs.com/shuangMrs/p/7323980.html
requestAnimationFrame,Web中写动画的另一种选择相关推荐
- web中“/”写在不同地方时的值不同
web 中的 / 到底代表什么? 用法: 1.若/交由浏览器来解析,代表当前web站点的根路径:例:http://localhost:8080/ >超链接:<a href=" ...
- EasyExcel在项目中的应用-在web中导出带下拉框和批注的excel文件
前言 好长一段时间没有更新博客了,最近刚刚找到实习工作,接触了企业中的项目,在这段时间的实习过程中,终于知道了企业级项目的体量和业务难度跟之前的小项目是完全不同的.10多天的适应期也逐渐让我找到了 ...
- web 移动端 ios 浏览器中 animation 动画异常
关键字:animation,ios,移动端,异常 解决问题的办法:页面dom加载完毕时延时给dom加上动画类名.即在vue的mounted钩子中用定时器延时100ms左右给需要动画的dom加上类名. ...
- css3中的动画学习分享
大家好,这里是demo软件园,今天为大家分享的是css3中的动画(animation). css3动画: 使元素从一种样式逐渐变化为另一种样式的效果. 动画原理:通过把人物的表情.动作.变化等分解后画 ...
- window.requestAnimationFrame强大的前端动画神器
今天介绍一个功能强大的api-window.requestAnimationFrame,它既可以实现如丝般顺滑的动画,又能充当性能优化的利器,还能代替setTimeout,setInterval等定时 ...
- 2D MMO中角色动画的优化总结
在深圳Cocos沙龙上,有幸结识了社区中大名顶顶的Colin,Shawn在社区论坛上第一次看到Colin的团队用CocosCreator制作的<热血暗黑>时就被深深地震撼到了!更为重要的是 ...
- 如何在html中加入动画效果,纯css如何实现按钮的水滴动画效果?
纯css如何实现按钮的水滴动画效果?下面本篇文章就来给大家介绍一下使用纯css实现Material Design中按钮的水滴动画效果.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. ...
- Web中的积累:外观模式 Facade
摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆木匠 希望转载,保留摘要,谢谢! 壹 前言 目测好久没写文章了,距离上一篇文章也有二十多天.我是怎么了?哈 ...
- part.write java_小白向:web中利用request.getPart()上传文件到服务器
被文件上传弄得焦头烂额的一天,果然web中的路径和各种设置真的好讨厌= = 下面是超级小白的.及其简约的"详"解 1.明确目的: 用户将 1.txt 文件 上传到 服务器(web工 ...
最新文章
- 微软CEO致雅虎董事会的最后通牒信
- java基础(5)----面向对象
- ReactNative用指定的设备/模拟器运行项目
- python大一知识点串讲_python-前20天的着重知识点
- spark mapreduce术语梳理
- flyme禁止系统更新_魅族Flyme更新8.1.2.3A:重要系统更新!
- MySQL5.5.15_linux下mysql-5.5.15安装详细步骤
- python爬虫select用法_Python爬虫利器二之Beautiful Soup的用法
- shell date mysql_shell脚本定时备份mysql数据库
- jQuery 学习-DOM篇(三):jQuery 在 DOM 外部插入元素
- android浮动按钮_Android浮动操作按钮示例教程
- Spine3.8.75 下载
- 2022秋招求职记录(图像 视觉 c++)
- 金山词霸2007两个小BUG
- 在ADS中进行DCR仿真
- 手把手教你搭建属于自己的服务器
- ncbi查找目的基因序列_如何用NCBI和uniprot数据库查找目的蛋白的氨基酸序列或目的基因的碱基序列...
- windows下制作iso文件,WinMount介绍
- 编译出错 Resource temporarily unavailable
- 【小万出生记——第0篇】想做一款机械手
热门文章
- 转:探讨SQL Server 2005的安全策略
- .Net并行库介绍——Task(1)
- 【Python自学】六个上手超强的学习工具,你值得有
- 70个Python练手项目列表,看了让你茅塞顿开~
- VictoriaMetrics如何运用?
- 简述SHELL全局环境变量与局变环境变量
- python的执行过程_在交互式环境中执行Python程序过程详解
- 保护站点上已存在另一个具有相同实例 UUID的虚拟机_LoadRunner性能测试系统学习教程:工具介绍(上)...
- BZOJ 2159 「国家集训队」Crash 的文明世界(第二类斯特林数,换根DP)【BZOJ计划】
- 0x32.数学知识 - 约数