React Native Lottie动画仅在第一次点击上播放

发布于 2025-01-18 07:34:21 字数 912 浏览 3 评论 0原文

所以本质上,我想在每次点击时播放 lotie 动画。这是我的 Lottie 动画的 UI 代码:

<Pressable onPress={playGame}>

<LottieView
   ref={loseAnimationRef}
   style={styles.egg}
   source={Lost}
   autoPlay={false}
   loop={false}
   onAnimationFinish={() => {
      resetAnimation();
   }}
/>

</Pressable>

这是我的 Lottie 动画的状态代码:

  const loseAnimationRef = useRef(null);

  const playGame = async () => {
    await mainGameLogicUC();
    playAnimation()
  };

  const playAnimation = () => {
      loseAnimationRef.current.play()
  }

  const resetAnimation = () => {
      loseAnimationRef.current.reset()
  }

第一次点击时,动画播放得非常好。但在所有其他点击上,动画将不会播放。我尝试在 onAnimationFinish 中暂停动画,然后恢复它,但这也不起作用。我错过了什么吗?

编辑

我摆脱了 onAnimationFinish 中的 resetAnimation() 并解决了最初的问题。但问题是,我希望动画每次都重置到开头。为什么当我重置动画时它会中断?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小巷里的女流氓 2025-01-25 07:34:21

你尝试过这样的事情吗?

const animationRef = useRef<AnimatedLottieView>()
const isAnimating = useRef<boolean>(false)

const onAnimationPress = () => {
    if (!isAnimating.current) {
        isAnimating.current = true
        animationRef.current.play()
    }
}

<TouchableWithoutFeedback onPress={onAnimationPress}>
    <AnimatedLottieView
        source={source}
        ref={animationRef}
        autoPlay={false}
        loop={false}
        onAnimationFinish={() => {
            isAnimating.current = false
            animationRef.current.reset()
        }}
    />
</TouchableWithoutFeedback>

Have you tried something like this?

const animationRef = useRef<AnimatedLottieView>()
const isAnimating = useRef<boolean>(false)

const onAnimationPress = () => {
    if (!isAnimating.current) {
        isAnimating.current = true
        animationRef.current.play()
    }
}

<TouchableWithoutFeedback onPress={onAnimationPress}>
    <AnimatedLottieView
        source={source}
        ref={animationRef}
        autoPlay={false}
        loop={false}
        onAnimationFinish={() => {
            isAnimating.current = false
            animationRef.current.reset()
        }}
    />
</TouchableWithoutFeedback>
莳間冲淡了誓言ζ 2025-01-25 07:34:21

几天后回到这个问题后,我找到了解决方案

播放lottie动画似乎被认为是副作用,因此,编辑对动画的引用应该在useEffect钩子中

完成对我有用的解决方案:(

同样,在这段代码中,我希望在用户再次点击屏幕之前动画重置到开头。

状态代码

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

用户界面代码

    <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>

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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文