关于 framer-motion-gestures
framer-motion-gestures 是用于 Framer Motion 手势交互与动画的技能,介绍拖动、平移、点击、悬停和键盘聚焦行为,以及约束和动作反馈。
主要功能
- 01按轴拖动与移动约束
- 02拖动惯性与弹簧设置
- 03平移指针追踪
- 04点击、悬停和聚焦状态
- 05手势回调与视觉反馈
适用场景
- 01创建受边界约束的可拖动界面元素
- 02为拖动交互添加惯性
- 03为按钮添加按下或悬停动画
- 04为键盘聚焦提供视觉反馈
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ c-jeril/ framer-motion-skills --skill framer-motion-gestures安装后在 Claude Code 中输入/framer-motion-gestures确认已加载。
详细介绍
Framer Motion 手势
何时使用此技能
在实现由手势驱动的动画时使用:拖动、平移、点击、悬停、聚焦或触摸交互。当用户询问 Framer Motion 中的拖放、交互元素或基于手势的 UI 时,也请使用。
相关技能: 核心动画请使用 framer-motion-core;变体请使用 framer-motion-variants;布局动画请使用 framer-motion-layout。
拖动
使用 drag 属性启用拖动:
<motion.div
drag="x"
dragConstraints={{ left: -100, right: 100 }}
whileDrag={{ scale: 1.1, cursor: "grabbing" }}
/>
拖动属性
| 属性 | 类型 | 描述 |
|---|---|---|
| drag | bool | "x" | "y" | 启用沿指定轴拖动 |
| dragConstraints | object | RefObject | 移动约束 |
| dragMomentum | boolean | 松开后继续保持惯性(默认值:true) |
| dragElastic | number | object | 边界弹性(默认值:0) |
| dragTransition | Transition | 惯性的弹簧配置 |
| whileDrag | MotionProps | 拖动时的动画 |
| onDrag | function | 拖动期间的回调 |
| onDragStart | function | 拖动开始时的回调 |
| onDragEnd | function | 拖动结束时的回调 |
拖动约束
<motion.div
drag
dragConstraints={{
left: -100,
right: 100,
top: -50,
bottom: 50
}}
/>
基于 Ref 的约束
function Draggable() {
const constraintsRef = useRef(null);
return (
<>
<motion.div
ref={constraintsRef}
style={{
width: 500,
height: 500,
backgroundColor: "#eee"
}}
/>
<motion.div
drag
dragConstraints={constraintsRef}
/>
</>
);
}
平移
平移类似于拖动,但适用于指针/触摸:
<motion.div
drag="x"
onDrag={(e, info) => {
console.log("Position:", info.point);
console.log("Velocity:", info.velocity);
}}
/>
平移与拖动的区别
- 拖动:鼠标/触摸交互,具有视觉反馈、惯性和约束
- 平移:更底层的指针跟踪,不带惯性
点击(whileTap)
按下时播放动画:
<motion.button
whileTap={{ scale: 0.95, opacity: 0.8 }}
whileHover={{ scale: 1.05 }}
>
Click me
</motion.button>
悬停(whileHover)
悬停时播放动画:
<motion.div
whileHover={{ scale: 1.1, backgroundColor: "#ff0000" }}
style={{ width: 100, height: 100, backgroundColor: "#00ff00" }}
/>
onHoverStart / onHoverEnd
<motion.div
onHoverStart={() => console.log("Hover started")}
onHoverEnd={() => console.log("Hover ended")}
/>
聚焦(whileFocus)
获得焦点时播放动画(键盘):
<motion.input
whileFocus={{ scale: 1.05, borderColor: "#00ff00" }}
style={{ borderWidth: 2 }}
/>
使用弹簧物理效果拖动
<motion.div
drag="x"
dragConstraints={{ left: -200, right: 200 }}
dragTransition={{
type: "spring",
stiffness: 300,
damping: 20,
mass: 1
}}
/>
使用约束的拖动控制
function DraggableBox() {
const constraintsRef = useRef(null);
return (
<>
<motion.div
ref={constraintsRef}
style={{
width: 500,
height: 500,
backgroundColor: "#f0f0f0"
}}
/>
{[1, 2, 3].map(i => (
<motion.div
key={i}
drag
dragConstraints={constraintsRef}
dragMomentum={false}
whileDrag={{ scale: 1.1 }}
/>
))}
</>
);
}
滑动检测
function Swipeable() {
const x = useMotionValue(0);
const { scrollYProgress } = useScroll();
const opacity = useTransform(x, [-100, 0, 100], [0, 1, 0]);
return (
<motion.div
style={{ x, opacity }}
drag="x"
dragConstraints={{ left: 0, right: 0 }}
dragElastic={1}
/>
);
}
手势状态信息
回调会接收 PointInfo 和 DragInfo:
onDrag={(e, info) => {
info.point // { x, y } position
info.velocity // { x, y } velocity
info.offset // { x, y } offset from start
}}
最佳实践
- ✅ 使用 dragConstraints 将元素限制在边界内。
- ✅ 使用 dragElastic 实现回弹效果。
- ✅ 使用 whileDrag 在拖动期间提供视觉反馈。
- ✅ 使用 dragMomentum 实现自然的惯性延续。
- ✅ 将 dragTransition 与弹簧结合,用于基于物理效果的拖动。
- ✅ 在容器内拖动时,使用 refs 设置约束。
请勿
- ❌ 如果元素应保持在边界内,请勿在没有
dragConstraints的情况下使用drag。 - ❌ 请记住,只有当指针移动超过一定阈值后,拖动事件才会触发。
- ❌ 不要使用过大的
dragElastic,否则可能导致视觉异常。 - ❌ 拖动期间不要对相互冲突的属性进行动画处理(例如 scale 和 x)。
了解更多
https://www.framer.com/motion/gestures/ https://www.framer.com/motion/drag/
评论
支持 Markdown