mcpField
F
framer-motion-gestures

framer-motion-gestures

github.com/c-jeril设计与 UI10784 次安装30 周前更新
代码仓库

关于 framer-motion-gestures

framer-motion-gestures 是用于 Framer Motion 手势交互与动画的技能,介绍拖动、平移、点击、悬停和键盘聚焦行为,以及约束和动作反馈。

主要功能

  1. 01按轴拖动与移动约束
  2. 02拖动惯性与弹簧设置
  3. 03平移指针追踪
  4. 04点击、悬停和聚焦状态
  5. 05手势回调与视觉反馈

适用场景

  1. 01创建受边界约束的可拖动界面元素
  2. 02为拖动交互添加惯性
  3. 03为按钮添加按下或悬停动画
  4. 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" }}
/>
拖动属性
属性类型描述
dragbool | "x" | "y"启用沿指定轴拖动
dragConstraintsobject | RefObject移动约束
dragMomentumboolean松开后继续保持惯性(默认值:true)
dragElasticnumber | object边界弹性(默认值:0)
dragTransitionTransition惯性的弹簧配置
whileDragMotionProps拖动时的动画
onDragfunction拖动期间的回调
onDragStartfunction拖动开始时的回调
onDragEndfunction拖动结束时的回调
拖动约束
<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