让 AI 帮忙总结了一下 Framer Motion 的用法,并整理成了速查手册。
动画和手势属性详解
动画属性
- initial
- 类型: boolean | Target | VariantLabels
- 描述: 定义元素的初始状态。
- 示例:
<motion.div initial={{ opacity: 0, scale: 0.5 }} />
<motion.div initial="hidden" /> // 使用变体
<motion.div initial={false} /> // 禁用初始动画
<motion.div initial={{ opacity: 0, scale: 0.5 }} />
<motion.div initial="hidden" /> // 使用变体
<motion.div initial={false} /> // 禁用初始动画
- animate
- 类型: boolean | Target | VariantLabels | AnimationControls
- 描述: 定义元素的目标动画状态。
- 示例:
<motion.div animate={{ opacity: 1, scale: 1 }} />
<motion.div animate="visible" /> // 使用变体
<motion.div animate={controls} /> // 使用动画控制器
<motion.div animate={{ opacity: 1, scale: 1 }} />
<motion.div animate="visible" /> // 使用变体
<motion.div animate={controls} /> // 使用动画控制器
- exit
- 类型: Target | VariantLabels
- 描述: 定义元素从 DOM 中移除时的动画状态。
- 示例:
<AnimatePresence>
{isVisible && <motion.div exit={{ opacity: 0 }} />}
</AnimatePresence>
<AnimatePresence>
{isVisible && <motion.div exit={{ opacity: 0 }} />}
</AnimatePresence>
- transition
- 类型: Transition
- 描述: 定义动画的过渡效果。
- 示例:
<motion.div
animate={{ x: 100 }}
transition={{ duration: 0.5, ease: "easeInOut" }}
/>
<motion.div
animate={{ x: 100 }}
transition={{ duration: 0.5, ease: "easeInOut" }}
/>
- variants
- 类型: Variants
- 描述: 变体,定义一组可重用的动画状态。
- 示例:
const variants = {
hidden: { opacity: 0 },
visible: { opacity: 1 }
}
<motion.div variants={variants} initial="hidden" animate="visible" />
const variants = {
hidden: { opacity: 0 },
visible: { opacity: 1 }
}
<motion.div variants={variants} initial="hidden" animate="visible" />
手势属性
- whileHover
- 类型: Target | VariantLabels
- 描述: 定义鼠标悬停时的动画状态。
- 示例:
<motion.button whileHover={{ scale: 1.1 }} />
<motion.button whileHover={{ scale: 1.1 }} />
- whileTap
- 类型: Target | VariantLabels
- 描述: 定义元素被点击时的动画状态。
- 示例:
<motion.button whileTap={{ scale: 0.9 }} />
<motion.button whileTap={{ scale: 0.9 }} />
- whileFocus
- 类型: Target | VariantLabels
- 描述: 定义元素获得焦点时的动画状态。
- 示例:
<motion.input whileFocus={{ borderColor: "#4299e1" }} />
<motion.input whileFocus={{ borderColor: "#4299e1" }} />
- whileDrag
- 类型: Target | VariantLabels
- 描述: 定义元素被拖动时的动画状态。
- 示例:
<motion.div
drag
whileDrag={{ scale: 1.1, boxShadow: "0px 5px 10px rgba(0,0,0,0.2)" }}
/>
<motion.div
drag
whileDrag={{ scale: 1.1, boxShadow: "0px 5px 10px rgba(0,0,0,0.2)" }}
/>
- whileInView
- 类型: Target | VariantLabels
- 描述: 定义元素进入视口时的动画状态。
- 示例:
<motion.div whileInView={{ opacity: 1 }} initial={{ opacity: 0 }} />
<motion.div whileInView={{ opacity: 1 }} initial={{ opacity: 0 }} />
这些属性允许您创建复杂的动画和交互效果。它们可以与变体(variants)结合使用,以创建可重用和可组合的动画。
例如,您可以创建一个按钮组件,它在不同状态下有不同的动画:
const buttonVariants = {
initial: { scale: 1 },
hover: { scale: 1.1 },
tap: { scale: 0.9 },
focus: { borderColor: "#4299e1" },
};
function AnimatedButton({ children }) {
return (
<motion.button
variants={buttonVariants}
initial="initial"
whileHover="hover"
whileTap="tap"
whileFocus="focus"
>
{children}
</motion.button>
);
}
const buttonVariants = {
initial: { scale: 1 },
hover: { scale: 1.1 },
tap: { scale: 0.9 },
focus: { borderColor: "#4299e1" },
};
function AnimatedButton({ children }) {
return (
<motion.button
variants={buttonVariants}
initial="initial"
whileHover="hover"
whileTap="tap"
whileFocus="focus"
>
{children}
</motion.button>
);
}
这个例子展示了如何使用变体来定义不同的状态,并在不同的手势属性中重用这些状态。这种方法可以使您的动画代码更加简洁和可维护。
拖拽属性详解
Framer Motion 提供了一套强大的拖拽属性,允许您轻松地为元素添加拖拽功能。以下是这些属性的详细说明:
- drag
- 类型: boolean | "x" | "y"
- 描述: 启用元素的拖拽功能。可以限制为只在 x 轴或 y 轴拖拽。
- 示例:
<motion.div drag /> // 可以在任何方向拖拽
<motion.div drag="x" /> // 只能水平拖拽
<motion.div drag="y" /> // 只能垂直拖拽
<motion.div drag /> // 可以在任何方向拖拽
<motion.div drag="x" /> // 只能水平拖拽
<motion.div drag="y" /> // 只能垂直拖拽
- dragConstraints
- 类型: false | Partial
<BoundingBox>
| RefObject<Element>
- 描述: 定义拖拽的约束范围。可以是一个对象指定具体的像素值,也可以是对另一个元素的引用。
- 示例:
<motion.div drag="x" dragConstraints={{ left: 0, right: 300 }} />;
const constraintsRef = useRef(null);
return (
<div ref={constraintsRef}>
<motion.div drag dragConstraints={constraintsRef} />
</div>
);
<motion.div drag="x" dragConstraints={{ left: 0, right: 300 }} />;
const constraintsRef = useRef(null);
return (
<div ref={constraintsRef}>
<motion.div drag dragConstraints={constraintsRef} />
</div>
);
- dragElastic
- 类型: number | false
- 描述: 定义拖拽的弹性。0 表示没有弹性,1 表示完全弹性。false 禁用弹性。
- 示例:
<motion.div drag dragElastic={0.5} />
<motion.div drag dragElastic={false} />
<motion.div drag dragElastic={0.5} />
<motion.div drag dragElastic={false} />
- dragMomentum
- 类型: boolean
- 描述: 控制释放拖拽后是否有动量效果。
- 示例:
<motion.div drag dragMomentum={false} />
<motion.div drag dragMomentum={false} />
- dragTransition
- 类型: InertiaOptions
- 描述: 自定义拖拽释放后的动量动画。
- 示例:
<motion.div drag dragTransition={{ bounceStiffness: 600, bounceDamping: 10 }} />
<motion.div drag dragTransition={{ bounceStiffness: 600, bounceDamping: 10 }} />
- dragPropagation
- 类型: boolean
- 描述: 允许拖拽事件传播到父元素。
- 示例:
<motion.div drag dragPropagation />
<motion.div drag dragPropagation />
- dragControls
- 类型: DragControls
- 描述: 允许以编程方式控制拖拽。
- 示例:
const dragControls = useDragControls();
return (
<>
<div onPointerDown={(e) => dragControls.start(e)}>Drag from here</div>
<motion.div drag="x" dragControls={dragControls} />
</>
);
const dragControls = useDragControls();
return (
<>
<div onPointerDown={(e) => dragControls.start(e)}>Drag from here</div>
<motion.div drag="x" dragControls={dragControls} />
</>
);
- dragListener
- 类型: boolean
- 描述: 当设置为 false 时,元素不会监听指针事件来启动拖拽。
- 示例:
<motion.div drag dragListener={false} />
<motion.div drag dragListener={false} />
- dragDirectionLock
- 类型: boolean
- 描述: 如果为 true,拖拽将在开始时锁定到主要方向(x或y)。
- 示例:
<motion.div drag dragDirectionLock />
<motion.div drag dragDirectionLock />
- dragSnapToOrigin
- 类型: boolean
- 描述: 如果为 true,元素在释放后会回到其原始位置。
- 示例:
<motion.div drag dragSnapToOrigin />
<motion.div drag dragSnapToOrigin />
这些拖拽属性可以组合使用,创建出复杂的交互效果。例如,您可以创建一个可以在特定区域内拖拽,并在释放后具有动量效果的元素:
function DraggableBox() {
const constraintsRef = useRef(null);
return (
<div
ref={constraintsRef}
style={{ width: 300, height: 300, border: "1px solid black" }}
>
<motion.div
drag
dragConstraints={constraintsRef}
dragElastic={0.5}
dragTransition={{ bounceStiffness: 600, bounceDamping: 10 }}
style={{ width: 50, height: 50, background: "blue" }}
/>
</div>
);
}
function DraggableBox() {
const constraintsRef = useRef(null);
return (
<div
ref={constraintsRef}
style={{ width: 300, height: 300, border: "1px solid black" }}
>
<motion.div
drag
dragConstraints={constraintsRef}
dragElastic={0.5}
dragTransition={{ bounceStiffness: 600, bounceDamping: 10 }}
style={{ width: 50, height: 50, background: "blue" }}
/>
</div>
);
}
这个例子创建了一个蓝色的方块,它可以在父 div 内自由拖动,具有弹性效果,并在释放后有动量动画。通过调整这些属性,您可以创建出各种不同的拖拽行为和效果。
布局动画属性详解
Framer Motion 的布局动画允许您在元素的大小或位置发生变化时创建平滑的过渡效果。以下是与布局动画相关的属性的详细说明:
- layout
- 类型: boolean | "position" | "size"
- 描述: 启用布局动画。当设置为 true 时,元素的位置和大小变化都会被动画化。
- 示例:
<motion.div layout /> // 位置和大小变化都会有动画
<motion.div layout="position" /> // 只有位置变化有动画
<motion.div layout="size" /> // 只有大小变化有动画
<motion.div layout /> // 位置和大小变化都会有动画
<motion.div layout="position" /> // 只有位置变化有动画
<motion.div layout="size" /> // 只有大小变化有动画
- layoutId
- 类型: string
- 描述: 为元素指定一个唯一的布局 ID。具有相同 layoutId 的元素会在它们之间创建共享布局动画。
- 示例:
function App() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
{isOpen ? (
<motion.div layoutId="box" style={{ width: 200, height: 200 }} />
) : (
<motion.div layoutId="box" style={{ width: 50, height: 50 }} />
)}
<button onClick={() => setIsOpen(!isOpen)}>Toggle</button>
</div>
);
}
function App() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
{isOpen ? (
<motion.div layoutId="box" style={{ width: 200, height: 200 }} />
) : (
<motion.div layoutId="box" style={{ width: 50, height: 50 }} />
)}
<button onClick={() => setIsOpen(!isOpen)}>Toggle</button>
</div>
);
}
- layoutDependency
- 类型: any
- 描述: 当这个值改变时,会触发布局动画。用于在某些值变化时强制进行布局动画。
- 示例:
const [count, setCount] = useState(0);
return (
<motion.div layout layoutDependency={count}>
{count}
</motion.div>
);
const [count, setCount] = useState(0);
return (
<motion.div layout layoutDependency={count}>
{count}
</motion.div>
);
- layoutScroll
- 类型: boolean
- 描述: 如果为 true,则元素会考虑滚动位置来计算其布局位置。
- 示例:
<motion.div layout layoutScroll />
<motion.div layout layoutScroll />
- layoutRoot
- 类型: boolean
- 描述: 将组件标记为布局根。布局根内的所有布局动画都会相对于这个根进行计算。
- 示例:
<motion.div layoutRoot>
<motion.div layout /> {/* 这个元素的布局动画会相对于父元素计算 */}
</motion.div>
<motion.div layoutRoot>
<motion.div layout /> {/* 这个元素的布局动画会相对于父元素计算 */}
</motion.div>
- layoutTransition
- 类型: Transition
- 描述: 为布局动画指定自定义的过渡效果。
- 示例:
<motion.div
layout
layoutTransition={{
duration: 0.3,
ease: "easeInOut",
}}
/>
<motion.div
layout
layoutTransition={{
duration: 0.3,
ease: "easeInOut",
}}
/>
布局动画是 Framer Motion 的一个强大特性,它可以帮助您创建流畅的布局变化效果。通过使用这些属性,您可以轻松地创建出各种复杂的布局动画,从而提升用户体验。