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颜色。
Reference:
1. article about rAF from css tricks: http://css-tricks.com/using-requestanimationframe/
2. article about rAF from Paul Irish:http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
3. what is polyfill http://remysharp.com/2010/10/08/what-is-a-polyfill/
requestAnimationFrame,Web中写动画的另一种选择的更多相关文章
- requestAnimationFrame Web中写动画的另一种选择
HTML5和CSS3盛行的今天 动画变得很简单实现 我们可以用transition . animation + keyframe .也可以用canvas等 我在上一篇 点击回到顶部的文章中发现的这个 ...
- 转: requestAnimationFrame,Web中写动画的另一种选择
HTML5/CSS3时代,我们要在web里做动画选择其实已经很多了: 你可以用CSS3的animattion+keyframes; 你也可以用css3的transition; 你还可以用通过在canv ...
- 【Filter 不登陆无法访问】web项目中写一个过滤器实现用户不登陆,直接给链接,无法进入页面的功能
在web项目中写一个过滤器实现用户不登陆,直接给链接,无法进入页面,而重定向到登陆界面的功能. 项目是用springMVC+spring+hibernate实现 (和这个没有多大关系) 第一步: 首先 ...
- 如何停止requestAnimationFrame方法启动的动画
HTML5/CSS3时代,我们要在web里做动画选择其实已经很多了:(1) 你可以用CSS3的animattion+keyframes;(2) 你也可以用css3的transition; (3) 你还 ...
- Web中的图标
随着时代的变迁与技术的不断的更新,在当今这个时代,Web中的图标(Icons)不再仅仅是局限于<img>.除了<img>直接调用Icons文件之外,还有Sprites(俗称雪碧 ...
- 史上最全的CSS hack方式一览 jQuery 图片轮播的代码分离 JQuery中的动画 C#中Trim()、TrimStart()、TrimEnd()的用法 marquee 标签的使用详情 js鼠标事件 js添加遮罩层 页面上通过地址栏传值时出现乱码的两种解决方法 ref和out的区别在c#中 总结
史上最全的CSS hack方式一览 2013年09月28日 15:57:08 阅读数:175473 做前端多年,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某些情况我 ...
- CSS3中的动画效果记录
今天要记录的是CSS3中的三种属性transform.transition以及animation,这三个属性大大提升了css处理动画的能力. 一.Transform 变形 CSS中transform ...
- 透过HT for Web 3D看动画Easing函数本质
http://www.hightopo.com/guide/guide/plugin/form/examples/example_easing.html 50年前的这个月诞生了BASIC这门计算机语言 ...
- 在C#代码中应用Log4Net(四)在Winform和Web中捕获全局异常
毕竟人不是神,谁写的程序都会有bug,有了bug不可怕,可怕的是出错了,你却不知道错误在哪里.所以我们需要将应用程序中抛出的所有异常都记录起来,不然出了错,找问题就能要了你的命.下面我们主要讨论的是如 ...
随机推荐
- Listview详解
Listview应该是最为常见的控件.对于大多数规则排列的界面,几乎都可以用ListView进行编写.对于单一界面来说,ListView既是最难的控件,又是使用最为频繁的控件.ListView 通常用 ...
- 转一篇简洁的UIView动画编程方法
iOS 中的 UIView 动画编程其实还是很简单的,像 CSS3 一样,在给定的时间内完成状态连续性的变化呈现.比如背景色,Frame 大小,位移.翻转,特明度等. 以前我使用的编程方式都是用下面 ...
- 如何获取ios 设备名字 model
由于需要获取设备名字,在网上找了一些方法,发现能够解决问题,但是需要做一个匹配,然后设备年年都会出新款,而且设备的种类又很多,所以在获取设备信息后我又做了一个操作,--->我在google上找到 ...
- SSIS 通过添加脚本组件 自定义转换数据
问题:从mysql导入到sql的汉字都是乱码或者干脆导入不成功,报”截断字符串“错误,错在mysql当时建立的都是使用的默认编码latin1;搞不明白,又不是瑞典人,你用这个干毛.导致现在遇到n多问题 ...
- Expdp 导数错误 ORA-00832
问题实验环境 操作系统:Red Hat Enterprise Linux Server release 5.7 (Tikanga) 数据库 :Oracle Database 10g Release ...
- HTML5 data-* 自定义属性
在jQuery的attr与prop提 到过在IE9之前版本中如果使用property不当会造成内存泄露问题,而且关于Attribute和Property的区别也让人十分头痛,在 HTML5中添加了da ...
- 【java开发】面向对象初步认识与基础概念讲解
简单的把前面的java基础知识讲了,接下来就开始面向对象的旅程了. 对象(Object):简而言之,世界是由对象组成的,一切可见的事物吧 类(class):说白了就是把具有相同的一些特征或是属性归为一 ...
- 漫谈c++11 Thread库之使写多线程程序
c++11中最重要的特性之一就是对多线程的支持了,然而<c++ primer>5th却没有这部分内容的介绍,着实人有点遗憾.在网上了解到了一些关于thread库的内容.这是几个比较不错的学 ...
- 【WPF系列】基础 PasswordBox
参考 How to bind to a PasswordBox in MVVM
- #essay 161218# 自己的markdown笔记(日记)方法
写在前面 本文可能极度无聊--自己markdown笔记方法 我的工具 1. computer 2. samsung mobile phone(自己的小S3) 3. markdownpad 2 4. p ...