So essentially, I want to play the lottie animation everytime it is tapped. Here is my UI code for the lottie animation:
<Pressable onPress={playGame}> <LottieView ref={loseAnimationRef} style={styles.egg} source={Lost} autoPlay={false} loop={false} onAnimationFinish={() => { resetAnimation(); }} /> </Pressable>
Here is my state code for the lottie animation:
const loseAnimationRef = useRef(null); const playGame = async () => { await mainGameLogicUC(); playAnimation() }; const playAnimation = () => { loseAnimationRef.current.play() } const resetAnimation = () => { loseAnimationRef.current.reset() }
On the first tap, the animation play perfefctly fine. But on all other taps, the animation won’t play. I tried pausing the animation in the onAnimationFinish
and then resuming it, but that also didn’t work. Am I missing something?
EDIT
I got rid of the resetAnimation()
in the onAnimationFinish
and that solved the initial problem. But the thing is, I want the animation to be reset to the beginning every time. Why does it break when I reset the animation?
Advertisement
Answer
After coming back to this problem a few days later, I found the solution
Playing the lottie animation seems to be considered a side effect, therefore, editing the references to the animations should be done in a useEffect
hook
The solution that worked for me:
(again, in this code, I want the animation to reset to the beginning before the user taps the screen screen again.
state code
const isMounted = useRef(false); const [isWonAnimationShowing, setIsWonAnimationShowing] = useState(false); const [isAnimationPlaying, setIsAnimationPlaying] = useState(false); const loseAnimationRef = useRef(null); const winAnimationRef = useRef(null); useEffect(() => { if (isMounted.current) { if (isAnimationPlaying) { _playAnimation(); } else { _resetAnimation(); } } else { isMounted.current = true; } }, [isAnimationPlaying]); const playAnimation = () => { setIsAnimationPlaying(true); }; const _playAnimation = () => { if (isWonAnimationShowing) { winAnimationRef.current.play(); } else { loseAnimationRef.current.play(); } }; const resetAnimation = () => { setIsAnimationPlaying(false); }; const _resetAnimation = () => { if (isWonAnimationShowing) { winAnimationRef.current.reset(); } else { loseAnimationRef.current.reset(); } };
UI code
<View style={styles.body}> <Pressable disabled={isAnimationPlaying} onPress={playGame}> {isWonAnimationShowing ? ( <LottieView ref={winAnimationRef} style={styles.egg} source={Won} autoPlay={false} loop={false} onAnimationFinish={() => { resetAnimation(); }} /> ) : ( <LottieView ref={loseAnimationRef} style={styles.egg} source={Lost} autoPlay={false} loop={false} onAnimationFinish={() => { resetAnimation(); }} /> )} </Pressable> </View>