# @dugyu/luna-stage 中文文档

规范地址：https://npmcn.com/package/%40dugyu/luna-stage/

版本：0\.2\.2
npm 元数据更新时间：2026-05-17T15:39:49.756Z
中文译文更新时间：2026-11-13T00:01:33.514Z
软件包许可：Apache-2\.0

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

原始 npm 页面：https://www.npmjs.com/package/%40dugyu/luna-stage
原文对照：https://npmcn.com/package/%40dugyu/luna-stage/?lang=original
项目主页：https://github.com/Dugyu/lunarium/tree/main/packages/luna-stage#readme
源码仓库：https://github.com/Dugyu/lunarium

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

- 包体积（解压后）：226 kB，145 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：1 个
- peer 依赖：@lynx-js/web-core \>=0\.20\.0，motion \>=12\.23\.16，react \>=18\.0\.0
- 首次发布：2026-05-06T13:00:20.722Z
- 最新版本发布：2026-05-17T15:39:49.505Z
- 近 30 天下载量：5523（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：6（近 12 个月 6 个）

## 中文简介

L.U.N.A项目的阶段系统和展示组件

## 安装

```sh
npm install @dugyu/luna-stage
```

也可以使用：`pnpm add @dugyu/luna-stage`、`yarn add @dugyu/luna-stage`、`bun add @dugyu/luna-stage`

## README

# 月相级

> L.U.N.A项目的阶段系统和展示组件. 将 Lynx 捆绑成设备外壳/ 在浏览器中的相位的原子组件 .

使用 `luna-stage` 当您需要单帧预览时 (`Stage` + 键 `LunaLynxStage`)或动议强化演示(`MotionStage`(见A/C.5/49/70,附件)。 关于多阶段管弦乐和工作室级别布局,见 [`@dugyu/luna-studio`](https://npmcn.com/package/%40dugyu/luna-studio)。 。 。 .

## 目录

-   [安装](https://npmcn.com/package/%40dugyu/luna-stage/#readme-installation)
-   [条目点](https://npmcn.com/package/%40dugyu/luna-stage/#readme-entry-points)
-   [概念](https://npmcn.com/package/%40dugyu/luna-stage/#readme-concepts)
-   [快速启动](https://npmcn.com/package/%40dugyu/luna-stage/#readme-quick-start)
-   [API 密码](https://npmcn.com/package/%40dugyu/luna-stage/#readme-api)
-   [用法实例](https://npmcn.com/package/%40dugyu/luna-stage/#readme-usage-examples)
-   [SSS / SSG 说明](https://npmcn.com/package/%40dugyu/luna-stage/#readme-ssr--ssg-notes)
-   [变形公用事业](https://npmcn.com/package/%40dugyu/luna-stage/#readme-transform-utilities)

## 安装

```sh
pnpm i @dugyu/luna-stage
```

**同伴依赖关系** 在应用程序中安装:

```sh
pnpm i react
```

用于 Lynx 渲染 (`LynxStage` 编号 : `LunaLynxStage`),安装Lynx Web运行时间:

```sh
pnpm i @lynx-js/web-core
```

对于运动能力,安装 `motion`数字 :

```sh
pnpm i motion
```

## 条目点

| 导入路径 | 要求数 `motion` | 要求数 `@lynx-js/web-core` | 使用时间 |
| --- | --- | --- | --- |
| `@dugyu/luna-stage` | 没有 | 没有 | 静态设备框架 + 共享钩 |
| `@dugyu/luna-stage/lynx` | 没有 | 对 | Lynx 捆绑渲染 (`LynxStage` 编号 : `LunaLynxStage`(中文(简体) ) |
| `@dugyu/luna-stage/motion` | 对 | 没有 | 动画过渡+取景相机(`MotionStage`(中文(简体) ) |

## 概念

### 设备框架模型

-   `baseWidth` 编号 : `baseHeight` 定义 **设计基线** (默认) `375×812`),而不是视图大小.
-   框架在其基维度并使用CSS `transform: scale()` 以适应于景点.
-   两个视觉层: **大纲** (装饰边框,模拟设备厚度)和 **边框** (内容区与夹道).
-   `Stage` 仅:一个绝对位置的 0×0 锚坐落于 `placeX/placeY` 位置; 轮廓和框架围绕此锚进行转换.

### 适应系统

-   `contain` ——平面向下完全适应于取景口(不收割).
-   `cover` ——天平向上完全覆盖取景口(可收成).
-   `alignX` 编号 : `alignY` ——风景区内框架对接. 单位 `cover` 模式还确定裁剪时框架的哪个部分被保留。 物理方向 : `left | center | right` 编号 : `top | center | bottom`。 。 。 .
-   `placeX` 编号 : `placeY` _(仅标出)_ ——将锚架放入取景所内,与 `alignX/Y`默认匹配 `alignX/Y` 用于对象位置类似语义学。 仅当您希望帧的内部对齐与其取景位置( rare) 不同时才会被覆盖 .
-   `fitProgress` _(仅限动议)_ 连续 `0→1` 插值间 `contain` 财务报告和审定财务报表 `cover`被弹簧所驱使.

### 相机模型 _(仅限动议)_

改造管道在两个独立空间运行:

**屏幕空间**

-   `fit` 编号 : `fitProgress` ——取景口驱动的被动缩放.
-   `zoom` ——由用户控制的活性缩放,在适量上应用.
-   `panX` 编号 : `panY` ——以像素进行屏幕-空间翻译,在所有缩放后应用.

**世界空间**

-   `world` ——框架的3D位置 `{ x, y, z }`。遵循CSS/OpenGL公约: `+Z` 指向观众.
-   `focalLength` ——视角强度. 何时 `> 0`,可以进行视角预测。 何时 `0` 或省去,正字形.
-   `world.x/y` 投放到屏幕空间中,然后与 `panX/panY`。弹簧动画将合并屏幕-空间值.

最后比额表= `lerpFitScale(contain, cover, fitSpring) × zoom × depthScale`

最后翻译 = `world.xy × depthScale + panXY`

## 快速启动

### 单帧预览 `LunaLynxStage`

```tsx
import { Stage, StageContainer } from '@dugyu/luna-stage';
import { LunaLynxStage } from '@dugyu/luna-stage/lynx';

export default function Preview() {
  return (
    <StageContainer className='w-full h-screen'>
      <Stage>
        <LunaLynxStage
          entry='my-component'
          bundleRoot='/bundles/'
          lunaTheme='lunaris-dark'
        />
      </Stage>
    </StageContainer>
  );
}
```

默认捆绑 URL 常规 : `${bundleRoot}${entry}.web.bundle`。 。 。 .

用它来代替它 `resolveBundleSrc` 当您的主机使用不同的命名规则时 .

`bundleRoot` 在内部实现正常化,在URL解析前总是以后向斜线结束。 也就是说打电话的人也可以通过 `'/bundles'` 或者说 `'/bundles/'`,以及 `resolveBundleSrc` 将永远得到正常值.

`lunaTheme` 将LUNA设计符号环球注入Lynx运行时间.

### 没有LUNA主题

使用 `LynxStage` 当您不需要LUNA全局道具时直接转发:

```tsx
import { Stage, StageContainer } from '@dugyu/luna-stage';
import { LynxStage } from '@dugyu/luna-stage/lynx';

<StageContainer className='w-full h-screen'>
  <Stage>
    <LynxStage entry='my-component' bundleRoot='/bundles/' />
  </Stage>
</StageContainer>;
```

### 独立 `LynxStage`

`LynxStage` 可用于独立于 `Stage` 如果您只想在 DOM 容器中显示 Lynx 视图:

```tsx
import { LynxStage } from '@dugyu/luna-stage/lynx';

export default function StandaloneView() {
  return (
    <div className='w-full h-screen'>
      <LynxStage entry='my-component' bundleRoot='/bundles/' />
    </div>
  );
}
```

## API 密码

### `Stage`

静态装置框架. 读取视图大小 `StageContainer` 如果存在上下文,否则会回到 `baseWidth/baseHeight`。 。 。 .

`Stage` 支持两种确定其视图大小的方法:

**自动适应父目录( 建议)** - 包起来 `StageContainer` 因此,视图自动计量和框架符合:

```tsx
<StageContainer className='w-full h-full'>
  <Stage>
    <YourContent />
  </Stage>
</StageContainer>;
```

**明确视图大小** - 通过 `width` 编号 : `height` 直接转到 `Stage`。对于固定大小的预览、服务器交付的布局或任何您不愿添加测量包装器的地方都是有用的:

```tsx
<Stage width={390} height={844}>
  <YourContent />
</Stage>;
```

> **说明:** 环绕 `Stage` 大小 `<div>` 无 `StageContainer` 不会使框架符合div -- `Stage` 无法读取神的大小 并且会回到 `baseWidth × baseHeight`启用 `StageContainer` 或通过 `width`编号 :`height` 直接说.

#### 道具

| Prop | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `baseWidth` | `number` | `375` | 以像素为单位设计基线宽度. |
| `baseHeight` | `number` | `812` | 以像素设计基线高度. |
| `width` | `number` | —— 说 | 显取观相大小. 驱动两种 `<div>` 大小和适合/尺度。 倒计时 `StageContainer` → `baseWidth`。 。 。 . |
| `height` | `number` | —— 说 | 显取观相大小. 驱动两种 `<div>` 大小和适合/尺度。 倒计时 `StageContainer` → `baseHeight`。 。 。 . |
| `fit` | `'contain' | 'cover'` | `'contain'` | 合适的模式. |
| `alignX` | `'left' | 'center' | 'right'` | `'center'` | 视野内帧水平对齐. 单位 `cover` 模式还决定了裁剪锚地. |
| `alignY` | `'top' | 'center' | 'bottom'` | `'center'` | 视野内帧垂直对齐. 单位 `cover` 模式还决定了裁剪锚地. |
| `placeX` | `'left' | 'center' | 'right'` | `alignX` | 在取景口内横向放置内部锚. 覆盖到从对齐解析位置 . |
| `placeY` | `'top' | 'center' | 'bottom'` | `alignY` | 在取景口内垂直放置内部锚. 覆盖到从对齐解析位置 . |
| `zoom` | `number` | `1` | 在合适的顶部增加缩放系数 . |
| `panX` | `number` | `0` | 沿X(px)进行屏幕-空间翻译. |
| `panY` | `number` | `0` | 沿Y(px)进行屏幕-空间翻译. |
| `className` | `string` | —— 说 | 适用于大纲层. |
| `style` | `CSSProperties` | —— 说 | 适用于大纲层. |
| `onClick` | `MouseEventHandler` | —— 说 | —— 说 |

### `StageContainer`

通过测量其DOM大小 `ResizeObserver` 并给孩子提供宽度/高度 `Stage` 组件通过上下文.

添加粘贴、边框或布局样式到 `StageContainer` 自由——测量的内容框是什么 `Stage` 适合,所以编织的作品 作为预期的视觉边框周围的帧.

避免设置 `transform`, (中文(简体) ), `filter`, (中文(简体) ), `perspective`, (中文(简体) ), `backdrop-filter`,或 `contain: paint/layout/strict` 打开 `StageContainer` ——这些设置了被夹住的块 `position: fixed` 舞台上的后代.

#### 道具

| Prop | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `fallbackWidth` | `number` | `0` | 在第一次测量之前使用. |
| `fallbackHeight` | `number` | `0` | 在第一次测量之前使用. |

继承所有 `<div>` HTML 属性 (`className`, (中文(简体) ), `style`(见a/c.5/49/70,附件).

### `LynxStage`

将 Lynx 捆绑成 DOM 容器的核心组件 .

| Prop | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `entry` | `string` | —— 说 | Lynx包的条目名 . |
| `bundleRoot` | `string` | `'/'` | 使用的资源根 `entry` 找到包裹 常态化到永远结束 `/` 在 URL 解析之前. |
| `resolveBundleSrc` | `function` | —— 说 | 可选的钩子, 用于构建最终捆绑的 URL 。 接收已规范 `bundleRoot` (总是结束于 `/`) (中文(简体) ). |
| `globalProps` | `Record<string, unknown>` | —— 说 | 注射到Lynx运行时间的全球道具. |
| `groupId` | `number` | `7` | 共享Lynx工人团体ID. |
| `onNativeModulesCall` | `function` | —— 说 | 从 Lynx 运行时间召回本地模块呼叫 . |
| `onReady` | `function` | —— 说 | 当视图成功渲染时调用 . |
| `onError` | `function` | —— 说 | 在加载或渲染过程中发生错误时召回 . |

### `LunaLynxStage`

扩展 `LynxStage` 带有 LUNA 主题属性.

| Prop | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `lunaTheme` | `LunaThemeKey` | `'luna-light'` | LUNA主题密钥( 如:. `'luna-light'`) (中文(简体) ). |
| `extraGlobalProps` | `Record<string, unknown>` | —— 说 | 新增全球道具. |
| _(其他人员)_ |  |  | 全体 `LynxStage` 道具( 除外) `globalProps`) (中文(简体) ). |

### `MotionStage`

动画设备框架. 扩展 `Stage`其基础道具有弹簧驱动的过渡和透视相机模型.

`MotionStage` 内部建议 `MotionStageContainer` 用于响应的大小和布局动画. 当独立化时,它会回落到基线大小,你可以通过 `width` 编号 : `height` `MotionValue<number>` 道具来.

#### 道具

| Prop | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `baseWidth` | `number` | `375` | 以像素为单位设计基线宽度. |
| `baseHeight` | `number` | `812` | 以像素设计基线高度. |
| `width` | `MotionValue<number>` | —— 说 | 覆盖取景口宽度( 从上下文) 。 对于高级病例. |
| `height` | `MotionValue<number>` | —— 说 | 覆盖取景口高度( 从上下文) 。 对于高级病例. |
| `fit` | `'contain' | 'cover'` | `'contain'` | 合适的模式。 忽略当 `fitProgress` 已经设定. |
| `fitProgress` | `number` | —— 说 | `0–1` 混入了被子和被子, 由一泉驱动. |
| `zoom` | `number` | `1` | 额外的缩放系数 . |
| `panX` | `number` | `0` | 沿X(px)进行屏幕-空间翻译. |
| `panY` | `number` | `0` | 沿Y(px)进行屏幕-空间翻译. |
| `world` | `{ x?, y?, z? }` | `{ x:0, y:0, z:0 }` | 世界空间位置. `+Z` 面向观众. |
| `focalLength` | `number` | —— 说 | 透视焦距 (px). 矫形术. |
| `alignX` | `'left' | 'center' | 'right'` | `'center'` | 视野内帧水平对齐. |
| `alignY` | `'top' | 'center' | 'bottom'` | `'center'` | 视野内帧垂直对齐. |
| `fitTransition` | `SpringOptions` | —— 说 | 春天来 `fit` 编号 : `fitProgress`。 。 。 . |
| `zoomTransition` | `SpringOptions` | —— 说 | 春天来 `zoom`。 。 。 . |
| `panTransition` | `SpringOptions` | —— 说 | 用于合并屏幕-空间翻译的春天(`panX/Y` + 预测 `world.x/y`) (中文(简体) ). |
| `maskColor` | `string` | `'transparent'` | 重叠口罩颜色. |
| `maskOpacity` | `number` | `0` | 重叠口罩不透明(动画). |
| `contentInteractive` | `boolean` | `false` | 帧子是否收到指针事件. |
| `className` | `string` | —— 说 | 适用于大纲层. |
| `style` | `MotionStyle` | —— 说 | 适用于大纲层. |

### `MotionStageContainer`

运动意识等同 `StageContainer`提供 `MotionValue<number>` 宽度/ 重至子 `MotionStage` 组件通过上下文。 处理布局动画并从中取出父缩放 `transformTemplate` 在过渡期间保持视觉大小的准确性.

必须是作为孩子 `<AnimatePresence>` 用于挂载/卸载动画工作.

#### 道具

| Prop | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `layoutId` | `string` | —— 说 | 跨挂载/卸载布局动画匹配的独特ID 。 要求. |
| `onLayoutMeasure` | `(box: Box) => void` | —— 说 | 从 `motion`。当布局框被测量时调用. |
| `onLayoutAnimationStart` | `() => void` | —— 说 | 从 `motion`。当布局动画开始时调用. |
| `onLayoutAnimationComplete` | `() => void` | —— 说 | 从 `motion`。当布局动画完成时调用. |

继承所有 `motion.div` 道具( 除外) `transformTemplate`页:1.

### `MotionPresentation`

一个零大小的以弹性为中心的主锚来包接 `AnimatePresence propagate` 为后人挂载/卸载动画.

**使用时 :** 项是动态添加/删除的,需要挂载/卸载动画.

**跳过时 :** 组件总是挂载的,或者只需要状态过渡动画.

继承所有 `motion.div` 道具( r)`variants`, (中文(简体) ), `initial`, (中文(简体) ), `animate`, (中文(简体) ), `exit`, (中文(简体) ), `transition`(见a/c.5/49/70,附件).

## 用法实例

### 运动: 无挂载/卸载

```tsx
import { MotionStage, MotionStageContainer } from '@dugyu/luna-stage/motion';

<MotionStageContainer className='w-full h-full' layoutId='stage-1'>
  <MotionStage fitProgress={0} zoom={1.2}>
    <YourContent />
  </MotionStage>
</MotionStageContainer>;
```

### 动画: 有挂载/卸载动画

```tsx
import { AnimatePresence } from 'motion/react';
import {
  MotionStage,
  MotionStageContainer,
  MotionPresentation,
} from '@dugyu/luna-stage/motion';

const variants = {
  initial: { opacity: 0, x: -300 },
  animate: { opacity: 1, x: 0 },
  exit: { opacity: 0, x: 300 },
};

<AnimatePresence mode='popLayout'>
  {items.map(item => (
    <MotionStageContainer key={item.id} layoutId={item.id}>
      <MotionPresentation
        variants={variants}
        initial='initial'
        animate='animate'
        exit='exit'
      >
        <MotionStage world={item.world} focalLength={500}>
          <YourContent />
        </MotionStage>
      </MotionPresentation>
    </MotionStageContainer>
  ))}
</AnimatePresence>;
```

### 透视旋转木马

沿圆弧排列相框. `+Z` 面向观众,所以物体在 `z < 0` 更远处出现:

```tsx
const theta = (index - mid) * (Math.PI / 9); // 20° apart
const world = {
  x: Math.sin(theta) * radius,
  z: -Math.cos(theta) * radius, // negative = further from viewer
};

<MotionStage world={world} focalLength={500}>
  <YourContent />
</MotionStage>;
```

### 整形比较布局

奥米 `focalLength` (或设置为 `0`——所有帧均以等比例制作,而不论 `world.z`数字 :

```tsx
<MotionStage world={{ x: offset, y: 0, z: 0 }}>
  <YourContent />
</MotionStage>;
```

## 构成部分表

| 构成部分 | 入境点 | 说明 |
| --- | --- | --- |
| `Stage` | `.` | 静态设备框架 |
| `StageContainer` | `.` | 自动计量容器,通过上下文提供大小 |
| `LynxStage` | `./lynx` | Core Lynx 捆绑渲染器( 无 LUNA 环球) |
| `LunaLynxStage` | `./lynx` | `LynxStage` + LUNA 主题道具注射 |
| `MotionStage` | `./motion` | 有透视相机的动画设备框架 |
| `MotionStageContainer` | `./motion` | 布局动画包装; 提供 `MotionValue` 大小 |
| `MotionPresentation` | `./motion` | 上山/下山过渡管弦乐团 |

## 钩子

| 导出 | 入境点 | 说明 |
| --- | --- | --- |
| `useEventCallback` | `.` | 固定的回调,总是调用最新的 `fn` |
| `useIsClient` | `.` | SSR 安全客户端挂载检测 |
| `useContainerResize` | `.` | 通过 `ResizeObserver` |
| `useMergedRefs` | `.` | 将多个 refs 合并到单个元素 |
| `useIsomorphicLayoutEffect` | `.` | 安保部门安全 `useLayoutEffect` |
| `useLynxStage` | `./lynx` | 用于管理 Lynx 运行时间和生命周期的核心钩 |

## SSS / SSG 说明

`LynxStage` 财务报告和审定财务报表 `LunaLynxStage` 为: **只有客户端**它们使 `null` 在服务器上挂载,只在水分化后挂载.

## 捆绑和资产公约

-   默认情况下, 捆绑文件遵循命名模式 `*.web.bundle`。 。 。 .
-   `bundleRoot` 由默认解析器规范为后继斜线.
-   默认解析的 URL : `${bundleRoot}${entry}.web.bundle`。 。 。 .
-   使用 `resolveBundleSrc` 当您的主机需要不同的文件命名规则或完整的 URL 组成 .

## 变形公用事业

职能 `src/utils/transform.ts` 是零依赖性纯函数,可安全复制到其他项目.

| 函数 | 说明 |
| --- | --- |
| `computeScaleRange(input)` | 回返 `{ contain, cover }` 比额表因数 |
| `lerpFitScale(range, t)` | 封面和封面之间的内插 |
| `computeFrameOffset(input)` | 回返 `{ offsetX, offsetY }` cSS 转换 |
| `computeDepthScale(focalLength, worldZ)` | 视角深度尺度 `f / (f - z)` |
| `computeScreenTranslation(input)` | 项目世界 XY + 屏幕平板 最终翻译 |

将适应/规模纳入 `lynx-view` 容器: 副本 `computeScaleRange`, (中文(简体) ), `lerpFitScale`,以及 `computeFrameOffset`修复 `lynx-view` 时间 `baseWidth × baseHeight`,通过 CSS 应用计算过的变换,并通过设计基线像素尺寸 `browserConfig` 而不是容器的大小.

## 常见问题

### @dugyu/luna-stage 是什么？

L\.U\.N\.A项目的阶段系统和展示组件

### 如何安装 @dugyu/luna-stage？

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

### @dugyu/luna-stage 支持 TypeScript 吗？

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

### @dugyu/luna-stage 支持 ESM 还是 CommonJS？

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

### @dugyu/luna-stage 可以商用吗？

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

### @dugyu/luna-stage 的下载量有多少？

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

### @dugyu/luna-stage 还在维护吗？

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

