1. 首页
  2. css

CSS在React中构建复杂的UI动画

让我们使用React、样式化组件和React-flip工具包在Stripe主页上创建自己版本的动画导航菜单。这是一个令人印象深刻的菜单,有一些圆滑的动画效果,这三种工具的结合可以使它相对容易地再现。
这是一个中级演练,假设熟悉React和基本动画概念。我们的React指南是一个很好的起点。
以下是我们的目标:
查看Repo分解动画首先,让我们将动画分解为不同的部分,以便更轻松地再现它。您可能希望以慢动作(使用切换)检查成品,以便捕捉所有细节。
1. 白色下拉式容器更新其大小和位置。
2. 下拉式容器下半部分的灰色背景会转换其高度。
3. 当下拉式容器移动时,以前的内容会淡出并稍微向相反的方向移动,就像下拉列表将它们抛在后面一样,而新内容则会滑入视图中。
当我们开始在React中复制此动画时,请记住一些有用的指导规则。在可能的情况下,让我们通过浏览器管理布局来保持简单。我们将通过在规则的DOM流中保留元素来实现这一点,而不是使用绝对定位和手动计算。我们将在相应的导航栏区域中呈现一个下拉列表,而不是每次用户鼠标位置改变时都要重新定位一个下拉列表组件。
我们将使用翻转技术创建一个假象,即三个单独的下拉列表组件实际上是一个单一的,移动组件。用样式化的组件搭建出用户界面
首先,我们将构建一个无动画的navbar组件,它只需获取标题和下拉组件的配置对象,并呈现navbar菜单。该组件将在mouseover上显示和隐藏相关的下拉列表。
我们将使用样式化组件构建UI组件。它们不仅是构建模块化UI的一种方便方法,而且还具有用于添加可配置的CSS关键帧动画的强大API。结果是CSS动画和React一起玩得非常好,所以我们稍后将使用CSS关键帧添加许多动画。
组件组装时没有任何动画,我们创建了如下内容:
请注意菜单底部的灰色背景丢失了。它是唯一一个我们必须从常规DOM流中去掉的元素,并且是绝对的位置,所以现在我们将忽略它。使用翻转技术为下拉菜单设置动画
我们将使用react FLIP工具箱库来帮助我们设置下拉菜单的大小和位置的动画。这是一个库,我把它放在一起,使高级和复杂的转换更容易和可配置的。
它为我们提供了两个组件:一个顶级的组件和一个组件来包装我们想要设置动画的任何子级。
首先,让我们在AnimatedNavbar的render函数中设置Flipper包装器组件:
// currentIndex is the index of the hovered dropdown {// render navbar items here})}
接下来,在我们的DropdownContainer组件中,我们将需要设置动画的元素包装在它们自己的Flipped组件中,一定要给每个人一个独特的flipdId道具:

We\”re animating the 组件和组件,这样组件上的overflow:hidden样式就不会干扰组件的渲染了。
现在我们有了一个工作翻转动画,但仍有一个问题:在动画过程中,下拉列表的内容会出现奇怪的拉伸:
这种不必要的效果是因为缩放变换适用于儿童。如果将scaleY(2)应用于内部有文本的div,则会放大文本并对其进行扭曲。
我们可以通过以下方法解决此问题:使用引用父组件flipId(在本例中为\”dropdown\”)的inverseFlipId将子组件包装到Flipped组件中,以请求取消子组件的父转换。因为我们仍然希望translate转换影响子项,所以我们还传递scale属性,将取消限制为仅缩放更改。

Whew. All that work and we\”ve created something that looks like this:It\”s all in the details
It\”s getting closer, but we still have to attend to the small details the make the animation look great: the subtle rotation animation when the dropdown appears and disappears, the cross-fade of previous and current dropdown children, and that silky-smooth gray background height animation.Configurable CSS keyframe animations with styled components
Styled-components, which we\”ve been using to build up the UI for this demo, offer a super convenient way to create configurable keyframe animations. We\”ll use this functionality for both the dropdown enter animation and the cross-fade of the contents. We can pass in some basic information about the desired animation — whether the contents are animating in or out, and the direction the user\”s mouse has moved — and automatically get the appropriate animation applied. Here, for example, is the code for the crossfade animation in the 组件:
const => {if (!direction) return;return keyframes`from {transform: translateX(${animatingOut ? 0 : direction === \”left\” ? 20 : -20}px);}to {transform: translateX(${!animatingOut ? 0 : direction === \”left\” ? -20 : 20}px);opacity: ${animatingOut ? 0 : 1};}`;};const => props.duration * 0.5}ms;animation-fill-mode: forwards;position: => (props.direction && !props.animatingOut ? 0 : 1)};animation-timing-function: linear;top: 0;left: 0;`;
每次用户悬停一个新项时,我们不仅将提供当前下拉列表,而且将以前的下拉列表作为子项提供给DropdownContainer组件,以及有关用户鼠标移动方向的信息。DropdownContainer组件将把它的两个子组件包装在一个新组件FadeContents中,该组件将使用上面的关键帧动画代码来添加适当的过渡。
这里是指向FadeContents组件完整代码的链接。
下拉菜单的输入/输出动画功能非常相似。鳍al touch:一个流体背景动画
最后,让我们添加灰色背景动画。为了使这个动画保持清晰,我们需要改变之前的策略,即保持正常的DOM嵌套并让浏览器处理布局,而是执行一些手动定位计算。我们还需要直接与DOM交互。简而言之,它会变得有点混乱。
这是我们基本方法的一个直观表示:
我们绝对会在***23***的顶部放置一个灰色div。在***25***的***24***生命周期函数中,我们将更新灰度背景的***26***变换。如果下拉列表容器组件只有一个子级(这意味着到目前为止用户只悬停了一个下拉列表),我们将把灰色div的s***27***设置为第一个下拉部分的高度。如果有两个子项,包括上一个下拉列表,我们将把初始的***28***设置为上一个下拉列表第一部分的高度,然后将***29***设置为当前下拉列表第一部分的高度。这是在***30***中调用的函数:
***31***
这种方法要求***32***使用***33***并在其子函数内部进行DOM测量***34***函数,这让人感觉很马虎。如果您有任何其他实现的想法,请在评论中告诉我!结束
希望本文有助于澄清下一次在React中构建动画时可以使用的一些技术。通常有多种方法可以达到任何效果,但通常从最简单的实现开始(基本组件带有一些CSS转换或关键帧动画)并在必要时从那里放大复杂性是有意义的。在我们的例子中,这意味着包含一个额外的库react flip toolkit,因此我们不必担心在屏幕上手动转换下拉组件的位置。为了完全重现动画,我们必须编写大量的代码。但是通过将这个动画分解成不同的部分并逐一处理,我们成功地在React中复制了一个非常酷的UI效果

CSS在React中构建复杂的UI动画 为WP2原创文章,链接:https://www.wp2.cn/css/css%e5%9c%a8react%e4%b8%ad%e6%9e%84%e5%bb%ba%e5%a4%8d%e6%9d%82%e7%9a%84ui%e5%8a%a8%e7%94%bb/