web-dev-qa-db-fra.com

Comment arrêter une animation en boucle dans React Native?

J'ai une animation en boucle simple dans mon composant comme ceci:

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

Comment pourrais-je arrêter cette animation? Par exemple, lors de la navigation vers un autre écran ou après qu'un utilisateur a cliqué sur un bouton.

J'ai essayé d'utiliser this.state.angle.stopAnimation () mais j'ai remarqué exécuter l'animation en cours d'impression dans la console. Existe-t-il une méthode d'arrêt différente que je devrais appeler pour empêcher l'exécution du rappel de démarrage?

8
Michael Cheng

D'après mon commentaire dans la réponse de Nguyên Hoàng. Voici un autre moyen d'arrêter l'animation en boucle si vous appelez 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();
    }
  });
}
14
max23_

Vous pouvez créer une variable stopAnimation pour arrêter l'animation quand vous le souhaitez, uniquement lorsque stopAnimation === false, puis rappeler la fonction runAnimation. Comme exemple:

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

Il suffit donc de créer un bouton qui appelle la fonction this.state = { stopAnimation: true } pour arrêter l’animation.

Exemple ici: https://rnplay.org/apps/Lpmh8A .

3
Nguyên Hoàng

Définir une variable globale

let dataloaded = false;

Pour arrêter l'animation, remplacez la variable (chargée de données) quand vous le souhaitez

componentWillUnmount() {
    dataloaded = true;
}

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

le code final ressemblera à

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