How to stop a looping animation in React Native?

心不动则不痛 提交于 2019-12-04 19:31:23

问题


I have a simple looping animation in my component like this:

runAnimation() {
    console.log('run animation');
    this.state.angle.setValue(0);
    Animated.timing(this.state.angle, {
        toValue: 360,
        duration: 8000,
        easing: Easing.linear
    }).start(() => this.runAnimation());
}

...

<Animated.Image
    style={[
        styles.rotate,
        { transform: [
            { rotate: this.state.angle.interpolate({
                inputRange: [0, 360],
                outputRange: ['0deg', '360deg']
            })},
        ]}
    ]}
    source={require('./spinning_ball.png')}
/>

How would I stop this animation? For example, when navigating away to another screen or after a user clicks on a button.

I tried using this.state.angle.stopAnimation() but noticed run animation still being printed in the console. Is there a different stop method I should be calling to prevent the start callback from being executed?


回答1:


Based on my comment in Nguyên Hoàng's answer. Here is another way to stop the looping animation if you call this.state.angle.stopAnimation():

runAnimation() {
  this.state.angle.setValue(0);
  Animated.timing(this.state.angle, {
    toValue: 360,
    duration: 8000,
    easing: Easing.linear
  }).start((o) => {
    if(o.finished) {
      this.runAnimation();
    }
  });
}



回答2:


You can create a variable stopAnimation to stop Animation whenever you want by only when stopAnimation === false then callback runAnimation function. Like example:

this.state = { stopAnimation: false }

runAnimation() {
  this.state.spinValue.setValue(0);
  Animated.timing(
    this.state.spinValue,
    {
      toValue: 1,
      duration: 3000,
      easing: Easing.linear
    }
  ).start( () => {
    if(this.state.stopAnimation === false) {
      this.runAnimation();
    }
  });
}

So you just need to create a button which call function this.state = { stopAnimation: true } to stop Animation.

Example here: https://rnplay.org/apps/Lpmh8A.




回答3:


Set a global variable

let dataloaded = false;

To stop animation override the variable (dataloaded) whenever you want

componentWillUnmount() {
    dataloaded = true;
}

onPress={() => {
    dataloaded = true;
}}

final code will look like

runAnimation() {
    console.log('run animation');
    this.state.angle.setValue(0);
    Animated.timing(this.state.angle, {
        toValue: 360,
        duration: 8000,
        easing: Easing.linear
    })
    .start(() => {
        if ( ! dataloaded) {
            this.runAnimation();
        }
    })
}



回答4:


You can stop the loop using:

componentWillUnmount() {
   Animated.timing(this.state.angle).stop();
}


来源:https://stackoverflow.com/questions/42149793/how-to-stop-a-looping-animation-in-react-native

工具导航Map