JavaScript 动画应该通过 requestAnimationFrame 实现。该内置方法允许设置回调函数,以便在浏览器准备重绘时运行。那通常很快,但确切的时间取决于浏览器。
当页面在后台时,根本没有重绘,因此回调将不会运行:动画将被暂停并且不会消耗资源。那很棒。
这是设置大多数动画的 helper 函数 animate

  1. function animate({timing, draw, duration}) {
  2. let start = performance.now();
  3. requestAnimationFrame(function animate(time) {
  4. // timeFraction 从 0 增加到 1
  5. let timeFraction = (time - start) / duration;
  6. if (timeFraction > 1) timeFraction = 1;
  7. // 计算当前动画状态
  8. let progress = timing(timeFraction);
  9. draw(progress); // 绘制
  10. if (timeFraction < 1) {
  11. requestAnimationFrame(animate);
  12. }
  13. });
  14. }

参数 :

  • duration —— 动画运行的总毫秒数。
  • timing —— 计算动画进度的函数。获取从 0 到 1 的小数时间,返回动画进度,通常也是从 0 到 1。
  • draw —— 绘制动画的函数。

示例 :

  1. animate({
  2. duration: 3000,
  3. timing: bounceEaseInOut,
  4. draw: function(progress) {
  5. brick.style.left = progress * 500 + 'px';
  6. }
  7. });

easeOut

  1. // 接受时序函数,返回变换后的变体
  2. function makeEaseOut(timing) {
  3. return function(timeFraction) {
  4. return 1 - timing(1 - timeFraction);
  5. }
  6. }

easeInOut

  1. function makeEaseInOut(timing) {
  2. return function(timeFraction) {
  3. if (timeFraction < .5)
  4. return timing(2 * timeFraction) / 2;
  5. else
  6. return (2 - timing(2 * (1 - timeFraction))) / 2;
  7. }
  8. }