3. Framer Motion 中 motion 组件
motion
组件:为 HTML 和 SVG 元素赋予动画能力
motion
对象是 Framer Motion 的核心,它是一个标签工厂函数。你可以使用它来创建能够进行动画和手势交互的 HTML 和 SVG 元素。其基本语法是 motion.<HTMLTag />
或 motion.<SVGTag />
。
1. HTML 元素
你可以将任何标准的 HTML 标签替换为 motion
对应的版本,从而使其具备动画能力。以下是一些常用的 HTML 元素及其 motion
版本:
<div>
-><motion.div />
<span>
-><motion.span />
<button>
-><motion.button />
<img>
-><motion.img />
<a>
-><motion.a />
<ul>
-><motion.ul />
<li>
-><motion.li />
<input>
-><motion.input />
<textarea>
-><motion.textarea />
<label>
-><motion.label />
<form>
-><motion.form />
- 等等…
用法示例 (针对不同 HTML 元素):
import { motion } from "framer-motion";
import { useState } from "react";function MotionHTMLElements() {const [isOpen, setIsOpen] = useState(false);return (<div style={{ display: "flex", flexDirection: "column", gap: 20 }}><motion.divinitial={{ opacity: 0, y: -20 }}animate={{ opacity: 1, y: 0 }}transition={{ duration: 0.5 }}style={{width: 200,height: 100,backgroundColor: "lightblue",display: "flex",justifyContent: "center",alignItems: "center",}}>Motion Div</motion.div><motion.spaninitial={{ scale: 0.8 }}animate={{ scale: 1.2 }}transition={{ type: "spring", stiffness: 300 }}style={{ fontSize: "1.5em", fontWeight: "bold" }}>Motion Span</motion.span><motion.buttonwhileHover={{ scale: 1.1 }}whileTap={{ scale: 0.9 }}style={{ padding: 10, backgroundColor: "lightcoral", color: "white", border: "none", borderRadius: 5, cursor: "pointer" }}onClick={() => setIsOpen(!isOpen)}>Motion Button</motion.button>{isOpen && (<motion.ulinitial={{ height: 0, opacity: 0 }}animate={{ height: "auto", opacity: 1 }}exit={{ height: 0, opacity: 0 }}transition={{ duration: 0.3 }}style={{ border: "1px solid #ccc", padding: 10 }}><motion.li>Item 1</motion.li><motion.li>Item 2</motion.li><motion.li>Item 3</motion.li></motion.ul>)}</div>);
}export default MotionHTMLElements;
正如你所见,你可以像使用普通的 HTML 标签一样使用 motion
版本,并为其添加 Framer Motion 特有的动画属性 (initial
, animate
, transition
, whileHover
, whileTap
, exit
等)。
2. SVG 元素
Framer Motion 也支持对 SVG 元素进行动画。你可以使用 motion
对象创建可动画的 SVG 元素:
<svg>
-><motion.svg />
<path>
-><motion.path />
<circle>
-><motion.circle />
<rect>
-><motion.rect />
<line>
-><motion.line />
<polygon>
-><motion.polygon />
<polyline>
-><motion.polyline />
<ellipse>
-><motion.ellipse />
<text>
-><motion.text />
<g>
-><motion.g />
- 等等…
SVG 动画示例 (路径绘制):
import { motion } from "framer-motion";
import { useState, useEffect, useRef } from "react";function MotionSVGElement() {const pathRef = useRef(null);const [pathLength, setPathLength] = useState(0);useEffect(() => {if (pathRef.current) {setPathLength(pathRef.current.getTotalLength());}}, []);return (<motion.svg width="200" height="200" viewBox="0 0 200 200"><motion.pathref={pathRef}d="M50,50 C70,10 130,10 150,50 C180,70 180,130 150,150 C130,190 70,190 50,150 C20,130 20,70 50,50"fill="none"stroke="blue"strokeWidth="3"initial={{ pathLength: 0, opacity: 0 }}animate={{ pathLength: 1, opacity: 1 }}transition={{ duration: 2, ease: "easeInOut" }}style={{ pathLength }} // 需要将 pathLength 应用到 style 上/><motion.circle cx="100" cy="100" r="10" fill="red" /></motion.svg>);
}export default MotionSVGElement;
在这个例子中,我们使用 <motion.path />
来绘制一个心形曲线。通过动画 pathLength
属性,我们可以实现路径的绘制动画效果。注意,对于一些 SVG 特有的属性(如 pathLength
, pathOffset
),你可能需要将其作为 style
属性传递,以便 Framer Motion 正确地处理。
核心动画属性回顾 (适用于所有 motion
组件):
initial
: 定义组件的初始状态。animate
: 定义组件要动画到的目标状态。可以是一个包含样式属性的对象,也可以是variants
中定义的状态名称。exit
: 定义组件卸载时的动画状态 (通常与<AnimatePresence />
组件一起使用)。transition
: 控制动画的过渡效果,包括duration
(持续时间),ease
(缓动函数),delay
(延迟),type
(动画类型:tween
,spring
,inertia
),repeat
(重复次数),repeatType
(loop
,reverse
,mirror
),repeatDelay
(重复延迟) 等。variants
: 一个对象,用于定义组件的不同动画状态 (例如"initial"
,"visible"
,"hidden"
,"hovered"
,"pressed"
等)。你可以在initial
,animate
,exit
和事件处理属性中引用这些变体名称。- 事件处理属性 (用于交互):
whileHover
: 定义鼠标悬停时的动画状态。whileTap
: 定义鼠标点击 (按下和释放) 时的动画状态。whileDrag
: 定义拖拽时的动画状态 (需要设置drag
属性为true
)。onHoverStart
,onHoverEnd
,onTap
,onTapCancel
,onDragStart
,onDrag
,onDragEnd
,onPan
,onPanStart
,onPanEnd
等事件回调函数。
drag
: 设置为true
使元素可以被拖拽。可以指定拖拽的方向 ("x"
,"y"
) 和边界 (dragConstraints
).layout
: 用于在布局更改时创建平滑的动画过渡 (Layout Animations)。
总结:
motion
组件是 Framer Motion 的基石,通过将标准的 HTML 和 SVG 元素包裹在 motion.<Tag />
中,你可以轻松地为其添加各种动画和交互效果。关键在于理解和使用这些丰富的动画属性,以及如何将它们与 variants
, useMotionValue
, useTransform
和 <AnimatePresence />
等其他 Framer Motion 功能结合起来,创建出复杂而流畅的用户界面动画。记住,几乎所有的视觉属性都可以通过 Framer Motion 进行动画控制,尽情发挥你的创造力吧!