React中常见的动画实现的几种方式(6)

在该示例中,我们在子组件 PhotocomponentWillEntercomponentWillLeave 两个 hook 函数中为每个子组件添加了入场动画 enterAnim 和 离场动画 LeaveAnim 。在入场动画中,使用 TimeLineMax.from(target, duration, vars, delay) 方式建立时间轴动画,指定了每个子组件的动画移动距离随 id 增大而减小,延期时间随着 id 增大而增大,离场动画中每个子组件的延期时间随着 id 增大而减小,从而实现根据组件 id 不同具有不同的动画效果。实际使用时,你可以根据需求对任一子组件添加不同的效果。该示例的效果如下图所示:

在使用 TransitionGroup 时,在 componentnWillAppear(callback)componentnWillEntercallback)componentnWillLeave(callback) 函数中一定要 在函数逻辑结束后调用 callback ,以保证 TransitionGroup 能正确维护子节点的状态序列 。

结合 hook 实现动画可以支持各种复杂动画,如时间序列动画等,由于依赖第三方库,往往动画效果比较流畅,用户体验较好。但是第三方库的引入,需要开发者额外学习对应的 api,也提升了代码复杂度。

五、其他第三方动画库

此外,还有很多优秀的第三方动画库,如 react-motion ,Animated, velocity-react 等,这些动画库在使用时也各有千秋。

Animated

Animated 是一个跨平台的动画库,兼容 React 和 React Native。由于在动画过程中,我们只关心动画的初始状态、结束状态和变化函数,并不关心每个时刻元素属性的具体值,所以 Animatied 采用声明式的动画,通过它提供的特定方法计算 css 对象,并传入 Animated.div 实现动画效果。

示例

我们使用 Animated 实现一个图片翻转的效果,代码如下。

import React, { Component } from 'react'; 
import Animated from 'animated/lib/targets/react-dom';

export default class PhotoPreview extends Component { 
  constructor(props) {
    super(props);
    this.state = {
      anim: new Animated.Value(0)
    };
  }

  handleClick = () => {
    const { anim } = this.state;
    anim.stopAnimation(value => {
      Animated.spring(anim, {
        toValue: Math.round(value) + 1
      }).start();
    });
  }

  render() {
    const { anim } = this.state;

    const rotateDegree = anim.interpolate({
      inputRange: [0, 4],
      outputRange: ['0deg', '360deg']
    });

    return (
      <div>
        <button onClick={this.handleClick}>向右翻转</button>
        <Animated.div
          style={{
            transform: [{
              rotate: rotateDegree
            }]
          }}
          className="preivew-wrapper"
        >
          <img
            alt="img"
            src="http://img4.imgtn.bdimg.com/it/u=1032683424,3204785822&fm=214&gp=0.jpg"
          />
        </Animated.div>
      </div>
    );
  }
}
      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/270.html