天天看点

React动画框架简介React 插件React MotionGSAP总结

由于 React 加持了虚拟 DOM 等诸多特性,所以在 React 上实现常规的动画效果有一些特别之处。本文不会深入探讨 React 对动画的处理逻辑,只会简单地演示如何使用 React 创建动画效果。

React 官方提供了两个插件用于处理动画效果:一个是偏底层的 react-addons-transition-group,一个是在前者基础上进一步封装的 react-addons-css-transition-group。在使用它们之前,需要先检查下你使用的是哪种类型的 React 版本,一般通过 npm 安装的 React 默认不会安装这两个插件,需要手动安装它们:

在这里先介绍 react-addons-css-transition-group 的使用方式,使用它可以快速利用 CSS 的能力实现组件的入场和出场动画。使用该插件实现 React 动画需要两个部分的协作,首先是 JS 部分的组件:

在 CSSTransitionGroup 组件上,我们声明了一堆以 transition 开头的属性,这些属性被用来控制动画效果:

transitionName,写样式时的前缀,比如这里的值为 todo,那么 CSS 的类型就应该是todo-enter、todo-leave 等等

transitionAppear,布尔值,是否在所有组件挂载时触发动画

transitionEnterTimeout,控制入场动画的时长

transitionLeaveTimeout,控制退场动画的时长

transitionAppearTimeout,控制所有组件挂载的动画时长

默认情况下,CSSTransitionGroup 组件会被渲染为 span 标签,如果你想修改标签类型,可以使用 component 属性进行修改。其次是 CSS 部分的样式,CSS 中类选择器遵循类似 ${transitionName}-appear 的命名格式:

通过上述两部分的结合,当我们删除 itemNodeList 中的某个组件时,React 会立即通过 key 找到这个组件,然后为其添加 todo-leave 类名,并瞬间添加 todo-leave-active 类名,在 500 毫秒之后移出该组件。

这种动画处理方式的优点如下:

简单快速,与 React 的融合性好,性能有保障

可以使用 Sass、Less 等预处理器,提高开发效率

易于上手,无第三方依赖,也就是无门的动画处理模块,这里的插件只是将类选择器应用到相关的节点上

不过缺点也很多:

只有入场和出场动画,无法实现复杂动画

组件之间的动画效果是独立的,无互动,动画效果生硬 要求和限制条件多

使用 CSS Modules 需要硬编码,也就是使用CSSTransitionGroup 组件自定义类名的功能

最后,列出使用 React 插件开发动画的几点要求:

组件必须挂载才能实现动画

组件必须设定独一无二的 key 值

transitionName 必须与 CSS 中的样式类名保持一致

从上面的示例可以看出,CSSTransitionGroup 组件主要用来在组件入场和出场时给 DOM 节点添加类名,相当于是与 CSS 的结合,那么我们是否能够通过 JS 生成行内样式,然后添加到 DOM 节点,实现更加灵活的动画效果呢?答案是可以的,React 提供了 ReactTransitionGroup 组件供开发者在以下六个阶段向 DOM 节点注入数据:

componentWillAppear(callback)

componentDidAppear()

componentWillEnter(callback)

componentDidEnter()

componentWillLeave(callback)

componentDidLeave()

使用react-motion之前需要先安装库,安装命令如下:

React动画框架简介React 插件React MotionGSAP总结

对于绝大多数的动画组件,我们往往不希望对动画属性(宽高、颜色等)的变化时间做硬编码处理,react-motion 提供的 spring 函数就是用来解决这一需求的,它可以逼真地模仿真实的物理效果,也就是我们常见的各类缓动效果。react-motion 一共提供了五个 API 接口,其中前两个是辅助类函数,后三个是具体的动画组件:

spring,声明动画的缓动效果,比如 spring(10, {stiffness: 120, damping: 17}),10是目标值,stiffness 是弹性动画的刚度值,影响弹性,damping 是弹性动画的阻尼;

presets,预置的缓动效果,比如 spring(10, preset.gentle);

Motion,该动画组件内部往往只有一个直接子组件,也就是只有一个动画目标;

StaggerdMotion,该动画组件内部有一个或多个直接子组件,多个子组件之间的动画效果由关联性;

TransitionMotion,该动画组件内部的一个或多个组件可以卸载或挂载,提供 Enter 和 Leave 动画效果;

示例代码如下:

上面代码演示了 Motion 组件的最基础使用方法。

defaultStyle?: PlainStyle,可选参数,PlainStyle 指的就是 React 常用作行内样式的对象类型的 {width: '10px', height: '10px' },见名知意,为动画设定初始值

style: Style,必选参数,指定动画完成的目标值,并设定动画的变化类型,实际上是一种数据驱动的形式

onRest?: () => void,可选参数,在动画完成后调用

children: (interpolatedStyle: PlainStyle) =>ReactElement,必选函数,接收一个从初始值到目标值中间的值,这个值不断变化,用于渲染子组件的样式

将 GSAP 与 React 结合最简单的方式是,使用 ref 或 findDOMNode()。例如:

TweenMax 的强大在于多年的动画开发经验所积累的技术底蕴,非一朝一夕可以被替代,上面简单演示了 TweenMax 的一小部分功能,像是 Timeline 的用法就没有介绍,当需要组织的元素越来越多时,其灵活性就会越加凸显。

React动画框架简介React 插件React MotionGSAP总结

GSAP 与 React 结合的另一种方式是使用 ReactTransitionGroup 组件,ReactTransitionGroup 组件提供了六个生命周期方法:

componnetDidAppear()

componnetDidEnter()

componnetDidLeave()

示例:

对于上面提到的几个动画框架,做一个简单的对比:

易用性:CSSTransitionGroup >= React Motion > GSAP

可维护性:看代码量和技术能力,CSSTransitionGroup 最简单

用户体验:GSAP >= React Motion > CSSTransitionGroup

对复杂动画的支持程度:GSAP > React Motion > CSSTransitionGroup

React动画框架简介React 插件React MotionGSAP总结

参考资料

<a href="https://facebook.github.io/react/docs/animation.html">React Animation</a>

<a href="https://github.com/chenglou/react-motion">React Motion</a>

<a href="https://css-tricks.com/comparison-animation-technologies/">A Comparison of Animation Technologies</a>

<a href="http://acgtofe.com/posts/2016/05/gsap-for-animation-pro">GSAP,专业的Web动画库</a>

<a href="https://github.com/azazdeaz/react-gsap-enhancer">React GSAP Enhancer</a>

<a href="https://medium.com/@cheapsteak/animations-with-reacttransitiongroup-4972ad7da286#.o7ta17de0">Animations with ReactTransitionGroup</a>

<a href="http://www.shanemielke.com/archives/usopen-sessions/">GSAP Examples</a>