React中常见的动画实现的几种方式(2)
在示例中,我们在 increase 和 decrease 函数中构建线性过渡函数 animation , requestAnimationFrame 在浏览器每次重绘前执行会执行过渡函数,计算当前进度条 width 属性并更新该 state ,使得进度条重新渲染。该示例的效果如下所示:

这种实现方式在使用 requestAnimationFrame 时性能不错,完全使用纯 js 实现,不依赖于 css,使用定时器时可能出现掉帧卡顿现象。此外,还需要开发者根据速度函数自己计算状态,比较复杂。
二、基于 css3 的简单动画
当 css3 中的 animation 和 transition 出现和普及后,我们可以轻松地利用 css 实现元素样式的变化,而不用通过人为计算实时样式。
示例
我们仍以上面的进度条为例,使用 css3 实现进度条动态效果,代码如下所示:
import React, { Component } from 'react';
export default class Progress extends Component {
constructor(props) {
super(props);
this.state = {
percent: 10
};
}
increase = () => {
const percent = this.state.percent + 10;
this.setState({
percent: percent > 100 ? 100 : percent,
})
}
decrease = () => {
const percent = this.state.percent - 10;
this.setState({
percent: percent < 0 ? 0 : percent,
})
}
render() {
// 同上例, 省略
....
}
}
.progress-inner {
transition: width 400ms cubic-bezier(0.08, 0.82, 0.17, 1);
// 其他样式同上,省略
...
}
在示例中, increase 和 decrease 函数中不再计算 width ,而是直接设置增减后的宽度。需要注意的是,在 css 样式中设置了 transition 属性,该属性在其指定的 transition-property 发生变化时自动实现样式的动态变化效果,并且可以设置不同的速度效果的速度曲线。该示例的效果如下图所示,可以发现,与上一个例子不同的是,右侧的进度数据是直接变化为目标数字,没有具体的变化过程,而进度条的动态效果因为不再是线性变化,效果更为生动。

基于 css3 的实现方式具有较高的性能,代码量少,但是只能依赖于 css 效果,对于复杂动画也很难实现。此外,通过修改 state 实现动画效果,只能作用于已经存在于 DOM 树中的节点。如果想用这种方式为组件添加入场和离场动画,需要维持至少两个 state 来实现入场和离场动画,其中一个
