JavaScript 动画应该通过 requestAnimationFrame
实现。该内置方法允许设置回调函数,以便在浏览器准备重绘时运行。那通常很快,但确切的时间取决于浏览器。
当页面在后台时,根本没有重绘,因此回调将不会运行:动画将被暂停并且不会消耗资源。那很棒。
这是设置大多数动画的 helper 函数 animate
:
function animate({timing, draw, duration}) {
let start = performance.now();
requestAnimationFrame(function animate(time) {
// timeFraction 从 0 增加到 1
let timeFraction = (time - start) / duration;
if (timeFraction > 1) timeFraction = 1;
// 计算当前动画状态
let progress = timing(timeFraction);
draw(progress); // 绘制
if (timeFraction < 1) {
requestAnimationFrame(animate);
}
});
}
参数 :
duration
—— 动画运行的总毫秒数。timing
—— 计算动画进度的函数。获取从 0 到 1 的小数时间,返回动画进度,通常也是从 0 到 1。draw
—— 绘制动画的函数。
示例 :
animate({
duration: 3000,
timing: bounceEaseInOut,
draw: function(progress) {
brick.style.left = progress * 500 + 'px';
}
});
easeOut
// 接受时序函数,返回变换后的变体
function makeEaseOut(timing) {
return function(timeFraction) {
return 1 - timing(1 - timeFraction);
}
}
easeInOut
function makeEaseInOut(timing) {
return function(timeFraction) {
if (timeFraction < .5)
return timing(2 * timeFraction) / 2;
else
return (2 - timing(2 * (1 - timeFraction))) / 2;
}
}