避免安装上的成帧器运动初始动画

问题描述 投票:0回答:5

请参阅此代码和框

我有一个基本的成帧器运动动画,其中盒子的高度在切换时会产生动画效果。但是,我希望默认情况下显示该框,但是当页面加载时会呈现初始动画。

我的问题是,如果组件应在安装时显示,但仍保持未来的进入和退出动画,如何避免组件的初始动画?谢谢!

reactjs framer-motion
5个回答
9
投票

这个问题有点老了,但以防万一有人偶然发现这个问题。如果您使用 AnimatePresence,则可以在

initial={false}
组件上使用
AnimatePresence
。就像这样,

<AnimatePresence initial={false}>
  {someCondition ? (
    <motion.h1 {...yourProps}>
      yooo
    </motion.h1>
  ) : null}
</AnimatePresence>

更多信息在这里: https://www.framer.com/motion/animate-presence/##suppressing-initial-animations

编辑:文档链接更新(2024 年 10 月 20 日)


4
投票

framermotion官方文档中提供了最简单的方法: 指定初始 prop 的值为 false


<motion.div
...
initial={false}
>

</motion.div>

https://www.framer.com/docs/animation/##enter-animations


1
投票

我想出了这样的解决方案;

1-我对组件内部进行了变体

2 - 我为不透明度和高度创建了两种状态

3 - 状态最初与您设置动画的位置相同。所以当你第一次渲染时基本上什么也没有发生。

4 - 使用 useEffect,您可以将这些值与实际的初始值交换,因此在首次渲染后,动画可以正常工作。


export const AnimatedFallback = ({ isVisible }) => {
  const [opacity, setOpacity] = useState(1);
  const [height, setHeight] = useState("200px");

  const variants = {
    initial: {
      opacity: opacity,
      height: height
    },
    enter: {
      opacity: 1,
      height: "200px",
      transition: { duration: 0.5 }
    },
    exit: {
      opacity: 0,
      height: 0,
      transition: { duration: 0.5 }
    }
  };

  useEffect(()=> {
    setHeight(0)
    setOpacity(0)
  }, [])

  return (
    <AnimatePresence>
      {isVisible && (
        <motion.div
          animate="enter"
          className="fallback"
          exit="exit"
          initial="initial"
          variants={variants}
        >
          Suspense Fallback Component
        </motion.div>
      )}
    </AnimatePresence>
  );
};


1
投票

您可以通过以下方式检查是否是组件首先渲染:

const firstRender = useRef(true);

useEffect(() => {
 if (firstRender.current) {
      firstRender.current = false;
      return;
    }
});

如果是组件的第一次渲染,请勿将变体传递给

motion.div
。在您的示例中,这看起来像这样:

const variants = {
  initial: {
    opacity: 0,
    height: 0
  },
  enter: {
    opacity: 1,
    height: "200px",
    transition: { duration: 0.5 }
  },
  exit: {
    opacity: 0,
    height: 0,
    transition: { duration: 0.5 }
  }
};

export const AnimatedFallback = ({ isVisible }) => {
  const firstRender = useRef(true);

  useEffect(() => {
    if (firstRender.current) {
      firstRender.current = false;
      return;
    }
  });
  
  return (
    <AnimatePresence>
      {isVisible && (
        <motion.div
          animate="enter"
          className="fallback"
          exit="exit"
          initial="initial"
          variants={firstRender.current ? {} : variants}
        >
          Suspense Fallback Component
        </motion.div>
      )}
    </AnimatePresence>
  );
};

0
投票

对我来说,在

initial
中指定
motion.div
属性有帮助

<motion.div initial={{ opacity: 0, height: 0}}>
...
</motion.div>
© www.soinside.com 2019 - 2024. All rights reserved.