React的动画小结

在搞Ember开发时,简单的做过一些CSS动画,主要参考了这篇文章。CSS简介。当时动画切换的基本思路定义几个animation,每个animation和一个cssclass绑定,改变动画就是改变当前divclass。但是这个方法在React里面似乎不起作用,尝试在Chrome里面直接修改React渲染好的dom的class,也没有效果,目前还不知道原因。

查了一下React官网的动画文档,其中的ReactCSSTransitionGroup是React推荐我们使用的动画组件。这个动画组件基于React组件的生命周期,也就是说我们需要在CSS文件里面定义一大堆以组件生命周期作为后缀的样式名称,组件会在其执行到不同的动画阶段调用不同的css样式。动画的生命周期分为enterenterActiveappearappearActiveleaveleaveActive。假设我们的动画名字叫anim,那么对应的css名字就需要有如anim-enteranim-enter-active之类的。而且还需要在代码中显式的指定css动画时间。

React提供的动画组件功能很简单,对动画的动态控制基本不支持,比如让动画倒着播一遍之类的。好处就是动画代码的维护成本比较低,都是一些css(动画时间在css里面和代码里面要一致这个问题有点坑)文件。

然后看到了Velocity.js,这是一个基于js的动画库,搜了一下,发现这个库有react版本velocity-react。用了一下,发现功能还是非常强大的。它内置了一系列的动画预设,如果我们需要自己定义动画,需要自定义一个动画对象,比如下面这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var ToolbarAnimation = {
up: velocityHelpers.registerEffect({
defaultDuration: 500,
calls: [
[{top: '-60px'}, 1]
]
}),
down: velocityHelpers.registerEffect({
defaultDuration: 500,
calls: [
[{top: 0}, 1]
]
})
}

这个库的具体用法就不说了,库自带例子。通过这个库,我们动画的定义从css变到了js里面,增加了对动画细节的控制力度,当然,代码维护量可能变大了。velocity也为我们提供了一个和ReactCSSTransitionGroup功能类似的库VelocityTransitionGroupVelocityTransitionGroupVelocityComponent的区别在于前者多了几个钩子函数,用来控制组件生命周期内,比如创建时,销毁时的动画行为。VelocityComponent组件让我们能最大化的定义组件出现后本身的动画行为。

注意:使用VelocityTransitionGroup动画的时候,请按照ReactCSSTransitionGroup文档的要求给子对象加上key,否则动画切换可能失效。

1
2
3
4
5
return (<VelocityTransitionGroup component="div"
enter={{animation: FadeAnimation.in}}
leave={{animation: FadeAnimation.out}}>
{this.state.view === 'userList' ? this.renderUserList() : this.renderLogin()}
</ VelocityTransitionGroup >)

上述代码需要给this.renderUserListthis.renderLogin对应的根节点加上key属性。

上述代码中,有一段时间userlist在淡出,login在淡入,也就说会同时出现两个界面,这个时候需要确保它们的动画容器使用正确的布局方式(通常是绝对布局)来达到重叠两个界面的效果。否则这段时间界面会根据css排版规则发生抖动。