HTML5/CSS3时代,我们要在web里做动画选择其实已经很多了:
(1) 你可以用CSS3的animattion+keyframes;
(2) 你也可以用css3的transition;

(3) 你还可以用通过在canvas上作图来实现动画,也可以借助jQuery动画相关的API方便地实现;

(4) 当然最原始的你还可以使用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开销。

基本语法
(1)可以直接调用,也可以通过window来调用,接收一个函数作为回调;
(2) 返回一个ID值,通过把这个ID值传给window.cancelAnimationFrame()可以取消该次动画。
    requestAnimationFrame(callback)//callback为回调函数

一个简单的例子
  模拟一个进度条动画,初始div宽度为1px,在step函数中将进度加1然后再更新到div宽度上,在进度达到100之前,一直重复这一过程。

为了演示方便加了一个运行按钮(点击观看效果

<html>
<head>
<meta charset="gbk">
<title>动画</title>
</head>
<body>
<div id="test" style="width:1px;height:17px;background:#0f0;">0%</div>
<input type="button" value="Run" id="run"/>
<input type="button" value="停止" id="stop"/>
</body>
<script> window.requestAnimationFrame =
window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame
|| window.msRequestAnimationFrame;
var start = null;
var ele = document.getElementById("test");
var progress = 0;
var stop=null;
function step(timestamp) {
if(progress>=100) progress=0;
progress += 1;
ele.style.width = progress + "%";
ele.innerHTML=progress + "%";
if (progress < 100) {
stop=requestAnimationFrame(step);
}
}
document.getElementById("run").addEventListener("click", function() {
ele.style.width = "1px";
step();
}, false);
document.getElementById("stop").addEventListener("click", function() {
window.cancelAnimationFrame(stop);//可以取消该次动画。
}, false);
</script>
</html>

浏览器支持情况

既然还是草案状态下引入的一个功能,在使用全我们就需要关心一下各浏览器对它的支持情况了。就目前来说,主流现代浏览器都对它提供了支持,请看下图:

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方法启动的动画的更多相关文章

  1. 如何停止和扭转UIView的动画

    本文转载至  http://codego.net/576089/ 我有它收缩时碰到切换按钮UIView的动画跳和它扩展恢复到原来的大小当再次接触到按钮.密封式前大灯一切都工作得很好.问题是,动画师注意 ...

  2. window.requestAnimationFrame() ,做逐帧动画,你值得拥有

    window.requestAnimationFrame() 方法告诉浏览器您希望执行动画,并请求浏览器调用指定的函数在下一次重绘之前更新动画.该方法使用一个回调函数作为参数,这个回调函数会在浏览器重 ...

  3. 网页性能管理详解:浅谈chrome-Timeline及window.requestAnimationFrame()方法

    你遇到过性能很差的网页吗? 这种网页响应非常缓慢,占用大量的CPU和内存,浏览起来常常有卡顿,页面的动画效果也不流畅. 你会有什么反应?我猜想,大多数用户会关闭这个页面,改为访问其他网站.作为一个开发 ...

  4. iOS 实现启动屏动画(Swift实现,包含图片适配)

    代码地址如下:http://www.demodashi.com/demo/12090.html 准备工作 首先我们需要确定作为宣传的图片的宽高比,这个一般是与 UI 确定的.一般启动屏展示会有上下两部 ...

  5. main方法启动spring

    main方式读取spring配置.main方法启动spring/ 有时候只想写一下简单的测试用一下. 新建一个maven项目 依赖pom <?xml version="1.0" ...

  6. qt程序启动播放动画

    qt程序启动播放动画 编辑删除转载 2016-01-20 10:23:11 标签:qt启动动画 1.播放动画 QAxWidget *flash = , ); //QAxWidget使用的是Active ...

  7. 活动a 使用 启动为结果 方法 启动 活动 b, b什么都不做 并返回给a,a中的 在活动结果时候 回调 是否被执行?

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 活动a 使用 启动为结果 方法 启动 活动 b, b什么都不做 并返回给a,a中的 在活 ...

  8. 2019-11-29-VisualStudio-使用三个方法启动最新-C#-功能

    原文:2019-11-29-VisualStudio-使用三个方法启动最新-C#-功能 title author date CreateTime categories VisualStudio 使用三 ...

  9. redis 3.2.5单机版安装、使用、systemctl管理Redis启动、停止、开机启动

    参照地址 http://www.mamicode.com/info-detail-1488639.html 前提:防火墙安装,然后打开端口,设置开机启动 一.redis源码安装 [root@host- ...

随机推荐

  1. hive中创建hive-json格式的表及查询

    在hive中对于json的数据格式,可以使用get_json_object或json_tuple先解析然后查询. 也可以直接在hive中创建json格式的表结构,这样就可以直接查询,实战如下(hive ...

  2. 实例具体解释Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(二)

    这是本系列的第二篇,内容是 prefetch_related() 函数的用途.实现途径.以及用法. 本系列的第一篇在这里 第三篇在这里 3. prefetch_related() 对于多对多字段(Ma ...

  3. easy UI动态赋值

    1,首先怎么清除这个值 $('#filegrid').datagrid('loadData', { total: 0, rows: [] }); 2,清除后,通过post提交请求,怎么将新植穿进去,这 ...

  4. 一个美国人对"智能制造"的思考!

    世界上制造业最强的国家仍然是美国!如今,国内工业4.0概念讨论日益喧嚣,中德合作如火如荼,但我们不能否认这个事实. “ 当下,美国似乎失去了世界第一制造大国的称号,而中国的企业也正面临产值下滑.利润下 ...

  5. php的form中元素name属性相同时的取值问题

    php的form中元素name属性相同时的取值问题:修改元素的名称,在名称后面加上 '[]',然后取值时即可得array()数组. 一.以复选框为例: <html> <head> ...

  6. git把任意代码提交到已存在的github库中

    git init git add . git remote add origin 远程urlgit branch --set-upstream-to=origin/mastergit pull --a ...

  7. 机器学习(Machine Learning)

    机器学习(Machine Learning)是一门专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能的学科.

  8. git练习

    git commit 提交记录 git branch <branch_name> 建立名为branch_name的分支 git checkout <name>:git comm ...

  9. Android 处理含有EditText的Activity虚拟键盘

    在Android的Activity放置EditText之后,如果没有做特别的调整,每次一进入Activity,EditText都会自动取得焦点,然后弹出虚拟键盘,造成画面变得拥挤.虽然Android这 ...

  10. 通过AnimationSet 同步或一部播放多个动画 Android 属性动画(Property Animation) 完全解析 (下)

    AnimationSet提供了一个把多个动画组合成一个组合的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等. 以下例子同时应用5个动画: 播放anim1: 同时播放anim2,anim3,a ...