2017-02-10 7 views
5

は、私はこのような私のコンポーネントでシンプルなループアニメーションを持っている: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')} 
/> 

私はこのアニメーションをどのように停止するでしょうか?たとえば、別の画面に移動するときや、ユーザーがボタンをクリックした後などです。

私は this.state.angle.stopAnimationを(使用してみました)まだコンソールに印刷されている 実行アニメーションに気づきました。開始コールバックが実行されないようにするためには、別の停止メソッドが必要ですか?

答えて

7

NguyênHoàngの答えに基づいています。

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

どちらのソリューションも機能しましたが、これははるかにクリーンな実装のようでした。 –

+0

ニースキャッチo.finished –

3

という変数を作成して、stopAnimation === falseコールバックrunAnimationが機能するときだけ、アニメーションを停止することができます。例のように:

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

+0

これは唯一の方法ですか?私はすでにこれを可能性と考えていましたが、最もクリーンなアプローチのようには感じません。アニメーションが技術的に終了しなかったときにstopAnimation()がコールバックをトリガーする理由を誰かが説明できるかどうかも疑問です。それとも?私には意味をなさないと思われます。 –

+0

ここでどこが 'this.state.angle.stopAnimation()'を呼び出す場所です@MichaelCheng –

+0

@MichaelCheng 'start()'のコールバックは、関係なく呼び出されます。正常終了した場合は、コールバックに '{finished:true}'のオブジェクトを取得します。しかし、( 'stopAnimation()'などで)中断された場合は、コールバックではなく '{finished:false}'を返します。 –

0

設定するグローバル変数変数(dataloaded)をオーバーライドアニメーションを停止するには

let dataloaded = false; 

あなたがをいつでも:ここでは、this.state.angle.stopAnimation()を呼び出す場合、ループアニメーションを停止する別の方法があります

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(); 
     } 
    }) 
} 
関連する問題