requestAnimationFrame动画控制详解

转载 2015年07月10日 15:07:38

还在使用setInterval吗,你out了,requestAnimationFrame可以实现更为经济、更加准确的控制动画,今天来看看它的来龙去脉。


以往

在web动画、app动画中,我们经常通过setInterval或setTimeout定时修改DOM、CSS实现动画,如下面代码所示。

var timer=setInterval(function(){
   //一些动画
},1000/60)
//清除动画
clearInterval(timer);

不过如此动画的方式极为耗费资源,经常是这样的结果,刚开始比较流畅,5分钟之后动画就卡住了,于是“大家”都看不下去了,开始想这种办法。

简介

2011年左右,Paul Irish的《 requestAnimationFrame for Smart Animating 》首先介绍了requestAnimationFrame的使用,然后经过大家的努力《 Timing control for script-based animations 》在2013年成为了w3c的候选标准。

requestAnimationFrame的方式的优势如下:

1.经过浏览器优化,动画更流畅

2.窗口没激活时,动画将停止,省计算资源

3.更省电,尤其是对移动终端

requestAnimationFrame的使用方式,简单调用代码如下。 

function animate() {
  // Do whatever
  requestAnimationFrame(animate);
  // Do something animate
  
}
//go->
requestAnimationFrame(animate);

有的时候我们必须要加一些控制, requestAnimationFrame也可以像setInterval一样返回一个句柄,然后我们可以取消它。控制动画代码如下。

var globalID;
function animate() {
  // Do whatever
  globalID=requestAnimationFrame(animate);
  // Do something animate
  
}
//when ot start
  globalID=requestAnimationFrame(animate);
//when to stop
  cancelAnimationFrame(globalID);

好了,介绍完了吧。先别走,对于一个前端开发者,我们不能如此“单纯”,因为浏览器太任性,谁知道这些浏览器都是怎么“想的”,我们要看看浏览器兼容情况。来上CanIUse 。


桌面端除了万恶的IE系列低版本9-,移动端除了Opera Mini和Android Browser4.3-其他都支持。总支持率83.38%,不加前缀支持率81.98%,支持率不错。作为一个富有极客精神的前端er,我们还得继续,拯救那些“手里没钱、手里有权却榆木疙瘩,还在使用低版本浏览器”的同胞,来个 polyfill 。

补丁

Paul Irish的简化版的补丁,补丁和使用如下代码所示。

// 补丁
window.requestAnimationFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();


// 使用

(function animate(){
  requestAnimationFrame(animate);
  //动画
})();

这个补丁可以较好的兼容支持该特性的浏览器,但是对于不支持的呢?这里讲了怎么添加,如何停止呢?于是我们的补丁还得继续……

(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);  
    };  
}());

有后来,又有了新更新,大家到 github查看详情 ,代码贴过来,大家研究。

// requestAnimationFrame polyfill by Erik Möller.
// Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon
// MIT license
if (!Date.now)
  Date.now = function() { return new Date().getTime(); };
(function() {
  'use strict';
  var vendors = ['webkit', 'moz'];
  for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
    var vp = vendors[i];
    window.requestAnimationFrame = window[vp+'RequestAnimationFrame'];
    window.cancelAnimationFrame = (window[vp+'CancelAnimationFrame']
                   || window[vp+'CancelRequestAnimationFrame']);
  }
  if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) // iOS6 is buggy
    || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
    var lastTime = 0;
    window.requestAnimationFrame = function(callback) {
      var now = Date.now();
      var nextTime = Math.max(lastTime + 16, now);
      return setTimeout(function() { callback(lastTime = nextTime); },
                nextTime - now);
    };
    window.cancelAnimationFrame = clearTimeout;
  }
}());

相关文章推荐

requestAnimationFrame动画控制详解

还在使用setInterval吗,你out了,requestAnimationFrame可以实现更为经济、更加准确的控制动画,今天来看看它的来龙去脉。...
  • whqet
  • whqet
  • 2015年01月20日 07:28
  • 8264

动画requestAnimationFrame实例

  • 2016年05月14日 22:53
  • 97KB
  • 下载

RequestAnimationFrame更好的实现Javascript动画

Javascript : RequestAnimationFrame更好的实现Javascript动画   ▼ 标签:  canvas   css3 ...

[前端] requestAnimationFrame 实现动画效果

概述 requestAnimationFrame是浏览器用于定时循环操作的一个接口,类似于setTimeout,主要用途是按帧对网页进行重绘。 设置这个API的目的是为了让各种网页动画效果(D...

优化JS动画之requestAnimationFrame

优化动画之requestAnimationFrame什么事requestAnimationFrame  requestAnimationFrame(请求动画帧)是浏览器的全局对象window下的一...

16 使用requestAnimationFrame()方法制作WebGL简单动画

首先上代码 Document body {

requestAnimationFrame,Web中写动画的另一种选择

requestAnimationFrame,Web中写动画的另一种选择 HTML5/CSS3时代,我们要在web里做动画选择其实已经很多了: 你可以用CSS3的...
  • cdnight
  • cdnight
  • 2016年02月19日 10:03
  • 363

性能更好的js动画实现方式——requestAnimationFrame

原文: http://www.cnblogs.com/2050/p/3871517.html 用js来实现动画,我们一般是借助setTimeout或setInterval这两个函数,css3...
  • for_cxc
  • for_cxc
  • 2016年06月06日 09:05
  • 157

CSS3动画那么强,requestAnimationFrame还有毛线用。

一、哟,requestAnimationFrame, 新同学,先自我介绍下 Hello, 大家好,我就是风姿卓越,万种迷人的requestAnimationFrame,呵呵呵呵。很高兴和...

HTML5 requestAnimationFrame( ) 动画API

简介当用JS做动画效果时,一般用setTimeout()或setInterval()来进行动画效果的制作,现在好了,出现了一个专门用于处理动画的API——requestAnimationFrame()...
  • lecepin
  • lecepin
  • 2016年12月02日 20:32
  • 802
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:requestAnimationFrame动画控制详解
举报原因:
原因补充:

(最多只允许输入30个字)