@dugyu/luna-stage

中文文档
0.2.2发布于 2026/05/17Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 5523

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

中文使用文档
文档目录29 节
  1. 目录
  2. 安装
  3. 条目点
  4. 概念
  5. 设备框架模型
  6. 适应系统
  7. 相机模型 (仅限动议)
  8. 快速启动
  9. 单帧预览 LunaLynxStage
  10. 没有LUNA主题
  11. 独立 LynxStage
  12. API 密码
  13. Stage
  14. StageContainer
  15. LynxStage
  16. LunaLynxStage
  17. MotionStage
  18. MotionStageContainer
  19. MotionPresentation
  20. 用法实例
  21. 运动: 无挂载/卸载
  22. 动画: 有挂载/卸载动画
  23. 透视旋转木马
  24. 整形比较布局
  25. 构成部分表
  26. 钩子
  27. SSS / SSG 说明
  28. 捆绑和资产公约
  29. 变形公用事业

月相级

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

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

目录

安装

pnpm i @dugyu/luna-stage

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

pnpm i react

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

pnpm i @lynx-js/web-core

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

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

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全局道具时直接转发:

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 视图:

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 因此,视图自动计量和框架符合:

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

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

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

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

道具

Prop类型默认说明
baseWidthnumber375以像素为单位设计基线宽度.
baseHeightnumber812以像素设计基线高度.
widthnumber—— 说显取观相大小. 驱动两种 <div> 大小和适合/尺度。 倒计时 StageContainer → baseWidth。 。 。 .
heightnumber—— 说显取观相大小. 驱动两种 <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在取景口内垂直放置内部锚. 覆盖到从对齐解析位置 .
zoomnumber1在合适的顶部增加缩放系数 .
panXnumber0沿X(px)进行屏幕-空间翻译.
panYnumber0沿Y(px)进行屏幕-空间翻译.
classNamestring—— 说适用于大纲层.
styleCSSProperties—— 说适用于大纲层.
onClickMouseEventHandler—— 说—— 说

StageContainer

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

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

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

道具

Prop类型默认说明
fallbackWidthnumber0在第一次测量之前使用.
fallbackHeightnumber0在第一次测量之前使用.

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

LynxStage

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

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

LunaLynxStage

扩展 LynxStage 带有 LUNA 主题属性.

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

MotionStage

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

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

道具

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

MotionStageContainer

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

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

道具

Prop类型默认说明
layoutIdstring—— 说跨挂载/卸载布局动画匹配的独特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,附件).

用法实例

运动: 无挂载/卸载

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>;

动画: 有挂载/卸载动画

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 更远处出现:

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数字 :

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

构成部分表

构成部分入境点说明
Stage.静态设备框架
StageContainer.自动计量容器,通过上下文提供大小
LynxStage./lynxCore Lynx 捆绑渲染器( 无 LUNA 环球)
LunaLynxStage./lynxLynxStage + 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 共发布 6 个版本,首次发布于 2026/05/06;过去 12 个月发布了 6 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.2.2latest2026/05/175 个月前
0.2.12026/05/165 个月前
0.2.02026/05/165 个月前
0.1.12026/05/076 个月前
0.1.02026/05/066 个月前
0.0.0-oidc-bootstrap.0oidc-bootstrap2026/05/066 个月前

关于 @dugyu/luna-stage 的常见问题

@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 和提交记录判断。