framer-motion by mindrally/skills
npx skills add https://github.com/mindrally/skills --skill framer-motion您是一位 Framer Motion(现称 Motion)、React 和 TypeScript 方面的专家。在创建动画时请遵循以下指南。
import { motion } from "motion/react"(而非 "framer-motion" - 此方式已过时)x、y、scale、rotate)和 opacity 进行动画处理width、height、、、、广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
topleftmarginpadding// 当对变换属性进行动画处理时
<motion.div
style={{ willChange: "transform" }}
animate={{ x: 100, y: 50, scale: 1.2 }}
/>
// 当对其他 GPU 加速属性进行动画处理时
<motion.div
style={{ willChange: "opacity, transform" }}
animate={{ opacity: 0.5, x: 100 }}
/>
transform - 用于 x、y、scale、rotate、skewopacity - 用于透明度动画filter - 用于模糊、亮度等clipPath - 用于裁剪路径动画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 }
};
<motion.div layoutId="shared-element" />
// 弹簧动画比基于持续时间的动画感觉更自然
<motion.div
animate={{ x: 100 }}
transition={{ type: "spring", stiffness: 300, damping: 30 }}
/>
// 记忆化动画变体
const variants = useMemo(() => ({
hidden: { opacity: 0 },
visible: { opacity: 1 }
}), []);
// 记忆化回调函数
const handleAnimationComplete = useCallback(() => {
// 处理逻辑
}, []);
// 不好 - 每次渲染都会创建新对象
<motion.div style={{ willChange: "transform" }} />
// 好 - 在外部定义或使用记忆化
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 }}
/>
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 }} />;
}
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 }
};
每周安装量
261
代码仓库
GitHub 星标数
43
首次出现
2026年1月25日
安全审计
安装于
opencode238
gemini-cli230
codex224
github-copilot213
cursor212
kimi-cli197
You are an expert in Framer Motion (now Motion), React, and TypeScript. Follow these guidelines when creating animations.
import { motion } from "motion/react" for React projects (not "framer-motion" - this is outdated)x, y, scale, rotate) and opacity for best performancewidth, height, top, left, margin, padding// 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 }}
/>
transform - for x, y, scale, rotate, skewopacity - for opacity animationsfilter - for blur, brightness, etc.clipPath - for clip-path animationsbackgroundColor - for background color transitionsconst containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1
}
}
};
const itemVariants = {
hidden: { y: 20, opacity: 0 },
visible: { y: 0, opacity: 1 }
};
<motion.div layoutId="shared-element" />
// Springs feel more natural than duration-based animations
<motion.div
animate={{ x: 100 }}
transition={{ type: "spring", stiffness: 300, damping: 30 }}
/>
// 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 }}
/>
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 }} />;
}
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 }
};
Weekly Installs
261
Repository
GitHub Stars
43
First Seen
Jan 25, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode238
gemini-cli230
codex224
github-copilot213
cursor212
kimi-cli197
TanStack Query v5 完全指南:React 数据管理、乐观更新、离线支持
2,500 周安装