搜索
首页web前端css教程您需要了解的有关Flip动画中的所有内容

Everything You Need to Know About FLIP Animations in React

最新 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,它会立即发生。

有很多事情要做。请注意所有工作是如何在生命周期钩子回调内发生的:useEffectuseLayoutEffect。让它有点令人困惑的是,我们的 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 获取动画。然后,我们需要获取正在移动元素的大小和位置。有两种方法可以做到这一点:

  1. 使用函数组件:只需在函数的主体中循环遍历每个动画元素并缓存当前位置即可。
  2. 使用类组件:使用 getSnapshotBeforeUpdate 生命周期方法。

事实上,官方 React 文档建议使用 getSnapshotBeforeUpdate,“因为渲染阶段的生命周期(如 render)和提交阶段的生命周期(如 getSnapshotBeforeUpdatecomponentDidUpdate)之间可能存在延迟。”但是,目前还没有此方法的钩子对应项。我发现使用函数组件的主体就足够了。

不要与浏览器对抗

我之前说过,但要避免与浏览器对抗,并尝试使事情以浏览器的方式发生。如果我们需要动画化简单的尺寸更改,那么请考虑 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中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
@KeyFrames vs CSS过渡:有什么区别?@KeyFrames vs CSS过渡:有什么区别?May 14, 2025 am 12:01 AM

@keyframesandCSSTransitionsdifferincomplexity:@keyframesallowsfordetailedanimationsequences,whileCSSTransitionshandlesimplestatechanges.UseCSSTransitionsforhovereffectslikebuttoncolorchanges,and@keyframesforintricateanimationslikerotatingspinners.

使用页面CMS进行静态站点内容管理使用页面CMS进行静态站点内容管理May 13, 2025 am 09:24 AM

我知道,我知道:有大量的内容管理系统选项可用,而我进行了几个测试,但实际上没有一个是一个,y'知道吗?怪异的定价模型,艰难的自定义,有些甚至最终成为整个&

链接HTML中CSS文件的最终指南链接HTML中CSS文件的最终指南May 13, 2025 am 12:02 AM

链接CSS文件到HTML可以通过在HTML的部分使用元素实现。1)使用标签链接本地CSS文件。2)多个CSS文件可通过添加多个标签实现。3)外部CSS文件使用绝对URL链接,如。4)确保正确使用文件路径和CSS文件加载顺序,优化性能可使用CSS预处理器合并文件。

CSS Flexbox与网格:全面评论CSS Flexbox与网格:全面评论May 12, 2025 am 12:01 AM

选择Flexbox还是Grid取决于布局需求:1)Flexbox适用于一维布局,如导航栏;2)Grid适合二维布局,如杂志式布局。两者在项目中可结合使用,提升布局效果。

如何包括CSS文件:方法和最佳实践如何包括CSS文件:方法和最佳实践May 11, 2025 am 12:02 AM

包含CSS文件的最佳方法是使用标签在HTML的部分引入外部CSS文件。1.使用标签引入外部CSS文件,如。2.对于小型调整,可以使用内联CSS,但应谨慎使用。3.大型项目可使用CSS预处理器如Sass或Less,通过@import导入其他CSS文件。4.为了性能,应合并CSS文件并使用CDN,同时使用工具如CSSNano进行压缩。

Flexbox vs Grid:我应该学习两者吗?Flexbox vs Grid:我应该学习两者吗?May 10, 2025 am 12:01 AM

是的,youshouldlearnbothflexboxandgrid.1)flexboxisidealforone-demensional,flexiblelayoutslikenavigationmenus.2)gridexcelstcelsintwo-dimensional,confffferDesignssignssuchasmagagazineLayouts.3)blosebothenHancesSunHanceSlineHancesLayOutflexibilitibilitibilitibilitibilityAnderibilitibilityAndresponScormentilial anderingStruction

轨道力学(或我如何优化CSS KeyFrames动画)轨道力学(或我如何优化CSS KeyFrames动画)May 09, 2025 am 09:57 AM

重构自己的代码看起来是什么样的?约翰·瑞亚(John Rhea)挑选了他写的一个旧的CSS动画,并介绍了优化它的思维过程。

CSS动画:很难创建它们吗?CSS动画:很难创建它们吗?May 09, 2025 am 12:03 AM

CSSanimationsarenotinherentlyhardbutrequirepracticeandunderstandingofCSSpropertiesandtimingfunctions.1)Startwithsimpleanimationslikescalingabuttononhoverusingkeyframes.2)Useeasingfunctionslikecubic-bezierfornaturaleffects,suchasabounceanimation.3)For

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具