【问题标题】:React Native Animations, Loop animation without resetting animated value after iterationReact Native Animations,循环动画,迭代后不重置动画值
【发布时间】:2020-06-20 20:29:18
【问题描述】:

React-Native Animated:如何循环动画而不在每次循环后重置动画值。

我一直在努力寻找一种循环 React Native Animations 而不将动画值重置回其初始值的方法。

例如,我制作了一个简单的“摇摆”动画,可以左右移动我的组件

  let animationX = new Animated.Value(0);

  const left = (toValue) => Animated.timing(animationX, {toValue: -toValue, duration: 1500})
  const right = (toValue) => Animated.timing(animationX, {toValue, duration: 1500})

  const startSwayAnimation = () => {
    Animated.loop(
      Animated.sequence([
        left(100),
        right(100),
      ])
    ).start()
  }

问题是我的 animationX 变量在每次循环后重置回 0。 我找不到任何有用的资源来说明如何在不重置值的情况下循环动画,尽管 github 上有两个死问题:

https://github.com/facebook/react-native/issues/18028 https://github.com/facebook/react-native/issues/20560

我几乎要考虑询问 SO,但后来我尝试创建一个递归函数来循环动画,效果很好

如果其他人为此苦苦挣扎,或者知道更好的解决方案(也许是一些我不知道的 Animated.loop 配置),我决定在 SO 上分享这个。

【问题讨论】:

    标签: javascript react-native animation react-animated


    【解决方案1】:

    上述答案的内存泄漏修复!!

    我之前的实现导致了内存泄漏 我还想出了如何使它在自定义钩子中可重用!

    const useLoopAnimation = (animationFn) => {
      // loopAnimation halts when changing state variables (using useState) for unknown reason
      // so use a let variable instead.
      let stopped = false;
      const loopAnimation = () => {
        if (stopped) return false;
        animationFn().start(() => loopAnimation());
      };
    
      // this runs on component dismount to stop the recursive loop.
      useEffect(() => () => {
        stopped = true;
      });
      return loopAnimation;
    };
    

    然后在你的组件中像这样使用它

      const loopAnimation = useLoopAnimation(() =>
        Animated.sequence([left(100), right(100)])
      );
    

    【讨论】:

      【解决方案2】:

      您可以通过在启动回调中调用相同的函数来使用递归来一遍又一遍地调用相同的动画

        let animationX = new Animated.Value(0);
        const left = (toValue: number) =>
          Animated.timing(animationX, { toValue: -toValue, duration: 1500 });
        const right = (toValue: number) =>
          Animated.timing(animationX, { toValue, duration: 1500 });
      
          const loopSway = () => {
              Animated.sequence([
                left(100),
                right(100),
              ]).start(() => loopSway())
          }
      

      但是,我无法创建可重用的 loopAnimation 函数。 当我尝试时,我收到错误undefined is not an object (evaluating 'animations[current].start')

          const sway = Animated.sequence([
            left(100),
            right(100),
          ])
      
          const loopAnimation = (animation) => {
              animation.start(() => loopAnimation(animation))
          }
      
          const loopSway = loopAnimation(sway)
      

      React Native Animated 中似乎有一些副作用,它不允许您将动画分配为常量:(

      我尝试克隆动画

          const loopAnimation = (animation) => {
              const animationClone = {...animation}
              animation.start(() => loopAnimation(animationClone))
          }
      
      

      我尝试将动画设为状态值。

      但是两者都没有成功,如果有人知道如何使这个 fn 可重用,将不胜感激!

      【讨论】:

      • 原来这会导致内存泄漏,我正在研究解决方案!
      猜你喜欢
      • 2021-04-10
      • 2022-06-19
      • 1970-01-01
      • 2021-05-15
      • 2021-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-21
      相关资源
      最近更新 更多