返回项目目录
开发工具精选项目

Motion

面向 React 和 JavaScript 的生产级动画库,统一处理弹簧、手势、布局、滚动和退出动画。

主要语言TypeScript
开源许可MIT
项目类型开发工具
维护状态活跃维护
OVERVIEW

项目概述

Motion(原 Framer Motion)通过混合引擎结合 Web Animations API 与 JavaScript,在简单声明式动画和复杂交互之间提供一致 API,可用于 React 界面、HTML、SVG 与对象动画。

Motion 是采用 MIT 许可证的 Web 动画库,原名 Framer Motion。React 用户通过 motion/react 获得 motion 组件、AnimatePresence、Layout Animation、Gestures 和 Motion Values;普通 JavaScript 项目则可以从 motion 导入 animate、scroll、stagger 等函数。它的 Hybrid Engine 会在适合时使用浏览器 Web Animations API 与 ScrollTimeline,在需要弹簧物理、可中断关键帧或手势跟踪时使用 JavaScript,从而让简单微交互与复杂产品动画共享一套模型。

当前版本Motion 12.43.0
原名称Framer Motion
核心引擎WAAPI + JavaScript
FEATURES

主要特点

Motion 覆盖组件进入退出、布局变化、手势、滚动和物理动画等现代界面需求。

01

声明式 motion 组件

为 HTML 和 SVG 元素增加 initial、animate、exit、transition 与 gesture Props,让动画直接跟随 React 状态。

02

Hybrid Engine

适合的动画交给 Web Animations API 和 ScrollTimeline 执行,复杂弹簧、手势与可中断序列则由 JavaScript 引擎处理。

03

Spring 与 Keyframes

支持物理弹簧、Tween、关键帧、惯性、延迟、重复和 Stagger,可用统一 Transition API 调整节奏。

04

跨设备手势

whileHover、whileTap、whileFocus 和 Drag 统一处理鼠标、触摸与指针输入,避免直接依赖不适合触屏的 Hover 事件。

05

布局动画

只需添加 layout 即可在尺寸和位置变化时生成平滑过渡,layoutId 还能实现跨组件共享元素动画。

06

AnimatePresence

在 React 节点移除前运行 exit 动画,并支持同步、等待和 Pop Layout 等进入退出编排模式。

07

滚动动画

whileInView 处理进入视口触发,useScroll 与 scroll() 则把动画值连续映射到页面或容器滚动进度。

08

Motion Values

useMotionValue、useTransform、useSpring 和 useVelocity 在 React Render 之外组合高频动画值,减少组件重渲染。

09

SVG 与对象动画

可动画 SVG 属性、路径长度、ViewBox,也能通过 JavaScript animate() 更新数字、颜色和 Three.js 对象属性。

10

Variants 与序列编排

命名 Variants 可沿组件树传播状态,配合 delayChildren、stagger 和 sequence 组织复杂进入与状态切换。

11

按需加载

包支持 Tree Shaking,React 还可使用 LazyMotion 和 m 组件延后加载动画功能,控制初始 JavaScript 体积。

12

Reduced Motion 支持

MotionConfig 的 reducedMotion 和 useReducedMotion 可响应系统偏好,自动关闭或替换容易引起不适的位移和布局动画。

USE CASES

适用场景

当动画需要与 React 状态、布局或用户输入紧密联动,且 CSS Transition 已难以维护时,Motion 更有价值。

产品微交互

为按钮反馈、卡片展开、表单状态、成功提示和导航选择提供与状态一致的轻量动画。

路由和页面过渡

结合 AnimatePresence、Layout Animation 与框架路由,在页面切换时维持清晰的进入退出关系。

拖拽与手势界面

适合滑动卡片、可拖拽面板、排序列表、轮播和带惯性的直接操作界面。

数据与列表变化

layout、Reorder 和 AnimatePresence 可平滑表达排序、筛选、插入、删除和尺寸变化。

滚动叙事与进度

可实现阅读进度、视差、分段揭示、固定章节和与 ScrollTimeline 联动的品牌页面。

SVG 图标和插图

路径绘制、颜色、Morph 周边属性与独立 Transform 可用于加载状态、数据图形和品牌动效。

无框架 JavaScript 动画

animate、scroll、inView 和 stagger 能直接用于普通 HTML、Web Components 或其他框架管理的 DOM。

EVALUATION

优点与注意事项

技术选型不仅要看能力,也要理解它带来的团队成本。

主要优点

Motion 擅长的地方

  • React 状态、组件生命周期与动画 Props 能自然组合
  • 同一 API 覆盖 Tween、Spring、手势、布局、滚动和退出动画
  • Hybrid Engine 在浏览器原生性能与 JavaScript 灵活性之间自动取舍
  • Motion Values 可在 React Render 之外驱动高频更新
  • layout 与 layoutId 显著降低 FLIP 和共享元素动画实现成本
  • AnimatePresence 解决普通 CSS 难以处理的卸载退出动画
  • Reduced Motion、焦点手势和触摸识别为可访问动效提供基础
  • React 与原生 JavaScript API 可以按项目需要独立采用

需要注意

采用前应考虑的问题

简单效果不一定需要动画库

颜色、透明度或单一 Transform 的 Hover 常用 CSS Transition 更轻量。只有状态、编排或交互复杂度增加时才引入 Motion。

Reduced Motion 必须纳入设计

不能只把动画速度调快。大幅位移、缩放、视差和自动播放应关闭或改为 Opacity 等更温和反馈。

动画属性决定性能

Transform 和 Opacity 通常成本较低;频繁动画 Width、Height、Top 或复杂 Filter 可能触发布局、绘制和合成压力。

AnimatePresence 依赖正确的 Key

直接子元素需要稳定且能反映身份变化的 key。组件层级或条件渲染位置错误会让 Exit 动画无法触发。

布局动画有测量边界

滚动容器、固定定位、Transform 父级、SVG 和高度自动变化等场景可能需要 layoutScroll、layoutRoot 或调整结构。

SSR 组件需要明确客户端边界

在 React Server Components 环境中,使用状态、手势或浏览器 API 的 Motion 组件通常应位于 Client Component 内。

手势不能替代语义和键盘操作

可拖拽或滑动界面仍需按钮、键盘路径、可见焦点和文本说明,不能把关键功能只绑定到 Pointer Gesture。

复杂动画容易失去一致节奏

页面各自设置 Duration、Spring 和 Delay 会形成视觉噪音。团队应维护 Motion Token 和少量标准 Transition。

需要控制 Bundle 体积

大量页面只用少数能力时,应检查实际输出,使用 Tree Shaking、LazyMotion 或更小的 mini 入口。

过度动画会损害任务效率

动画应解释变化、建立空间关系或提供反馈,而不是延迟用户操作;高频业务界面尤其要限制时长和数量。

QUICK START

快速开始

下面从一个交互卡片开始,逐步加入退出动画、布局过渡、滚动进度和 Reduced Motion。

1安装 Motion
bash
npm install motion
2创建交互卡片
tsx
import { motion } from "motion/react";

export function ProjectCard() {
  return (
    <motion.article
      initial={{ opacity: 0, y: 16 }}
      animate={{ opacity: 1, y: 0 }}
      whileHover={{ y: -4 }}
      whileTap={{ scale: 0.98 }}
      transition={{ type: "spring", stiffness: 320, damping: 24 }}
      className="project-card"
    >
      <h2>Motion</h2>
      <p>Production-ready animations for React and JavaScript.</p>
    </motion.article>
  );
}
3为列表添加进入和退出动画
tsx
import { AnimatePresence, motion } from "motion/react";

export function ProjectList({ projects }: { projects: string[] }) {
  return (
    <motion.ul layout>
      <AnimatePresence mode="popLayout">
        {projects.map((project) => (
          <motion.li
            layout
            key={project}
            initial={{ opacity: 0, scale: 0.96 }}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 0.96 }}
          >
            {project}
          </motion.li>
        ))}
      </AnimatePresence>
    </motion.ul>
  );
}
4实现共享布局指示器
tsx
import { motion } from "motion/react";

export function Tabs({
  items,
  active,
  onChange,
}: {
  items: string[];
  active: string;
  onChange: (value: string) => void;
}) {
  return (
    <div role="tablist">
      {items.map((item) => (
        <button
          key={item}
          role="tab"
          aria-selected={item === active}
          onClick={() => onChange(item)}
        >
          {item}
          {item === active ? (
            <motion.span layoutId="active-tab" className="active-tab" />
          ) : null}
        </button>
      ))}
    </div>
  );
}
5绑定页面滚动进度
tsx
import { motion, useScroll, useSpring } from "motion/react";

export function ScrollProgress() {
  const { scrollYProgress } = useScroll();
  const scaleX = useSpring(scrollYProgress, {
    stiffness: 120,
    damping: 24,
  });

  return (
    <motion.div
      aria-hidden="true"
      style={{ scaleX, transformOrigin: "0 50%" }}
      className="scroll-progress"
    />
  );
}
6响应 Reduced Motion
tsx
import {
  MotionConfig,
  motion,
  useReducedMotion,
} from "motion/react";

function Sidebar({ open }: { open: boolean }) {
  const reduceMotion = useReducedMotion();

  return (
    <motion.aside
      animate={{
        opacity: open ? 1 : 0,
        x: open || reduceMotion ? 0 : "-100%",
      }}
    />
  );
}

export function App() {
  return (
    <MotionConfig reducedMotion="user">
      <Sidebar open />
    </MotionConfig>
  );
}
7在普通 JavaScript 中使用
javascript
import { animate, stagger } from "motion";

animate(
  ".project-card",
  {
    opacity: [0, 1],
    y: [20, 0],
  },
  {
    duration: 0.45,
    delay: stagger(0.06),
    ease: "easeOut",
  },
);
8运行类型检查与构建
bash
npm run dev

# 发布前执行项目自己的检查
npm run typecheck
npm run build

下一步:先确认动画是否帮助用户理解状态变化。简单 Hover 和颜色过渡优先使用 CSS;使用 Motion 时优先动画 transform 与 opacity,并始终为 prefers-reduced-motion 提供更温和的替代方案。

ALTERNATIVES

类似项目

React 是 Motion 最成熟的组件集成,Radix UI 和 shadcn/ui 常与它组合实现可访问、带动画的产品组件;其他动画引擎列为外部参考。

COMPARISON

Motion vs GSAP

Motion 与 GSAP 都能完成生产级 Web 动画,但 Motion 更贴近 React 状态、布局和手势模型,GSAP 则以命令式 Timeline 与跨技术对象控制见长。

比较维度MotionGSAP
核心风格React 声明式组件,同时提供 JavaScript 函数 API命令式 Tween、Timeline 与插件 API
React 集成motion 组件、Hooks、Presence 和 Layout 原生集成通过 Ref、Context 和 useGSAP 控制 DOM 动画
布局动画layout 与 layoutId 自动测量和过渡通常使用 Flip Plugin 或自定义 Timeline
进入退出AnimatePresence 直接理解 React 节点卸载由 Timeline、Callback 和组件生命周期协调
复杂编排Variants、Sequence、Delay 与 StaggerTimeline 控制精细,适合长序列和艺术指导
手势Hover、Tap、Focus、Drag 与 React Props 一体化可通过 Draggable、Observer 等能力实现
非 React 场景提供 animate、scroll 等原生 JavaScript API长期面向 DOM、Canvas、SVG 和多种运行环境
更适合React 产品界面、状态动画、布局和手势交互营销动效、复杂 Timeline、创意编码和精细控制
如何选择

如果动画主要服务 React 组件状态、列表布局、页面切换和手势交互,Motion 通常更自然;如果项目需要长时间线、复杂艺术编排、精细播放控制或跨多种渲染对象,GSAP 更有优势。两者都应通过真实设备验证流畅度、Reduced Motion、可维护性和最终体积。

VERIFICATION

资料核验

版本、维护信息与本页采用的官方资料来源。

最后核验2026 年 7 月 29 日
核验版本Motion 12.43.0
内容维护Docs100 编辑整理
项目维护状态活跃维护

本页依据 Motion 官方 React 入门、JavaScript Quick Start、AnimatePresence、Layout Animation、Reduced Motion 与可访问性文档,以及 npm Registry 和官方源码仓库整理。Motion+ 属于额外产品,本页主要介绍 MIT 许可的 motion 开源包。

维护状态核验2026 年 7 月 26 日 · 最近可见代码活动:2026 年 7 月 28 日

官方仓库未归档,核验时最近可见的代码活动日期为 2026 年 7 月 28 日。该状态表示项目近期仍有公开维护活动,不代表固定发布频率或长期支持承诺。

查看官方仓库