使用新的动画api重复动画

时间:2015-07-23 04:17:59

标签: animation react-native

React-native引入了新的Animated API,我希望制作一个循环动画,例如缩小气泡,然后按比例缩小并重复该进度。

然而我无法弄明白。我尝试过写下面的代码

class TestProject extends React.Component {

  constructor(): void {
    super();
    this.state = {
      bounceValue: new Animated.Value(0),
      v: 1,
    };
  }

  componentDidMount() {
    this.state.bounceValue.setValue(1.5);

    let animation = Animated.timing(this.state.bounceValue, {
      toValue: this.state.v,
    });

    setInterval(() => {
      animation.stop();

      if (this.state.flag) {
        this.state.v = 0.5;
        this.state.bounceValue.setValue(0.5);
      }
      else {
        this.state.v = 1.5;
        this.state.bounceValue.setValue(1.5);
      }

      animation.start();
    }, 5000);

  }

  render(): ReactElement {
    return (
      <View style={styles.imageContainer}>
        <Image
          style={styles.image}
          source={{uri: 'http://image142-c.poco.cn/best_pocoers/20130517/91062013051716553599334223.jpg'}}
        />
        <Animated.Text
          style={[
            styles.test,
            {transform: [
              {scale: this.state.bounceValue},
            ],}
          ]
          }>
          haha
        </Animated.Text>
      </View>
    );
  }

}

但效果不佳。

任何建议都会受到赞赏。

7 个答案:

答案 0 :(得分:101)

现在有loop animation可用:

Animated.loop(
  Animated.sequence([
    Animated.timing(this.state.animatedStartValue, {
      toValue: 1,
      duration: 500,
      delay: 1000
    }),
    Animated.timing(this.state.animatedStartValue, {
      toValue: 0,
      duration: 500
    })
  ]),
  {
    iterations: 4
  }
).start()

答案 1 :(得分:38)

我使用序列方法将一组动画传递给循环,然后重复该函数。

//this.state.animatedStartValue = 0;

function cycleAnimation() {
  Animated.sequence([
    Animated.timing(this.state.animatedStartValue, {
      toValue: 1,
      duration: 500,
      delay: 1000
    }),
    Animated.timing(this.state.animatedStartValue, {
      toValue: 0,
      duration: 500
    })
  ]).start(() => {
    cycleAnimation();
  });
}

如果我在它上面切换动画,它会淡入/淡出,但是我将它叠加在一个基础之上以模仿活动状态或热点样式按钮

  <TouchableOpacity>
    <Animated.Image
      source={activeImageSource}
      style={this.state.animatedStartValue}}
    />
    <Image source={nonActiveImageSource}
    />
  </TouchableOpacity>

React Native Sequence Documentation

答案 2 :(得分:18)

@bcomerford答案的改进版

//this.state.animatedStartValue = 0;

function cycleAnimation() {
  Animated.sequence([
    Animated.timing(this.state.animatedStartValue, {
      toValue: 1,
      duration: 500,
      delay: 1000
    }),
    Animated.timing(this.state.animatedStartValue, {
      toValue: 0,
      duration: 500
   })
  ]).start(event => {
    if (event.finished) {
      cycleAnimation();
    }
  });
}

答案 3 :(得分:4)

尝试这样的事情:

componentDidMount() {
    this.bootAnimation();
  }

  bootAnimation() {
    this.animation = Animated.loop(
      Animated.timing(this.state.progress, {
        toValue: 1,
        duration: 5000
      })
    ).start();
  }

答案 4 :(得分:0)

您可以设置另一个动画,然后再次调用动画:

我做了一个淡入淡出文本的例子:

  textAnimate: function() {
    Animated.timing(
      this.state.textOpacity,
      {
        toValue: 0.3,                         
        duration: 500, 
      }
    ).start(() => {
      Animated.timing(  
        this.state.textOpacity,            
        {
          toValue: 1,                    
          duration: 500,          
        }
      ).start(() => {
          this.textAnimate();
        });
    });    
  },

  componentDidMount: function() {
    this.state.textOpacity.setValue(1)
    this.textAnimate();
  },

答案 5 :(得分:0)

不知道它是否很hacky,但是我用这个:

Animated.spring(this.state.rotation, {
  toValue: 5,
  stiffness: 220, // the higher value, the faster the animation
  damping: 0.000001, // never stop wiggle wiggle wiggle
}).start();

它正在创建春天的动画,从技术上讲,它永远不会停止挥舞。

对于我的大多数情况而言,这就足够了。此外,由于在动画过程中不需要任何JS踩踏动作,因此它具有出色的性能。

如果最终您想优雅地停止它:

Animated.spring(this.state.rotation, {
  toValue: 0,
  stiffness: 220, // the higher value, the faster the animation
  damping: 10, // never stop wiggle wiggle wiggle
}).start();

它会很好地“减速”直到停止。

答案 6 :(得分:0)

这是使用挂钩并将iterations设置为“ infinity”的无限动画的另一个示例。避免在先前的答案中使用递归,有时在我们进行e2e测试期间会导致时髦的行为。

  const rotation = React.useRef(new Animated.Value(0)).current;

  function runAnimation() {
    return Animated.loop(
      Animated.timing(rotation, {
        toValue: 1,
        duration: 1200,
        easing: Easing.linear,
        useNativeDriver: true,
      }),
      {resetBeforeIteration: true, iterations: Number.MAX_SAFE_INTEGER},
    );
  }

  React.useEffect(() => {
    const animation = runAnimation();
    return () => animation.stop();
  }, []);