HTML5动画API:requestAnimationFrame和cancelAnimationFrame使用
七娃博客55人阅读
requestAnimationFrame是HTML5用于浏览器为动画提供API(类似setTimeout定时器)的一种刷新机制,根据设备的屏幕刷新频率有关,例如:60Hz 的刷新频率就相当于一秒刷新60次,平均16.7ms执行一次。
与setTimeout不一样的是:不需要设置时间间隔,如同上面说的,默认间隔是由设备系统的屏幕刷新频率决定的。
requestAnimationFrame用法
let raf = window.requestAnimationFrame(fun) //接受一个回调函数,返回一个数字类型的动画id
执行动画如果不做防抖处理,也会和setTimeout一样,动画越来越快——“被加速”,使用的时候一定要注意。
清除requestAnimationFrame动画需要用cancelAnimationFrame,如下:
window.cancelAnimationFrame(raf)
动画案例
利用requestAnimationFrame实现一个盒子移动的动画,left小于500的时候终止动画,代码如下:
HTML代码:
<style type="text/css"> #box{width: 100px;height: 100px;background: red;position: absolute;left: 0;top: 50px;} </style> <button onclick="start()">start</button> <button onclick="end()">end</button> <div id="box"></div>
JS代码
let lefts = 0,tops=0,ref,flag = false; let box = document.getElementById("box") function move(){ if(lefts<500 ){ lefts++; tops=tops+1; }else{ lefts = 0 tops = 0 } box.style.left=lefts+'px' box.style.top=tops+'px' ref = window.requestAnimationFrame(move) } function end(){ if(ref){ flag = false window.cancelAnimationFrame(ref) } } function start(){ //防抖,不然动画会越来越快 if(!flag){ flag = true ref = window.requestAnimationFrame(move) } }
效果如下:
关于兼容性
现代浏览器随便玩,毕竟是HTML5官方的api,支持率还是可以的,如果是老版本内核,或者IE系列的话还是需要回退到setTimeout定时器时代。网上有以下兼容代码,可以借鉴:
// 使用 Date.now 获取时间戳性能比使用 new Date().getTime 更高效 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"]; } // 上面方法都不支持的情况,以及IOS6的设备 // 使用 setTimeout 模拟实现 if ( /iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame ) { var lastTime = 0; // 和通过时间戳实现节流功能的函数相似 window.requestAnimationFrame = function(callback) { var now = Date.now(); var nextTime = Math.max(lastTime + 16, now); // 实际上第1帧是不准确的,首次nextTime - now = 0 return setTimeout(function() { callback((lastTime = nextTime)); }, nextTime - now); }; window.cancelAnimationFrame = clearTimeout; } })();
以上就是requestAnimationFrame简单的用法了,可以利用这个刷新机制使svg,canvas,Dom等动起来,大家学起来,用起来!2023年的第一篇文章,又是从新开始的一年,也是学习不停的一年,加油!
评论 | 0 条评论
登录之后才可留言,前往登录