用 Framer Motion 打造令人惊艳的 Web 动画
动画是现代 Web 体验的重要组成部分。Framer Motion 让 React 开发者能够轻松创建复杂而流畅的动画效果。
基础动画
最简单的动画只需要 motion 组件和 animate 属性:
import { motion } from 'framer-motion';
function FadeIn() {
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
>
Hello, Animation!
</motion.div>
);
}
手势交互
Framer Motion 内置了丰富的手势支持:
function InteractiveCard() {
return (
<motion.div
whileHover={{ scale: 1.05, rotateY: 5 }}
whileTap={{ scale: 0.95 }}
drag
dragConstraints={{ left: 0, right: 0, top: 0, bottom: 0 }}
className="card"
>
拖拽我试试!
</motion.div>
);
}
滚动驱动动画
使用 useScroll 和 useTransform 创建视差效果:
import { motion, useScroll, useTransform } from 'framer-motion';
function ParallaxSection() {
const { scrollYProgress } = useScroll();
const y = useTransform(scrollYProgress, [0, 1], [0, -200]);
const opacity = useTransform(scrollYProgress, [0, 0.5, 1], [1, 0.8, 0]);
return (
<motion.div style={{ y, opacity }}>
<h1>视差滚动效果</h1>
</motion.div>
);
}
布局动画
layoutId 实现跨组件的平滑过渡:
function TabContent({ activeTab }) {
return (
<div className="tabs">
{tabs.map(tab => (
<button key={tab.id}>
{tab.label}
{activeTab === tab.id && (
<motion.div
layoutId="activeTab"
className="indicator"
/>
)}
</button>
))}
</div>
);
}
3D 倾斜卡片效果
结合 useMotionValue 和 useTransform 实现 3D 效果:
function TiltCard() {
const x = useMotionValue(0);
const y = useMotionValue(0);
const rotateX = useTransform(y, [-100, 100], [10, -10]);
const rotateY = useTransform(x, [-100, 100], [-10, 10]);
return (
<motion.div
style={{ rotateX, rotateY, transformStyle: 'preserve-3d' }}
onMouseMove={(e) => {
const rect = e.currentTarget.getBoundingClientRect();
x.set(e.clientX - rect.left - rect.width / 2);
y.set(e.clientY - rect.top - rect.height / 2);
}}
onMouseLeave={() => { x.set(0); y.set(0); }}
>
3D 倾斜卡片
</motion.div>
);
}
性能优化建议
- 使用
transform属性 - GPU 加速,避免触发重排 - 合理使用
will-change- 提示浏览器优化 - 避免同时动画过多元素 - 使用
staggerChildren错开 - 使用
useReducedMotion- 尊重用户的无障碍设置
import { useReducedMotion } from 'framer-motion';
function AccessibleAnimation() {
const shouldReduceMotion = useReducedMotion();
return (
<motion.div
animate={{ x: shouldReduceMotion ? 0 : 100 }}
/>
);
}
总结
Framer Motion 是 React 生态中最强大的动画库之一。通过合理运用这些技巧,你可以为用户创造出既美观又流畅的交互体验。
记住:好的动画应该是有目的的、自然的、不干扰用户的。