我相信网页动画不仅有趣,而且引人入胜,可以将网站的访问者转化为客户。 想想 Twitter 上的“点赞”按钮。 当您“点赞”一条推文时,细小的彩色气泡会在爱心按钮周围扩散,而爱心按钮则会变形为按钮周围的圆圈,然后最终变成红色填充的“点赞”状态。 如果爱心按钮只是从空心变成实心,那就会少了很多乐趣。 这种兴奋和满足感是动画如何增强用户体验的完美例证。
本文将介绍使用 Adobe After Effects 动画和 Lottie 在网页上渲染动画的概念,这使得高级动画(例如 Twitter 按钮)成为可能。

Bodymovin 是 Adobe After Effects 的一个插件,它将动画导出为 JSON,而 Lottie 是一个库,可以在移动设备和网页上本地渲染这些动画。 它是由 Hernan Torrisi 创建的。 如果您正在想 哦,我不使用 After Effects,这篇文章可能不适合我
,请稍等片刻。 我也不使用 After Effects,但我曾在项目中使用过 Lottie。
当然,您并不必须使用 Lottie 来在网页上进行动画。 一种替代方法是从头开始设计动画。 但这可能很费时,尤其是对于 Lottie 擅长的复杂动画类型而言。 另一种替代方法是使用 GIF 动画,这种动画可以显示无限类型的动画,但通常是 Bodymovin 生成的 JSON 文件的两倍大小。
所以让我们开始吧,看看它是如何工作的。
获取 JSON
要使用 Lottie,我们需要一个包含 After Effects 中动画的 JSON 文件。 对我们来说幸运的是,Icons8 提供了许多免费的动画图标 这里,包括 JSON、GIF 和 After Effects 格式。

将脚本添加到 HTML
我们还需要在 HTML 中获取 Bodymovin 播放器的 JavaScript 库,并调用其 loadAnimation()
方法。 基本原理在这里演示
<div id="icon-container"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.7.4/lottie.min.js">
<script>
var animation = bodymovin.loadAnimation({
// animationData: { /* ... */ },
container: document.getElementById('icon-container'), // required
path: 'data.json', // required
renderer: 'svg', // required
loop: true, // optional
autoplay: true, // optional
name: "Demo Animation", // optional
});
</script>
激活动画
动画加载到容器中后,我们可以使用事件监听器配置动画的激活方式和触发动画的动作。 以下是要使用的属性
container
:加载动画的 DOM 元素path
:包含动画的 JSON 文件的相对路径renderer
:动画的格式,包括 SVG、canvas 和 HTMLloop
:布尔值,用于指定动画是否应循环播放autoplay
:布尔值,用于指定动画是否应在加载后立即播放name
:用于将来引用的动画名称
请注意,在前面的示例中,animationData
属性已注释掉。 它与 path
属性互斥,并且是一个包含已导出动画数据的对象。
让我们尝试一个示例
我想用这个 动画播放/暂停控制图标 演示如何使用 Lottie,这个图标来自 Icons8

Bodymovin 播放器库是静态托管的 这里,可以这样将其放到 HTML 中,但它也可以作为包使用
npm install lottie-web ### or yarn add lottie-web
然后,在您的 HTML 文件中,包含已安装包中 dist
文件夹中的脚本。 您也可以从 Skypack 导入库作为模块
import lottieWeb from "https://cdn.skypack.dev/lottie-web";
现在,我们的暂停按钮处于循环播放状态,并且还会自动播放
让我们将其更改为由动作触发动画。
触发动画
如果我们将 autoplay
关闭,我们将看到一个静态的暂停图标,因为这是它从 After Effects 导出的方式。
但不用担心! Lottie 提供了一些方法,这些方法可以应用于动画实例。 也就是说,the npm 包的文档 更全面。
我们需要在这里做几件事
- 使其最初显示为“播放”状态。
- 在点击时将其动画设置为“暂停”状态。
- 在后续点击时在两者之间进行动画切换。
goToAndStop(value, isFrame)
方法在这里适用。 当动画加载到容器中时,此方法会将动画设置为转到提供的 value,然后在该位置停止。 在这种情况下,我们必须找到动画在播放时的值并将其设置。 第二个参数指定提供的 value 是基于时间还是帧。 它是一个布尔类型,默认值为 false
(即基于时间的 value)。 因为我们要将动画设置为播放帧,所以我们将其设置为 true
。
基于时间的 value 会将动画设置为时间轴上的特定点。 例如,动画开始时的暂停时间值为 1
。 但是,基于帧的 value 会将动画设置为特定帧值。 根据 TechTerms 的说法,帧是图像序列中的单个图片。 所以,如果我将动画的帧值设置为 5
,动画将转到动画中的第五帧(在这种情况下为“图像序列”)。
尝试了不同的值后,我发现动画从帧值 11 到 16 播放。 因此,我选择 14 作为安全起见。
现在,我们必须将动画设置为在用户点击时更改为暂停,并在用户再次点击时播放。 接下来,我们需要 playSegments(segments, forceFlag)
方法。 segments
参数是一个包含两个数字的数组类型。 第一个和第二个数字分别表示方法应读取的第一个和最后一个帧。 forceFlag
是一个布尔值,指示方法是否应立即触发。 如果设置为 false
,它将等到动画播放到 segments
数组中指定为第一个帧的值后才会触发。 如果设置为 true
,它将立即播放片段。
在这里,我创建了一个标志,用于指示何时从播放到暂停,以及从暂停到播放播放片段。 我还将 forceFlag
布尔值设置为 true
,因为我想要立即过渡。
就这样! 我们将 After Effects 中的动画渲染到了浏览器! 感谢 Lottie!
画布?
我更喜欢使用 SVG 作为渲染器,因为它支持缩放,而且我认为它可以渲染最清晰的动画。 Canvas 渲染效果不太好,而且也不支持缩放。 但是,如果您想使用现有画布来渲染动画,您需要做一些 额外的事情。
做更多事情
动画实例还有一些事件,也可以用来配置动画的行为。
例如,在下面的 Pen 中,我在动画中添加了两个事件监听器,并设置了一些文本,以便在触发事件时显示。
所有事件都可以在 npm 包的 文档 中找到。 这样一来,您可以继续渲染一些令人惊叹的动画!
我曾在与团队合作的项目中见过 Lottie 的使用,但从未查看过它。
这真是一个救星。
感谢分享。
不客气。
您好!我不明白这段代码的目的是什么,因为除了复数词“时间/次”之外,count === 1 和 count >== 1 之间似乎没有区别。
if(count !== 1) {
document.body.lastChild.textContent = text;
} else document.body.appendChild(p);
好的,当动画加载时,一个
<p>
元素会通过 DOMLoaded 事件附加到<body>
元素(即,添加到关闭</body>
标记之前)。现在,当动画播放一次时,我们想要显示:“您已播放动画 1 次……”。
当它再次播放时,我们想要更新动画播放的次数(即,“您已播放动画 2 次……”)。
所以,该条件块的作用是检查显示动画计数的
<p>
元素是否存在。如果存在,则更新元素的内容。如果不存在,则将<p>
元素附加到<body>
元素。现在,如果该块不存在,将会有多个
<p>
元素用于动画播放的不同次数。希望这很清楚。
感谢您提供精彩的文章,Idorenyin!
我正在尝试根据“喜欢按钮”的 Lottie 动画是否具有 CSS 类来显示它。例如,如果页面加载时它具有类“liked”,则 Lottie 动画应显示最后一帧(一个填充的红色心形),如果它没有类“liked”,则它应显示初始帧(只是心形的轮廓)。单击时,它应该播放动画。
您知道这是否可行吗?
谢谢!
嗨,Drew,
我建议您使用按钮的单击事件处理程序和窗口的加载事件处理程序。在加载事件处理程序中,如果按钮具有“liked”类,则可以使用 Lottie 的
goToAndStop()
方法显示喜欢的帧。如果它不存在,则显示初始轮廓帧,如下所示const button = document.querySelector('#like-button');
window.addEventListener('load', () => {
if(button.classList.contains('liked')) {
previouslyLoadedAnimation.goToAndStop(15, true); // 假设第 15 帧是喜欢的帧
} else {
previouslyLoadedAnimation.goToAndStop(0, true);
}
});
然后,在按钮的单击事件处理程序中,检查类是否存在。然后,使用 Lottie 的
playSegments()
方法播放预期的动画。以下是一个示例button.addEventListener('click', () => {
if(button.classList.contains('liked')) {
previouslyLoadedAnimation.playSegments([15, 30], true);
button.classList.remove('liked');
} else {
previouslyLoadedAnimation.playSegments([0, 15], true);
button.classList.add('liked');
}
});
希望这有帮助,我很高兴你喜欢这篇文章。
感谢 Idorenyin!我设法让它工作了。唯一的问题似乎是 Lottie 的“容器”参数。它似乎只在它找到的第一个元素上加载 Lottie(我做了一些类似的事情
`var button = document.querySelector(“.bodymovinanim”);
var buttonAnim = bodymovin.loadAnimation({
container: button,
renderer: “svg”,
loop: false,
autoplay: false,
path: “data.json”
});`
不确定为什么它没有在页面上的其他按钮上加载。每个按钮使用相同的类,但具有不同的数据属性。
嗨,Drew,
querySelector()
方法返回第一个匹配元素。您要使用的是querySelectorAll()
方法。然后您需要在该集合中返回的所有元素中加载动画。这就是我的意思const buttons = document.querySelectorAll('.bodymovinanim');
buttons.forEach((element) => {
const animation = bodymovin.loadAnimation({
container: element,
renderer: 'svg',
// 其余...
});
});
希望这有帮助。
太棒了!谢谢!
这些动画会使页面渲染或性能变慢吗?
加载动画时可能会出现延迟,因为要获取所需的 JSON 文件。但是,这种情况发生在 JSON 文件位于与网页不同的源的情况下。
此外,如果您使用 Skypack 而不是 npm,则可以避免由于另一个依赖项造成的性能延迟。
希望这有帮助!
css-tricks 真是救命稻草!我在任何地方都没有找到这个用于 Lottie 动画的 onClick 动画更改!非常感谢 :)
不客气!
如何根据从范围滑块获得的值设置 Lottie 动画的帧位置。
例如,一个动画有 400 帧,范围滑块有 min:1 max:400,我希望从滑块获取值
然后显示相应的帧。
为此,要使用的适当 Lottie 方法是
goToAndStop(value, isFrame)
方法。value
参数将是从范围滑块获取的值,而isFrame
参数将设置为 true,因为它是您希望动画转到的帧。希望这有帮助!
嗨,我尝试在 asp.net default.aspx 页面中使用您在最后一部分“做更多”中的代码,并出现错误
Uncaught SyntaxError: Cannot use import statement outside a module
在以下代码行中。
import lottieWeb from ‘https://cdn.skypack.dev/lottie-web’;
有什么建议吗?
在包含脚本元素的 html 文件中,将
type=“module”
属性添加到脚本开始标签中。您好,
我试图让动画播放,然后在特定时间暂停,然后在变量从 false 更改为 true 时完成动画。
我将 isMarkerVisited 设置为 false,然后
if (isMarkerVisited === true) {animation.playSegements([37, 141], true)}
但是当我尝试在控制台中将变量更改为 true 时,什么也没有发生。