我被问到最多的问题是:您推荐什么动画工具?
使用过很多工具后,我可以告诉您 **没有正确答案**。这是一个复杂的问题,答案也很复杂。这篇文章旨在阐明何时使用什么工具,从而帮助您使用合适的工具完成工作。
如果您是 React 用户,我们也为您准备了内容!请跳至下方 React 部分,我们将分解要使用什么以及如何使用它。
不可能涵盖所有现有的动画库,因此我将重点介绍我使用过或感兴趣的库。请记住,这些是我根据自身经验给出的建议,Web 世界存在很多灰色地带,因此您可能会有不同的体验或意见。这没问题。
原生动画
在讨论任何库之前,让我们先了解一些原生动画实现。大多数库都在底层使用了原生动画技术,因此您对这些技术的了解越多,在抽象化发生时就越能理解正在发生的事情。
CSS
CSS 仍然是我最喜欢的动画方式之一。我使用它已经很多年了,并且继续 成为它的粉丝,因为它 **易读且性能出色**。CSS 动画使您可以使用一组 关键帧 在不同状态之间进行过渡。
优点
- 您不需要外部库。
- 性能非常好,尤其是在执行本质上是硬件加速(卸载到 GPU)的操作时。 这是一篇关于相关属性的文章,可以帮助您实现这一点。
- 预处理器(如 Sass 或 Less)允许您创建变量(用于缓动函数或时间等),您希望这些变量保持一致,以及在函数中使用
:nth-child
伪类以产生交错效果。 - 您可以使用 原生 JavaScript 监听
onAnimationEnd
和一些其他动画钩子。 - 沿路径运动 即将推出,这将非常棒。
- 它易于用于响应式开发,因为您可以使用 媒体查询 修改动画。
缺点
- 贝塞尔缓动 可能有点限制。由于只有两个控制点来塑造贝塞尔曲线,因此无法产生一些复杂的物理效果,而这些效果对于逼真的运动很有用(但并非总是必要)。
- **如果您要连续链接三个以上的动画,我建议切换到 JavaScript。** CSS 中的动画排序会因为延迟而变得复杂,并且如果调整时间,您最终需要进行大量重新计算。 查看 Val Head 的这篇示例,它说明了我的意思。 交错效果也更容易用 JavaScript 编写。您可以挂接到我之前提到的原生 JavaScript 事件以解决此问题,但这会导致在语言之间切换上下文,这也不是理想的选择。长而复杂、顺序的动画更容易用 JavaScript 编写和阅读。
- 对沿路径运动的支持尚未到位。您可以在此处为 Firefox 投票 支持。据我所知,在 Safari 中投票支持的方式更个性化。我注册了 填写错误报告 并请求将 CSS 中的运动路径模块作为一项功能。
- CSS + SVG 动画在行为上有一些奇怪的特性。例如,在 Safari 浏览器中,不透明度和变换组合可能会失败或产生奇怪的效果。另一个例子是,规范中对变换原点的定义,当顺序应用时,可能会以 非直观的方式 显示。这是规范的编写方式。希望 SVG 2 会对此有所帮助,但目前,CSS 和 SVG 在移动设备上有时需要使用奇怪的技巧才能正常工作。
requestAnimationFrame
requestAnimationFrame
(rAF) 是 JavaScript 中 window 对象上可用的原生方法。它非常棒,因为在底层,它会确定您所处环境中动画的适当帧速率,并且只会将其推送到该级别。例如,当您在移动设备上时,它不会像在桌面设备上那样使用那么高的帧速率。当标签页处于非活动状态时,它也会停止运行,以避免不必要地使用资源。因此,
requestAnimationFrame
是一种非常高效的动画方式,我们即将介绍的大多数库都在内部使用了它。requestAnimationFrame
的工作方式类似于递归,在绘制下一帧之前,它会执行逻辑,然后再次调用自身以继续执行。这听起来可能有点复杂,但它实际上意味着您有一系列不断运行的命令,因此它会非常漂亮地为您插值渲染中间步骤的方式。
Canvas
Canvas 非常适合让像素动起来!您在 CodePen 上看到的很多 炫酷效果 都是由 canvas 专家制作的。顾名思义,canvas 提供了一个可视化脚本空间,您可以在其中创建复杂的绘图和交互,所有这些都具有高性能渲染。我们在这里处理的是像素,这意味着它们是 光栅(而不是矢量)。
优点
- 由于我们不是在 DOM 中移动元素,而是在移动像素块,因此您可以在不降低性能的情况下实现大量复杂的效果。
- **Canvas 在交互方面非常出色**。您已经在 JavaScript 中,它提供了很多控制权,无需切换上下文。
- 性能非常好。尤其考虑到您可以创建的内容。
- 您可以创建任何想要的东西。
缺点
- 难以使其具有可访问性。您需要使用 React 之类的东西为您创建 DOM,Flipboard 之前曾尝试过,尽管在 他们的案例研究 中,似乎他们还有更多工作要做。不过,如果您有兴趣承担这项任务,这里可能存在一个机会。
- 我发现使其具有响应性非常不直观。这里我指的是,不仅仅是让小版本在手机上工作,因为它在这方面做得很好。我的意思是根据视口移动、切换和重新组织内容。我相信有一些非常优秀的开发者可以轻松地做到这一点,但我认为它并不十分简单。
- 它不是视网膜就绪的。与分辨率无关的 SVG 动画不同,我看到的多数 canvas 动画在视网膜显示屏上并不清晰。
- 调试起来可能很困难。当您构建的内容出现故障时,它会通过显示空白来表明故障,这与在 DOM 中进行动画不同,在 DOM 中,元素仍然存在,只是行为怪异。
SMIL
SMIL 是原生的 SVG 动画规范。它允许您直接在 SVG DOM 中移动、变形甚至与 SVG 交互。使用 SMIL 有很多优点和缺点,但最大的缺点将导致我完全忽略它:**它正在失去支持**。 这是我写的一篇关于如何迁移到支持更好的技术的文章。
Web Animations API
Web Animations API 是原生 JavaScript,允许您创建更复杂的顺序动画,无需加载任何外部脚本。或者说,当支持度提高时会是这样。目前,您可能需要一个 polyfill。这个原生 API 的创建是为了补充人们已经在 Web 上使用 JavaScript 创建的众多优秀库和工作。这是为了将 CSS 动画的性能和 JavaScript 中的顺序灵活性整合到一起。如果您有兴趣了解更多信息,有一期 ShopTalk 节目专门介绍了它。
优点
- 顺序动画很容易理解和编写。请查看Dan Wilson 的这个示例,它比较了 CSS 关键帧和 Web 动画 API。
- 性能似乎正在朝着非常好的方向发展。我还没有很好地测试过,但计划进行测试。(您也可以并且应该进行自己的性能测试)。
缺点
- 目前支持度并不理想。它还在不断变化,因此在规范仍在发展过程中,我建议谨慎地在生产环境中使用它。
- GSAP(我们稍后会介绍)的时间轴中还有很多更强大的功能。对我来说,重要的功能包括 SVG 的跨浏览器稳定性和用一行代码就能完成大量顺序动画的能力。
WebGL
您可以使用 WebGL 做一些非常棒的事情。如果有什么东西让您惊叹不已,那么很有可能它是用 WebGL 制作的。它真正擅长的是交互式和 3D 效果。查看一些演示。从技术上讲,它使用的是 canvas,但我喜欢做出区分,因为,我不知道,当名称有助于识别细微差异时,它们就很酷。
优点
- 惊人的视觉效果
- 三维意味着一个全新的交互世界
- 硬件加速
- VR 的可能性
缺点
- 比我们之前介绍的其他原生动画更难学习。我做的前两个动画,我以为它们没有工作,因为我的相机指向错误的方向(唉)。与其他我提到的技术相比,真正好的文章和书籍来解释如何使用它也比较少,但是它们正在增长。
- 难以使其响应式。我见过的使用 WebGL 的大多数网站都回退到“请在桌面电脑上查看此网站”的屏幕。
外部库
GreenSock (GSAP)
GreenSock 是我迄今为止最喜欢的库。请理解,这种偏见来自于我使用、尝试过以及在许多不同的动画工具上碰壁的经历,因此当我给出强烈的推荐时,它来自于我的血汗和泪水。我特别喜欢它在 SVG 上的表现。GreenSock 动画 API 几乎拥有太多优秀的特性,无法在这里一一列举,但它们提供了文档和论坛供您探索。
优点
- 对于非原生库来说,它的性能非常出色。也就是说,性能表现得非常好,这非常重要。
- 顺序工具(如时间轴)既易于阅读又易于编写。调整时间、让多个内容同时触发(使用相对标签)以及用一行代码加快或减慢动画的速度都非常简单。
- 如果您想做一些花哨的事情,比如动画文本、变形 SVG 或绘制路径,它们还有许多其他插件。
- 它们在贝塞尔插件中的路径运动具有最长的支持历史。
- 它解决了 SVG 的跨浏览器问题。感谢这个功能。尤其是在移动端。他们写的一篇文章中有一些关于此方面的信息。
- 它们提供了非常棒的、非常真实的缓动效果。
- 由于您可以对任意两个整数进行缓动,因此您可以做一些很酷的事情,比如为一些很棒的效果制作 SVG 滤镜动画,甚至可以在 canvas 中使用。您可以动画化任何东西,天马行空。
- GSAP 是唯一一个允许您使用数量不等的点来变形路径数据的动画库,包括原生的 SMIL。这为运动和移动带来了新的机遇。(如果您想亲眼看看,请在桌面电脑上点击此页面顶部的 logo 上的橙色部分)。
缺点
- 如果您要将产品转售给多个用户(应用程序和付费访问网站),则需要支付许可费用。这可能不是大多数情况。我还要补充一点,支持这项工作并非坏事。
- 与任何外部库一样,您需要关注在生产环境中使用的版本。当新版本发布时,升级将需要一些测试(就像任何库一样)。您还需要考虑库的大小。
VelocityJS
VelocityJS 提供了许多 GreenSock 提供的顺序动画功能,但没有那么多的花哨功能。由于以下缺点,我已不再使用 Velocity。Velocity 的语法看起来有点像 jQuery,所以如果您之前一直在使用 jQuery,它会很熟悉。
优点
- 链接许多动画比 CSS 要容易得多。
- 对于缓动效果的细化,可以使用阶梯缓动,您可以传入一个数组。
- 文档非常不错,因此很容易学习和上手。
缺点
- 性能不太好。尽管有些人声称并非如此,但当我进行自己的测试时,我发现它并没有真正经受住考验。不过,我建议您也进行自己的测试,因为 Web 始终在发展,而这篇文章是时间静止的。
- GSAP 在性能和跨浏览器稳定性方面提供了更多功能,而且不会增加更多负担。我还想说,jQuery 过去在性能测试中会输,但这在它们采用 RAF 后可能已经改变了,因此 Velocity 并不是说不好,但在比较中它处于劣势。
- 据我所知,它不再积极维护了。我听说 Julian Shapiro 已将项目移交给其他人,因此它可能在未来某个时候会重新出现。
jQuery
jQuery 本身并不是一个纯粹的动画库,但它有动画方法,而且很多人都在使用它,所以我认为我应该介绍一下它。
优点
- 许多网站已经加载了它,因此它通常是现成的。
- 语法非常易于阅读和编写。
- 它们最近迁移到了
requestAnimationFrame
,因此在3.0.0 及更高版本中,性能将比之前更好。
缺点
- 3.0.0 之前的版本的性能不是很好,不建议使用。我没有以非常正式的方式测试过,但是除了查看 Chrome DevTools 中的重绘和绘制之外,您还可以用肉眼观察到这一点。
- 在任何版本中都不支持 SVG 动画.
- jQuery 仅限于 DOM,不像 GSAP 等工具可以作用于任何内容。
Snap.svg
许多人认为 Snap 是一个动画库,但它从未打算成为一个动画库。我本来打算对 Snap 进行性能基准测试,但即使是 Dmitri Baranovskiy(Snap.svg 及其前身 Rafael 的才华横溢的作者)在SVG Immersion Podcast 上也表示,它不是正确的工具,并且在发给我的消息中说
注意:Snap 不是一个动画库,当您需要严肃的动画时,我始终建议与 GSAP 一起使用。
也就是说,jQuery 对 SVG 的支持不是很好,尽管它们现在支持类操作。如果我需要对 SVG 进行任何 DOM 操作,Snap 在这方面非常棒。
最近发布了一个名为SnapFoo 的库,它将 Snap 的领域扩展到了动画。我自己还没有尝试过,但看起来非常酷,值得一试。如果您尝试了,请反馈或在下面发表评论!
Mo.js
这是一个库,由一位名叫LegoMushroom 的很棒的家伙创建。他是一位非常有才华的动画师,并且已经为这个库制作了一些很棒的演示,让我感到非常兴奋。这个库仍在测试版阶段,现在即将发布。如果您有兴趣了解更多信息,我在这里写了一篇关于如何使用它的入门指南。
优点
- 它包含形状、爆发和漩涡等功能,这些功能非常易于使用
并且为你启动一些东西——所以你不需要成为世界上最好的或最有创意的插画家就能获得不错的效果。 - Mo.js 提供了一些网络上最好和最漂亮的工具,包括
播放器、时间线和自定义路径创建器。这本身就是使用它的最令人信服的原因之一。 - 有几种不同的动画方式——一种是对象,一种是在
缓动过程中绘制变化——所以你可以选择你觉得更舒服的方式。
缺点
- 它还没有提供使用 SVG 作为自定义形状父元素的功能(我
相信 LegoMushroom 正在开发此功能),因此使用坐标系和缩放进行响应式设计不太直观,并且难以在移动设备上实现。不过,这是一种相当高级的技术,你可能不需要它。 - 它不像 GreenSock 那样修复跨浏览器行为,这意味着
你可能需要像使用 CSS 一样编写一些 hack。他提到他也正在开发此功能。
Three.js
Three.js 是一款很棒的三维动画工具!查看一些示例。我还没有太多使用它,所以我不太敢对其进行评价,但我计划学习,并在了解更多后更新这篇文章。人们通常将它与原生 WebGL 结合起来讨论。
Bodymovin’
Bodymovin’ 旨在在 Adobe After Effects 中创建动画,你可以轻松导出到 SVG 和 JavaScript。一些演示非常令人印象深刻。。我不用它是因为我真的很喜欢用代码从头开始构建东西(所以这对我来说违背了目的),但是如果你更像是一个设计师而不是开发人员,这个工具可能对你来说非常棒。我看到的唯一缺点是,如果你以后需要更改它,则必须重新导出它。这可能是一个奇怪的工作流程。此外,输出的代码通常有点糟糕,但我还没有看到它对 Bodymovin’ 的性能产生太大影响,所以可能没问题。
React 特定工作流
在我们讨论 React 之前,让我们先了解一下为什么我们必须以不同的方式处理 React 中的动画。DOM 代表文档对象模型。它是我们如何使用对象创建结构化文档,我们将这些对象的节点称为树。React 与虚拟 DOM交互,这与原生浏览器 DOM 实现不同,它是一个抽象。
React 使用虚拟 DOM 有很多原因,其中最引人注目的是能够找出发生了哪些变化,并仅更新它需要更新的部分。这种抽象是有代价的,你习惯使用的一些旧技巧在 React 环境中会给你带来麻烦。例如,jQuery 无法与 React 良好地配合使用,因为它的主要功能是与浏览器的原生 DOM 交互和操作。我甚至看到了一些奇怪的 CSS 竞争条件。以下是一些我在 React 工作流中进行良好动画的建议。
React-Motion
React-Motion 是在 React 中进行动画的非常流行的方法,并且社区已经采用它来替代以前最常用的ReactCSSTransitionGroup
。我非常喜欢它,但是使用它有一些关键点,如果你不理解,就会让你感到头疼。
React-Motion 与基于游戏的动画非常相似,你为一个元素赋予质量和物理特性并将其发送出去,它到达目的地的时间取决于它本身。这意味着你没有像使用 CSS 或任何其他传统的基于网络的顺序运动那样指定时间量。这是一种思考动画的截然不同的方式。这意味着运动具有看起来非常逼真的能力,这可能非常漂亮。但是 UI 比游戏有不同的需求,因此使用它可能会变得棘手。假设你有两个必须独立触发并在同一时间到达的不同事物。将它们完全对齐可能很困难。
直到最近,还没有可用的排序功能。就在上周,Cheng Lou 添加了onRest
,它允许这种回调工作流。在不编写无限循环(糟糕)的情况下编写循环仍然不容易。你可能不需要它,但我认为我应该提一下。作为对性能敏感的用户的信息,它使用重新渲染。
优点
- 动画看起来非常漂亮和逼真,弹簧选项也很不错。
- 交错效果非常好。它也存在于大多数 JS 库中,但这个库是基于最后一次运动创建的,而不是复制最后一次运动,因此有一些不错的运动可能性。
- 添加
onRest
是一件大事。它允许进行以前无法进行的一些排序,因此如果你查看演示,你甚至还没有看到它提供的所有功能。 - 我目前认为这是与 React 配合得最好的动画工具。
缺点
- 它不像其他一些库或原生库那样超级即插即用,这意味着你最终会编写更多代码。有些人喜欢这一点,有些人不喜欢。不过,对于初学者来说,它并不友好。
- 由于代码的复杂性,排序不像一些替代方案那样简单或易读。
onRest
还不适用于交错参数。
React 中的 GSAP
GreenSock 提供了如此多的功能,因此它仍然值得在 React 环境中使用。对于更复杂的排序来说尤其如此,因为 React-Motion 没有提供简单的解决方案,而 GreenSock 在这方面表现出色。它需要比平时更多的调整,并且有些在 DOM 中应该工作并且确实工作的东西在 React 中却无法工作。也就是说,我现在已经让 React 和 GSAP 以几种不同的方式良好地配合使用,所以以下是我的做法。
- 挂接到原生的 React 组件生命周期方法。
这是我的做法。当我想让它立即触发时,我使用componentDidMount
。 - 创建一个包含时间线的函数,然后在用于交互的某些内容中调用该函数。我可以使用内联事件处理程序,例如
onClick()
,并在为其创建的自定义函数中,我将调用另一个函数,该函数在其内部包含一个时间线。在 jQuery 或原生 JS 设置中,我将最初暂停时间线并点击播放,但在这里我不需要这样做。 - 这是一篇不错的文章,Chang Wang 在文章中写了如何将它们挂接到
ReactTransitionGroup()
,这是一种非常酷的做法。 - 你可以使用像React-Gsap-Enhancer这样的库。我自己还没有太多使用这个库,但是有一些非常棒的演示。其中一个是基于我自己的一个演示的 fork,我必须说,当我查看代码时,它似乎比我编写的代码冗长得多。我不确定这是由于库还是 React 本身,或者他们的风格。
React 中的 CSS
CSS 动画最近复苏了一些,这可能是因为它是在 React 中进行动画的最简单方法。我喜欢将它们用于一些小东西,例如 UI/UX 交互。如果尝试使用延迟来链接内容,我发现它们的行为有点奇怪。除此之外,它们非常棒,尤其是在进行少量 UI 调整时。在网络上的真实世界动画方面,有时 CSS 就是奥卡姆剃刀。
结论
这是一篇来自一位持续专注于动画工作的作者的观点文章,这些是我在大量使用这些技术后总结出的经验。我的观点可能并不被所有人认同,这没关系。除了作为开发者,考虑到其通用性、性能和易用性之外,我并没有特别偏袒任何技术。希望这些信息能为您节省一些时间。
这就是我的大脑处理 React 中动画奇怪的原因
所以我觉得您能做的最好的事情就是……
我是一个 React 新手,但这与我对这个问题的思考完全一致。一些组件生命周期函数,特别是 shouldComponentUpdate(),应该为选项 #3 提供一种方法。
显然,这取决于用例,但使用 Canvas 在 React 中是否是一种选择?Canvas 只是一个节点,因此您执行的任何绘制都不会影响 React 的更新循环,对吗?
非常好的观点,Casey。我在 Canvas 部分简要提到了 React + Canvas,但值得在下面再提一下。我稍后会更新这篇文章。
我遇到的唯一动画问题与新创建的 DOM 相关——但这在普通的旧 JS 中一直很奇怪。正如 Sarah 提到的,有一些工具可以解决这个问题。
至于在您希望动画开始时已经存在的 DOM,例如滑入菜单或其他内容(同样,假设菜单已经存在)——可以简单地使用普通的旧类状态技术。即:类名的突然出现触发了一个 CSS 选择器,该选择器被动画化。
“React 可能会决定移除并重新渲染该节点。”
React 的协调算法非常好,它通常只会在真实的 DOM 上执行反映您从渲染函数中返回的内容所需的最小更改次数,因此它并不像您所说的那样不可预测。如果您确实在动画过程中遇到 React 重新渲染节点的问题,那么您可能在其中一个节点上缺少一个
key
。这有助于 React 更智能地协调事物。好文章!基本上可以归结为:对基本内容使用 css,对链式动画使用 greensock,对 3D 使用基于 webgl 的框架。 :)
SMIL 是制作 SVG 动画的唯一真正方法。其他所有方法都只是权宜之计。我已经使用了 10 年,它运行起来非常棒。您可以在应用程序中创建动画并在浏览器或手机上播放,它的表现会完全一样。无需脚本或 CSS 技巧。对于所有其他方法来说,这几乎是不可能的,通常移植和维护都很麻烦。SMIL 坚如磐石,并且有适用于任何浏览器的 polyfill,因此即使有一天有人要放弃 SMIL 支持(Chrome 宣布了弃用的意图,但尚未执行,因为 SMIL 的使用正在增长,尤其是在移动设备上。甚至像 Viber 这样非常流行的应用程序也在使用 SMIL 在 Android 上制作其动画贴纸)。
使用 SMIL 的 polyfill 与使用 JavaScript 库没有区别,那么您为什么包含 GSAP 而没有包含 SMIL 呢?我当然更喜欢标准的东西,例如我可以从流行的动画工具(例如 Adobe Animate CC)中导出的一些东西(例如,使用其插件“flash2svg”,您可以将您在单个 SVG 文件中创建的任何动画导出为 SMIL 动画,无需代码或 CSS)。并且 Toonz(吉卜力工作室使用的强大动画软件)的开源版本在其开发路线图中提供了导出 SVG SMIL 动画的选项。SMIL 将会存在,作为原生标准或像 GSAP 这样的外部库,但它将永远存在。
我觉得你对 SMIL 的未来过于乐观了。
Chrome 开发人员在 Web Animation API 上做了一项非常出色的工作,并且在此基础上,他们渴望放弃 SMIL 以使他们的代码库大大减轻。他们会的,请相信这一点。
微软甚至不会开始开发 SMIL 支持,因为这个新的方向。您应该知道,因为您也对此发表了评论:https://wpdev.uservoice.com/forums/257854-microsoft-edge-developer/suggestions/6509024-svg-animation-elements
简而言之,SMIL 基本上已经死了。
@MaxArt:也许你错过了我的重点。SMIL 不会仅仅因为某些浏览器供应商决定这样做而消失。在最坏的情况下,它将需要使用动画库,就像此处审查的其他库一样。
已经有三个流行的 JavaScript 库用于在不支持 SMIL 的浏览器上运行 SMIL 动画:Eric Willigers 的 polyfill、SIE 和 Fakesmile。如果您打算使用 JavaScript 库进行动画,那么使用 SMIL 库是您可以做出的最佳选择。无论是否原生支持,SMIL 都是 SVG 动画的最佳选择。并且您可以在真实的动画工具中创建 SMIL 动画,并与任何图形艺术家交换您的 SVG 动画资产,因为它们以标准格式编码,而不是用自定义 JavaScript 代码编写。相信我:SMIL 不会消失。至少在出现新的矢量动画标准格式之前。
事实上,有一个新的标准:它叫做 Web Animation。与此同时,SMIL 已经消失了,连同其笨拙和笨重的声明式语法。我们已经有一种声明式的方式来定义动画,那就是 CSS。更复杂和动态的动画根本不适合任何声明式语言。所有内容都变成了越来越多的晦涩难懂的行,几乎不可能维护。
SMIL 在性能方面与 CSS 或 Web Animation 相比没有任何优势,因此没有人会为以后不再受任何浏览器支持的东西使用 polyfill。这根本没有意义。
网络上的专业动画大多是用 GSAP 制作的,它具有出色的性能和一个良好且易于使用的 API。对于其他用例,设计师根本不在乎其矢量动画的底层技术,因为他们使用的工具会为他们处理这些问题。
@MaxArt:我非常喜欢 GSAP 团队,多年前我使用 ActionScript 时,他们的库帮了大忙。但这里我说的不是编程。我指的是艺术家使用数位板和绘图软件(如 OpenToonz、Animate CC、CACANi 或 Anime Studio 等)创作的动画。艺术家使用这些应用创建矢量动画,他们不会使用 JavaScript。那么,这些矢量动画如何在网页上显示和播放?它们能导出成什么格式?它必须是一种描述性的图形动画格式,例如 SVG 和 SMIL。一个由 W3C 制定的标准,任何人都可以使用,而不是某个公司用来锁定用户并强迫他们使用其库或工具的专有格式。SMIL 代表自由。它可以让矢量动画文件数据可被所有人使用、交换和理解。SMIL 就像矢量动画的 PNG 格式。你还记得 PNG 是如何诞生的吗?我记得。创建 PNG 格式的动机是,在 1995 年初,人们发现图形交换格式 (GIF) 中使用的 Lempel-Ziv-Welch (LZW) 数据压缩算法已获得 Unisys 的专利。GIF 使用了专有技术。而 PNG 是免费的。今天,我们只有一个开放的矢量动画标准格式,那就是 SMIL。将动画导出为依赖于 “GSAP” 的代码?一个随时可能更改的专有库,会永远锁定开发者和艺术家?甚至可能破坏兼容性,仅仅因为公司决定强迫用户升级以赚取更多利润,或规定规范,从而使所有矢量动画突然变得“过时”和“无法播放”?不,我拒绝。如果你不理解使用开放标准的重要性,那么你应该学习 Web 以及所有信息技术的演变历史。因为数据专有格式最终都会带来负面影响,并损害整个生态系统,包括格式的拥有者。看看 Silverlight/XAML 或 Flash 的失败就知道了。它们都是专有的,然后变成了封闭的花园。而封闭的花园最终都会枯萎。它们越努力维护封闭状态,其围墙就越会将它们与世界隔绝,直到没有人再使用它们。这就是为什么我将所有矢量动画文件存储为 SVG SMIL 格式。软件会更改,浏览器和库也会更改,但 .SVG 文件将始终保持不变,因为它是一个标准,就像 PNG 一样。这就是为什么最终 SMIL 会获胜。即使它不被浏览器支持,而仅被 SIE 或 Fakesmile 等 JavaScript 库支持,它也会获胜。因为它是一个标准。作为一个标准,你不仅可以拥有像 GSAP 这样的一个库,还可以拥有成千上万个独立的 JavaScript 库来播放它。你可以从 AnimateCC 或 OpenToonz 中保存它,并在你开发的移动应用(如 Viber)中、网页中或使用 Unity SVG 导入器等工具的游戏主机游戏中重现它。正如你所看到的,将代码与数据分离具有明显的优势。不幸的是,SVG 是你可以保存的唯一动画数据格式。GSAP 或任何其他库都是代码,它们依赖于平台和特定版本的软件,例如浏览器。而动画的数据格式则是通用的。使用 GSAP 或其他用 JavaScript 编写的动画库无法实现代码和数据的清晰分离。毕竟,艺术家不是用代码绘制动画,而是用笔和数位板绘制的。SVG SMIL 是他们可以保存的唯一真正的数据格式。这一点不会因为 Google 的某个盲目经理为了省钱而决定在 Chrome 中停止支持 SMIL 而改变。
@Emanuele,你提出了很多有效的观点。我理解人们害怕使用没有官方标准机构认可的任何东西。但是,请考虑以下几点:
1) 像 GSAP 这样的库是用基于标准的技术 (JS) 编写的,所以 GSAP 基于的动画在 5 年后不会突然停止工作。你自己编写的任何原生 JS 代码都存在同样的风险,你提到的 SMIL polyfill 库也是如此。
2) 仅仅因为某些东西得到了标准机构的批准,并不意味着它不会被淘汰(或者根本不会被实现——看看 IE,它对 SMIL 的支持为零)。最终,浏览器决定支持哪些技术,而不管“标准”如何。
3) GSAP 已经存在十年了,并且从未将免费工具更改为付费工具,也从未提高任何产品的价格或采取你所假设的任何卑鄙手段。信任对我们来说非常重要。但指出可能性是公平的。
4) 在某些方面,像 GSAP 这样的库“更安全”,因为它更加灵活,并且可以比标准机构或浏览器供应商更快地应对浏览器错误和不一致性。我认为 GSAP 的往绩证明了这一点。
如果没有标准,Web 将会变得残疾……但是,想象一下,如果我们 *只* 依赖标准(没有库/框架/插件),那么今天的 Web 将会多么有限!我也不会认为将标准描述成如此不易改变或弃用是公平的。我猜想,在 5 年内,基于 GSAP 的动画在浏览器上的运行将比今天创建的任何 SMIL 动画都更稳定,而这最终是许多开发者所关心的。
@Jack,你说的都对,Jack。但你仍然错过了最重要的观点:你所说的一切对程序员来说都是有道理的。但是,艺术家如何使用 GSAP?他如何在 OpenToonz 或 Animate 中使用特定的 JavaScript 库保存和存储他创建的动画?你需要一些独立于特定库的东西。并且数据应该与代码分离,因为你不能依赖于实现。此外,像 GSAP 这样的专有库在 Web 上很酷,但移动应用却没有 GSAP。如果我想在 iOS 应用中重现我的动画,我该怎么做?即使我购买了一些能够在 iOS 上回放混乱包 (html+javascript+css) 的库,它也需要模拟 JavaScript VM,这非常慢(此外,iOS 上根本不允许使用 VM,但那是另一回事)。另一种方法是让某人为 iOS 编写一个特定于 “GSAP” 的查看器,但这会违反你的版权,因为这样的库必须以原生方式重写相同的 GSAP 库函数。
正如你所看到的,无论 GSAP 对程序员来说有多好,它对艺术家和动画师来说都没有用。以制作动画 SVG 图标为生的艺术家只有一个选择,那就是 SMIL。当然,这里每个人都是程序员,包括我在内,所以我们不在乎艺术家和图形设计师。但我向你保证,如果这些人被排除在该技术之外,你将永远看不到动画质量比你通过编程创建动画所能达到的水平有显著提高。这就像强迫人们在 Web 上使用一堆 .putpixel() 函数通过 JavaScript 制作位图图像,而不是使用 Photoshop 中创建的 JPG 和 PNG。我怀疑 Web 会是一个美丽的景象。
这就是为什么需要一个用于保存矢量动画的数据标准。SVG SMIL 做到了这一点,而且做得很好。没有其他标准可以替代它。也许有一天另一个标准会诞生。但在那一天到来之前,SMIL 将是专业艺术家和动画师唯一严肃的选择。
这是一个带有卡通片段和嵌入音频的 SVG SMIL 文件示例,音频与动画同步,只有艺术家才能做到这一点。
https://imgh.us/LoveDota.svg
动画和音频在 Chrome 和 Firefox 上可以正常播放。
Safari 上没有音频,但该错误目前正在审查中。
https://bugs.webkit.org/show_bug.cgi?id=155778
你认为用 Animate CC 制作这个动画的动画师会使用 GSAP 或任何其他 JavaScript 库来做同样的事情吗?我不这么认为。
没有 SMIL,你就会失去在 Web 上拥有这种复杂动画的选项。这就是 SMIL 会继续存在的原因。
如果你担心自动输出,可以考虑 bodymovin,上面列出的库之一。它输出到 SVG 和 JavaScript。谢谢!
谢谢 @Sarah,我喜欢 After Effects 的 Bodymovin 插件。但不幸的是,它仍然无法导出像标准格式一样可以在不同的图形应用程序之间交换的数据文件。它不是像 SVG 一样可以加载的文件格式。它是一个完整的网站,由 HTML、JavaScript、CSS 和 SVG 文件组成,这些文件是为非常特定的平台和技术组合在一起的。它不像 SVG 或 PNG 那样与平台无关。例如,你不能只用这种格式保存你的矢量动画,然后将其用作移动应用中的动画图标。当然,你可以使用本机的 After Effects 项目文件作为动画格式,但它是一个专有格式。因此,它具有专有格式的所有缺点,最重要的是,你不能在不支付版税给 Adobe 的情况下制作一个编辑此类文件的工具。此外,Adobe 规定了格式,并且让他们保持锁定、模糊以及仅与其工具相关联符合他们的最大利益。
使用 SVG SMIL,艺术家可以在任何软件工具中创建动画,导出并在任何其他不同的工具中加载它,用于合成或为移动应用程序、网站或电子游戏 UI 构建 UI。SVG SMIL 动画是一种标准,因此它允许艺术家将动画保存到其中并在任何地方使用它们,从使用 SVG 导入器的 Unity 中的电子游戏中,到使用 OpenToonz 或 AfterEffects 进行专业电视视频制作,再到 Adobe Experience Design 或 Invision 用于设计带有动画组件的应用程序 UI,以及电子书教科书或移动应用程序中。您可以在整个生产链中有效地使用该 SVG 文件,并具有 PNG 文件在任何现在和未来平台上的可靠性。您不必担心专有锁定或解释为浏览器编写的某些 JavaScript 代码,并尝试将其转换为某些原生代码。使用 SVG SMIL 制作的动画按钮在网页、移动应用程序、电子书、电子游戏 UI 或任何视频中都能完美运行。你能说 Adobe After Effects 项目文件可以做到这一点吗?或者从 Bodymovin 插件导出的 Web 包?不能,你做不到。没有办法让它在生产链中工作。Bodymovin 是一种非常特定且自定义的解决方案。它不是 PNG。SVG SMIL 是矢量动画的 PNG。并且那里的每个开发人员都可以像 PNG 图像一样在他的软件中添加对它的支持。我们应该捍卫 SVG SMIL 标准的宝贵财富。这是一件非常难以实现的事情。许多贪婪的公司多年来一直努力避免这种情况,并且他们成功地减缓了 SVG 的采用速度,并通过否决添加文本换行等基本功能来削弱它。直到现在,多亏了像您一样非凡人士的辛勤工作,例如 Sara Soueidan 或 Dmitry Baranovskiy,SVG 才开始复仇。现在是人们知道更好的 Web 在 10 年前就已经可能实现的时候了,但由于一些私营公司的贪婪,它被故意阻止了。但是你不能阻止一件好事太久。最终人们会发现它。这就是为什么即使 Google 最近废弃 SMIL 的举动最终也会失败,就像微软首先,然后是 Adobe 试图摧毁 SVG 的举动最终失败一样。开放和标准总是战胜封闭和专有。Web 本身就是证明这一点的真理旗帜。
老实说,Emanuele,你听起来有点像一张破唱片。我不明白你为什么要用你的话来争取每个人的支持,但这不会发生。吉卜力工作室正在使用 SMIL 导出,Viber 正在使用带有 SMIL 的 SVG……唉,老实说,谁在乎呢?我敢打赌,*他们*也不在乎。
你说你没有站在开发人员的角度,这是公平的,但关键是,每个不是为开发人员设计的工具都不应该让其用户负担诸如用于动画 SVG 的技术的细节。对于设计师/动画师来说,他们的工具是否使用 SMIL 或 Web 动画导出都没有区别,应该是完全透明的。我不应该提醒你 SVG 可以包含 JavaScript 代码,对吧?
只是从开发的角度来看,SMIL 很糟糕,所以它正在走向终结。就这么简单。而且这篇文章讨论的是开发,这就是问题所在。事实上,GSAP 已经被谈论过,因为它非常适合开发。甚至原始的 Web Animation API 也比 SMIL 好得多。
现在,我们正处于过渡期,也许这就是你感到担忧/困惑/迷茫的原因,但试图让你的世界停留在过去并不好。这需要一段时间,但最终一切都会好起来的,因为行业需要它。
@MaxArt 首先,SMIL 根本不糟糕。它是迄今为止设计最优雅的动画描述语言。问问任何 IT 学术界人士。其次:公司关心 SMIL 因为它是一种数据描述语言。换句话说:它包含有关矢量动画的信息。它不会告诉你如何运行它。它不包含需要在应用程序中运行的代码。相信我:即使你定义了一种在 SVG+JAVASCRIPT 文件中保存矢量动画的标准方法,也没有一家软件开发公司会将其加载到其应用程序中。因为在你的应用程序中加载和运行不受信任的代码是不安全的。你真的认为 Adobe、Serif 或 Autodesk、Corel、Microsoft、Google 或任何其他公司会选择包含潜在恶意代码的文件格式吗?你需要运行才能播放动画的代码?这将是有史以来最糟糕的软件设计决策。没有软件工程师会定义一个包含要运行的代码的文件格式。问题不仅在于不受信任的代码的危险,还在于你需要运行才能解码它。你不知道其中的代码,所以了解第 291 帧发生了什么的唯一方法是播放整个动画。相反,数据描述格式为你提供信息,而不是代码。你不需要运行任何东西。你确切地知道第 291 帧将会是什么样子,因为该帧以唯一、可预测和标准的方式由这些信息定义。
此外,每次加载文件时解释语言都比使用你的原生应用程序代码慢。从性能角度来看,这是一个杀手。就像 MPEG 标准强迫你在运行时运行 .mpeg 文件中包含的 JavaScript 代码片段,并且每个渲染帧都这样做。只有最愚蠢的工程师才会这样定义视频标准。然而,你认为这对 SVG 动画来说是一件好事吗?我不相信你。我认为你知道以这种方式存储动画是多么低效和愚蠢,而且我认为你知道我们之所以这样做是因为 Web 是一团糟。它背后没有理性的愿景,只有一群商业竞争对手,他们正在尽其所能地避免一个他们不拥有的单一标准确立自身。他们不关心 Web 的真正标准,甚至更不关心理性的标准。他们只关心锁定开发人员,强迫他们使用我们的库和工具,并利用 Web 标准之争来赢得和控制移动应用程序生态系统。为什么你认为 JavaScript 仍然是 Web 的语言?JavaScript 甚至不是真正的编程语言。它是由 Netscape 在一周内创建的一团糟!它是迄今为止最糟糕的语言,但我们却用它来运行万维网!W3C 明天早上可以批准许多现代且很棒的语言作为新的 Web 标准。那么,他们为什么不这样做呢?因为他们需要浏览器供应商的批准,而且他们不想同意一些设计良好的、效果最佳的东西。他们想互相争斗。这就是为什么今天需要创建简单动画图标的艺术家现在被迫使用 4 种不同的语言标准(HTML、CSS、JavaScript、SVG)来制作一些理性的设计师可以使用 SVG 制作的东西。幸运的是,在许多其他领域,人们越来越多地使用纯 SVG 进行矢量动画。移动应用程序、电子游戏、视频编辑……在所有这些领域,人们都在使用 SVG。而不是与 HTML、JavaScript 和 CSS 混合使用。只是 SVG。而且它出色地完成了自己的工作。但在 Web 上,存在浏览器战争,因此对于贪婪的浏览器供应商来说,矢量动画的简单标准文件格式是异端邪说。好吧,他们不会赢。因为人类思维能够做到比现在的 Web 混乱状态好得多,如果我们遵循我们的理性而不是为了盲目的贪婪而阻碍它,我们就能创造出惊人的东西。
虽然旧的画布图形/动画可能无法在高 DPI 下渲染是事实,但这样做已经有一段时间了。这只是将画布和上下文尺寸放大,同时保持恒定的 CSS 宽度/高度的问题。
https://jsfiddle.net/yokf2qmk/
这篇旧文章更详细地描述了正在发生的事情
http://www.html5rocks.com/en/tutorials/canvas/hidpi/
根据个人经验——我仍然经常在非高 DPI 中创建我的画布演示,以获得更好的帧率。我更喜欢在画布上获得流畅的动画而不是清晰的动画。
感谢 Sarah 提供的这篇有帮助的文章!
如果其他人需要更多 React + GSAP 的示例,我的网站有一些:https://kylegach.com,以及GitHub 上提供了完整的源代码。
太棒了!谢谢。
嗯,GIF 不在列表中。什么 GIF?(注意:“gif”的复数发音类似于“gives”)
Bool,听着朋友。GIF 显然不是 W3C CSS3 规范,我建议你继续前进并适应时代。
恰恰相反。https://www.w3.org/Graphics/GIF/spec-gif89a.txt
该你走了。或者我们应该说,“将死?”
GIF 不是你可以以编程方式处理的东西,在本次讨论中没有位置。
(如果你想谈论动画图像,至少不要选择像 GIF 这样过时且低效的格式。)
我知道你不能比较每个工具,但我认为你没有包含的一个重要的工具是Pixi.js。我甚至不确定它属于你的哪个类别。它是一个 2D 画布库,但它也具有完整的 WebGL 支持。它就像 Flash,但没有 GUI。
与大多数画布库一样,Pixi 使用完整的场景图,因此它不仅仅是一堆像素。存在一个实际的层次结构,这意味着你可以将 HTML 元素和事件映射到它。这意味着什么?你可以使画布可访问。
看看。你可以通过所有按钮,并通过按空格/回车键与它们交互。
http://www.goodboydigital.com/pixijs/accessibility/accessibility.html
我还没有怎么听说过这个。看起来很酷,Blake!是的,正如我在文章中提到的,我将其限制在我使用过或感到兴奋的技术。不过,发现它很不错。
您可以使用 SVG 的运动路径 - 在 Path 元素上使用 getPointAtLength()。
因为没有作者关心它。就像所有领域一样,视网膜支持也是手动的,但它已经准备好了。
澄清一下,视网膜就绪表示分辨率无关。您可以在 Canvas 中创作高像素密度,但这需要思考和创作。这就是我们在这里区分的地方,与矢量不同,矢量不需要这样做。
优点和缺点并非旨在贬低该技术,而是帮助人们决定使用哪种技术的信息。也就是说,由于人们似乎感到困惑,我用额外的句子澄清了该部分。
哇!谢谢!
这并不太难。将画布尺寸在内容中放大 200%(或在 3 倍屏幕上放大 300%),并在 CSS 中将其设为 100%。现在您的画布在视网膜显示屏上看起来很清晰。
请参见上面的评论,谢谢。
这不容易做到,因为以下原因
1 - 您不知道当前显示器的真实分辨率。
2 - 现在有太多显示器,分辨率太多,无法通过某个 switch 语句来处理。
3 - 很少有移动浏览器提供查询真实显示器分辨率的 API
4 - 即使在台式计算机上,视网膜或更高密度的显示器也变得越来越普遍
5 - 许多用户希望在页面上捏合缩放,因为他们的显示器太小了(在网页上禁用缩放会让所有 3.5 英寸设备的所有者感到生气,这是一个不好的做法)。缩放不会影响 SVG 元素和图标的清晰度,但会使画布元素出现像素化和锯齿。
这,再加上画布元素无法像 SVG 那样被搜索引擎索引的事实,使得画布对于大多数网站来说几乎毫无用处,除了在线网络游戏,这些游戏不需要搜索引擎索引,并且用户很少阅读需要页面捏合缩放的文本。
@Sarah
谢谢。我发布此评论后读到了它。
我想说,画布不是分辨率无关的,但它是视网膜就绪的。
您只需要一个通用实用程序函数来放大画布并在每个画布上调用它。(它是 CreateJS 代码,但相同概念适用于所有画布 API)。一开始需要一些计划,但相同的修复适用于所有项目,无需进一步思考。
感谢@Emanuele 也。
我们不需要分辨率。我们不是在谈论响应式,对吧?
我们需要的是每个像素的密度。(从技术上讲,每个点)
Window.devicePixelRatio
提供 2 倍、3 倍信息,大多数浏览器都支持它,无论是在移动设备还是台式机上。你说得对。Canvas 不是矢量。它是位图,使用画布缩放页面与使用 PNG/JPEG 图像缩放页面相同。但这并不能否定画布支持视网膜的事实。缩放是关于矢量与位图/布局策略,而不是视网膜的重点。
这取决于具体的项目。假设您已将最佳可访问性实践添加到画布中,搜索引擎和残疾人应该不难理解画布的内容。这同样适用于在
<img>
中包含文本并尝试向搜索机器人或视障人士提供图像含义。我不会偏袒画布或任何技术。它们是为特定目的而设计的。如果它们还没有过时,它们仍在发挥其价值。因此,我不同意画布“对于大多数网站来说毫无用处”。只是你还没有找到在你的项目中使用它的方法。
再次感谢 :-)
令我惊讶的是,人们仍然使用 velocityjs,几年前它还不错,但现在显然落后于其他动画库,比如 animateplus https://github.com/bendc/animateplus,这是我最喜欢的动画库,正在等待 waapi 在所有地方可用:es6 优先,umd 构建,npm 发布,良好的性能,更轻的重量……
我属于 SMIL 阵营。为什么要用 Javascript 包装渲染,当你拥有 SVG/XML 以及回退(HTML5、Web GL、链接到本地加载符号库的 CSS)并使用 Greensock/Animate CC 创建时?您实际上可以使用品牌内容进行设计,并与您的客户预览您构建的内容。能够在转译前/后更改您呈现的内容具有巨大的价值。我以前是 Flash 开发者。我处理图片。
这是一个很好的总结!但是,我想澄清一些性能信息。
首先,CSS 动画/过渡在性能方面的主要优势不是卸载到 GPU。动画图层的 GPU 合成也可以应用于脚本化动画(前提是它们正在动画化相同类型的属性:转换、不透明度)。
will-change
在这里有所帮助,但许多浏览器会在几帧后自动检测脚本生成的动画并应用此优化。CSS 动画/过渡的性能优势在于,这些可以在 GPU 上合成的动画也可以委托给单独的线程或进程。这使它们即使在主线程繁忙时也能平稳运行。脚本化动画无法做到这一点,除非它们在幕后使用 CSS 动画/过渡或 Web 动画 API。(并且在低端移动设备上这是一个非常重要的优化!)
至于 Web 动画 API 的性能,它与 CSS 动画/过渡相同。运行两者的代码完全相同。Web 动画 API 的全部目的是成为一个低级 API,CSS 动画/过渡在其之上运行。(而且 SMIL 也是如此。)
此外,关于 React,请注意
react-router
和ReactCSSTransitionGroup
之类的东西。如果您尝试在响应 URL 更改时在下一部分内容中进行动画处理,此设置最终会在您想要进行动画处理时将内容添加到 DOM 中。这将导致动画开始出现明显的延迟。最好将您要进行动画处理的内容已放在 DOM 中,但只需将其移出屏幕或使其透明(并标记为will-change: transform
或其他)。然后,在您导航时,您将获得即时响应。感谢您提供的宝贵信息,Brian。
您是目前负责编写有史以来最重要的 Web 标准的人:SVG 2.0 动画(链接:https://svgwg.org/specs/animations/)。
考虑到您在 Web 未来中的关键作用,这里有一些问题
1 - 规范是否会及时完成以供正式的 SVG 2.0 最终版本使用?
2 - SVG 2.0 动画规范是否会向后兼容当前的 SMIL 动画?
3 - 根据您的文档,SVG 2.0 动画规范的目的是更类似于 CSS,然后使浏览器供应商能够对 CSS 和 SVG 动画使用相同的代码。这是否意味着我们可以看到乒乓动画(即定义动画方向的可动画属性)添加到 SVG 动画规范中?
谢谢! :)