关于 framer-motion
为 React 和 TypeScript 中使用 Motion 动画提供实现指导,涵盖性能、无障碍、滚动联动效果与过渡模式。
主要功能
- 01Motion API 使用指导
- 02变换与透明度性能建议
- 03减少动态效果的无障碍支持
- 04滚动联动动画
- 05退出与页面过渡
适用场景
- 01为 React 界面添加动画
- 02构建滚动驱动效果
- 03遵循减少动态效果设置
- 04实现退出和页面过渡
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mindrally/ skills --skill framer-motion安装后在 Claude Code 中输入/framer-motion确认已加载。
详细介绍
Framer Motion / Motion 动画指南
你是 Framer Motion(现称 Motion)、React 和 TypeScript 专家。创建动画时请遵循以下指南。
核心原则
从正确的程序包导入
- React 项目中使用
import { motion } from "motion/react"(不要使用 "framer-motion"——它已过时) - 该库已从 Framer Motion 更名为 Motion
- 始终使用最新的 Motion API
性能优先
- 为获得最佳性能,请为变换属性(
x、y、scale、rotate)和opacity添加动画 - 这些属性可以通过硬件加速,且不会触发布局重新计算
- 避免为会导致布局偏移的属性添加动画,例如
width、height、top、left、margin、padding
硬件加速
正确使用 will-change
// When animating transforms
<motion.div
style={{ willChange: "transform" }}
animate={{ x: 100, y: 50, scale: 1.2 }}
/>
// When animating other GPU-accelerated properties
<motion.div
style={{ willChange: "opacity, transform" }}
animate={{ opacity: 0.5, x: 100 }}
/>
添加到 willChange 的属性
transform——用于 x、y、scale、rotate、skewopacity——用于 opacity 动画filter——用于模糊、亮度等效果clipPath——用于 clip-path 动画backgroundColor——用于背景颜色过渡
动画最佳实践
复杂动画使用变体
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1
}
}
};
const itemVariants = {
hidden: { y: 20, opacity: 0 },
visible: { y: 0, opacity: 1 }
};
共享元素过渡使用 layoutId
<motion.div layoutId="shared-element" />
优先使用 spring 动画
// Springs feel more natural than duration-based animations
<motion.div
animate={{ x: 100 }}
transition={{ type: "spring", stiffness: 300, damping: 30 }}
/>
React 集成
通过记忆化提升性能
// Memoize animation variants
const variants = useMemo(() => ({
hidden: { opacity: 0 },
visible: { opacity: 1 }
}), []);
// Memoize callbacks
const handleAnimationComplete = useCallback(() => {
// handler logic
}, []);
避免内联样式对象
// Bad - creates new object on every render
<motion.div style={{ willChange: "transform" }} />
// Good - define outside or memoize
const style = { willChange: "transform" };
<motion.div style={style} />
无障碍
遵循减少动态效果偏好设置
import { useReducedMotion } from "motion/react";
function Component() {
const shouldReduceMotion = useReducedMotion();
return (
<motion.div
animate={{ x: shouldReduceMotion ? 0 : 100 }}
transition={{ duration: shouldReduceMotion ? 0 : 0.3 }}
/>
);
}
手势动画
正确使用手势属性
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
transition={{ type: "spring", stiffness: 400, damping: 17 }}
/>
滚动动画
使用 useScroll 创建滚动关联动画
import { useScroll, useTransform, motion } from "motion/react";
function ParallaxComponent() {
const { scrollYProgress } = useScroll();
const y = useTransform(scrollYProgress, [0, 1], [0, -100]);
return <motion.div style={{ y }} />;
}
退出动画
使用 AnimatePresence 创建退出动画
import { AnimatePresence, motion } from "motion/react";
<AnimatePresence mode="wait">
{isVisible && (
<motion.div
key="modal"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
/>
)}
</AnimatePresence>
常见模式
错开列表动画
<motion.ul
initial="hidden"
animate="visible"
variants={{
visible: { transition: { staggerChildren: 0.07 } }
}}
>
{items.map((item) => (
<motion.li
key={item.id}
variants={{
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0 }
}}
/>
))}
</motion.ul>
页面过渡
const pageTransition = {
initial: { opacity: 0, x: -20 },
animate: { opacity: 1, x: 0 },
exit: { opacity: 0, x: 20 },
transition: { duration: 0.3 }
};
性能调试
- 使用 React DevTools 检查重新渲染
- 使用 Chrome DevTools 的 Performance 标签页找出动画卡顿
- 最低目标为 60fps;在高刷新率显示器上目标为 120fps
- 在实际设备上测试,尤其是中端 Android 手机
评论
支持 Markdown