月相级
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 | 类型 | 默认 | 说明 |
|---|---|---|---|
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,附件).
用法实例
运动: 无挂载/卸载
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 | ./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 而不是容器的大小.