requestAnimationFrame绘制图像

2024-05-26 01:58

本文主要是介绍requestAnimationFrame绘制图像,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载自http://blog.csdn.net/whqet/article/details/42911059

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


------------------------------------------------------------

--我参加了博客之星评选,如果你喜欢我的博客,求投票,您的支持是我的动力之源,走起!

-----------------------------------------------------------------------------------------------------------------

以往

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

[javascript] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. var timer=setInterval(function(){  
  2.    //一些动画  
  3. },1000/60)  
  4. //清除动画  
  5. clearInterval(timer);  

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

简介

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

requestAnimationFrame的方式的优势如下:

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

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

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

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

[javascript] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. function animate() {  
  2.   // Do whatever  
  3.   requestAnimationFrame(animate);  
  4.   // Do something animate  
  5.     
  6. }  
  7. //go->  
  8. requestAnimationFrame(animate);  

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

[javascript] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. var globalID;  
  2. function animate() {  
  3.   // Do whatever  
  4.   globalID=requestAnimationFrame(animate);  
  5.   // Do something animate  
  6.     
  7. }  
  8. //when ot start  
  9.     globalID=requestAnimationFrame(animate);  
  10. //when to stop  
  11.     cancelAnimationFrame(globalID);  

好了,介绍完了吧。

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

来,上CanIUse。


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

补丁

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

[javascript] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // 补丁  
  2. window.requestAnimationFrame = (function(){  
  3.   return  window.requestAnimationFrame       ||  
  4.           window.webkitRequestAnimationFrame ||  
  5.           window.mozRequestAnimationFrame    ||  
  6.           function( callback ){  
  7.             window.setTimeout(callback, 1000 / 60);  
  8.           };  
  9. })();  
  10.   
  11.   
  12. // 使用  
  13.   
  14. (function animate(){  
  15.   requestAnimationFrame(animate);  
  16.   //动画  
  17. })();  

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

[javascript] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. (function() {    
  2.     var lastTime = 0;    
  3.     var vendors = ['ms''moz''webkit''o'];    
  4.     for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {    
  5.         window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];    
  6.         window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']     
  7.                                    || window[vendors[x]+'CancelRequestAnimationFrame'];    
  8.     }    
  9.      
  10.     if (!window.requestAnimationFrame)    
  11.         window.requestAnimationFrame = function(callback, element) {    
  12.             var currTime = new Date().getTime();    
  13.             var timeToCall = Math.max(0, 16 - (currTime - lastTime));    
  14.             var id = window.setTimeout(function() { callback(currTime + timeToCall); },     
  15.               timeToCall);    
  16.             lastTime = currTime + timeToCall;    
  17.             return id;    
  18.         };    
  19.      
  20.     if (!window.cancelAnimationFrame)    
  21.         window.cancelAnimationFrame = function(id) {    
  22.             clearTimeout(id);    
  23.         };    
  24. }());  

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

[javascript] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // requestAnimationFrame polyfill by Erik Möller.  
  2. // Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon  
  3.   
  4. // MIT license  
  5.   
  6. if (!Date.now)  
  7.     Date.now = function() { return new Date().getTime(); };  
  8.   
  9. (function() {  
  10.     'use strict';  
  11.       
  12.     var vendors = ['webkit''moz'];  
  13.     for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {  
  14.         var vp = vendors[i];  
  15.         window.requestAnimationFrame = window[vp+'RequestAnimationFrame'];  
  16.         window.cancelAnimationFrame = (window[vp+'CancelAnimationFrame']  
  17.                                    || window[vp+'CancelRequestAnimationFrame']);  
  18.     }  
  19.     if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) // iOS6 is buggy  
  20.         || !window.requestAnimationFrame || !window.cancelAnimationFrame) {  
  21.         var lastTime = 0;  
  22.         window.requestAnimationFrame = function(callback) {  
  23.             var now = Date.now();  
  24.             var nextTime = Math.max(lastTime + 16, now);  
  25.             return setTimeout(function() { callback(lastTime = nextTime); },  
  26.                               nextTime - now);  
  27.         };  
  28.         window.cancelAnimationFrame = clearTimeout;  
  29.     }  
  30. }());  

当然,实战的时候我们把这些代码单独放到一个文件中,到这里下载。

案例

最后,我们来个粒子案例,体会体会requestAnimatonFrame的使用。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------
== 粒子案例== 全屏预览== 在线编辑== 下载收藏==
------------------------------------------------------------------------------------------------------------------------------------------------------------------------

参考文献和深入阅读

1. Paul Irish, requestAnimationFrame for Smart Animating

2. MDN, Window.requestAnimationFrame()

3. Chris Coyier, Using requestAnimationFrame

4. Matt West, Efficient Animations with requestAnimationFrame

5. W3C CR, Timing control for script-based animations

6. Polyfill for requestAnimationFrame/cancelAnimationFrame

7. 张鑫旭, CSS3动画那么强,requestAnimationFrame还有毛线用?

8. 朱永盛, 理解WebKit和Chromium: 渲染主循环(main loop)和requestAnimationFrame

感谢您耐心读完,如果对您有帮助,请支持我

----------------------------------------------------------

前端开发whqet,关注web前端开发,分享相关资源,欢迎点赞,欢迎拍砖。







==========================================================================================

以上是原文内容  下面是我对绘制上面canvas的js脚本的注解


//解决Date.now() 函数的浏览器支持问题
if (!Date.now)
    Date.now = function() { return new Date().getTime(); };
    
    
//解决requestAnimationFrame的浏览器支持问题
(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;
    }
}());

//定义获取随机颜色的函数
var getRandomColor = function(){
  return '#'+(Math.random()*0xffffff<<0).toString(16);
}

//获取绘图对象
var canvas = document.getElementById("motion"),
    c = canvas.getContext("2d"),
    particles = {},  //定义记录颗粒的数组
    particleIndex = 0,  //颗粒index
    particleNum = 0.2;   //一个限定值 来控制颗粒出现的概率  具体见后文

canvas.width = window.innerWidth/2;
canvas.height = window.innerHeight/2;

//生成一个颗粒相关的参数
function Particle(){
  this.x = canvas.width/2;   //所在位置
  this.y = canvas.height/2;

  this.vx = Math.random() * 6 - 3;  //偏移参数
  this.vy = Math.random() * 4 - 2;

  this.growth = ( Math.abs(this.vx) + Math.abs(this.vy) ) * 0.007;

  particleIndex++;
  particles[particleIndex] = this;
  this.id = particleIndex;
  this.size = Math.random() * 1;
  this.color = getRandomColor();
}

//定义绘图函数
Particle.prototype.draw = function(){
  this.x += this.vx;
  this.y += this.vy;

  this.size += this.growth;
  if(this.x > canvas.width || this.y > canvas.height){
    delete particles[this.id];
  }
//调用从canvas拿来的上下文对象绘图
  c.fillStyle = this.color;
  c.beginPath();
  c.arc(this.x, this.y, this.size,0*Math.PI,2*Math.PI);
  c.fill();
};

//动画
function animate(){
  requestAnimationFrame( animate );
  //绘制背景黑幕
  c.fillStyle = "#000";
  c.fillRect(0,0,canvas.width,canvas.height);
  //决定是否产生新点
  if(Math.random() > particleNum){
    new Particle();
  }
  //绘制点
  for(var i in particles){
    particles[i].draw();
  }
}

//开始动画
requestAnimationFrame( animate );

这篇关于requestAnimationFrame绘制图像的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1003238

相关文章

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

c/c++的opencv图像金字塔缩放实现

《c/c++的opencv图像金字塔缩放实现》本文主要介绍了c/c++的opencv图像金字塔缩放实现,通过对原始图像进行连续的下采样或上采样操作,生成一系列不同分辨率的图像,具有一定的参考价值,感兴... 目录图像金字塔简介图像下采样 (cv::pyrDown)图像上采样 (cv::pyrUp)C++ O

QT6中绘制UI的两种方法详解与示例代码

《QT6中绘制UI的两种方法详解与示例代码》Qt6提供了两种主要的UI绘制技术:​​QML(QtMeta-ObjectLanguage)​​和​​C++Widgets​​,这两种技术各有优势,适用于不... 目录一、QML 技术详解1.1 QML 简介1.2 QML 的核心概念1.3 QML 示例:简单按钮

Python+wxPython构建图像编辑器

《Python+wxPython构建图像编辑器》图像编辑应用是学习GUI编程和图像处理的绝佳项目,本教程中,我们将使用wxPython,一个跨平台的PythonGUI工具包,构建一个简单的... 目录引言环境设置创建主窗口加载和显示图像实现绘制工具矩形绘制箭头绘制文字绘制临时绘制处理缩放和旋转缩放旋转保存编

python+OpenCV反投影图像的实现示例详解

《python+OpenCV反投影图像的实现示例详解》:本文主要介绍python+OpenCV反投影图像的实现示例详解,本文通过实例代码图文并茂的形式给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前言二、什么是反投影图像三、反投影图像的概念四、反向投影的工作原理一、利用反向投影backproj

Python使用Matplotlib绘制3D曲面图详解

《Python使用Matplotlib绘制3D曲面图详解》:本文主要介绍Python使用Matplotlib绘制3D曲面图,在Python中,使用Matplotlib库绘制3D曲面图可以通过mpl... 目录准备工作绘制简单的 3D 曲面图绘制 3D 曲面图添加线框和透明度控制图形视角Matplotlib

使用Python实现图像LBP特征提取的操作方法

《使用Python实现图像LBP特征提取的操作方法》LBP特征叫做局部二值模式,常用于纹理特征提取,并在纹理分类中具有较强的区分能力,本文给大家介绍了如何使用Python实现图像LBP特征提取的操作方... 目录一、LBP特征介绍二、LBP特征描述三、一些改进版本的LBP1.圆形LBP算子2.旋转不变的LB

OpenCV图像形态学的实现

《OpenCV图像形态学的实现》本文主要介绍了OpenCV图像形态学的实现,包括腐蚀、膨胀、开运算、闭运算、梯度运算、顶帽运算和黑帽运算,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起... 目录一、图像形态学简介二、腐蚀(Erosion)1. 原理2. OpenCV 实现三、膨胀China编程(

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像