Как остановить цикл анимации в React Native?

У меня есть простая анимация цикла в моем компоненте, как это:

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')}
/>

Как остановить эту анимацию? Например, при переходе на другой экран или после нажатия пользователем кнопки.

Я попытался с помощью этого.государство.угол.stopAnimation () но заметил запустить анимацию все еще печатается в консоли. Есть ли другой метод stop, который я должен вызывать, чтобы предотвратить выполнение обратного вызова start?

3 ответов


на основе моего комментария в ответе Нгуена Хоанга. Вот еще один способ остановить цикл анимации, если вы вызываете 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();
    }
  });
}

вы можете создать переменную stopAnimation чтобы остановить анимацию, когда вы хотите, только тогда, когда stopAnimation === false затем обратного вызова . Как пример:

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();
    }
  });
}

поэтому вам просто нужно создать кнопку, которая вызовет функцию this.state = { stopAnimation: true } чтобы остановить анимацию.

пример здесь:https://rnplay.org/apps/Lpmh8A.


установить глобальную переменную

let dataloaded = false;

чтобы остановить анимацию, переопределите переменную (dataloaded), когда захотите

componentWillUnmount() {
    dataloaded = true;
}

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

окончательный код будет выглядеть как

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();
        }
    })
}