requestAnimationFrame替代setTimout 和 setInterval的方案

requetAnimationFrame

requestAnimationFrame的基本用法

let myReq
let i = 0 
function step(timestamp){
	// step的函数体
	console.log(i++)
	myReq = window.requestAnimationFram(step)
}
document.onclick = function(){
	window.cancelAnimationFrame(myReq)
}

requetAnimationFrame 替代setInterval

如果我们想用requestAnimationFrame实现动画,不难发现它现在只能根据浏览器的刷新频率自动执行(频率为60HZ时,每秒执行60次),而不能自定义每秒次数,所以我们可以封装一下

思路
目标: animate(cb, time)

1. requestAnimationFrame() , 每秒执行60次,即 1000ms执行 60次
2. eg: 要想达到animate(cb,1000)  每秒调用一次cb函数,应该怎么做? 
3. 首先用一个计数器记录requestAnimationFrame() 执行的次数,也就是说 60次 为1秒,1秒到了就应该立即执行cb 。依次类推。
 animation(cb, 1000ms){
	let i = 0 
	let myReq;
	myReq = requestAnimationFrame(function fn(){
			if( i %   60次  === 0  )){
				cb()
			}
			// i 用来记录requestAnimationFrame() 执行的次数,如果执行达到60次说明已经有1s钟了
			i++; 
			myReq = requestAnimationFrame(fn)
			window.myReq = myReq
	})
}
4. 那如果,想2s执行一次cb,3s执行一次cb呢?
    1s执行一次cb:      if(  i %  60次  === 0){  cb() }
    2s执行一次cb:         if( i % 120次 === 0){  cb() }  --->   i % (  60次  / ( 1000ms / 2000ms )  )
    3s执行一次cb:      if( i  % 180次 === 0){  cb() } ----> 1 % ( 60 次 /   (1000ms /  3000ms)  )
    ....
5. 因此,   if(i % 60 / (1000/timer) ===0) { cb() }
function animate(cb,time){
	let myReq;
	let i = 1;
	myReq = requestAnimationFrame(function fn(){

	if( i % parseInt(60/ (1000/time)) ){
		cb()
	}
	i++; // 记录requestAnimationFrame执行的次数
	myReq = requestAnimationFrame(fn)// 开启下次requestAnimationFrame
	window.myReq = myReq;
	})
}
animate(function(){
	console.log("这是回调函数的内容~");
},1000)
document.onClick = function(){
	// 清除动画
	cancelAnimationFrame(myReq)
}

requetAnimationFrame 替代setTimeout

和上述替代setInterval的方案一致,唯一的区别就是setTimeout只需要执行一次

function animateTimeout(cb,time){
	let myRef = null
	let i = 0 
	myRef = requestAnimationFrame(function fn(){
		if( i % parseInt(60 / (1000/time)) === 0 ){
			cb()
			window.cancelAnimation(myRef)			
		}
		i++
		myRef = requestAnimationFrame(fn)
	})
}
animateTimeout(function(){
	console.log('测试')
}, 1000)

requetAnimationFrame兼容性方案

const requestAnimationFrame = window.requestAnimationFrame 
|| window.mozRequestAnimationFram 
|| window.webkitRequestAnimationFrame 
|| window.msRequestAnimationFrame 
|| function(callback){ window.setTimeout(callback, 1000/ 60)}

const cancelAnimationFrame = window.cancelAnimationFrame 
|| window.mozCancelAnimationFrame;

参考文献
详解requestAnimationFrame,并模拟setInterval效果

使用requestAnimationFrame替换setInterval

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值