「React」如何在React中优雅的实现动画

Posted 张越

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「React」如何在React中优雅的实现动画相关的知识,希望对你有一定的参考价值。

有没有内推的,求个机会,QQ: 1025873823

最简单的动画组件实现

动画的本质,无非就是一个状态样式到另一个状态样式的过渡。最简单的动画组件,我们只需要指定两个状态的样式(进入的样式,离开的样式),以及一个开关(控制状态),即可完成。

codepen地址

实现一组动画的过渡

实现一组动画的过渡。我们只需要在多个最简单的动画组件的基础之上,设置一个统一的开关,统一控制,多个动画组件动画的状态即可。如果想实现有交错的过渡(有时间间隔的过渡),我们只需要根据动画组件在一组元素中的索引位置,设置合适的延迟即可。

为了引入统一的开关的控制,我们为动画组件添加一个父级组件,父级组件的开关控制所有子组件的开关状态。父组件使用React.Context将自己开关的状态,下发给子组件。

为了实现交错效果,我们需要为列表中子组件设置不同长度的延迟。延迟时长和子组件在列表索引,以及开关的状态有关。

比如:

在开关设置为true, 需要显示入场的动画。延迟自上而下,依次增大(0ms, 100ms, 200ms, 300ms)

在开关设置为false, 需要显示出场的动画。延迟自上而下,依次减小(300ms, 200ms, 100ms, 0ms)

codepen地址

上述组件目前存在的问题

  1. 节点必须事先已经渲染好,对于动态插入的节点,这些动画组件无能为力。(在下方我们参考了`react-transition-group实现解决这个问题)
  2. 如果元素起始样式有display: none动画将不会起效果(这个问题其实和动态插入节点属于一类问题)。
  3. 对于一组列表节点。新的节点的插入,和删除时。其他节点的过渡很生硬,没有动画效果(我们可以使用flip动画解决这个问题)。

FLIP动画

FLIP动画实现原理是: 缓存元素起点的位置, 然后将元素置于终点的位置,计算终点与起点的差值,根据差值应用动画。

我们先看看flip动画强大的效果

接下来,我们来一步一步实现一个简易的flip动画,然后再尝试在react中实现。

闪烁

请问下面的代码,会造成闪烁的问题吗?

codepen演示

答案: 是不会。具体原因和浏览器的事件队列有关。点击事件的代码,我们必须执行完成当前的任务(当前代码段的执行)才会进行浏览器渲染。

这一点对我们很重要。再重申一遍flip动画的原理,缓存元素起点的位置, 然后将元素置于终点的位置,计算终点与起点的差值,根据差值应用动画。

雏形

然后基于上面的代码,我们目前可以实现一个简易的flip动画

codepen演示

我们可以看到,动画已经实现,但是目前动画的计算还是固定的,我们接下来尝试让它自动化。

完善

我们尝试对, 之前状态和当前状态的属性,做自动的差值计算。

codepen演示

我们目前已经实现了,宽度和x轴的flip动画。

以上是关于「React」如何在React中优雅的实现动画的主要内容,如果未能解决你的问题,请参考以下文章

React 如何优雅地实现标签页切换

如何实现React原生倒计时圈

React实现优雅的弹窗

React实现优雅的弹窗

在 React 中处理滚动动画

关于React组件之间如何优雅地传值的探讨