mcpField
M
motion

motion

github.com/lucking7设计与 UI90 次安装
代码仓库

关于 motion

Motion 是面向 JavaScript、React 和 Vue 界面开发的动画库,提供手势、滚动和布局动画 API,并可通过 LazyMotion 优化包体积。

主要功能

  1. 01支持 JavaScript、React 和 Vue 动画
  2. 02滚动与视口动画
  3. 03拖动和手势交互
  4. 04使用变体编排动画
  5. 05通过 LazyMotion 优化包体积

适用场景

  1. 01为 Web 应用界面添加动画
  2. 02编排子元素的错开动画
  3. 03制作滚动或视口触发效果
  4. 04在 React 中缩减动画包体积

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/lucking7/motiondev-skills --skill motion

安装后在 Claude Code 中输入/motion确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

reference/
examples.json
examples.md
javascript.md
react.md
vue.md
scripts/
get-example.sh
search-examples.sh

详细介绍

Motion 动画库

Motion(包名:motion,曾用名 framer-motion)是 JavaScript、React 和 Vue 的行业标准动画库。

安装

npm install motion      # React/JS
npm install motion-v    # Vue

平台快速参考

JavaScript
import { animate, scroll, inView, stagger, hover, press } from "motion"

// Basic animation
animate("#box", { x: 100, opacity: 1 })

// With spring physics
animate(element, { scale: 1.2 }, { type: "spring", stiffness: 300, damping: 30 })

// Staggered list
animate("li", { opacity: 1 }, { delay: stagger(0.1) })

// Scroll-linked
scroll(animate("#progress", { scaleX: [0, 1] }))

// Viewport detection
inView(".card", ({ target }) => {
  animate(target, { opacity: 1, y: 0 })
})

// Gestures
hover(".btn", el => {
  animate(el, { scale: 1.1 })
  return () => animate(el, { scale: 1 })
})

press(".btn", el => {
  animate(el, { scale: 0.95 })
  return () => animate(el, { scale: 1 })
})
React
import { motion, AnimatePresence, useScroll, useTransform } from "motion/react"

// Basic motion component
<motion.div
  initial={{ opacity: 0, y: 20 }}
  animate={{ opacity: 1, y: 0 }}
  exit={{ opacity: 0 }}
  transition={{ type: "spring" }}
/>

// Gestures
<motion.button
  whileHover={{ scale: 1.1 }}
  whileTap={{ scale: 0.95 }}
  drag="x"
  dragConstraints={{ left: 0, right: 100 }}
/>

// Layout animations
<motion.div layout layoutId="shared-element" />

// Scroll animations
const { scrollYProgress } = useScroll()
const y = useTransform(scrollYProgress, [0, 1], [0, -300])
<motion.div style={{ y }} />
Vue
<script setup>
import { motion, AnimatePresence } from "motion-v"
</script>

<template>
  <motion.div
    :initial="{ opacity: 0 }"
    :animate="{ opacity: 1 }"
    :exit="{ opacity: 0 }"
    :whileHover="{ scale: 1.1 }"
  />
</template>

核心 API

API平台描述
animate()全部使用弹簧或补间动画来为元素添加动画
scroll()JS与滚动关联的动画
inView()JS视口检测
hover()JS悬停手势
press()JS按压/轻触手势
stagger()全部错开延迟
React 专用
API描述
motion.div增强了 Motion 功能的元素
AnimatePresence退出动画
LayoutGroup协调布局动画
LazyMotion优化包体积(约 4.6kb)
useMotionValue()响应式动画值
useTransform()派生运动值
useSpring()弹簧动画值
useScroll()滚动进度
useAnimate()命令式控制

转场选项

弹簧(基于物理效果)
{
  type: "spring",
  stiffness: 300,    // Higher = snappier
  damping: 30,       // Higher = less bounce
  mass: 1,           // Higher = more momentum
  bounce: 0.25,      // 0-1, alternative to stiffness/damping
  visualDuration: 0.5
}
补间(基于持续时间)
{
  duration: 0.5,
  ease: "easeInOut", // or cubic bezier [0.4, 0, 0.2, 1]
  delay: 0.2,
  repeat: Infinity,
  repeatType: "reverse" // "loop" | "mirror"
}
缓动函数

"linear"、"easeIn"、"easeOut"、"easeInOut"、"circIn"、"circOut"、"backIn"、"backOut"、"anticipate"

常见模式

AnimatePresence(退出动画)
// CRITICAL: AnimatePresence must stay mounted, children need unique keys
<AnimatePresence>
  {isVisible && (
    <motion.div
      key="modal"
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
    />
  )}
</AnimatePresence>
布局动画
<motion.div layout>
  {isExpanded ? <FullContent /> : <Summary />}
</motion.div>

// Shared element transitions
<motion.div layoutId="card-123" />
滚动动画
// Viewport-triggered
<motion.div
  initial={{ opacity: 0, y: 50 }}
  whileInView={{ opacity: 1, y: 0 }}
  viewport={{ once: true, margin: "-100px" }}
/>

// Scroll-linked
const { scrollYProgress } = useScroll()
const y = useTransform(scrollYProgress, [0, 1], [0, -300])
<motion.div style={{ y }} />
拖动手势
<motion.div
  drag="x"
  dragConstraints={{ left: 0, right: 300 }}
  dragElastic={0.2}
  dragMomentum={true}
  dragSnapToOrigin
/>
SVG 线条绘制
<motion.path
  initial={{ pathLength: 0 }}
  animate={{ pathLength: 1 }}
  transition={{ duration: 2, ease: "easeInOut" }}
/>
变体(编排)
const container = {
  hidden: { opacity: 0 },
  show: {
    opacity: 1,
    transition: { staggerChildren: 0.1 }
  }
}

const item = {
  hidden: { opacity: 0, y: 20 },
  show: { opacity: 1, y: 0 }
}

<motion.ul variants={container} initial="hidden" animate="show">
  <motion.li variants={item} />
  <motion.li variants={item} />
</motion.ul>

性能

优化包体积
// Full bundle: ~34 KB
import { motion } from "motion/react"

// Optimized: ~4.6 KB
import { LazyMotion, domAnimation, m } from "motion/react"

<LazyMotion features={domAnimation}>
  <m.div animate={{ x: 100 }} />
</LazyMotion>

// Minimal: 2.3 KB
import { useAnimate } from "motion/react"
避免与 Tailwind 冲突
// WRONG - causes stuttering
<motion.div className="transition-all" animate={{ x: 100 }} />

// CORRECT
<motion.div animate={{ x: 100 }} />

Next.js 集成

App Router(RSC)
// components/motion-client.tsx
"use client"
import * as motion from "motion/react-client"
export { motion }

// app/page.tsx
import { motion } from "@/components/motion-client"
直接使用客户端组件
"use client"
import { motion } from "motion/react"

无障碍

import { MotionConfig } from "motion/react"

<MotionConfig reducedMotion="user">
  <App />
</MotionConfig>

故障排除

AnimatePresence 退出动画不起作用

问题:退出动画未播放
原因:

  1. AnimatePresence 与子元素一起卸载
  2. 缺少唯一的 key 属性
  3. 子元素不是直接后代

解决方案:

// WRONG
{isVisible && <AnimatePresence><motion.div /></AnimatePresence>}

// CORRECT
<AnimatePresence>
  {isVisible && <motion.div key="unique" exit={{ opacity: 0 }} />}
</AnimatePresence>
可滚动容器的布局问题
<motion.div layoutScroll style={{ overflow: "auto" }}>
  <motion.div layout />
</motion.div>
固定定位的布局问题
<motion.div layoutRoot style={{ position: "fixed" }}>
  <motion.div layout />
</motion.div>
布局缩放失真
// Set borderRadius/boxShadow via style for scale correction
<motion.div layout style={{ borderRadius: 20, boxShadow: "..." }} />
大型列表的性能

使用虚拟化库:react-window、react-virtuoso、@tanstack/react-virtual

参考文档

平台专属文档详见 reference/ 文件夹:

  • reference/react.md - React 组件和钩子
  • reference/javascript.md - 原生 JS API
  • reference/vue.md - Vue 指令和组件
  • reference/examples.md - 按类别划分的示例索引

资源

评论

支持 Markdown