# @aphrody/m3-motion 中文文档

规范地址：https://npmcn.com/package/%40aphrody/m3-motion/

版本：1\.4\.7
npm 元数据更新时间：2026-10-23T03:51:16.272Z
中文译文更新时间：2026-11-06T23:25:55.481Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40aphrody/m3-motion
原文对照：https://npmcn.com/package/%40aphrody/m3-motion/?lang=original
项目主页：https://github.com/aphrody-labs/bun-distribution/tree/os/packages/m3-motion#readme
源码仓库：https://github.com/aphrody-labs/bun-distribution

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：187 kB，31 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：1 个
- peer 依赖：react \>=18\.0\.0，motion \>=12\.0\.0
- 首次发布：2026-06-03T22:55:33.381Z
- 最新版本发布：2026-10-23T03:51:16.008Z
- 近 30 天下载量：2172（2026-10-06 至 2026-11-04，npm 官方下载统计）
- 已发布版本数：17（近 12 个月 17 个）

## 中文简介

材质 3 动画插件由 Motion 提供动力(前作 Framer Motion)

## 安装

```sh
npm install @aphrody/m3-motion
```

也可以使用：`pnpm add @aphrody/m3-motion`、`yarn add @aphrody/m3-motion`、`bun add @aphrody/m3-motion`

## README

# @aphrody/m3-运动

反应组件和钩用于材料 3 运动模式(容器变换,共享轴,淡出,倒塌, 开始 [动议](https://motion.dev/),带有M3弹簧,放松和持续符.

```sh
bun add @aphrody/m3-motion motion react
```

```tsx
import { M3Fade, M3FadeThrough } from "@aphrody/m3-motion";

<M3Fade in={open}>Details</M3Fade>;
<M3FadeThrough stateKey={tab}>{panel}</M3FadeThrough>;
```

许可证: Apache-2.0(`LICENSE`) (中文(简体) ). 安装指南 : [文件/材料/立方米/INSTALL.md](https://github.com/aphrody-labs/bun-distribution/blob/os/docs/material/m3/INSTALL.md)。 。 。 .

* * *

## 1\. 集装箱转换`M3ContainerTransform`(中文(简体) )

容器将一个UI元素转换为另一个元素(例如将一个小卡片组件变形为一整页详细视图).

### 关键特性

-   **光谱比保全**: 使用布局-位置校正在容器形态时自动地防止儿童的布局扭曲(skewing/stritching).
-   **Spec-compliant 交叉淡出**: 提前显示起始内容(0%到30%的过渡),并延迟目标内容的淡出(20%到100%的过渡)来避免混乱的中间状态.
-   **指针事件管理**:防止不活动,隐藏内容被拦截指针交互.
-   **灵活性**: 支持两个 **单容器切换** 方法(在同一集装箱内重新提交)和 **双容器共享布局** 方法(通过 `layoutId`) (中文(简体) ).

### 子组件

-   `M3ContainerTransform`: 家长形态容器.
-   `M3ContainerTransformStart`: srapper 用于起始内容(例如倒卡细节).
-   `M3ContainerTransformEnd`: 收尾内容的收尾(如扩充的页面细节).

* * *

### 代码示例

#### 单一集装箱切换方法

使用状态对单个组件实例进行形态化的最佳方式 .

```tsx
import React, { useState } from "react";
import {
  M3ContainerTransform,
  M3ContainerTransformStart,
  M3ContainerTransformEnd,
} from "@aphrody/m3-motion";

export const MorphingCard = () => {
  const [isExpanded, setIsExpanded] = useState(false);

  return (
    <M3ContainerTransform
      isExpanded={isExpanded}
      speed="default"
      style={{
        width: isExpanded ? 500 : 250,
        height: isExpanded ? 400 : 150,
        borderRadius: isExpanded ? 28 : 16,
        backgroundColor: "var(--md-sys-color-surface-container)",
        cursor: "pointer",
      }}
      onClick={() => setIsExpanded(!isExpanded)}
    >
      {/* Start state (collapsed content) */}
      <M3ContainerTransformStart>
        <div style={{ padding: 16 }}>
          <h3>Collapsed Card</h3>
          <p>Click me to expand...</p>
        </div>
      </M3ContainerTransformStart>

      {/* End state (expanded detail content) */}
      <M3ContainerTransformEnd>
        <div style={{ padding: 24 }}>
          <h2>Detailed View</h2>
          <p>This is the expanded content showing the full detail surface.</p>
          <button
            onClick={e => {
              e.stopPropagation();
              setIsExpanded(false);
            }}
          >
            Close
          </button>
        </div>
      </M3ContainerTransformEnd>
    </M3ContainerTransform>
  );
};
```

#### 双集装箱共享版式办法(通过 `layoutId`(中文(简体) )

最适合页面/路由转换或单独的 DOM 元素 。 环绕条件渲染到 `<AnimatePresence>` 以启用退出淡出过渡.

```tsx
import React, { useState } from "react";
import { AnimatePresence } from "motion/react";
import {
  M3ContainerTransform,
  M3ContainerTransformStart,
  M3ContainerTransformEnd,
} from "@aphrody/m3-motion";

export const ListView = () => {
  const [selectedId, setSelectedId] = useState<string | null>(null);

  return (
    <div>
      {/* List of items */}
      {!selectedId && (
        <div className="grid">
          <M3ContainerTransform
            layoutId="card-item-1"
            onClick={() => setSelectedId("1")}
            style={{
              borderRadius: 16,
              background: "#eee",
              width: 200,
              height: 120,
            }}
          >
            <M3ContainerTransformStart>
              <div style={{ padding: 12 }}>Card Content 1</div>
            </M3ContainerTransformStart>
          </M3ContainerTransform>
        </div>
      )}

      {/* Expanded detail page */}
      <AnimatePresence>
        {selectedId === "1" && (
          <div className="backdrop">
            <M3ContainerTransform
              layoutId="card-item-1"
              style={{
                borderRadius: 24,
                background: "#fff",
                width: 600,
                height: 450,
              }}
            >
              <M3ContainerTransformEnd>
                <div style={{ padding: 24 }}>
                  <h2>Expanded Title 1</h2>
                  <p>Long detail text...</p>
                  <button onClick={() => setSelectedId(null)}>
                    Back to List
                  </button>
                </div>
              </M3ContainerTransformEnd>
            </M3ContainerTransform>
          </div>
        )}
      </AnimatePresence>
    </div>
  );
};
```

* * *

## 2\. 共有轴心国(`M3SharedAxis`(中文(简体) )

用于具有空间或导航关系的UI元素之间的过渡(例如:页面分步器,分页切换,或对话框覆盖等). 支助 `x`, (中文(简体) ), `y`,以及 `z` 斧头.

-   默认输入时间 : **300ms (英语)** (单位:千美元)`medium2`与 `emphasizedDecelerate` 放松点.
-   默认退出时间 : **200米长** (单位:千美元)`short4`与 `emphasizedAccelerate` 放松点.

### 代码示例

```tsx
import React, { useState } from "react";
import { M3SharedAxis } from "@aphrody/m3-motion";

export const StepWizard = () => {
  const [step, setStep] = useState(0);

  return (
    <div>
      <M3SharedAxis
        stateKey={step}
        axis="x"
        forward={step > 0}
        style={{ padding: 20 }}
      >
        {step === 0 && <div>Step 1: Enter details</div>}
        {step === 1 && <div>Step 2: Review options</div>}
        {step === 2 && <div>Step 3: Confirm purchase</div>}
      </M3SharedAxis>

      <button onClick={() => setStep(prev => Math.max(0, prev - 1))}>
        Back
      </button>
      <button onClick={() => setStep(prev => Math.min(2, prev + 1))}>
        Next
      </button>
    </div>
  );
};
```

* * *

## 3\. 通过(`M3FadeThrough`(中文(简体) )

用于没有很强空间关系的主视图之间的过渡(如底层导航切换,设置屏幕等).

-   默认退出时间( 取消) : **90分钟** 与 `emphasizedAccelerate` 放松点.
-   默认输入持续时间( 从92% 中取消) : **210毫米口径** 与 `emphasizedDecelerate` 放松点.

### 代码示例

```tsx
import React, { useState } from "react";
import { M3FadeThrough } from "@aphrody/m3-motion";

export const AppNavigation = () => {
  const [currentTab, setCurrentTab] = useState("home");

  return (
    <div>
      <M3FadeThrough stateKey={currentTab} style={{ height: 400 }}>
        {currentTab === "home" && <div>Home View Content</div>}
        {currentTab === "search" && <div>Search Page Content</div>}
        {currentTab === "profile" && <div>User Profile Settings</div>}
      </M3FadeThrough>

      <nav>
        <button onClick={() => setCurrentTab("home")}>Home</button>
        <button onClick={() => setCurrentTab("search")}>Search</button>
        <button onClick={() => setCurrentTab("profile")}>Profile</button>
      </nav>
    </div>
  );
};
```

* * *

## 4\. 期限和缓解预设

开发者可直接访问官方"材料设计"3分计时和曲线:

```tsx
import { m3Easings, m3Durations, m3Springs } from "@aphrody/m3-motion";

// Custom animation example using M3 tokens
const myCustomTransition = {
  ease: m3Easings.emphasizedDecelerate,
  duration: m3Durations.medium4, // 400ms
};
```

### 动议预设摘要

-   **`m3Easings`**: Bezier 曲线用于 `emphasized` (约), `emphasizedDecelerate` (进入), `emphasizedAccelerate` (出狱), `standard`, (中文(简体) ), `standardDecelerate`,以及 `standardAccelerate`。 。 。 .
-   **`m3Durations`**: 计时表 `short1` (50毫秒)至 `extraLong4` (1000ms) (英语).
-   **`m3Springs`**: 手调取出春常数`fast`, (中文(简体) ), `default`, (中文(简体) ), `slow`拆分为 `spatial` (义务)和 `effects` (严重被挡住).

* * *

## 许可证

阿帕奇 - 2.0

## 常见问题

### @aphrody/m3-motion 是什么？

材质 3 动画插件由 Motion 提供动力\(前作 Framer Motion\)

### 如何安装 @aphrody/m3-motion？

在项目目录运行 npm install @aphrody/m3-motion，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（\>=18\.0\.0）、motion（\>=12\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @aphrody/m3-motion 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @aphrody/m3-motion 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @aphrody/m3-motion 可以商用吗？

@aphrody/m3-motion 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @aphrody/m3-motion 的下载量有多少？

根据 npm 官方下载统计，@aphrody/m3-motion 在 2026/10/06 – 2026/11/04 这 30 天内被下载 2,172 次，日均约 72 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @aphrody/m3-motion 还在维护吗？

最新版本 1\.4\.7 发布于 2026/10/23（15 天前）；至今共发布 17 个版本，其中过去 12 个月发布了 17 个；首次发布于 2026/06/04。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

