typescript 框架运动交错子项移除时的子项动画不触发动画

p4rjhz4m  于 2022-11-18  发布在  TypeScript
关注(0)|答案(1)|浏览(140)

我有一个列表(ParentBox.tsx),其中包含许多项(Box.tsx)。单击 * 添加 * 按钮时,ParentBox会多一个唯一的Box。动画效果很好。但是,在两种情况下效果不好:
1.当我点击Box时,它会从列表中删除该项目。Framer Motion会在没有退出动画的情况下从用户界面中删除Box
1.当单击“全部删除”时,将删除整个项目列表。没有退出交错效果。
我想有一个单独的元素的列表动画了,当整个列表被清除,有他们一个接一个动画了。
CodeSanbox中的完整重现

父框

const variantsBoxContainer: Variants = {
  hidden: {
    transition: {
      staggerChildren: 0.1,
      delayChildren: 0.3,
      staggerDirection: -1
    }
  },
  show: {
    transition: {
      staggerChildren: 0.1,
      delayChildren: 0.3,
      staggerDirection: 1
    }
  }
};

let id = 3;
export const ParentBox = (props: ParentBoxProps) => {
  const [items, setItems] = useState<Item[]>([
    { id: 1, text: "Test #1" },
    { id: 2, text: "Test #2" }
  ]);
  return (
    <motion.div
      className="parentbox"
    >
      <button
        onClick={() => {
          id++;
          setItems([...items, { id: id, text: `Click to delete id ${id}` }]);
        }}
      >
        Add
      </button>
      <button
        onClick={() => {
          id++;
          setItems([]);
        }}
      >
        Remove All
      </button>

      <motion.ol
        variants={variantsBoxContainer}
        initial="hidden"
        animate="show"
        exit="hidden"
      >
        <AnimatePresence mode="popLayout">
          {items
            .sort((a, b) => a.id - b.id)
            .map((d) => (
              <Box
                key={d.id}
                data={d}
                onRemove={(item) => {
                  const newList = items.filter((i) => i.id !== item.id);
                  console.log(newList);
                  setItems(newList);
                }}
              />
            ))}
        </AnimatePresence>
      </motion.ol>
    </motion.div>
  );
};

Package 盒

const variantBox: Variants = {
  hidden: { opacity: 0, top: -100, transition: { duration: 2 } },
  show: { opacity: 1, top: 0, transition: { duration: 2 } }
};
export const Box = (props: BoxProps) => {
  return (
    <motion.li
      className="box"
      variants={variantBox}
      onClick={() => {
        props.onRemove(props.data);
      }}
    >
      {props.data.text}
    </motion.li>
  );
};

到目前为止,我已经尝试过:
1.在Box组件上添加/删除对initialanimateexit的明确提及。
1.添加/删除when选项。
1.已尝试AnimatedPresence中的所有mode
1.尝试为hidden(exit)变量添加一个函数,以便为每个索引自定义延迟
1.确保所有Box都具有唯一的key
让我知道,如果你有任何想法,我错过了什么有动画的Box删除(儿童)。
CodeSanbox

ee7vknir

ee7vknir1#

如果您明确指示要为动画状态使用的变体,则退出动画将起作用:

export const Box = (props: BoxProps) => {
  return (
    <motion.li
      custom={props.index}
      className="box"
      variants={variantBox}
      exit="hidden"
      initial="hidden"
      animate="show"
      onClick={() => {
        props.onRemove(props.data);
      }}
    >
      {props.data.text}
    </motion.li>
  );
};

我认为AnimatePresencestaggerChildren属性冲突,因为它出现在父级和子级之间。请在GitHub上查看此问题。
最快的解决方法可能是使用动态变量,并在Box组件的变量中手动设置delay(基于items数组中的索引)。

相关问题