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;