Loading...
Loading...
Compare original and translation side by side
layout<motion.div layout>
{items.map(item => (
<motion.div key={item.id} layout />
))}
</motion.div>layout<motion.div layout>
{items.map(item => (
<motion.div key={item.id} layout />
))}
</motion.div>| Mode | Behavior |
|---|---|
| Animate position and size |
| Animate only position |
| Animate only size |
<motion.div layout="position" />
<motion.div layout="size" />| 模式 | 行为 |
|---|---|
| 动画位置和尺寸 |
| 仅动画位置 |
| 仅动画尺寸 |
<motion.div layout="position" />
<motion.div layout="size" />layoutIdlayoutId// Page A
function CardA() {
return <motion.div layoutId="card" />;
}
// Page B
function CardB() {
return <motion.div layoutId="card" />;
}layoutId// 页面A
function CardA() {
return <motion.div layoutId="card" />;
}
// 页面B
function CardB() {
return <motion.div layoutId="card" />;
}layoutIdfunction ListItem({ item, onClick }) {
return (
<motion.div layoutId={`item-${item.id}`} onClick={onClick}>
{item.name}
</motion.div>
);
}
function Modal({ item }) {
return (
<motion.div layoutId={`item-${item.id}`}>
<h2>{item.name}</h2>
<p>{item.description}</p>
</motion.div>
);
}function ListItem({ item, onClick }) {
return (
<motion.div layoutId={`item-${item.id}`} onClick={onClick}>
{item.name}
</motion.div>
);
}
function Modal({ item }) {
return (
<motion.div layoutId={`item-${item.id}`}>
<h2>{item.name}</h2>
<p>{item.description}</p>
</motion.div>
);
}import { AnimatePresence, motion } from "framer-motion";
function TodoList({ todos }) {
return (
<motion.ul>
<AnimatePresence>
{todos.map(todo => (
<motion.li
key={todo.id}
layout
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: 20 }}
/>
))}
</AnimatePresence>
</motion.ul>
);
}import { AnimatePresence, motion } from "framer-motion";
function TodoList({ todos }) {
return (
<motion.ul>
<AnimatePresence>
{todos.map(todo => (
<motion.li
key={todo.id}
layout
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: 20 }}
/>
))}
</AnimatePresence>
</motion.ul>
);
}<AnimatePresence mode="wait">
{isOpen && <Modal key="modal" />}
</AnimatePresence>| Mode | Description |
|---|---|
| All animations run simultaneously (default) |
| Exit completes before enter starts |
| Exiting element removed from layout immediately |
<AnimatePresence mode="wait">
{isOpen && <Modal key="modal" />}
</AnimatePresence>| 模式 | 描述 |
|---|---|
| 所有动画同时运行(默认) |
| 退出动画完成后再开始进入动画 |
| 退出元素立即从布局中移除 |
function ReorderableList({ items, setItems }) {
return (
<AnimatePresence>
{items.map(item => (
<motion.div
key={item.id}
layout
drag
dragConstraints={{ top: 0, bottom: 0 }}
onDragEnd={({ info, target }) => {
// Calculate new index and update
}}
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.8 }}
/>
))}
</AnimatePresence>
);
}function ReorderableList({ items, setItems }) {
return (
<AnimatePresence>
{items.map(item => (
<motion.div
key={item.id}
layout
drag
dragConstraints={{ top: 0, bottom: 0 }}
onDragEnd={({ info, target }) => {
// 计算新索引并更新
}}
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.8 }}
/>
))}
</AnimatePresence>
);
}function Grid({ items }) {
return (
<motion.div
layout
style={{
display: "grid",
gridTemplateColumns: "repeat(auto-fill, minmax(100px, 1fr))",
gap: 10
}}
>
{items.map(item => (
<motion.div
key={item.id}
layout
style={{
width: "100%",
aspectRatio: 1,
backgroundColor: item.color
}}
/>
))}
</motion.div>
);
}function Grid({ items }) {
return (
<motion.div
layout
style={{
display: "grid",
gridTemplateColumns: "repeat(auto-fill, minmax(100px, 1fr))",
gap: 10
}}
>
{items.map(item => (
<motion.div
key={item.id}
layout
style={{
width: "100%",
aspectRatio: 1,
backgroundColor: item.color
}}
/>
))}
</motion.div>
);
}<motion.div
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0 }}
/><motion.div
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0 }}
/><motion.div
layout
exit={{ opacity: 0, x: -100, transition: { duration: 0.3 } }}
/><motion.div
layout
exit={{ opacity: 0, x: -100, transition: { duration: 0.3 } }}
/>function Toggle() {
const [showA, setShowA] = useState(true);
return (
<AnimatePresence mode="popLayout">
{showA ? (
<motion.div
key="a"
layoutId="shape"
style={{ backgroundColor: "red" }}
/>
) : (
<motion.div
key="b"
layoutId="shape"
style={{ backgroundColor: "blue", borderRadius: "50%" }}
/>
)}
</AnimatePresence>
);
}function Toggle() {
const [showA, setShowA] = useState(true);
return (
<AnimatePresence mode="popLayout">
{showA ? (
<motion.div
key="a"
layoutId="shape"
style={{ backgroundColor: "red" }}
/>
) : (
<motion.div
key="b"
layoutId="shape"
style={{ backgroundColor: "blue", borderRadius: "50%" }}
/>
)}
</AnimatePresence>
);
}