使用 Velocity.js 提升 UI 动画工作流

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

以下是 Julian Shapiro 的客座文章。Julian 最近发布了 Velocity.js,这是一个比 .animate() 性能更高的 jQuery 替代方案。他最近在 David Walsh 的博客上 撰写了关于 JavaScript 动画如何如此快速的 文章,我们也曾 在这里 讨论过这个话题。在这篇文章中,Julian 介绍了 Velocity.js 本身。

Velocity.js 是一个 jQuery 插件,它重新实现了 jQuery 的 $.animate() 函数,以产生更高的性能(在许多情况下,Velocity 也比 CSS 过渡更快),同时还包含一些新功能来改进动画工作流。

Velocity 压缩后只有 7Kb,包含了 $.animate() 的所有功能,同时还打包了变形动画、循环、类动画和滚动。简而言之,Velocity 旨在成为 jQuery、jQuery UI 和 CSS 过渡的最佳结合。

Velocity 在所有地方都能工作——回溯到 IE8 和 Android 2.3。此外,由于 Velocity 的语法与 $.animate() 的语法相同,因此您页面上的任何代码都不需要更改。

Velocity 的目标是在 DOM 动画性能和便利性方面成为领导者。本文重点关注后者。要了解有关前者的更多信息,请参阅 Velocity 在 VelocityJS.org 上的性能比较。特别是,本文演示了如何使用 Velocity 来改进您的 UI 动画工作流。在一个简洁的对比中,将 Velocity 的八个功能与其 jQuery 对应功能进行了比较。

如果您觉得当前的 UI 工作流混乱、分割不佳或过分依赖 jQuery 的各种样式函数,那么本演练适合您。

简要概述

在深入了解 Velocity 之前,让我们快速了解一下基础知识:需要指出的是,$.animate()$.velocity() 都支持灵活的选项语法。您可以将选项作为逗号分隔的值传递,也可以将选项作为独立的选项对象传递。

以下是用逗号分隔语法的一个示例,其中整数被视为动画的持续时间,字符串被视为缓动类型,函数被视为回调函数(在动画完成后触发)

$div.animate(
  { 
    opacity: 1 
  }, 
  1000, 
  "linear", 
  function() { 
    alert("Done animating."); 
  }
);

接下来,这是一个对象语法的示例

$div.animate(
  { 
    opacity: 1 
  }, 
  { 
    duration: 1000, 
    easing: "linear", 
    complete: function() { 
      alert("Done animating!") 
    }, 
    queue: "myQueue" 
  }
);

除了生成更清晰的代码外,使用选项对象还可以访问其他动画参数,而这些参数无法通过逗号分隔语法指定。

jQuery 提供的一个此类选项示例是“queue”。Velocity 也提供了 queue 选项,并且链到单个元素上的多个动画调用会自动排队。

这里,div 的不透明度将以 1000 毫秒动画到 1,然后在接下来的 1000 毫秒内动画回 0

$div
  .animate({ opacity: 1 }, 1000)
  .animate({ opacity: 0 }, 1000);

现在,在了解了基础知识后,让我们开始比较 Velocity 和 jQuery。

反转

Velocity 除了接受属性映射之外,还接受 "reverse" 作为其第一个参数。Reverse 将目标元素动画到其上一个 Velocity 调用之前的值。

在 jQuery 中,这就像

$div
  /* Fade an element in while sliding it into view. */
  .animate({ opacity: 1, top: "50%" })
  /* The values below are what we originally set the element to in our stylesheet. Animate back to them. */ 
  .animate({ opacity: 0, top: "-25%" });

在 Velocity 中,它更容易,因为它不仅代码更少,而且您不必重复样式表中的值

$div
  .velocity({ opacity: 1, top: "50%" })
  .velocity("reverse");

默认情况下,Velocity 的 reverse 命令使用传递到上一个 Velocity 调用的相同选项。可以通过将新选项传递到“reverse”调用中来扩展这些选项。例如

$div
  .velocity({ opacity: 1, top: "50%" }, 1000)
  /* Animate back to the prior visual state at half the duration of the previous animation. */
  .velocity("reverse", 500);

滚动

一种流行的 UI 技术是滚动浏览器,使其与页面下方某个元素对齐,然后使用引人注目的修饰来动画化该元素。使用 jQuery 实现此操作会涉及混乱且性能不佳的代码

在 jQuery 中,动画化 scrollTop 属性需要同时定位 html 元素和 body 元素,才能使动画在旧版 Internet Explorer 中正常工作。

$("html, body").animate(
  { 
    scrollTop: $div.offset().top 
  }, 
  1000, 
  function() {
    /* We use a callback to fade in the div once the browser has completed scrolling. */
    $div.animate({ opacity: 1 });
  }
);

在 Velocity 中,您可以定位要滚动到的元素

$div
  .velocity("scroll", 1000)
  .velocity({ opacity: 1 });

就像 Velocity 的“reverse”命令一样,“scroll”可以作为 Velocity 的第一个参数传递,以代替属性映射。与 reverse 命令一样,scroll 命令接受动画选项,并且可以链到其他调用中。

scroll 命令的行为很简单:将浏览器滚动到 Velocity 调用目标元素的顶部。

循环

通常,元素的动画需要循环。例如,摇动对话框以指示用户输入无效,或弹跳通知图标以吸引用户的注意力。

在 jQuery 中,循环动画需要通过将其一部分分解为 for 语句来弄乱动画逻辑

for (var i = 0; i < 5; i++) {
  $div
    /* Slide the element up by 100px. */
    .animate({ top: -100 })
    /* Then animate back to the original value. */
    .animate({ top: 0 });
}

在 Velocity 中,只需将 loop 选项设置为等于所需循环次数的整数即可。一个循环周期包括向属性映射中的值动画化,然后反向动画回原始值。

$div.velocity(
  { top: -100 }, 
  { loop: 5 }
);

淡入淡出元素

您经常会发现自己淡入一个最初将 display 属性设置为 none 的元素,以便该元素在页面加载时不会立即可见。随后淡入这些元素需要几行 jQuery 代码

$div
  /* Use jQuery's $.show() function to make the element visible by switching its display property to "block"/"inline" as appropriate. */
  .show()
  /* Set the element's starting opacity to 0 so that it can be gradually faded in by the subsequent animation call. */
  .css("opacity", 0)
  /* Fade in and slide into view. */
  .animate({ 
    opacity: 1, 
    top: "50%" 
  });

在 Velocity 中,您只需将 display 作为选项传递即可。display 选项接受与其 CSS 属性对应部分相同的取值集(例如,“block”、“inline”和“none”)。

$div.velocity(
  { 
    opacity: 1, 
    top: "50%" 
  },
  { 
    display: "block" 
  }
);

display 选项设置为除 none 之外的值时,元素的 display 属性会在动画的 开始 设置为提供的值。相反,当 display 传递的值为 none 时,display 属性会在动画 完成 时设置。

$div
  /* Fade out and slide out of view. */
  .animate({ opacity: 0, top: "-50%" })
  /* Then set the display property to "none" via a queued $.fadeOut() call. */
  .fadeOut(1);
$div.velocity(
  { 
    opacity: 0,
    top: "-50%" 
  }, 
  { 
    display: "none" 
  }
);

此外,如果元素的 opacity 正在动画化为非零值,而其 display 选项正在设置为除 none 之外的值,则 Velocity 会方便地将 opacity 的起始值默认为 0。

延迟

Velocity 接受 delay 选项,它取代了在动画代码中散布 $.delay() 调用的做法

$div
  .delay(1000)
  .animate({ 
    opacity: 1 
  });
$div.velocity(
  { 
    opacity: 1 
  }, 
  { 
    delay: 1000 
  }
);

除了将动画逻辑合并到单个调用中之外,使用 Velocity 的内置 delay 选项还允许 Velocity 通过缓存它们之间的值来优化链式动画。

序列

Velocity 独有的功能是 序列,它是动画的宏:动画序列创建一次,然后可以在需要时跨所有页面上的元素触发。

序列的好处包括:

  • 命名动画以实现更好的代码组织。
  • 将 UI 动画逻辑与 UI 交互逻辑分开。
  • 打包动画以在您的项目之间以及与其他开发人员共享。

序列是通过扩展 $.Velocity.Sequences 对象创建的。此后,通过将序列的名称作为 Velocity 的第一个参数传递来触发它们。

下面是一个简单的“hover”序列

$.Velocity.Sequences.hover = function (element, options) {
  var duration = options.duration || 750;

  $.Velocity.animate(element,
    { 
      translateY: "-=10px",
    }, { 
      /* Delay is relative to user-adjustable duration. */
      delay: duration * 0.033,
      duration: duration,
      loop: 3,
      easing: "easeInOutSine"
    });
};

现在,您可以将其应用于元素

$div.velocity("hover");

在上述序列中,元素向上然后向下平移 10px 三次(loop: 3),并带有短暂的延迟。

要了解有关序列细微差别的更多信息,请 阅读其文档

Velocity 使用其自己的序列功能预先打包了 fadeInfadeOutslideUpslideDown 函数(与它们的 jQuery 等效项相同)。

例如,将容器 div 向下滑动到视图中

$div.velocity("slideDown", function() {
  /* Then fade in its children over a duration of 1000ms. */
  $children.velocity("fadeIn", 1000);
});

强制硬件加速

在元素上强制启用硬件加速 (HA) 是一种简单易行的方法,可以显著提升移动设备上的动画性能。传统上,启用 HA 是通过将元素的 transform 属性设置为 `translateZ(0)` 来实现的。

$div
  .css("transform", "translateZ(0)")
  .animate({ opacity: 1 })
  .css("transform", "none");

在 Velocity 中,HA 会自动应用于移动设备(桌面设备上不会带来性能提升)。Velocity 对 HA 的控制进行了高度优化。

$div.velocity({ opacity: 1 });

总结

本教程的目的是演示 Velocity 如何将动画逻辑整合到你的代码中。简而言之,Velocity 是一款功能强大且高效的 UI 动画制作工具。

虽然 jQuery 功能非常强大,但它从未将自身定位为一个优化的动画引擎,因此在性能和工作流程方面存在一些不足。Velocity 压缩后仅 7Kb,却包含了足够多的功能和速度提升,足以让你考虑将其作为首选动画引擎。

要探索 Velocity 的其他功能,包括颜色和变换动画,请查看 Velocity 的文档 VelocityJS.org。

在结束之前,让我们看看一些通过 Velocity 的功能和速度实现的极端 Web 动画示例。