requestAnimationFrame
动画的原理
物体通过连续不断的改变物体的位置,而发生移动变化,当这种变化过快时,在我们人眼中就形成了连续不断的动画。
requestAnimationFrame的由来
当我们想要使用JS实现一个动画,大家肯定先想到使用setInterval,刚开始我也是,我想说的是,虽然这样也行,也可以达成目的,不过效果不是很好,他很有可能会造成丢帧的显现(即使是设置了16.6ms,不过但有一些屏幕的刷新频率低于60HZ的时候,那么就会出现问题——丢帧),为了解决这个问题,一个新的解决方法就出现了——requestAnimationFrame
requestAnimationFrame的优点
- 与setTimeout相比,requestAnimationFrame最大的优势是由系统来决定回调函数的执行时机。具体一点讲,如果屏幕刷新率是60Hz,那么回调函数就每16.7ms被执行一次,如果刷新率是75Hz,那么这个时间间隔就变成了1000/75=13.3ms,换句话说就是,requestAnimationFrame的步伐跟着系统的刷新步伐走。它能保证回调函数在屏幕每一次的刷新间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。
- CPU节能
- 函数节流
requestAnimationFrame的实现
在这个新的东西出现之前,让我们来看看我们以前是如何制作一个动画的:
<!doctype html>
<html lang="en">
<head>
<title>Document</title>
<style>
#e {
width: 100px;
height: 100px;
background: red;
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div id="e"></div>
<script>
var e = document.getElementById("e");
var flag = true;
setInterval(function () {
if (flag == true) {
if (e.offsetLeft >= 100) {
flag = false
}
e.style.left = e.offsetLeft + 1 + 'px'
} else {
if (e.offsetLeft <= 0) {
flag = true
}
e.style.left = e.offsetLeft - 1 + 'px'
}
}, 16.6)
</script>
</body>
</html>
最终实现的效果如下——这是一个循环的动画:
然后使用requestAnimationFrame的用法如下:
<!doctype html>
<html lang="en">
<head>
<title>Document</title>
<style>
#e {
width: 100px;
height: 100px;
background: red;
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div id="e"></div>
<script>
var e = document.getElementById("e");
var flag = true;
function fn() {
if (flag == true) {
if (e.offsetLeft >= 100) {
flag = false
}
e.style.left = e.offsetLeft + 1 + 'px'
} else {
if (e.offsetLeft <= 0) {
flag = true
}
e.style.left = e.offsetLeft - 1 + 'px'
}
}
(function loop() {
fn()
window.requestAnimationFrame(loop)
})()
</script>
</body>
</html>
最终实现的效果一样:
关于requestAnimationFrame的其他用法请点击这里