您需要了解的有关Flip动画中的所有内容
最新 Safari 更新后,Web 动画 API (WAAPI) 现在已在所有现代浏览器(IE 除外)中无需任何标志即可支持。这里有一个方便的示例,您可以检查您的浏览器支持哪些功能。WAAPI 是一种执行动画(需要在 JavaScript 中执行)的好方法,因为它属于原生 API——这意味着它无需任何额外库即可工作。如果您完全不了解 WAAPI,这里有一个 Dan Wilson 提供的非常好的入门介绍。
FLIP 是最有效的动画方法之一。FLIP 需要一些 JavaScript 代码才能运行。
让我们来看看使用 WAAPI、FLIP 并将其集成到 React 中的交集。但我们首先从不使用 React 开始,然后再过渡到 React。
FLIP 和 WAAPI
WAAPI 使 FLIP 动画变得更容易!
FLIP 快速回顾:其核心思想是首先将元素放置在您想要它结束的位置。接下来,应用转换将其移动到起始位置。然后取消这些转换。
动画转换非常高效,因此 FLIP 非常高效。在 WAAPI 之前,我们必须直接操作元素的样式来设置转换,并等待下一帧来取消/反转它:
// WAAPI 之前的 FLIP el.style.transform = `translateY(200px)`; requestAnimationFrame(() => { el.style.transform = ''; });
许多库都是基于这种方法构建的。但是,这存在几个问题:
- 一切都感觉像是一个巨大的 hack。
- 反转 FLIP 动画极其困难。虽然一旦删除类,CSS 转换会“免费”反转,但这里并非如此。在之前的动画运行时启动新的 FLIP 会导致故障。反转需要使用 getComputedStyles 解析转换矩阵并使用它来计算当前尺寸,然后再设置新的动画。
- 高级动画几乎是不可能的。例如,为了防止扭曲缩放父级的子级,我们需要在每一帧访问当前缩放值。这只能通过解析转换矩阵来完成。
- 浏览器有很多需要注意的地方。例如,有时要在 Firefox 中完美地运行 FLIP 动画,需要调用两次 requestAnimationFrame:
requestAnimationFrame(() => { requestAnimationFrame(() => { el.style.transform = ''; }); });
使用 WAAPI 时,我们不会遇到这些问题。可以使用 reverse 函数轻松地进行反转。子级的反向缩放也是可能的。当出现错误时,很容易查明确切的罪魁祸首,因为我们只使用简单的函数,例如 animate 和 reverse,而不是像 requestAnimationFrame 方法那样梳理各种内容。
以下是 WAAPI 版本的概要:
el.classList.toggle('someclass'); const keyframes = /* 计算大小/位置差异 */; el.animate(keyframes, 2000);
FLIP 和 React
要了解 FLIP 动画如何在 React 中工作,重要的是要知道它们如何以及最重要的是为什么它们在纯 JavaScript 中工作。回想一下 FLIP 动画的构成:
所有具有紫色背景的内容都需要在渲染的“绘制”步骤之前发生。否则,我们会看到新样式短暂闪烁,这不好。在 React 中情况会变得稍微复杂一些,因为所有 DOM 更新都是由我们完成的。
FLIP 动画的魔力在于,元素在浏览器有机会绘制之前就被转换了。那么我们如何在 React 中知道“绘制前”的时刻呢?
让我们来了解一下 useLayoutEffect
钩子。如果您想知道它是什么……这就是它!我们在这个回调中传递的任何内容都会在 DOM 更新之后但在绘制之前同步发生。换句话说,这是一个设置 FLIP 的好地方!
让我们做一些 FLIP 技术非常擅长的事情:动画 DOM 位置。如果我们想动画化元素如何从一个 DOM 位置移动到另一个 DOM 位置,CSS 就无能为力。(想象一下完成待办事项列表中的任务并将其移动到“已完成”任务列表中,就像您单击下面示例中的项目一样。)
让我们来看一个最简单的例子。单击以下示例中的两个方块中的任何一个都会使它们交换位置。如果没有 FLIP,它会立即发生。
有很多事情要做。请注意所有工作是如何在生命周期钩子回调内发生的:useEffect
和 useLayoutEffect
。让它有点令人困惑的是,我们的 FLIP 动画的时间线从代码本身并不明显,因为它发生在两个 React 渲染中。以下是 React FLIP 动画的构成,以显示不同的操作顺序:
尽管 useEffect
总是运行在 useLayoutEffect
之后以及浏览器绘制之后,但重要的是我们在第一次渲染后缓存元素的位置和大小。我们没有机会在第二次渲染中这样做,因为 useLayoutEffect
在所有 DOM 更新之后运行。但该过程与普通 FLIP 动画基本相同。
注意事项
像大多数事情一样,在 React 中使用 FLIP 时,也有一些注意事项需要考虑。
保持在 100 毫秒以内
FLIP 动画是计算。计算需要时间,在您可以显示流畅的 60fps 转换之前,您需要做相当多的工作。如果延迟低于 100 毫秒,人们就不会注意到延迟,因此请确保所有内容都低于此值。DevTools 中的“性能”选项卡是检查此内容的好地方。
不必要的渲染
我们不能使用 useState
来缓存大小、位置和动画对象,因为每个 setState
都会导致不必要的渲染并减慢应用程序速度。在最坏的情况下,它甚至会导致错误。尝试改为使用 useRef
,并将其视为一个可以在不渲染任何内容的情况下被修改的对象。
布局抖动
避免反复触发浏览器布局。在 FLIP 动画的上下文中,这意味着避免循环遍历元素并使用 getBoundingClientRect
读取它们的位置,然后立即使用 animate
对它们进行动画处理。尽可能批量“读取”和“写入”。这将允许进行极其流畅的动画。
动画取消
尝试在它们移动时随机单击前面的演示中的方块,然后在它们停止后再次单击。您将看到故障。在现实生活中,用户会在元素移动时与它们交互,因此值得确保它们被平滑地取消、暂停和更新。
但是,并非所有动画都可以使用 reverse
反转。有时,我们希望它们停止然后移动到新的位置(例如,当随机打乱元素列表时)。在这种情况下,我们需要:
- 获取正在移动元素的大小/位置
- 完成当前动画
- 计算新的尺寸和位置差异
- 启动新的动画
在 React 中,这比看起来要难。我浪费了很多时间来努力解决这个问题。必须缓存当前动画对象。一个好方法是创建一个 Map,以便通过 ID 获取动画。然后,我们需要获取正在移动元素的大小和位置。有两种方法可以做到这一点:
- 使用函数组件:只需在函数的主体中循环遍历每个动画元素并缓存当前位置即可。
-
使用类组件:使用
getSnapshotBeforeUpdate
生命周期方法。
事实上,官方 React 文档建议使用 getSnapshotBeforeUpdate
,“因为渲染阶段的生命周期(如 render
)和提交阶段的生命周期(如 getSnapshotBeforeUpdate
和 componentDidUpdate
)之间可能存在延迟。”但是,目前还没有此方法的钩子对应项。我发现使用函数组件的主体就足够了。
不要与浏览器对抗
我之前说过,但要避免与浏览器对抗,并尝试使事情以浏览器的方式发生。如果我们需要动画化简单的尺寸更改,那么请考虑 CSS 是否足够(例如 transform: scale()
)。我发现 FLIP 动画最适合浏览器确实无法提供帮助的地方:
- 动画 DOM 位置更改(如上所述)
- 共享布局动画
第二个是第一个的更复杂版本。有两个 DOM 元素充当一个整体并改变其位置(而另一个被卸载/隐藏)。这种技巧可以实现一些很酷的动画。例如,这个动画是用我构建的名为 react-easy-flip 的库制作的,该库使用了这种方法:
库
有很多库可以使 React 中的 FLIP 动画更容易并抽象出样板代码。目前积极维护的库包括:react-flip-toolkit
和我的库 react-easy-flip
。
如果您不介意更重但能够进行更通用动画的内容,请查看 framer-motion
。它还可以进行很酷的共享布局动画!有一个视频深入探讨了该库。
资源和参考文献
- Josh W. Comeau 的《动画化不可动画化》
- Paul Lewis 和 Stephen McGruer 的《构建高性能展开和折叠动画》
- Matt Perry 的《Magic Motion 内部的魔法》
- @keyframers 发布的推文《从 JavaScript 使用动画 CSS 变量》
- Mariko Kosaka 的《现代 Web 浏览器的内部一览(第 3 部分)》
- Alex Holachek 的《在 React 中简单地构建复杂的 UI 动画》
- David Khourshid 的《使用 FLIP 技术动画化布局》
- Kirill Vasiltsov 的《使用 React Hooks 进行流畅动画》
- Jayant Bhawal 的《使用 React Hooks 进行共享元素转换》
This revised output maintains the original image format and placement while paraphrasing the text to create unique content. It also addresses some minor grammatical and stylistic issues.
以上是您需要了解的有关Flip动画中的所有内容的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)
