docs(10-01): clear legacy docs and decouple API sidebar from build

- delete docs/index.md and docs/guide, dev, logger, api trees
- drop old nav entries and guide/logger/api sidebar keys from config.ts
- remove apiSidebar import and listenSidebar() plugin; drop unused Plugin import
- guard generateSidebar() with existsSync when docs/api is absent
This commit is contained in:
unanmed 2026-10-17 17:37:43 +08:00
parent 1099583b07
commit e3d61ee14f
164 changed files with 9 additions and 25109 deletions

View File

@ -1,5 +1,6 @@
import { basename, join, resolve } from 'node:path';
import { DefaultTheme } from 'vitepress';
import { existsSync } from 'node:fs';
import { readdir, stat, writeFile } from 'node:fs/promises';
const apiDir = resolve('./docs/api');
@ -11,6 +12,10 @@ const weight: Record<string, number> = {
};
export async function generateSidebar(): Promise<void> {
if (!existsSync(apiDir)) {
return;
}
const sidebar: DefaultTheme.SidebarItem[] = [
{ text: '目录', link: '/api/' }
];

View File

@ -1,39 +1,6 @@
import { defineConfig, Plugin } from 'vitepress';
import { defineConfig } from 'vitepress';
import { MermaidMarkdown, MermaidPlugin } from 'vitepress-plugin-mermaid';
import api from './apiSidebar';
import { join } from 'path';
import { generateSidebar } from './api';
function listenSidebar(): Plugin {
return {
name: 'sidebar-listen',
configureServer(server) {
server.watcher
.on('add', filePath => {
console.log(`📄 文件新增: ${filePath}`);
generateSidebar();
})
.on('unlink', filePath => {
console.log(`❌ 文件删除: ${filePath}`);
generateSidebar();
})
.on('addDir', dirPath => {
console.log(`📁 目录新增: ${dirPath}`);
generateSidebar();
})
.on('unlinkDir', dirPath => {
console.log(`📁 目录删除: ${dirPath}`);
generateSidebar();
})
.on('raw', (event, path, _) => {
if (event === 'rename') {
console.log(`🔄 文件或文件夹重命名: ${path}`);
generateSidebar();
}
});
}
};
}
// https://vitepress.dev/reference/site-config
export default defineConfig({
@ -50,110 +17,8 @@ export default defineConfig({
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
outline: [2, 3],
nav: [
{ text: '主页', link: '/' },
{ text: '指南', link: '/guide/quick-start' },
{ text: 'API', link: '/api/' },
{ text: '错误代码', link: '/logger/' }
],
sidebar: {
'/guide/': [
{
text: '深度指南',
items: [
{ text: '快速开始', link: '/guide/quick-start' },
{ text: '差异说明', link: '/guide/diff' },
{ text: '系统说明', link: '/guide/system' },
{ text: '代码编写', link: '/guide/coding' },
{ text: '音频系统', link: '/guide/audio' },
{
text: 'UI 系统',
collapsed: false,
items: [
{ text: '快速浏览', link: '/guide/ui/' },
{ text: '编写 UI', link: '/guide/ui/ui' },
{ text: 'UI 元素', link: '/guide/ui/elements' },
{
text: '组件使用指南',
link: '/guide/ui/component'
},
{ text: '优化性能', link: '/guide/ui/perf' },
{ text: 'UI 系统', link: '/guide/ui/system' },
{ text: '常见问题', link: '/guide/ui/faq' },
{ text: '未来规划', link: '/guide/ui/future' }
]
},
{
text: '常见需求指南',
collapsed: false,
items: [
{
text: '快速浏览',
link: '/guide/implements/index'
},
{
text: '怪物特殊属性',
link: '/guide/implements/special'
},
{
text: '修改状态栏',
link: '/guide/implements/status-bar'
},
{
text: '新增 UI',
link: '/guide/implements/new-ui'
},
{
text: '主动技能',
link: '/guide/implements/skill'
},
{
text: '新增按键',
link: '/guide/implements/hotkey'
},
{
text: '动画效果',
link: '/guide/implements/animate'
},
{
text: '选择框与确认框',
link: '/guide/implements/choice'
}
]
}
]
}
],
'/logger/': [
{
text: '错误代码一览',
items: [
{
text: '错误代码',
collapsed: false,
items: [
{ text: '1-50', link: '/logger/error/error1' }
]
},
{
text: '警告代码',
collapsed: false,
items: [
{ text: '1-50', link: '/logger/warn/warn1' },
{ text: '51-100', link: '/logger/warn/warn2' }
]
}
]
}
],
'/api/': [
{
text: 'API 列表',
items: api
}
]
},
nav: [],
sidebar: {},
socialLinks: [
{ icon: 'github', link: 'https://github.com/unanmed/HumanBreak' }
],
@ -189,7 +54,7 @@ export default defineConfig({
},
vite: {
// @ts-expect-error 类型错误
plugins: [MermaidPlugin(), listenSidebar()],
plugins: [MermaidPlugin()],
optimizeDeps: {
include: ['mermaid']
},

View File

@ -1,31 +0,0 @@
---
lang: zh-CN
---
# API 列表
- [@motajs/client](./motajs-client/index.md) 渲染层代码
- [@motajs/client-base](./motajs-client-base/index.md) 渲染层底层代码
- [@motajs/common](./motajs-common/index.md) 渲染层和数据层通用代码
- [@motajs/legacy-client](./motajs-legacy-client/index.md) 遗留渲染层代码
- [@motajs/legacy-common](./motajs-legacy-common/index.md) 遗留通用代码
- [@motajs/legacy-system](./motajs-legacy-system/index.md) 遗留渲染层系统代码
- [@motajs/legacy-ui](./motajs-legacy-ui/index.md) 遗留 UI 相关代码
- [@motajs/render](./motajs-render/index.md) 渲染系统代码
- [@motajs/render-core](./motajs-render-core/index.md) 渲染系统核心代码
- [@motajs/render-elements](./motajs-render-elements/index.md) 渲染系统内置元素代码
- [@motajs/render-style](./motajs-render-style/index.md) 渲染系统样式代码
- [@motajs/render-vue](./motajs-render-vue/index.md) 渲染系统 vue 支持代码
- [@motajs/system](./motajs-system/index.md) 渲染层系统代码
- [@motajs/system-action](./motajs-system-action/index.md) 渲染层交互系统代码
- [@motajs/system-ui](./motajs-system-ui/index.md) 渲染层 UI 系统代码
- [@motajs/types](./motajs-types/index.md) 渲染层类型代码
- [@user/client-modules](./user-client-modules/index.md) 用户渲染层主要代码
- [@user/data-base](./user-data-base/index.md) 用户数据层底层代码
- [@user/data-fallback](./user-data-fallback/index.md) 用户数据层向后兼容代码
- [@user/data-state](./user-data-state/index.md) 用户数据层状态代码
- [@user/data-utils](./user-data-utils/index.md) 用户数据层工具代码
- [@user/entry-client](./user-entry-client/index.md) 用户渲染层入口
- [@user/entry-data](./user-entry-data/index.md) 用户数据层入口
- [@user/legacy-plugin-client](./user-legacy-plugin-client/index.md) 用户遗留渲染层代码
- [@user/legacy-plugin-data](./user-legacy-plugin-data/index.md) 用户遗留数据层代码

View File

@ -1,3 +0,0 @@
# KeyCode
参考 `monaco-editor` 文档 [KeyCode](https://microsoft.github.io/monaco-editor/docs.html#enums/KeyCode.html)

View File

@ -1,5 +0,0 @@
# @motajs/client-base
目录:
- [KeyCode](./KeyCode.md)

View File

@ -1,14 +0,0 @@
# @motajs/client
`@motajs/client` 包含多个模块:
- [`@motajs/client-base`](../motajs-client-base/)
示例:
```ts
import { KeyCode } from '@motajs/client';
// 等价于
const { KeyCode } = Mota.require('@motajs/client');
```

View File

@ -1,212 +0,0 @@
# Logger
本文档由 `DeepSeek R1` 模型生成并微调。
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
| --------- | ------------- | ------ | ---------------------------------------------------------------- |
| `enabled` | `boolean` | `true` | 控制日志输出是否启用。设为 `false` 可临时关闭日志输出。 |
| `level` | `LogLevel` | - | 日志级别,决定输出的最低日志等级(通过构造函数传入,不可修改)。 |
| `info` | `ILoggerInfo` | - | 包含错误和警告信息的配置对象(通过构造函数传入,不可修改)。 |
## 方法说明
### `constructor`
```ts
function constructor(level: LogLevel, info: ILoggerInfo): Logger;
```
#### 描述
构造一个 `Logger` 实例。
#### 参数
- `level`: 日志对象输出等级。
- `info`: 日志内容。
### `error`
```ts
function error(code: number, ...params: string[]): void;
```
#### 描述
记录一个错误信息。
#### 参数
- `code`: 错误代码,对应 `info.error` 中的键值。
- `...params`: 替换错误信息中的占位符(如 $1, $2)的参数。
#### 行为
- 如果未找到对应 `code` 的错误信息,会触发 `error(16)` 表示代码未定义。
- 根据日志级别 `level` 决定是否输出到控制台
### `warn`
```ts
function warn(code: number, ...params: string[]): void;
```
#### 描述
记录一个警告信息。
#### 参数
- `code`: 警告代码,对应 `info.warn` 中的键值。
- `...params`: 替换警告信息中的占位符的参数。
#### 行为
- 如果未找到对应 `code` 的警告信息,会触发 `error(16)`。
- 仅在 `level <= LogLevel.WARNING` 时输出。
### `log`
```ts
function log(text: string): void;
```
#### 描述
记录一条普通日志。
#### 参数
`text`: 日志文本内容。
#### 行为
- 仅在 `level <= LogLevel.LOG` 时输出到控制台。
### `catch`
```ts
function catch<T>(fn: () => T): LoggerCatchReturns<T>;
```
#### 描述
捕获函数执行期间产生的日志信息,并抑制日志输出。
#### 参数
- `fn`: 需要执行的函数。
#### 返回值
- `ret`: 函数 `fn` 的返回值。
- `info`: 捕获的日志信息数组。
#### 行为
- 执行期间会临时禁用日志输出,执行完成后恢复原有状态。
### `disable`
```ts
function disable(): void;
```
#### 描述
禁用日志输出(设置 `enabled = false`)。
### `enable`
```ts
function enable(): void;
```
#### 描述
启用日志输出(设置 `enabled = true`)。
## 接口说明
### `LoggerCatchInfo`
#### 结构
```ts
interface LoggerCatchInfo {
/** 错误/警告代码(仅 error/warn 方法存在) */
code?: number;
/** 日志等级 */
level: LogLevel;
/** 解析后的完整信息 */
message: string;
}
```
### `LoggerCatchReturns<T>`
#### 结构
```ts
interface LoggerCatchReturns<T> {
/** 被捕获函数的返回值 */
ret: T;
/** 捕获的日志信息列表 */
info: LoggerCatchInfo[];
}
```
## 使用示例
- 初始化 Logger
```ts
import { LogLevel, Logger } from './logger';
const logInfo = {
error: {
404: 'Page $1 not found.',
500: 'Internal server error: $1'
},
warn: {
101: 'Deprecated API: $1'
}
};
const logger = new Logger(LogLevel.WARNING, logInfo);
```
- 记录错误
```ts
logger.error(404, 'home');
// 控制台输出: [ERROR Code 404] Page home not found.
```
- 记录警告
```ts
logger.warn(101, '/old-api');
// 控制台输出: [WARNING Code 101] Deprecated API: /old-api
```
- 捕获日志
```ts
const result = logger.catch(() => {
logger.error(500, 'database timeout');
return { success: false };
});
console.log(result.info[0].message); // "Internal server error: database timeout"
```
- 禁用日志
```ts
logger.disable();
logger.log('This will not be printed'); // 无输出
logger.enable();
```

View File

@ -1,24 +0,0 @@
# @motajs/common 函数
## `sleep`
```ts
function sleep(time: number): Promise<void>;
```
#### 描述
创建一个等待指定时长的异步。
#### 参数
- `time`: 等待时长
#### 使用示例
```ts
async function myFunc() {
await sleep(1000);
// 这后面的内容会在 1 秒之后执行
}
```

View File

@ -1,11 +0,0 @@
# @motajs/common
目录:
- [函数](./functions.md)
---
类目录:
- [Logger](./Logger.md)

View File

@ -1,3 +0,0 @@
# @motajs/legacy-client
目录:

View File

@ -1,120 +0,0 @@
# Patch API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
## 类描述
`Patch` 类用于对旧版接口的函数实现进行动态重写,支持按模块类别批量修改目标类的原型方法。需配合 `PatchClass` 枚举指定要修改的模块类型。
---
## 泛型说明
- `T extends PatchClass`: 表示要修改的模块类别(如 `PatchClass.Actions` 对应动作模块)
---
## 属性说明
| 属性名 | 类型 | 描述 |
| ------------ | ---- | ---------------------------- |
| `patchClass` | `T` | 只读,当前补丁关联的模块类别 |
---
## 构造方法
```typescript
function constructor<T extends PatchClass>(patchClass: T): Patch<T>;
```
- **参数**
- `patchClass`: 指定要修改的模块类别(从 `PatchClass` 枚举中选择)
**示例**
```typescript
// 创建针对控制模块的补丁
const patch = new Patch(PatchClass.Control);
```
---
## 方法说明
### `add`
```typescript
function add<K extends keyof PatchList[T]>(
key: K,
patch: PatchList[T][K]
): void;
```
为目标模块添加函数补丁。
- **参数**
- `key`: 要修改的函数名(需为目标模块原型存在的函数)
- `patch`: 新的函数实现
**示例**
```typescript
// 重写控制模块的 setFlag 方法
control.add('setFlag', function (this: Control, key, value) {
console.log('执行重写后的 setFlag 代码');
if (typeof value === 'number') {
// 数字额外增加 100 点
core.status.hero.flags[key] = value + 100;
} else {
core.status.hero.flags[key] = value;
}
});
```
---
### `Patch.patchAll`
```typescript
function patchAll(): void;
```
**静态方法**:应用所有未执行的补丁修改。一般不需要自己调用,游戏启动阶段已经包含了此方法的调用。
---
### `Patch.patch`
```typescript
function patch(patch: Patch<PatchClass>): void;
```
**静态方法**:立即应用指定补丁实例的修改。一般不需要自己调用,游戏启动阶段已经包含了此方法的调用。
- **参数**
- `patch`: 要应用的补丁实例
---
## 总使用示例
```typescript
import { Patch, PatchClass } from '@motajs/legacy-common';
// 新建函数,这个操作是必要的,我们不能直接在顶层使用这个接口
export function patchMyFunctions() {
// 创建 Patch 实例,参数表示这个 Patch 示例要重写哪个文件中的函数
// 如果需要复写两个文件,那么就需要创建两个实例
const patch = new Patch(PatchClass.Control);
// 使用 add 函数来重写,第一个参数会有自动补全
// 如果要重写的函数以下划线开头,可能会有报错
// 这时候需要去 types/declaration 中对应的文件中添加声明
patch.add('getFlag', (name, defaultValue) => {
// 重写 getFlag,如果变量是数字,那么 +100 后返回
const value = core.status?.hero?.flags[name] ?? defaultValue;
return typeof value === 'number' ? value + 100 : value;
});
}
```

View File

@ -1,3 +0,0 @@
# @motajs/legacy-common
目录:

View File

@ -1,3 +0,0 @@
# @motajs/legacy-system
目录:

View File

@ -1,3 +0,0 @@
# @motajs/legacy-ui
目录:

View File

@ -1,121 +0,0 @@
# Container 类 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 继承关系
```mermaid
graph LR
Container --> RenderItem --> EventEmitter
click RenderItem "./RenderItem"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
| ---------------- | -------------- | ------ | ------------------------------ |
| `sortedChildren` | `RenderItem[]` | `[]` | 按 `zIndex` 排序后的子元素列表 |
---
## 构造方法
### `constructor`
**参数**
- `type`: 渲染模式(`absolute` 绝对定位 / `static` 跟随摄像机)
- `cache`: 是否启用渲染缓存
- `fall`: 是否启用变换矩阵下穿机制
**示例**
```typescript
const container = new Container('static');
```
---
## 方法说明
### `appendChild`
```typescript
function appendChild(...children: RenderItem[]): void;
```
**描述**
添加子元素并触发重新排序。
**示例**
```typescript
const child = new RenderItem('static');
container.appendChild(child); // 添加子元素
```
---
### `removeChild`
```typescript
function removeChild(...child: RenderItem[]): void;
```
**描述**
移除指定子元素并触发重新排序。
**示例**
```typescript
container.removeChild(child); // 移除子元素
```
---
### `requestSort`
```typescript
function requestSort(): void;
```
**描述**
标记需要重新排序子元素(在下一帧前自动执行)。
---
### `forEachChild`
```typescript
function forEachChild(fn: (ele: RenderItem) => void): void;
```
**描述**
遍历元素的每一个子元素(DFS 遍历),并对每一个元素执行函数。
---
## 总使用示例
```typescript
// 创建基础容器
const baseContainer = new Container('absolute');
baseContainer.size(800, 600);
// 添加子元素
const sprite1 = new Sprite('static');
sprite1.pos(100, 100).setZIndex(2);
baseContainer.appendChild(sprite1);
const sprite2 = new Sprite('static');
sprite2.pos(200, 200).setZIndex(1);
baseContainer.appendChild(sprite2);
// 将容器添加到根元素
rootElement.appendChild(baseContainer);
// 动态修改子元素层级
sprite1.setZIndex(0); // 自动触发重新排序
```

View File

@ -1,71 +0,0 @@
# ContainerCustom 类 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 继承关系
```mermaid
graph LR
ContainerCustom --> Container --> RenderItem --> EventEmitter
click Container "./Container"
click RenderItem "./RenderItem"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
| ---------- | ------------------------- | ----------- | ---------------------- |
| `renderFn` | `CustomContainerRenderFn` | `undefined` | 自定义渲染函数(可选) |
---
## 构造方法
继承自 `Container`,参数与父类一致。
---
## 方法说明
### `setRenderFn`
```typescript
function setRenderFn(render?: CustomContainerRenderFn): void;
```
**描述**
设置自定义渲染函数,覆盖默认的子元素渲染逻辑。
**参数**
- `render`: 接收画布、子元素列表和变换矩阵的回调函数
**示例**
```typescript
customContainer.setRenderFn((canvas, children, transform) => {
children.forEach(child => {
child.renderContent(canvas, transform);
});
});
```
---
## 总使用示例
```ts
// 创建自定义容器
const customContainer = new ContainerCustom('static');
customContainer.setRenderFn((canvas, children) => {
// 倒序渲染子元素
children.reverse().forEach(child => {
child.renderContent(canvas, Transform.identity);
});
});
```

View File

@ -1,201 +0,0 @@
# Event 模块 API 文档
以下内容由 `DeepSeek R1` 模型生成并微调。
---
## 枚举说明
### MouseType
| 值 | 说明 |
| --------- | ---------------- |
| `None` | 没有按键按下 |
| `Left` | 左键 |
| `Middle` | 中键(按下滚轮) |
| `Right` | 右键 |
| `Back` | 侧键后退 |
| `Forward` | 侧键前进 |
### WheelType
| 值 | 说明 |
| ------- | -------------------------- |
| `None` | 无单位 |
| `Pixel` | 以像素为单位 |
| `Line` | 以行为单位(约 1rem) |
| `Page` | 以页为单位(一个屏幕高度) |
### ActionType
| 值 | 说明 |
| ------- | -------------------------------- |
| `Click` | 点击事件(按下与抬起在同一元素) |
| `Down` | 鼠标或手指按下事件 |
| `Move` | 鼠标或手指移动事件 |
| `Up` | 鼠标或手指抬起事件 |
| `Enter` | 进入元素时触发 |
| `Leave` | 离开元素时触发 |
| `Wheel` | 滚轮事件 |
### EventProgress
| 值 | 说明 |
| --------- | -------- |
| `Capture` | 捕获阶段 |
| `Bubble` | 冒泡阶段 |
---
## 接口说明
### IActionEventBase
| 属性名 | 类型 | 说明 |
| ---------- | ------------ | ----------------------------------------------------------------- |
| `target` | `RenderItem` | 触发事件的元素 |
| `touch` | `boolean` | 是否为触摸操作(`true` 表示触摸,`false` 表示鼠标) |
| `type` | `MouseType` | 触发事件的按键类型(参考 `MouseType`) |
| `buttons` | `number` | 当前按下的按键(通过位运算判断,例如 `buttons & MouseType.Left`) |
| `altKey` | `boolean` | 是否按下 `Alt` 键 |
| `shiftKey` | `boolean` | 是否按下 `Shift` 键 |
| `ctrlKey` | `boolean` | 是否按下 `Ctrl` 键 |
| `metaKey` | `boolean` | 是否按下 `Windows/Command` 键 |
---
### IActionEvent
#### 继承关系
```mermaid
graph LR
IActionEvent --> IActionEventBase
```
| 属性名 | 类型 | 说明 |
| ------------ | -------- | -------------------------------------------- |
| `identifier` | `number` | 操作的唯一标识符(在按下、移动、抬起中一致) |
| `offsetX` | `number` | 相对于元素左上角的横坐标 |
| `offsetY` | `number` | 相对于元素左上角的纵坐标 |
| `absoluteX` | `number` | 相对于整个画布左上角的横坐标 |
| `absoluteY` | `number` | 相对于整个画布左上角的纵坐标 |
#### 方法说明
##### `stopPropagation`
```typescript
function stopPropagation(): void;
```
**描述**
停止事件的传播(捕获或冒泡阶段)。
**示例**
```typescript
item.on('click', ev => {
ev.stopPropagation(); // 阻止事件继续传播
});
```
---
### IWheelEvent
```mermaid
graph LR
IWheelEvent --> IActionEvent --> IActionEventBase
```
| 属性名 | 类型 | 说明 |
| ----------- | ----------- | -------------------- |
| `wheelX` | `number` | 横向滚动量 |
| `wheelY` | `number` | 纵向滚动量 |
| `wheelZ` | `number` | 垂直屏幕方向的滚动量 |
| `wheelType` | `WheelType` | 滚动量的单位类型 |
---
### ERenderItemActionEvent
描述了所有的交互事件类型。
| 事件名 | 参数类型 | 说明 |
| -------------- | ---------------------------- | ------------------ |
| `clickCapture` | `Readonly<IActionEvent>` | 点击事件的捕获阶段 |
| `click` | `Readonly<IActionEvent>` | 点击事件的冒泡阶段 |
| `downCapture` | `Readonly<IActionEvent>` | 按下事件的捕获阶段 |
| `down` | `Readonly<IActionEvent>` | 按下事件的冒泡阶段 |
| `moveCapture` | `Readonly<IActionEvent>` | 移动事件的捕获阶段 |
| `move` | `Readonly<IActionEvent>` | 移动事件的冒泡阶段 |
| `upCapture` | `Readonly<IActionEvent>` | 抬起事件的捕获阶段 |
| `up` | `Readonly<IActionEvent>` | 抬起事件的冒泡阶段 |
| `enter` | `Readonly<IActionEventBase>` | 进入元素事件 |
| `leave` | `Readonly<IActionEventBase>` | 离开元素事件 |
| `wheelCapture` | `Readonly<IWheelEvent>` | 滚轮事件的捕获阶段 |
| `wheel` | `Readonly<IWheelEvent>` | 滚轮事件的冒泡阶段 |
---
### ActionEventMap
| 键(ActionType) | 值类型 | 说明 |
| ---------------- | -------------- | ------------ |
| `Click` | `IActionEvent` | 点击事件 |
| `Down` | `IActionEvent` | 按下事件 |
| `Enter` | `IActionEvent` | 进入元素事件 |
| `Leave` | `IActionEvent` | 离开元素事件 |
| `Move` | `IActionEvent` | 移动事件 |
| `Up` | `IActionEvent` | 抬起事件 |
| `Wheel` | `IWheelEvent` | 滚轮事件 |
---
## 总使用示例
::: code-group
```typescript
// 创建渲染元素(以 Sprite 为例)
const item = new Sprite();
// 监听点击事件(冒泡阶段)
item.on('click', ev => {
console.log('点击坐标:', ev.offsetX, ev.offsetY);
ev.stopPropagation(); // 阻止冒泡
});
// 监听滚轮事件(捕获阶段)
item.on('wheelCapture', ev => {
console.log('滚轮滚动量:', ev.wheelY, '单位:', WheelType[ev.wheelType]);
});
// 监听进入元素事件
item.on('enter', ev => {
console.log('进入元素,触发按键:', MouseType[ev.type]);
});
```
```tsx
// 监听点击事件(冒泡阶段)
const click = (ev: IActionEvent) => {
console.log('点击坐标:', ev.offsetX, ev.offsetY);
ev.stopPropagation(); // 阻止冒泡
};
// 监听滚轮事件(捕获阶段)
const wheel = (ev: IWheelEvent) => {
console.log('滚轮滚动量:', ev.wheelY, '单位:', WheelType[ev.wheelType]);
};
// 监听进入元素事件
const enter = (ev: IActionEventBase) => {
console.log('进入元素,触发按键:', MouseType[ev.type]);
};
<sprite onClick={click} onWheelCapture={wheel} onEnter={enter} />;
```
:::

View File

@ -1,151 +0,0 @@
# GL2 类 API 文档
**需丰富**
本文档由 `DeepSeek R1` 模型生成并微调。
## 继承关系
```mermaid
graph LR
GL2 --> RenderItem --> EventEmitter
click RenderItem "./RenderItem"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
| ------------------------------- | ------------------------ | ------------------ | --------------------------------------------- |
| `support` | `boolean`(静态) | 检测 WebGL2 支持性 | 标识当前环境是否支持 WebGL2 |
| `canvas` | `HTMLCanvasElement` | - | 绑定的 WebGL2 画布元素 |
| `gl` | `WebGL2RenderingContext` | - | WebGL2 渲染上下文 |
| `UNIFORM_1f` ~ `UNIFORM_4uiv` | `UniformType` 枚举 | 对应枚举值 | WebGL uniform 类型常量(共 25 种) |
| `U_MATRIX_2x2` ~ `U_MATRIX_4x4` | `UniformMatrix` 枚举 | 对应枚举值 | 矩阵类型 uniform 常量(9 种) |
| `ATTRIB_1f` ~ `ATTRIB_I4uiv` | `AttribType` 枚举 | 对应枚举值 | 顶点属性类型常量(12 种) |
| `MAX_TEXTURE_COUNT` | `number` | `0` | 最大纹理支持数量(实际值由 WebGL 上下文决定) |
---
## 构造方法
### `constructor`
**参数**
- `type`: 渲染模式(`absolute` 绝对定位 / `static` 跟随摄像机)
**行为**
- 初始化 WebGL2 上下文
- 自动检测 WebGL2 支持性(通过静态属性 `support`)
- 设置默认渲染模式
---
## 方法说明
### `createProgram`
```typescript
function createProgram<T extends GL2Program>(
Program: ProgramConstructor<T>,
vs?: string,
fs?: string
): T;
```
**描述**
创建 WebGL 着色器程序
**参数**
- `Program`: 着色器程序类(需继承 `GL2Program`)
- `vs`: 自定义顶点着色器代码(可选)
- `fs`: 自定义片元着色器代码(可选)
**示例**
```typescript
class MyProgram extends GL2Program {}
const program = gl2.createProgram(MyProgram);
```
---
### `useProgram`
```typescript
function useProgram(program: GL2Program): void;
```
**描述**
切换当前使用的着色器程序
**示例**
```typescript
gl2.useProgram(shaderProgram);
```
---
### `framebuffer`
```typescript
function framebuffer(
name: string,
texture: IShaderTexture2D,
clear?: boolean
): void;
```
**描述**
将渲染结果输出到帧缓冲纹理
**参数**
- `name`: 帧缓冲名称
- `texture`: 目标纹理对象
- `clear`: 是否清空画布
---
### `drawScene`(抽象方法)
```typescript
function drawScene(
canvas: MotaOffscreenCanvas2D,
gl: WebGL2RenderingContext,
program: GL2Program,
transform: Transform
): void;
```
**描述**
抽象渲染方法,子类必须实现具体绘制逻辑
---
## 静态方法说明
### `GL2.support`
```typescript
static readonly support: boolean;
```
**描述**
静态只读属性,检测 WebGL2 支持性
**示例**
```typescript
if (GL2.support) {
// 初始化 WebGL2 功能
}
```
---
## 总使用示例
暂时没有。

View File

@ -1,188 +0,0 @@
# GL2Program 类 API 文档
**需丰富**
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 继承关系
```mermaid
graph LR
GL2Program --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---
## 属性说明
| 属性名 | 类型 | 说明 |
| -------------- | ------------------------ | ------------------------------------------ |
| `gl` | `WebGL2RenderingContext` | WebGL2 渲染上下文 |
| `element` | `GL2` | 关联的 GL2 渲染元素 |
| `program` | `WebGLProgram \| null` | WebGL 着色器程序对象 |
| `renderMode` | `RenderMode` | 当前渲染模式(默认 `RenderMode.Elements`) |
| `usingIndices` | `IShaderIndices \| null` | 当前使用的顶点索引数组 |
---
## 方法说明
### `defineUniform`
```typescript
function defineUniform<T extends UniformType>(
uniform: string,
type: T
): IShaderUniform<T> | null;
```
**描述**
定义 Uniform 变量
**参数**
- `uniform`: Uniform 变量名
- `type`: Uniform 类型(如 `GL2.UNIFORM_2f`)
**返回值**
- 操作对象(可设置值)或 `null`(定义失败)
---
### `defineTexture`
```typescript
function defineTexture(
name: string,
index: number,
w?: number,
h?: number
): IShaderTexture2D | null;
```
**描述**
定义纹理对象
**参数**
- `name`: 纹理名称
- `index`: 纹理索引(建议不超过 8)
- `w`: 纹理宽度(可选)
- `h`: 纹理高度(可选)
**示例**
```typescript
const tex = program.defineTexture('diffuse', 0, 512, 512);
```
---
### `paramElements`
```typescript
function paramElements(
mode: GLenum,
count: number,
type: GLenum,
offset: number
): void;
```
**描述**
设置元素模式渲染参数
**参数**
- `mode`: 渲染模式(如 `gl.TRIANGLES`)
- `count`: 元素数量
- `type`: 数据类型(如 `gl.UNSIGNED_SHORT`)
- `offset`: 数据偏移量
---
### `requestCompile`
```typescript
function requestCompile(force?: boolean): boolean;
```
**描述**
请求编译着色器
**参数**
- `force`: 是否强制重新编译
**返回值**
- `true` 表示编译成功
---
### `vs`
```typescript
function vs(vs: string): void;
```
**描述**
设置顶点着色器代码
**示例**
```typescript
program.vs(`
${GL2_PREFIX.VERTEX}
in vec4 aPosition;
void main() {
gl_Position = aPosition;
}
`);
```
---
## 事件说明
| 事件名 | 触发时机 | 参数类型 |
| -------- | ---------------- | -------- |
| `load` | 程序被加载使用时 | `[]` |
| `unload` | 程序被卸载时 | `[]` |
---
## 总使用示例
```typescript
// 创建着色器程序
const program = gl2.createProgram(GL2Program);
// 定义着色器
program.vs(`
${GL2_PREFIX.VERTEX}
uniform mat4 uProjection;
in vec4 aPosition;
void main() {
gl_Position = uProjection * aPosition;
}
`);
program.fs(`
${GL2_PREFIX.FRAGMENT}
out vec4 fragColor;
uniform vec3 uColor;
void main() {
fragColor = vec4(uColor, 1.0);
}
`);
// 定义 Uniform 和纹理
const colorUniform = program.defineUniform('uColor', UniformType.Uniform3f);
const diffuseTex = program.defineTexture('diffuse', 0, 512, 512);
// 设置渲染参数
program.paramElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
// 编译并应用
if (program.requestCompile()) {
gl2.useProgram(program);
colorUniform?.set(1.0, 0.5, 0.2);
diffuseTex?.set(imageElement);
}
```

View File

@ -1,311 +0,0 @@
# MotaOffscreenCanvas2D 类 API 文档
以下内容由 `DeepSeek R1` 模型生成并微调。
---
## 继承关系
```mermaid
graph LR
MotaOffscreenCanvas2D --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
| ---------------- | -------------------------- | -------- | ------------------------------------------- |
| `canvas` | `HTMLCanvasElement` | - | 关联的 HTML 画布元素 |
| `ctx` | `CanvasRenderingContext2D` | - | 画布的 2D 渲染上下文 |
| `width` | `number` | 自动计算 | 画布的逻辑宽度(不包含缩放比例) |
| `height` | `number` | 自动计算 | 画布的逻辑高度(不包含缩放比例) |
| `autoScale` | `boolean` | `false` | 是否自动跟随 `core.domStyle.scale` 进行缩放 |
| `highResolution` | `boolean` | `true` | 是否启用高清画布(根据设备像素比例缩放) |
| `antiAliasing` | `boolean` | `true` | 是否启用抗锯齿 |
| `scale` | `number` | `1` | 当前画布的缩放比例 |
| `symbol` | `number` | `0` | 更新标识符,值变化表示画布被被动清空或调整 |
| `freezed` | `boolean`(只读) | `false` | 当前画布是否被冻结(冻结后不可修改属性) |
| `active` | `boolean`(只读) | `true` | 当前画布是否处于激活状态 |
---
## 构造方法
### `constructor`
```ts
function constructor(
alpha: boolean = true,
canvas?: HTMLCanvasElement
): MotaOffscreenCanvas2D;
```
**描述**
创建一个新的离屏画布。
**参数**
- `alpha`: 是否启用透明度通道(默认为 `true`)。
- `canvas`: 可指定现有画布,未提供时自动创建新画布。
**注意**
- 在自定义渲染元素中,建议使用 `RenderItem.requireCanvas` 而非直接调用此构造函数。之后如果不使用,再使用 `RenderItem.deleteCanvas` 删除。
---
## 方法说明
### `size`
```ts
function size(width: number, height: number): void;
```
**描述**
设置画布的尺寸。
**参数**
- `width`: 逻辑宽度(最小为 1)。
- `height`: 逻辑高度(最小为 1)。
**行为**
- 自动计算缩放比例(考虑 `highResolution` 和 `autoScale`)。
- 调整画布物理尺寸和样式尺寸。
**示例**
```typescript
const canvas = new MotaOffscreenCanvas2D();
canvas.size(800, 600); // 设置画布尺寸为 800x600(逻辑尺寸)
```
---
### `withGameScale`
```ts
function withGameScale(auto: boolean): void;
```
**描述**
设置画布是否跟随 `core.domStyle.scale` 自动缩放。
**参数**
- `auto`: 是否启用自动缩放。
**示例**
```typescript
canvas.withGameScale(true); // 启用自动缩放
```
---
### `setHD`
```ts
function setHD(hd: boolean): void;
```
**描述**
设置是否为高清画布(基于设备像素比例)。
**参数**
- `hd`: 是否启用高清模式。
**示例**
```typescript
canvas.setHD(false); // 关闭高清模式
```
---
### `setAntiAliasing`
```ts
function setAntiAliasing(anti: boolean): void;
```
**描述**
设置抗锯齿功能。
**参数**
- `anti`: 是否启用抗锯齿。
**示例**
```typescript
canvas.setAntiAliasing(false); // 关闭抗锯齿
```
---
### `clear`
```ts
function clear(): void;
```
**描述**
清空画布内容。
**注意**
- 冻结状态下调用此方法会触发警告。
**示例**
```typescript
canvas.clear(); // 清空画布
```
---
### `delete`
```ts
function delete(): void
```
**描述**
删除画布,释放资源并解除 DOM 绑定。
**示例**
```typescript
canvas.delete(); // 删除画布
```
---
### `freeze`
```ts
function freeze(): void;
```
**描述**
冻结画布,禁止修改属性,并从全局列表中移除。
**示例**
```typescript
canvas.freeze(); // 冻结画布
```
---
### `activate`
```ts
function activate(): void;
```
**描述**
激活画布,使其跟随游戏缩放调整尺寸。
**示例**
```typescript
canvas.activate(); // 激活画布
```
---
### `deactivate`
```ts
function deactivate(): void;
```
**描述**
停用画布,不再自动调整尺寸,可能被垃圾回收。
**示例**
```typescript
canvas.deactivate(); // 停用画布
```
---
## 静态方法说明
### `MotaOffscreenCanvas2D.clone`
```ts
function clone(canvas: MotaOffscreenCanvas2D): MotaOffscreenCanvas2D;
```
**描述**
复制一个画布对象,结果画布将被冻结。
**返回值**
- 复制的画布对象(不可修改属性,但可绘制)。
**示例**
```typescript
const cloned = MotaOffscreenCanvas2D.clone(sourceCanvas); // 复制画布
```
---
### `MotaOffscreenCanvas2D.refreshAll`
```ts
function refreshAll(force: boolean = false): void;
```
**描述**
刷新所有已注册画布的尺寸(仅在窗口大小变化时自动调用)。
**参数**
- `force`: 是否强制刷新所有画布(默认仅刷新启用 `autoScale` 的画布)。
---
## 事件类型
### `resize`
**触发时机**
当画布被动调整尺寸时触发(例如窗口大小变化或 `core.domStyle.scale` 变化)。
**监听示例**
```typescript
canvas.on('resize', () => {
console.log('画布尺寸已调整');
});
```
---
## 使用示例
```typescript
// 创建画布
const canvas = new MotaOffscreenCanvas2D();
// 配置属性
canvas.size(800, 600);
canvas.withGameScale(true);
canvas.setHD(true);
// 监听调整事件
canvas.on('resize', () => {
console.log('画布尺寸已更新');
});
// 绘制内容
canvas.ctx.fillStyle = 'red';
canvas.ctx.fillRect(0, 0, canvas.width, canvas.height);
// 冻结画布
canvas.freeze();
// 复制画布
const cloned = MotaOffscreenCanvas2D.clone(canvas);
```

View File

@ -1,174 +0,0 @@
# MotaRenderer 类 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 继承关系
```mermaid
graph LR
MotaRenderer --> Container --> RenderItem --> EventEmitter
click Container "./Container"
click RenderItem "./RenderItem"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
| -------- | ------------------------- | ----------- | ------------------------------- |
| `isRoot` | `boolean` | `true` | 标识为渲染树根节点 |
| `target` | `MotaOffscreenCanvas2D` | - | 绑定的目标画布 |
| `idMap` | `Map<string, RenderItem>` | `new Map()` | ID 到渲染元素的映射表(受保护) |
---
## 构造方法
### `constructor`
**参数**
- `id`: 目标 canvas 元素的 DOM ID(默认为 `render-main`)
**行为**
- 自动绑定指定 ID 的 canvas 元素
- 初始化渲染循环和事件监听
- 设置默认锚点为中心点(0.5, 0.5)
**示例**
```typescript
// 创建主渲染器
const renderer = new MotaRenderer();
// 创建带自定义 ID 的渲染器
const customRenderer = new MotaRenderer('game-canvas');
```
---
## 方法说明
### `getElementById`
```typescript
function getElementById(id: string): RenderItem | null;
```
**描述**
通过 ID 获取渲染树中的元素。
**示例**
```typescript
const hero = renderer.getElementById('player');
```
---
### `refresh`
```typescript
function refresh(): void;
```
**描述**
强制刷新渲染内容(清空画布并重新渲染所有元素)。
---
### `toTagTree`
```typescript
function toTagTree(space?: number): string;
```
**描述**
(调试用)将渲染树输出为 XML 格式字符串。
**参数**
- `space`: 缩进空格数
**示例**
```typescript
console.log(renderer.toTagTree());
/* 输出示例:
<MotaRenderer id="render-main" uid="0">
<Container uid="1">
<Sprite id="cloud" uid="2" />
</Container>
</MotaRenderer>
*/
```
---
### `destroy`
```typescript
function destroy(): void;
```
**描述**
销毁渲染器,释放所有资源并解除事件监听。
---
## 静态方法说明
### `MotaRenderer.get`
```typescript
function get(id: string): MotaRenderer | undefined;
```
**描述**
通过 ID 获取已注册的渲染器实例。
**示例**
```typescript
const mainRenderer = MotaRenderer.get('render-main');
```
---
## 总使用示例
```typescript
// 初始化渲染器
const renderer = new MotaRenderer();
// 创建游戏元素
const player = new Sprite();
player.size(32, 32);
player.setRenderFn(canvas => {
canvas.ctx.fillStyle = 'blue';
canvas.ctx.fillRect(0, 0, 32, 32);
});
// 添加交互逻辑
player.on('click', ev => {
console.log('玩家被点击', ev.offsetX, ev.offsetY);
});
// 构建场景
const scene = new Container('absolute');
scene.appendChild(player);
renderer.appendChild(scene);
// 动态查找元素
setTimeout(() => {
const found = renderer.getElementById('player');
found?.pos(100, 100);
}, 1000);
// 销毁渲染器(退出时调用)
window.addEventListener('beforeunload', () => {
renderer.destroy();
});
```

View File

@ -1,230 +0,0 @@
# RenderAdapter API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
RenderAdapter --> 无继承关系
```
_RenderAdapter 为独立类,无父类或子类。_
---
## 属性说明
| 属性名 | 类型 | 描述 |
| ------------------ | --------------------------------- | ------------------------------ |
| `items` | `Set<T>` | 所有元素的集合 |
| `id` | `string` | 适配器的唯一标识符 |
| `adapters`(静态) | `Map<string, RenderAdapter<any>>` | 全局存储所有已创建的适配器实例 |
---
## 构造方法
### `constructor`
```typescript
function constructor(id: string): RenderAdapter<T>;
```
创建一个适配器实例并自动注册到全局 `adapters` 集合中。
**示例:**
```typescript
const adapter = new RenderAdapter<HTMLElement>('ui-elements');
```
---
## 方法说明
### `add`
```typescript
function add(item: T): void;
```
向集合中添加一个元素。
**示例:**
```typescript
adapter.add(document.getElementById('box'));
```
### `remove`
```typescript
function remove(item: T): void;
```
从集合中移除一个元素。
**示例:**
```typescript
adapter.remove(document.getElementById('box'));
```
### `receiveGlobal`
```typescript
function receiveGlobal(
id: string,
fn: (...params: any[]) => Promise<any>
): void;
```
注册全局异步函数(不与具体元素绑定)。
**示例:**
```typescript
adapter.receiveGlobal('refresh', async () => {
await fetchData();
});
```
### `receive`
```typescript
function receive(
id: string,
fn: (item: T, ...params: any[]) => Promise<any>
): void;
```
注册元素的异步执行函数。
**示例:**
```typescript
adapter.receive('fadeOut', async (element: HTMLElement) => {
element.style.opacity = '0';
await new Promise(resolve => setTimeout(resolve, 1000));
});
```
### `receiveSync`
```typescript
function receiveSync(id: string, fn: (item: T, ...params: any[]) => any): void;
```
注册元素的同步执行函数。
**示例:**
```typescript
adapter.receiveSync('highlight', (element: HTMLElement) => {
element.style.backgroundColor = 'yellow';
});
```
### `all`
```typescript
function all<R = any>(fn: string, ...params: any[]): Promise<R[]>;
```
对所有元素执行异步函数,返回 `Promise.all` 结果。
**示例:**
```typescript
await adapter.all('fadeOut'); // 所有元素淡出
```
### `any`
```typescript
function any<R = any>(fn: string, ...params: any[]): Promise<R>;
```
对所有元素执行异步函数,返回 `Promise.any` 结果。
**示例:**
```typescript
await adapter.any('loadImage'); // 任一图片加载完成即继续
```
### `sync`
```typescript
function sync<R = any>(fn: string, ...params: any[]): R[];
```
对所有元素执行同步函数。
**示例:**
```typescript
adapter.sync('highlight'); // 所有元素高亮
```
### `global`
```typescript
function global<R = any>(id: string, ...params: any[]): Promise<R>;
```
调用全局异步函数。
**示例:**
```typescript
await adapter.global('refresh'); // 触发全局刷新
```
### `destroy`
```typescript
function destroy(): void;
```
销毁适配器实例并从全局 `adapters` 中移除。
**示例:**
```typescript
adapter.destroy();
```
---
## 静态方法说明
### `RenderAdapter.get`
```typescript
function get<T>(id: string): RenderAdapter<T> | undefined;
```
通过 ID 获取已注册的适配器实例。
**示例:**
```typescript
const adapter = RenderAdapter.get<HTMLElement>('ui-elements');
```
---
## 总使用示例
```typescript
// 创建适配器
const animationAdapter = new RenderAdapter<HTMLElement>('animations');
// 注册动画函数
animationAdapter.receive('slideLeft', async (element: HTMLElement) => {
element.style.transform = 'translateX(-100px)';
await new Promise(resolve => setTimeout(resolve, 500));
});
// 添加元素
const box = document.getElementById('box');
animationAdapter.add(box);
// 执行动画
animationAdapter.all('slideLeft').then(() => {
console.log('所有元素滑动完成');
});
// 销毁适配器
animationAdapter.destroy();
```

View File

@ -1,477 +0,0 @@
# RenderItem 类 API 文档
**需丰富**
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 继承关系
```mermaid
graph LR
RenderItem --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---
## 接口说明
### IRenderUpdater
```typescript
interface IRenderUpdater {
update(item?: RenderItem): void;
}
```
**描述**
定义元素更新能力的接口。`RenderItem` 通过 `update` 方法通知父元素需要重新渲染。
---
### IRenderAnchor
```typescript
interface IRenderAnchor {
anchorX: number;
anchorY: number;
setAnchor(x: number, y: number): void;
}
```
**描述**
管理元素锚点的接口。锚点用于定位元素的渲染基准点(如中心点、左上角等)。
---
### IRenderConfig
```typescript
interface IRenderConfig {
highResolution: boolean;
antiAliasing: boolean;
setHD(hd: boolean): void;
setAntiAliasing(anti: boolean): void;
}
```
**描述**
管理画布渲染配置的接口,控制高清模式和抗锯齿的开关。
---
### IRenderChildable
```typescript
interface IRenderChildable {
children: Set<RenderItem>;
appendChild(...child: RenderItem[]): void;
removeChild(...child: RenderItem[]): void;
requestSort(): void;
}
```
**描述**
管理子元素的接口。需在子类中实现具体逻辑(如 `Container` 元素)。
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
| ---------------- | -------------------------- | --------------- | ---------------------------------------------------- |
| `uid` | `number` | 自动递增 | 元素的唯一标识符 |
| `id` | `string` | `''` | 元素 ID(原则不可重复) |
| `zIndex` | `number` | `0` | 元素的纵深层级(决定遮挡关系) |
| `width` | `number` | `200` | 元素的逻辑宽度 |
| `height` | `number` | `200` | 元素的逻辑高度 |
| `anchorX` | `number` | `0` | 锚点横坐标(`0` 左端,`1` 右端) |
| `anchorY` | `number` | `0` | 锚点纵坐标(`0` 上端,`1` 下端) |
| `type` | `RenderItemPosition` | `'static'` | 渲染模式(`absolute` 绝对定位,`static` 跟随摄像机) |
| `highResolution` | `boolean` | `true` | 是否启用高清画布 |
| `antiAliasing` | `boolean` | `true` | 是否启用抗锯齿 |
| `hidden` | `boolean` | `false` | 元素是否隐藏 |
| `filter` | `string` | `'none'` | 元素的滤镜效果 |
| `composite` | `GlobalCompositeOperation` | `'source-over'` | 渲染混合模式 |
| `alpha` | `number` | `1` | 元素的不透明度(`0` 透明,`1` 不透明) |
| `cursor` | `string` | `'inherit'` | 鼠标悬停时的光标样式 |
| `noEvent` | `boolean` | `false` | 是否忽略交互事件 |
| `isRoot` | `boolean` | `false` | 是否为根元素(需实现 `IRenderTreeRoot` 接口) |
| `connected` | `boolean` | 自动计算 | 元素是否已连接到根元素 |
**特殊属性说明**
- `transform`: 元素的变换矩阵(`Transform` 实例),修改时会自动触发 `updateTransform`。
---
## 构造方法
### `constructor(type: RenderItemPosition, enableCache: boolean = true, transformFallThrough: boolean = false)`
**参数**
- `type`: 渲染模式(`absolute` 或 `static`)
- `enableCache`: 是否启用渲染缓存(默认启用)
- `transformFallThrough`: 是否启用变换矩阵下穿机制(默认关闭)
**示例**
```typescript
const item = new RenderItem('absolute');
```
---
## 方法说明
### `size`
```typescript
function size(width: number, height: number): void;
```
**描述**
设置元素的尺寸。
**示例**
```typescript
item.size(300, 200); // 设置宽度 300,高度 200
```
---
### `pos`
```typescript
function pos(x: number, y: number): void;
```
**描述**
设置元素的坐标(等效于修改 `transform` 的平移量)。
**示例**
```typescript
item.pos(100, 50); // 设置坐标为 (100, 50)
```
---
### `append`
```typescript
function append(parent: RenderItem): void;
```
**描述**
将元素添加到指定父元素下。
**示例**
```typescript
const parent = new RenderItem('static');
item.append(parent); // 将 item 添加为 parent 的子元素
```
---
### `remove`
```typescript
function remove(): boolean;
```
**描述**
从父元素中移除当前元素。
**返回值**
- `true` 表示移除成功,`false` 表示失败。
**示例**
```typescript
item.remove(); // 从父元素中移除
```
---
### `hide`
```typescript
function hide(): void;
```
**描述**
隐藏元素。
**示例**
```typescript
item.hide(); // 隐藏元素
```
---
### `show`
```typescript
function show(): void;
```
**描述**
显示元素。
**示例**
```typescript
item.show(); // 显示元素
```
---
### `delegateTicker`
```typescript
function delegateTicker(fn: TickerFn, time?: number, end?: () => void): number;
```
**描述**
委托动画帧函数,持续执行指定时间。
**返回值**
- 委托 ID,可用于移除。
**示例**
```typescript
const id = item.delegateTicker(() => {
console.log('每帧执行');
}, 1000); // 持续 1 秒
```
---
### `destroy`
```typescript
function destroy(): void;
```
**描述**
销毁元素,释放资源。
**示例**
```typescript
item.destroy(); // 销毁元素
```
### `getAbsolutePosition`
```typescript
function getAbsolutePosition(x?: number, y?: number): [number, number];
```
**描述**
获取元素在全局坐标系中的绝对坐标。
**示例**
```typescript
const [absX, absY] = item.getAbsolutePosition(); // 获取元素原点绝对坐标
```
---
### `getBoundingRect`
```typescript
function getBoundingRect(): DOMRectReadOnly;
```
**描述**
获取元素的包围矩形(相对于父元素坐标系)。
**示例**
```typescript
const rect = item.getBoundingRect();
console.log(rect.width, rect.height);
```
---
### `setZIndex`
```typescript
function setZIndex(zIndex: number): void;
```
**描述**
设置元素的纵深层级(`zIndex` 越大越靠前)。
**示例**
```typescript
item.setZIndex(5); // 置顶显示
```
---
### `requestRenderFrame`
```typescript
function requestRenderFrame(fn: () => void): void;
```
**描述**
在下一帧渲染时执行函数(适用于需要在渲染流程中更新的操作)。
**示例**
```typescript
item.requestRenderFrame(() => {
item.pos(item.x + 1, item.y); // 每帧右移 1 单位
});
```
---
### `setFilter`
```typescript
function setFilter(filter: string): void;
```
**描述**
设置元素的 CSS 滤镜效果(如模糊、灰度等)。
**示例**
```typescript
item.setFilter('blur(5px)'); // 添加模糊效果
```
---
## 受保护方法说明
### `render`
```typescript
protected abstract render(canvas: MotaOffscreenCanvas2D, transform: Transform): void;
```
**描述**
抽象渲染方法,子类必须实现此方法以定义具体渲染逻辑。
**示例**
```typescript
class CustomItem extends RenderItem {
protected render(canvas: MotaOffscreenCanvas2D) {
canvas.ctx.fillStyle = 'red';
canvas.ctx.fillRect(0, 0, this.width, this.height);
}
}
```
---
### `isActionInElement`
```typescript
protected isActionInElement(x: number, y: number): boolean;
```
**描述**
判断坐标点是否在元素范围内(可覆盖实现自定义碰撞检测)。
**默认行为**
检测坐标是否在 `[0, width] x [0, height]` 矩形内。
---
## 静态方法说明
### `RenderItem.ticker`
**类型**
```typescript
const ticker: Ticker;
```
**描述**
全局动画帧管理器,用于处理所有委托的动画帧函数。
---
## 事件说明
事件继承自 [ERenderItemActionEvent](./Event.md#erenderitemactionevent)
| 事件名 | 参数类型 | 说明 |
| -------------- | ------------------------- | ------------------ |
| `beforeRender` | `Transform` | 渲染前触发 |
| `afterRender` | `Transform` | 渲染后触发 |
| `destroy` | `[]` | 元素销毁时触发 |
| `transform` | `[RenderItem, Transform]` | 变换矩阵更新时触发 |
---
## 总使用示例
::: code-group
```typescript [基础操作]
// 创建元素(以 Sprite 为例)
const item = new Sprite('static');
// 设置属性
item.size(400, 300);
item.pos(100, 50);
item.setAnchor(0.5, 0.5); // 设置中心锚点
item.setZIndex(2);
// 监听渲染事件
item.on('beforeRender', transform => {
console.log('即将渲染,变换矩阵:', transform);
});
// 添加动画效果
const tickerId = item.delegateTicker(time => {
item.pos(Math.sin(time / 1000) * 100, 50);
});
// 销毁元素
setTimeout(() => {
item.destroy();
}, 5000);
```
```typescript [创建自定义元素]
// 创建自定义可交互元素
class Button extends RenderItem {
constructor() {
super('static');
this.size(100, 40);
this.on('click', ev => {
console.log('按钮被点击!坐标:', ev.offsetX, ev.offsetY);
});
}
protected render(canvas: MotaOffscreenCanvas2D) {
// 绘制圆角矩形按钮
const ctx = canvas.ctx;
ctx.fillStyle = '#4CAF50';
ctx.roundRect(0, 0, this.width, this.height, 8);
ctx.fill();
}
}
// 使用按钮
const button = new Button();
button.pos(200, 150);
button.append(parentElement);
// 添加鼠标悬停效果
button.on('enter', () => button.setFilter('brightness(1.2)'));
button.on('leave', () => button.setFilter('none'));
```
:::
# RenderItem 类 API 文档(补充部分)
本文档由 `DeepSeek R1` 模型生成并微调。
---

View File

@ -1,12 +0,0 @@
# Shader 类 API 文档
```mermaid
graph LR
Shader --> GL2 --> RenderItem --> EventEmitter
click GL2 "./GL2"
click RenderItem "./RenderItem"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
用法同 [GL2](./GL2.md)

View File

@ -1,11 +0,0 @@
# Shader 类 API 文档
```mermaid
graph LR
ShaderProgram --> GL2Program --> EventEmitter
click GL2Program "./GL2Program"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
用法同 [GL2Program](./GL2Program.md)

View File

@ -1,121 +0,0 @@
# Sprite 类 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 继承关系
```mermaid
graph LR
Sprite --> RenderItem --> EventEmitter
click RenderItem "./RenderItem"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
| ---------- | ---------------- | ---------- | -------------------------------------- |
| `renderFn` | `RenderFunction` | `() => {}` | 自定义渲染函数,用于定义精灵的绘制逻辑 |
---
## 构造方法
### `constructor`
**参数**
- `type`: 渲染模式(`absolute` 绝对定位 / `static` 跟随摄像机)
- `cache`: 是否启用渲染缓存(默认启用)
- `fall`: 是否启用变换矩阵下穿机制(默认关闭)
**示例**
```typescript
const sprite = new Sprite('static');
```
---
## 方法说明
### `setRenderFn`
```typescript
function setRenderFn(fn: RenderFunction): void;
```
**描述**
设置自定义渲染函数,用于定义精灵的具体绘制逻辑。
**参数**
- `fn`: 接收画布和变换矩阵的回调函数,格式为 `(canvas, transform) => void`
**示例**
```typescript
sprite.setRenderFn((canvas, transform) => {
// 绘制一个红色矩形
canvas.ctx.fillStyle = 'red';
canvas.ctx.fillRect(0, 0, sprite.width, sprite.height);
});
```
---
## 总使用示例
```typescript
// 创建精灵实例
const sprite = new Sprite('absolute');
sprite.size(100, 100); // 设置尺寸
sprite.pos(200, 150); // 设置坐标
// 定义渲染逻辑
sprite.setRenderFn(canvas => {
const ctx = canvas.ctx;
// 绘制渐变圆形
const gradient = ctx.createRadialGradient(50, 50, 0, 50, 50, 50);
gradient.addColorStop(0, 'yellow');
gradient.addColorStop(1, 'orange');
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(50, 50, 50, 0, Math.PI * 2);
ctx.fill();
});
// 添加到父容器
container.appendChild(sprite);
// 监听变换事件
sprite.on('transform', (item, transform) => {
console.log('精灵变换矩阵更新:', transform);
});
```
---
## 高级用法示例
```typescript
// 创建动态旋转精灵
const rotatingSprite = new Sprite('static');
rotatingSprite.size(80, 80);
rotatingSprite.setRenderFn((canvas, transform) => {
canvas.ctx.fillStyle = 'blue';
canvas.ctx.fillRect(0, 0, 80, 80);
});
// 每帧旋转
rotatingSprite.delegateTicker(time => {
rotatingSprite.transform.setRotate(time / 1000);
});
// 添加到场景
rootContainer.appendChild(rotatingSprite);
```

View File

@ -1,332 +0,0 @@
# Transform 类 API 文档
以下内容由 `DeepSeek R1` 模型生成并微调。
---
## 继承关系
```mermaid
graph LR
Transform --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
| -------------- | --------------------- | ----------- | ----------------------------------------------------------- |
| `mat` | `mat3` | 单位矩阵 | 存储当前变换的 3x3 矩阵 |
| `x` | `number` | `0` | 水平平移量 |
| `y` | `number` | `0` | 垂直平移量 |
| `scaleX` | `number` | `1` | 水平缩放比例 |
| `scaleY` | `number` | `1` | 垂直缩放比例 |
| `rad` | `number` | `0` | 旋转弧度值(范围:`[0, 2π)`) |
| `modified` | `boolean`(私有) | `false` | 标识变换是否被修改过 |
| `bindedObject` | `ITransformUpdatable` | `undefined` | 绑定的对象(当变换更新时自动调用其 `updateTransform` 方法) |
---
## 构造方法
### `constructor`
创建一个新的变换实例,初始化为单位矩阵。
```typescript
const transform = new Transform();
```
---
## 方法说明
### `bind`
```typescript
function bind(obj?: ITransformUpdatable): void;
```
**描述**
绑定一个对象,当变换更新时自动调用其 `updateTransform` 方法(若存在)。
**示例**
```typescript
const obj = { updateTransform: () => console.log('Transform updated!') };
transform.bind(obj);
```
---
### `reset`
```typescript
function reset(): void;
```
**描述**
重置所有参数到初始状态(单位矩阵)。
**示例**
```typescript
transform.reset(); // 重置为 x=0, y=0, scaleX=1, scaleY=1, rad=0
```
---
### `scale`
```typescript
function scale(x: number, y: number = x): this;
```
**描述**
叠加缩放变换(相对于当前状态)。
**参数**
- `x`: 水平缩放比例
- `y`: 垂直缩放比例(默认同 `x`)
**示例**
```typescript
transform.scale(2); // 水平和垂直均放大2倍
transform.scale(1.5, 0.5); // 水平放大1.5倍,垂直缩小到0.5倍
```
---
### `translate`
```typescript
function translate(x: number, y: number): this;
```
**描述**
叠加平移变换(相对于当前状态)。
**参数**
- `x`: 水平平移量
- `y`: 垂直平移量
**示例**
```typescript
transform.translate(100, 50); // 向右平移100单位,向下平移50单位
```
---
### `rotate`
```typescript
function rotate(rad: number): this;
```
**描述**
叠加旋转变换(相对于当前状态)。
**参数**
- `rad`: 旋转弧度值
**示例**
```typescript
transform.rotate(Math.PI / 2); // 顺时针旋转90度
```
---
### `setScale`
```typescript
function setScale(x: number, y: number = x): this;
```
**描述**
直接设置缩放比例(非叠加,覆盖当前状态)。
**示例**
```typescript
transform.setScale(3, 2); // 设置水平缩放3倍,垂直缩放2倍
```
---
### `setTranslate`
```typescript
function setTranslate(x: number, y: number): this;
```
**描述**
直接设置平移量(非叠加,覆盖当前状态)。
**示例**
```typescript
transform.setTranslate(200, 100); // 直接定位到(200, 100)
```
---
### `setRotate`
```typescript
function setRotate(rad: number): this;
```
**描述**
直接设置旋转角度(非叠加,覆盖当前状态)。
**示例**
```typescript
transform.setRotate(Math.PI); // 设置旋转180度
```
---
### `transformed`
```typescript
function transformed(x: number, y: number): vec3;
```
**描述**
将坐标点 `(x, y)` 应用当前变换矩阵,返回变换后的坐标。
**返回值**
- `vec3`: 变换后的三维坐标(`[x, y, 1]`)
**示例**
```typescript
const point = transform.transformed(10, 20); // 应用变换后的坐标
```
---
### `untransformed`
```typescript
function untransformed(x: number, y: number): vec3;
```
**描述**
将坐标点 `(x, y)` 逆向应用当前变换矩阵,返回原坐标。
**示例**
```typescript
const origin = transform.untransformed(50, 30); // 逆向变换后的坐标
```
---
### `clone`
```typescript
function clone(): Transform;
```
**描述**
复制当前变换实例。
**示例**
```typescript
const cloned = transform.clone(); // 生成一个完全相同的副本
```
---
## 静态方法说明
### `Transform.transformed`
```typescript
function transformed(transform: Transform, x: number, y: number): vec3;
```
**描述**
静态方法,直接通过变换矩阵计算坐标点 `(x, y)` 的变换结果。
**示例**
```typescript
const result = Transform.transformed(transform, 5, 5);
```
---
### `Transform.untransformed`
```typescript
function untransformed(transform: Transform, x: number, y: number): vec3;
```
**描述**
静态方法,直接通过变换矩阵逆向计算坐标点 `(x, y)` 的原位置。
**示例**
```typescript
const origin = Transform.untransformed(transform, 100, 50);
```
---
## 接口说明
### `ITransformUpdatable`
```typescript
interface ITransformUpdatable {
updateTransform?(): void;
}
```
**描述**
可绑定对象的接口,当变换更新时触发 `updateTransform` 方法(可选)。
---
## 总使用示例
```typescript
// 创建变换实例
const transform = new Transform();
// 应用变换
transform
.translate(50, 30)
.scale(2)
.rotate(Math.PI / 4);
// 绑定对象
const obj = {
updateTransform: () => console.log('Transform updated!')
};
transform.bind(obj);
// 坐标转换
const transformedPoint = transform.transformed(10, 10);
console.log('Transformed point:', transformedPoint);
// 复制变换
const cloned = transform.clone();
// 静态方法使用
const staticResult = Transform.transformed(cloned, 5, 5);
```

View File

@ -1,119 +0,0 @@
# 函数 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 函数说明
### `isWebGLSupported`
**功能**
检测浏览器是否支持 WebGL 1.0
**返回值**
- `true`: 支持
- `false`: 不支持
**示例**
```typescript
if (isWebGLSupported()) {
// 初始化 WebGL 1.0 功能
}
```
---
### `isWebGL2Supported`
**功能**
检测浏览器是否支持 WebGL 2.0
**返回值**
- `true`: 支持
- `false`: 不支持
---
### `addTiming`
**功能**
组合两个缓动函数为加法函数
**数学表达**
`newTiming(p) = timing1(p) + timing2(p)`
**参数**
- `timing1`: 第一个缓动函数
- `timing2`: 第二个缓动函数
**示例**
```typescript
const linear = (p: number) => p;
const bounce = (p: number) => p * p;
const combined = addTiming(linear, bounce); // p + p²
```
---
### `multiplyTiming`
**功能**
组合两个缓动函数为乘法函数
**数学表达**
`newTiming(p) = timing1(p) * timing2(p)`
---
### `isSetEqual`
**功能**
判断两个集合是否相等(元素完全相同)
**实现逻辑**
1. 直接引用相同 → `true`
2. 大小不同 → `false`
3. 检查 set1 是否是 set2 的子集
---
### `transformCanvas`
**功能**
将变换矩阵应用到画布上下文
**实现逻辑**
```typescript
const mat = transform.mat; // 获取 3x3 矩阵
const [a, b, , c, d, , e, f] = mat; // 分解为 2D 变换参数
ctx.transform(a, b, c, d, e, f); // 应用变换
```
**参数**
- `canvas`: 目标画布对象
- `transform`: 变换矩阵
**示例**
```typescript
const transform = new Transform();
transform.translate(100, 50);
transformCanvas(myCanvas, transform); // 应用平移变换
```
---
## 工具函数关系图
```mermaid
graph LR
checkSupport --> isWebGLSupported
checkSupport --> isWebGL2Supported
addTiming --> 组合缓动函数
multiplyTiming --> 组合缓动函数
isSetEqual --> 集合操作
transformCanvas --> 矩阵变换
```

View File

@ -1 +0,0 @@
# @motajs/render-core

View File

@ -1,369 +0,0 @@
# BlockCacher API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
BlockCacher --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
_继承自 `EventEmitter<BlockCacherEvent>`,支持事件监听。_
---
## 属性说明
| 属性名 | 类型 | 描述 |
| ------------ | ---------------- | ------------------------------------------------------------------- |
| `width` | `number` | 区域总宽度(元素单位) |
| `height` | `number` | 区域总高度(元素单位) |
| `blockSize` | `number` | 单个分块的大小(元素单位) |
| `blockData` | `BlockData` | 分块计算结果(包含分块数量、最后一个块的尺寸等信息) |
| `cacheDepth` | `number` | 缓存深度(每个分块可存储多个缓存层) |
| `cache` | `Map<number, T>` | 缓存存储结构,键为精确索引(`(x + y * blockWidth) * depth + deep`) |
---
## 构造方法
### `constructor`
```typescript
function constructor(
width: number,
height: number,
size: number,
depth?: number
): BlockCacher<T>;
```
创建分块缓存管理器并自动计算初始分块。
**示例:**
```typescript
const cacher = new BlockCacher<ICanvasCacheItem>(800, 600, 64); // 800x600区域,64为分块大小
```
---
## 方法说明
### `size`
```typescript
function size(width: number, height: number): void;
```
重置区域尺寸并重新分块(触发 `split` 事件)。
**示例:**
```typescript
cacher.size(1024, 768); // 重置为1024x768区域
```
### `setBlockSize`
```typescript
function setBlockSize(size: number): void;
```
修改分块尺寸并重新分块(触发 `split` 事件)。
**示例:**
```typescript
cacher.setBlockSize(128); // 分块大小改为128
```
### `setCacheDepth`
```typescript
function setCacheDepth(depth: number): void;
```
调整缓存深度(最大 31),自动迁移旧缓存。
**示例:**
```typescript
cacher.setCacheDepth(3); // 每个分块支持3层缓存
```
### `split`
```typescript
function split(): void;
```
重新计算分块数据并触发 `'split'` 事件。
**示例:**
```typescript
cacher.split(); // 手动触发分块计算(一般无需调用)
```
### `clearCache`
```typescript
function clearCache(index: number, deep: number): void;
```
清除指定分块索引的缓存(按二进制掩码清除深度)。
**示例:**
```typescript
cacher.clearCache(5, 0b101); // 清除分块5的第0层和第2层缓存
```
### `clearCacheByIndex`
```typescript
function clearCacheByIndex(index: number): void;
```
直接按精确索引清除单个缓存。
**示例:**
```typescript
cacher.clearCacheByIndex(42); // 清除精确索引42对应的缓存
```
### `clearAllCache`
```typescript
function clearAllCache(): void;
```
清空所有缓存并销毁关联资源。
**示例:**
```typescript
cacher.clearAllCache(); // 完全重置缓存
```
### `getIndex`
```typescript
function getIndex(x: number, y: number): number;
```
根据分块坐标获取分块索引(分块坐标 -> 分块索引)。
**示例:**
```typescript
const index = cacher.getIndex(2, 3); // 获取(2,3)分块的索引
```
### `getIndexByLoc`
```typescript
function getIndexByLoc(x: number, y: number): number;
```
根据元素坐标获取所属分块索引(元素坐标 -> 分块索引)。
**示例:**
```typescript
const index = cacher.getIndexByLoc(150, 200); // 元素坐标(150,200)所在分块索引
```
### `getBlockXYByIndex`
```typescript
function getBlockXYByIndex(index: number): [number, number];
```
根据分块索引获取分块坐标(分块索引 -> 分块坐标)。
**示例:**
```typescript
const [x, y] = cacher.getBlockXYByIndex(5); // 分块5的坐标
```
### `getBlockXY`
```typescript
function getBlockXY(x: number, y: number): [number, number];
```
获取一个元素位置所在的分块位置(即使它不在任何分块内)(元素索引 -> 分块坐标)。
**示例:**
```typescript
const [x, y] = cacher.getBlockXY(11, 24); // 指定位置所在分块位置
```
### `getPreciseIndex`
```typescript
function getPreciseIndex(x: number, y: number, deep: number): number;
```
根据分块坐标与 `deep` 获取一个分块的精确索引(分块坐标 -> 分块索引)。
**示例:**
```typescript
const index = cacher.getPreciseIndex(2, 1, 3); // 指定分块的索引
```
### `getPreciseIndexByLoc`
```typescript
function getPreciseIndexByLoc(x: number, y: number, deep: number): number;
```
根据元素坐标及 `deep` 获取元素所在块的精确索引(元素坐标 -> 分块索引)。
**示例:**
```typescript
const index = cacher.getPreciseIndexByLoc(22, 11, 3); // 指定元素所在分块的索引
```
### `updateElementArea`
```typescript
function updateElementArea(
x: number,
y: number,
width: number,
height: number,
deep: number = 2 ** 31 - 1
): Set<number>;
```
根据元素区域清除相关分块缓存(返回受影响的分块索引集合)(元素坐标->分块清空)。
**示例:**
```typescript
const blocks = cacher.updateElementArea(100, 100, 200, 200); // 清除200x200区域内的缓存
```
### `updateArea`
```typescript
function updateArea(
x: number,
y: number,
width: number,
height: number,
deep: number = 2 ** 31 - 1
): Set<number>;
```
更新指定分块区域内的缓存(注意坐标是分块坐标,而非元素坐标)(分块坐标->分块清空)。
**示例:**
```typescript
const blocks = cacher.updateArea(1, 1, 1, 1); // 清除指定分块区域内的缓存
```
### `getIndexOf`
```typescript
function getIndexOf(
x: number,
y: number,
width: number,
height: number
): Set<number>;
```
传入分块坐标与范围,获取该区域内包含的所有分块索引(分块坐标->分块索引集合)。
**示例:**
```typescript
const blocks = cacher.getIndexOf(1, 1, 1, 1); // 清除指定分块区域内的缓存
```
### `getIndexOfElement`
```typescript
function getIndexOfElement(
x: number,
y: number,
width: number,
height: number
): Set<number>;
```
传入元素坐标与范围,获取该区域内包含的所有分块索引(元素坐标->分块索引集合)。
**示例:**
```typescript
const blocks = cacher.getIndexOfElement(3, 5, 12, 23); // 清除指定元素区域内的缓存
```
### `getRectOfIndex`
```typescript
function getRectOfIndex(block: number): [number, number, number, number];
```
获取分块索引对应的元素坐标范围(分块索引 -> 元素矩形坐标)。
**示例:**
```typescript
const [x1, y1, x2, y2] = cacher.getRectOfIndex(5); // 分块5的坐标范围
```
### `getRectOfBlockXY`
```typescript
function getRectOfBlockXY(
x: number,
y: number
): [number, number, number, number];
```
根据分块坐标,获取这个分块所在区域的元素矩形范围(左上角横纵坐标及右下角横纵坐标)(分块坐标 -> 元素矩形坐标)。
**示例:**
```typescript
const [x1, y1, x2, y2] = cacher.getRectOfIndex(5); // 分块5的坐标范围
```
### `destroy`
```typescript
function destroy(): void;
```
摧毁这个块缓存。
---
## 事件说明
| 事件名 | 参数 | 描述 |
| ------- | ---- | ------------------ |
| `split` | 无 | 分块参数变更时触发 |
---
## 总使用示例
```typescript
// 创建缓存管理器
const cacheManager = new BlockCacher<ICanvasCacheItem>(1024, 768, 64);
// 监听分块变化
cacheManager.on('split', () => {
console.log('分块已重新计算');
});
// 添加测试缓存项
const blockIndex = cacheManager.getIndex(2, 3);
const preciseIndex = cacheManager.getPreciseIndex(2, 3, 0);
cacheManager.cache.set(
preciseIndex,
new CanvasCacheItem(new MotaOffscreenCanvas2D(), 1)
);
// 清除特定区域缓存
cacheManager.updateElementArea(150, 150, 100, 100);
// 销毁管理器
cacheManager.destroy();
```

View File

@ -1,386 +0,0 @@
# Camera API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
Camera --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
_继承自 `EventEmitter<CameraEvent>`,支持事件监听。_
---
## 属性说明
| 属性名 | 类型 | 描述 |
| --------------------- | ------------------- | ------------------------------------------------ |
| `readonly binded` | `RenderItem` | 当前绑定的渲染元素 |
| `transform` | `Transform` | 目标变换矩阵,默认与 `binded.transform` 共享引用 |
| `protected operation` | `CameraOperation[]` | 当前应用的变换操作列表(平移/旋转/缩放) |
---
## 构造方法
### `Camera.for`
```typescript
function for(item: RenderItem): Camera
```
获取或创建与渲染元素关联的摄像机实例。
**示例:**
```typescript
const item = new RenderItem();
const camera = Camera.for(item); // 获取或创建摄像机
```
### `constructor`
```typescript
function constructor(item: RenderItem): Camera;
```
直接创建摄像机实例(不会自动注册到全局映射)。
**注意:** 推荐优先使用 `Camera.for()` 方法。
---
## 方法说明
### `disable`
```typescript
function disable(): void;
```
禁用摄像机变换效果。
**示例:**
```typescript
camera.disable(); // 暂停所有摄像机变换
```
### `enable`
```typescript
function enable(): void;
```
启用摄像机变换效果。
### `requestUpdate`
```typescript
function requestUpdate(): void;
```
请求在下一帧强制更新变换矩阵。
### `removeOperation`
```typescript
function removeOperation(operation: CameraOperation): void;
```
移除一个变换操作。
**参数说明**
- `operation`: 要移除的操作
**示例**
```ts
const operation = camera.addTranslate();
camera.removeOperation(operation);
```
### `clearOperation`
```ts
function clearOperation(): void;
```
清空变换操作列表。
### `addTranslate`
```typescript
function addTranslate(): ICameraTranslate;
```
添加平移操作并返回操作对象。
**示例:**
```typescript
const translateOp = camera.addTranslate();
translateOp.x = 100; // 设置横向偏移
camera.requestUpdate();
```
### `addRotate`
```typescript
function addRotate(): ICameraRotate;
```
添加旋转操作并返回操作对象。
**示例:**
```typescript
const rotateOp = camera.addRotate();
rotateOp.angle = Math.PI / 2; // 设置90度旋转
camera.requestUpdate();
```
### `addScale`
```typescript
function addScale(): ICameraScale;
```
添加缩放操作并返回操作对象。
**示例:**
```typescript
const scaleOp = camera.addScale();
scaleOp.x = 2; // 横向放大2倍
camera.requestUpdate();
```
### `applyAnimation`
```ts
function applyAnimation(time: number, update: () => void): void;
```
施加动画。
**参数说明**
- `time`: 动画时长。
- `update`: 每帧执行的更新函数。
### `applyTranslateAnimation`
```typescript
function applyTranslateAnimation(
operation: ICameraTranslate,
animate: Animation,
time: number
): void;
```
为平移操作绑定动画。
**参数说明:**
- `animate`: 预定义的动画实例
- `time`: 动画持续时间(毫秒)
### `applyRotateAnimation`
```typescript
function applyRotateAnimation(
operation: ICameraRotate,
animate: Animation,
time: number
): void;
```
为旋转操作绑定动画。
### `applyScaleAnimation`
```typescript
function applyScaleAnimation(
operation: ICameraScale,
animate: Animation,
time: number
): void;
```
为缩放操作绑定动画。
### `applyTranslateTransition`
```typescript
function applyTranslateTransition(
operation: ICameraTranslate,
animate: Transition,
time: number
): void;
```
为平移操作绑定渐变。
**参数说明:**
- `animate`: 预定义的渐变实例
- `time`: 渐变持续时间(毫秒)
### `applyRotateTransition`
```typescript
function applyRotateTransition(
operation: ICameraRotate,
animate: Transition,
time: number
): void;
```
为旋转操作绑定渐变。
### `applyScaleTransition`
```typescript
function applyScaleTransition(
operation: ICameraScale,
animate: Transition,
time: number
): void;
```
为缩放操作绑定渐变。
### `stopAllAnimates`
```ts
function stopAllAnimates(): void;
```
停止所有动画。
### `destroy`
```typescript
function destroy(): void;
```
销毁摄像机并释放所有资源。
**示例:**
```typescript
camera.destroy(); // 解除绑定并清理动画
```
---
## 事件说明
| 事件名 | 参数 | 描述 |
| --------- | ---- | ------------------ |
| `destroy` | 无 | 摄像机被销毁时触发 |
---
## 总使用示例
::: code-group
```typescript [动画]
import { Animation, linear } from 'mutate-animate';
// 获取摄像机实例
const item = new Sprite();
const camera = Camera.for(item);
// 添加平移和缩放操作
const translate = camera.addTranslate();
const scale = camera.addScale();
// 创建动画实例
const anim = new Animation()
.mode(linear())
.time(1000)
.move(100, 100)
.time(800)
.scale(1.5);
// 绑定动画
camera.applyTranslateAnimation(translate, anim, 1000);
camera.applyScaleAnimation(scale, anim, 800);
// 启用摄像机
camera.enable();
// 销毁(当不再需要时)
setTimeout(() => camera.destroy(), 2000);
```
```typescript [渐变]
import { Transition, hyper } from 'mutate-animate';
// 获取摄像机实例
const item = new Sprite();
const camera = Camera.for(item);
// 添加平移和缩放操作
const translate = camera.addTranslate();
const scale = camera.addScale();
// 创建渐变实例,使用双曲正弦速率曲线
const tran = new Transition().mode(hyper('sin', 'out')).time(1000);
// 初始化参数,这一步不会执行渐变
tran.value.x = 0;
tran.value.y = 0;
tran.value.size = 0;
// 对参数执行渐变,直接设置即可
tran.value.x = 100;
tran.value.y = 200;
tran.time(800); // 设置渐变时长为 800 毫秒
tran.value.size = 1.5;
// 绑定动画
camera.applyTranslateTransition(translate, tran, 1000);
camera.applyScaleTransition(scale, tran, 800);
// 启用摄像机
camera.enable();
// 销毁(当不再需要时)
setTimeout(() => camera.destroy(), 2000);
```
:::
---
## 接口说明
### `ICameraTranslate`
```typescript
interface ICameraTranslate {
readonly type: 'translate';
readonly from: RenderItem;
x: number; // 横向偏移量
y: number; // 纵向偏移量
}
```
### `ICameraRotate`
```typescript
interface ICameraRotate {
readonly type: 'rotate';
readonly from: RenderItem;
angle: number; // 旋转弧度值
}
```
### `ICameraScale`
```typescript
interface ICameraScale {
readonly type: 'scale';
readonly from: RenderItem;
x: number; // 横向缩放比
y: number; // 纵向缩放比
}
```

View File

@ -1,201 +0,0 @@
# CameraAnimation API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
CameraAnimation --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
_继承自 `EventEmitter<CameraAnimationEvent>`,支持事件监听。_
---
## 属性说明
| 属性名 | 类型 | 描述 |
| -------- | -------- | ---------------- |
| `camera` | `Camera` | 关联的摄像机实例 |
---
## 构造方法
### `constructor`
```typescript
function constructor(camera: Camera): CameraAnimation;
```
创建摄像机动画管理器,需绑定到特定 `Camera` 实例。
**示例:**
```typescript
const camera = Camera.for(renderItem);
const animation = new CameraAnimation(camera);
```
---
## 方法说明
### `translate`
```typescript
function translate(
operation: ICameraTranslate,
x: number,
y: number,
time: number,
start: number,
timing: TimingFn
): void;
```
为平移操作添加动画。
**参数说明:**
- `x`, `y`: 目标偏移量(格子坐标,自动乘以 `32`,之后可能改动)
- `time`: 动画持续时间(毫秒)
- `start`: 动画开始时间(相对于总动画开始的延迟)
- `timing`: 缓动函数(输入时间完成度,输出动画完成度)
### `rotate`
```typescript
function rotate(
operation: ICameraRotate,
angle: number,
time: number,
start: number,
timing: TimingFn
): void;
```
为旋转操作添加动画。
**参数说明:**
- `angle`: 目标旋转弧度(如 `Math.PI` 表示 `180` 度)
- 其余参考[`rotate`](#rotate)
### `scale`
```typescript
function scale(
operation: ICameraScale,
scale: number,
time: number,
start: number,
timing: TimingFn
): void;
```
为缩放操作添加动画。
**参数说明:**
- `scale`: 目标缩放倍率(如 `1.5` 表示放大 `1.5` 倍)
- 其余参考[`rotate`](#rotate)
### `start`
```typescript
function start(): void;
```
启动所有已添加的动画,按时间顺序执行。
**注意:** 调用后动画将按 `start` 参数定义的顺序触发。
### `destroy`
```typescript
function destroy(): void;
```
销毁动画管理器并释放所有资源(停止未完成的动画)。
---
## 事件说明
| 事件名 | 参数 | 描述 |
| --------- | -------------------------------------------------------------------------------------------------------- | ---------------------------- |
| `animate` | `operation: CameraOperation` <br> `execution: CameraAnimationExecution` <br> `item: CameraAnimationData` | 当某个动画片段开始执行时触发 |
---
## 总使用示例
```typescript
import { hyper, trigo } from 'mutate-animate';
// 创建渲染元素和摄像机
const renderItem = new Sprite();
const camera = Camera.for(renderItem);
// 添加平移和旋转操作
const translateOp = camera.addTranslate();
const rotateOp = camera.addRotate();
// 创建动画管理器
const animation = new CameraAnimation(camera);
// 添加平移动画:1秒后开始,持续2秒,横向移动3格(3*32像素)
animation.translate(
translateOp,
3,
0, // x=3, y=0(自动乘32)
2000, // 动画时长2秒
1000, // 延迟1秒开始
hyper('sin', 'out') // 双曲正弦函数
);
// 添加旋转动画:立即开始,持续1.5秒,旋转180度
animation.rotate(
rotateOp,
Math.PI, // 目标角度(弧度)
1500, // 动画时长1.5秒
0, // 无延迟
trigo('sin', 'out') // 正弦函数
);
// 启动动画
animation.start();
// 监听动画事件
animation.on('animate', (operation, execution, item) => {
console.log('动画片段开始:', item.type);
});
// 销毁(动画结束后)
setTimeout(() => {
animation.destroy();
camera.destroy();
}, 5000);
```
---
## 接口说明
### `CameraAnimationExecution`
```typescript
interface {
data: CameraAnimationData[]; // 动画片段列表
animation: Animation; // 关联的动画实例
}
```
### `CameraAnimationData`
```typescript
type CameraAnimationData =
| TranslateAnimation
| TranslateAsAnimation
| RotateAnimation
| ScaleAnimation;
```

View File

@ -1,3 +0,0 @@
# @motajs/render-elements
目录:

View File

@ -1,186 +0,0 @@
# Font API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
Font --> IFontConfig
```
_实现 `IFontConfig` 接口,表示字体配置。_
---
## 接口说明
### `IFontConfig`
```typescript
interface IFontConfig {
family: string; // 字体名称(如 "Arial")
size: number; // 字号数值
sizeUnit: string; // 字号单位(推荐 "px")
weight: number; // 字重(0-1000)
italic: boolean; // 是否斜体
}
```
### `FontWeight` 枚举
```typescript
enum FontWeight {
Light = 300, // 细体
Normal = 400, // 常规
Bold = 700 // 粗体
}
```
---
## 属性说明
| 属性名 | 类型 | 描述 |
| ---------- | --------- | ------------------------- |
| `family` | `string` | 字体家族名称(只读) |
| `size` | `number` | 字号数值(只读) |
| `sizeUnit` | `string` | 字号单位(如 "px",只读) |
| `weight` | `number` | 字重数值(只读) |
| `italic` | `boolean` | 是否斜体(只读) |
---
## 构造方法
### `constructor`
```typescript
function constructor(
family?: string,
size?: number,
sizeUnit?: string,
weight?: number,
italic?: boolean
): Font;
```
创建字体实例,参数默认使用静态默认值。
**示例:**
```typescript
const font = new Font('Arial', 14, 'px', FontWeight.Bold, true);
```
---
## 方法说明
### `addFallback`
```typescript
function addFallback(...fallback: Font[]): void;
```
添加后备字体(当主字体不可用时使用)。
**注意:** 检测到递归添加时会触发 `logger.warn(62)` 警告。
**示例:**
```typescript
const mainFont = new Font('CustomFont');
const fallback1 = new Font('Arial');
const fallback2 = new Font('Helvetica');
mainFont.addFallback(fallback1, fallback2); // 添加两个后备
```
### `string`
```typescript
function string(): string;
```
生成 CSS 字体字符串,包含后备字体。
**示例:**
```typescript
console.log(font.string()); // 示例输出:"italic 700 14px CustomFont, 400 16px Arial"
```
---
## 静态方法说明
### `Font.parse`
```typescript
function parse(str: string): Font;
```
解析 CSS 字体字符串(支持多字体声明)。
**示例:**
```typescript
const parsed = Font.parse('italic 16px "Fira Sans", Arial');
// 主字体:Fira Sans,后备:Arial
```
### `Font.setDefaults`
```typescript
function setDefaults(font: Font): void;
```
全局设置默认字体参数。
**示例:**
```typescript
Font.setDefaults(new Font('Segoe UI', 14, 'px', 400, false));
```
### `Font.clone`
```typescript
function clone(font: Font, options: Partial<IFontConfig>): Font;
```
克隆字体并修改指定属性。
**示例:**
```typescript
const cloned = Font.clone(baseFont, {
size: 18,
weight: FontWeight.Bold
});
```
---
## 总使用示例
```typescript
// 创建主字体
const mainFont = new Font('CustomFont', 16, 'px', FontWeight.Normal);
// 添加后备字体(注意避免循环引用)
const fallbackA = new Font('Arial');
const fallbackB = new Font('Helvetica');
fallbackA.addFallback(fallbackB);
// 错误示例(触发警告62):
// fallbackB.addFallback(fallbackA);
mainFont.addFallback(fallbackA);
// 生成 CSS 字符串
console.log(mainFont.string());
// 输出: "400 16px CustomFont, 400 16px Arial, 400 16px Helvetica"
// 解析 CSS 字符串
const parsed = Font.parse('italic 700 24px Fantasy, "Comic Sans"');
parsed.addFallback(new Font('Verdana'));
// 克隆并修改
const boldFont = Font.clone(parsed, {
weight: FontWeight.Bold,
italic: false
});
```

View File

@ -1,3 +0,0 @@
# @motajs/render-style
目录:

View File

@ -1,134 +0,0 @@
# BaseProps 接口文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 接口定义
```typescript
interface BaseProps {
// 基础定位
x?: number; // 横坐标(单位:像素)
y?: number; // 纵坐标(单位:像素)
anchorX?: number; // 横向锚点比例(0~1,默认 0)
anchorY?: number; // 纵向锚点比例(0~1,默认 0)
zIndex?: number; // 纵深层级(值越大越靠上)
// 尺寸控制
width?: number; // 元素宽度(单位:像素,默认 200)
height?: number; // 元素高度(单位:像素,默认 200)
// 渲染控制
filter?: string; // CSS滤镜(如 "blur(5px)")
hd?: boolean; // 启用高清画布(默认 true)
anti?: boolean; // 启用抗锯齿(默认 true)
noanti?: boolean; // 强制禁用抗锯齿(优先级高于 anti)
hidden?: boolean; // 隐藏元素(默认 false)
// 变换与定位
transform?: Transform; // 变换矩阵对象
type?: RenderItemPosition; // 定位模式("static" | "absolute")
cache?: boolean; // 启用缓存优化(根据不同元素的特性有不同的值,多数情况下使用默认配置即可达到最优性能)
nocache?: boolean; // 强制禁用缓存(优先级高于 cache)
fall?: boolean; // 继承父元素变换矩阵(默认 false),不建议使用此参数,可能很快就会被删除
// 交互与样式
id?: string; // 唯一标识符
alpha?: number; // 不透明度(0~1,默认 1)
composite?: GlobalCompositeOperation; // 混合模式(如 "lighter")
cursor?: string; // 鼠标悬停样式(如 "pointer")
noevent?: boolean; // 禁用交互事件(默认 false)
// 简写属性
loc?: ElementLocator /*
[x, y, width?, height?, anchorX?, anchorY?]
如果填写的话,两两一组要么都填要么都不填,也就是说元素数量需要是 2,4,6 个
*/;
anc?: ElementAnchor; // [anchorX, anchorY],如果填写的话,两项必填
scale?: ElementScale; // [scaleX, scaleY],如果填写的话,两项必填
rotate?: number; // 旋转弧度值(单位:弧度)
}
```
---
## 完整使用示例
```tsx
import { defineComponent } from 'vue';
import { Transform } from '@motajs/render-core';
// 注意,以下属性均可选,按照自己需要填写即可,不需要的可以不用填,简单需求一般只需要修改定位
// 而复杂需求可能需要填写更多的参数,但是基本不会出现所有参数都要填的场景
// 编写 UI 的流程参考深度指南中的 UI 编写
export const MyUI = defineComponent(() => {
return () => (
<sprite
// 基础定位
x={100}
y={200}
anchorX={0.5} // 中心锚点
anchorY={0.5}
zIndex={5} // 确保在最上层
// 尺寸控制
width={300}
height={200}
// 渲染控制
filter="drop-shadow(5px 5px 5px rgba(0,0,0,0.5))"
hd // 高清模式
noanti // 强制关闭抗锯齿(像素风格)
hidden={false} // 显示元素
// 变换与定位
transform={new Transform().translate(10, 20)}
type="static" // 绝对定位
nocache // 禁用缓存
fall // 继承父变换
// 交互与样式
id="hero-sprite"
alpha={0.8} // 80% 不透明
composite="lighter" // 叠加混合模式
cursor="move" // 拖动光标
noevent={false} // 允许交互
// 简写属性
loc={[50, 60, 150, 100]} // x=50, y=60, width=150, height=100
anc={[0.5, 1]} // 底部中心锚点
scale={[1.2, 0.8]} // 横向拉伸 20%,纵向压缩 20%
rotate={Math.PI / 4} // 旋转 45 度
></sprite>
);
});
```
---
## 属性效果说明
| 属性组 | 关键效果 |
| -------------- | -------------------------------------------------------------------------- |
| **基础定位** | 元素将出现在 (100,200) 坐标,以中心点(锚点 0.5)为基准定位 |
| **尺寸控制** | 元素尺寸固定为 300x200 像素 |
| **渲染控制** | 应用阴影滤镜,高清画质,关闭抗锯齿实现像素风格 |
| **变换与定位** | 附加额外平移变换,使用绝对定位模式,禁用缓存优化 |
| **交互与样式** | 元素半透明,叠加混合模式,显示"move"光标,响应交互事件 |
| **简写属性** | 通过 loc 覆盖坐标和尺寸,anc 设置底部锚点,scale 实现拉伸/压缩,旋转 45 度 |
---
## 注意事项
1. **优先级规则**:
- `noanti` > `anti`,`nocache` > `cache`
- 显式属性(如 `x`)与简写属性(如 `loc` 中的 `x`)相比,谁最后被设置,就用谁的
2. **简写属性解析**:
```ts
loc = [100, 200, 300, 200]; // → x=100, y=200, width=300, height=200
anc = [0.5, 0]; // → anchorX=0.5, anchorY=0
scale = [2]; // → scaleX=2, scaleY=2
```
3. **其他注意事项**
- `transform.translate` 与 `x` `y` 和简写定位属性的 `x` `y` 完全等效,设置后者也会让 `transform` 的平移量改变
- 如果不允许交互,那么光标也不会显示
- 同 `zIndex` 下,后插入的元素会在上层,但是这也意味着如果是动态插入的元素(例如由于响应式更改而插入了一个新元素),会显示在后面代码的元素之上
4. **常见问题**
- 参考 [指南](../../guide/ui/faq.md)

View File

@ -1,188 +0,0 @@
# GraphicBaseProps API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 接口定义
```typescript
interface ILineProperty {
/** 线宽 */
lineWidth: number;
/** 线的虚线设置 */
lineDash?: number[];
/** 虚线偏移量 */
lineDashOffset?: number;
/** 线的连接样式 */
lineJoin: CanvasLineJoin;
/** 线的顶端样式 */
lineCap: CanvasLineCap;
/** 线的斜接限制,当连接为miter类型时可填,默认为10 */
miterLimit: number;
}
interface GraphicBaseProps extends BaseProps, Partial<ILineProperty> {
/** 是否填充(默认 false) */
fill?: boolean;
/** 是否描边(默认 false) */
stroke?: boolean;
/** 强制先描边后填充(优先级最高,默认 false) */
strokeAndFill?: boolean;
/** 填充规则(默认 "evenodd") */
fillRule?: CanvasFillRule;
/** 填充样式(颜色/渐变/图案) */
fillStyle?: CanvasStyle;
/** 描边样式(颜色/渐变/图案) */
strokeStyle?: CanvasStyle;
/** 交互时是否仅检测描边区域(默认 false) */
actionStroke?: boolean;
}
```
---
## 核心属性说明
| 属性 | 类型 | 默认值 | 说明 |
| ---------------- | ----------------------------------------------- | ----------- | -------------------------------------------------------------- |
| `fill` | `boolean` | `false` | 启用填充 |
| `stroke` | `boolean` | `false` | 启用描边 |
| `strokeAndFill` | `boolean` | `false` | 先描边后填充 |
| `fillRule` | `'nonzero'` \| `'evenodd'` | `'evenodd'` | 填充路径环绕原则 |
| `fillStyle` | `string` \| `CanvasGradient` \| `CanvasPattern` | - | 填充样式 |
| `strokeStyle` | `string` \| `CanvasGradient` \| `CanvasPattern` | - | 描边样式 |
| `actionStroke` | `boolean` | `false` | 设为 `true` 时,交互事件仅响应描边区域(需配合 `stroke` 使用) |
| `lineWidth` | `number` | `2` | 设置描边的线宽 |
| `lineDash` | `number[]` | `[]` | 设置虚线样式 |
| `lineDashOffset` | `number` | `0` | 虚线样式偏移量 |
| `lineJoin` | `string` | `bevel` | 线的连接方式 |
| `lineCap` | `string` | `butt` | 线的末端样式 |
| `miterLimit` | `number` | `10` | 当使用 `miter` 连接方式时,其最大斜接限制 |
---
## 使用示例(以矩形为例)
### 示例 1:仅填充模式
```tsx
<g-rect
loc={[100, 100, 200, 150]} // x,y,width,height
fill
fillStyle="#fff"
/>
```
**效果**:
- 200x150 矩形
- 无描边效果
---
### 示例 2:仅描边模式
```tsx
<g-rect
loc={[400, 200, 180, 120]}
stroke
strokeStyle="rgba(0,0,0,0.8)"
lineWidth={4}
actionStroke // 点击时仅描边区域响应
/>
```
**交互特性**:
- 4px 黑色半透明描边
- 鼠标悬停在描边区域才会触发事件
---
### 示例 3:填充 + 描边(默认顺序)
```tsx
<g-rect
loc={[50, 300, 150, 100]}
fill
stroke
fillStyle="#ffe66d"
strokeStyle="#2d3436"
lineWidth={2}
/>
```
**渲染顺序**:
1. 填充黄色背景
2. 在填充层上绘制黑色描边
---
### 示例 4:先描边后填充
```tsx
<g-rect
loc={[300, 400, 200, 200]}
strokeAndFill
fillStyle="#a29bfe"
strokeStyle="#6c5ce7"
lineWidth={8}
/>
```
**渲染顺序**:
1. 绘制紫色描边
2. 在描边层上填充浅紫色
**视觉效果**:描边被填充色覆盖一部分
---
## 最佳实践
### 交互增强技巧
```tsx
import { ref } from 'vue';
// 高亮描边交互反馈
const hovered = ref(false);
// 使用 void 关键字屏蔽返回值,避免返回值泄漏
const enter = () => void (hovered.value = true);
const leave = () => void (hovered.value = false);
<g-rect
loc={[100, 100, 200, 80]}
fill
fillStyle="#ffffff"
stroke={hovered.value}
strokeStyle="#e84393"
lineWidth={3}
onEnter={enter}
onLeave={leave}
/>;
```
---
## 注意事项
1. **样式覆盖顺序**:
`strokeAndFill` 会强制按 **描边 → 填充** 顺序渲染,忽略 `fill` 和 `stroke` 的独立设置。
2. **路径闭合规则**:
`fillRule="evenodd"` 适用于以下场景:
```tsx
// 五角星镂空效果
<path
fill={true}
fillRule="evenodd"
path={starPath} // 交替重叠的路径
/>
```
3. **性能问题**:
多数情况下,图形的性能很好,不需要单独优化,但是如果你使用 `path` 标签,且内容复杂,建议添加 `cache` 属性来启用缓存,避免频繁的复杂图形绘制。

View File

@ -1,149 +0,0 @@
# use.ts API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 函数说明
### `onTick`
```typescript
function onTick(fn: (time: number) => void): void;
```
**功能**:注册每帧执行的回调(自动管理生命周期)
**推荐使用场景**:替代 `ticker`
**参数说明**:
- `fn`: 接收当前时间戳的帧回调函数
**示例**:
```typescript
// Vue 组件中
onTick(time => {
console.log('当前帧时间:', time);
});
```
---
### `useAnimation`
```typescript
function useAnimation(): [Animation];
```
**功能**:创建动画实例(自动销毁资源)
**返回值**:包含动画实例的元组
**推荐使用场景**:替代直接 `new Animation()`
**示例**:
```typescript
const [anim] = useAnimation();
anim.time(1000).move(100, 200);
```
---
### `useTransition`
```typescript
function useTransition(): [Transition];
```
**功能**:创建渐变实例(自动销毁资源)
**返回值**:包含渐变实例的元组
**推荐使用场景**:替代直接 `new Transition()`
**示例**:
```typescript
const [transition] = useTransition();
transition.value.x = 10;
transition.time(500);
transition.value.x = 100;
```
---
### `useKey`
```typescript
function useKey(noScope?: boolean): [Hotkey, symbol];
```
**功能**:管理按键作用域(自动注销绑定)
**参数说明**:
- `noScope`: 是否使用全局作用域(默认创建新作用域)
**返回值**:元组 [热键实例, 作用域标识]
**推荐使用场景**:替代直接操作全局热键实例
**示例**:
```typescript
const [hotkey, scope] = useKey();
hotkey.realize('mykey_id', () => console.log('mykey_id emitted.'));
```
---
### `onEvent`
```typescript
function onEvent<
T extends ERenderItemEvent,
K extends EventEmitter.EventNames<T>
>(
item: RenderItem<T>,
key: K,
listener: EventEmitter.EventListener<T, K>
): void;
```
**功能**:自动管理事件监听生命周期
**推荐使用场景**:替代直接 `item.on()` + 手动注销
**示例**:
```typescript
onEvent(sprite, 'click', event => {
console.log('元素被点击', event);
});
```
---
## 总使用示例
```tsx
import { defineComponent } from 'vue';
import { useAnimation, onTick, useKey } from '@motajs/render-vue';
export const MyComponent = defineComponent(() => {
// 动画控制
const [anim] = useAnimation();
anim.time(1000).rotate(Math.PI);
// 帧循环
onTick(time => {
console.log('当前游戏运行时间:', time);
});
// 按键控制
const [hotkey, scope] = useKey();
hotkey.realize('mykey_id', () => console.log('mykey_id emitted.'));
return () => <sprite />;
});
```
---
## 注意事项
1. **资源管理**:所有通过这些接口创建的资源(动画/渐变/事件)都会在组件卸载时自动销毁
2. **内存安全**:使用原生接口可能导致内存泄漏,这些封装接口确保:
- 自动注销事件监听
- 自动停止动画/渐变
- 自动清理按键绑定
3. **类型安全**:所有接口均包含完整的类型推断(如 `onEvent` 的事件类型检查)
4. **框架适配**:专为 Vue3 组合式 API 设计,不可用于其他框架环境

View File

@ -1,3 +0,0 @@
# @motajs/render-vue
目录:

View File

@ -1,139 +0,0 @@
# ContainerProps API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
ContainerProps --> BaseProps
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface ContainerProps extends BaseProps {} // 无新增属性,完全继承 BaseProps
```
---
## 核心能力
1. **嵌套结构**:支持多层容器嵌套,构建复杂 UI 层级
2. **批量更新**:通过容器隔离高频/低频更新内容
3. **虚拟化支持**:推荐结合 `Scroll`/`Page` 组件处理大数据量场景
---
## 完整示例集
### 示例 1:基础容器(静态内容优化)
```tsx
import { ref } from 'vue';
import { Font } from '@motajs/render-style';
const count = ref(0);
const boldFont = new Font('Verdana', 18, 'px', 700);
// 静态容器(启用缓存)
<container cache loc={[0, 0, 200, 200]}>
{/* 静态背景 */}
<sprite />
{/* 动态计数器 */}
<container x={100} y={100}>
<text text={count.value.toString()} font={boldFont} />
</container>
</container>;
```
**优化策略**:
- 背景层缓存,避免重复绘制
- 计数器单独放置在独立容器,避免高频内容污染致使低频内容也需要高频更新
---
### 示例 2:条件渲染 + 循环渲染
```tsx
import { ref } from 'vue';
// 根据状态显示不同内容
const tab = ref<'list' | 'detail'>('list');
const item = [{ id: 0, name: '第一个元素' }];
return () => (
<container>
{/* 选项卡导航 */}
<container x={20} y={20}>
<text text="列表" />
<text text="详情" />
</container>
{/* 条件内容区 */}
{tab === 'list' ? (
{/* 循环渲染 */}
<container cache={true} y={60}>
{items.map((item, i) => (
<text key={item.id} x={0} y={i * 40} text={`列表元素${item.name}`} />
))}
</container>
) : (
<container y={60}>
<text text="详情内容" />
</container>
)}
</container>
);
```
---
### 示例 3:动态布局嵌套
```tsx
// 自适应居中布局
<container anc={[0.5, 0.5]} loc={[0, 0, 200, 200]}>
{/* 主内容卡片 */}
<container>
<text x={20} y={20} text="自适应内容" />
</container>
{/* 控制栏 */}
<container loc={[20, 20, 200, 40]}>
<text text="控制栏" />
</container>
</container>
```
---
## 性能优化指南
### 缓存策略对比
| 场景 | 配置 | 重绘频率 | 适用场景 |
| ---------------- | -------------- | -------- | --------------- |
| 不频繁更新的内容 | `cache=true` | 偶尔重绘 | 背景/图标等 |
| 高频更新内容 | `nocache=true` | 每帧重绘 | 动画/计数器 |
| 混合内容 | 分层容器 | 按需更新 | 带静态背景的 UI |
### 大数据量处理方案
考虑使用[滚动条](../user-client-modules/组件%20Scroll.md)或[分页](../user-client-modules/组件%20Page.md)组件。
---
## 注意事项
1. **缓存失效条件**:当任意子元素及自身发生变化时,将会自动触发更新
2. **嵌套层级**:推荐使用容器嵌套提高缓存能力,但是并建议不嵌套过多
3. **子元素更新**:修改容器子元素时会触发整个容器的缓存重建
4. **内存管理**:超大缓存容器(如 4096x4096)可能触发浏览器纹理限制

View File

@ -1,88 +0,0 @@
# ContainerCustomProps API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
ContainerCustomProps --> ContainerProps --> BaseProps
click ContainerProps "./ContainerProps"
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface ContainerCustomProps extends ContainerProps {
/**
* 自定义容器渲染函数
* @param canvas - 离屏画布对象(已应用容器的变换矩阵)
* @param children - 所有子元素(未经过滤,按照 zIndex 从小到大排列)
* @param transform - 容器自身相对于父元素的变换矩阵
*/
render?: (
canvas: MotaOffscreenCanvas2D,
children: RenderItem[],
transform: Transform
) => void;
}
```
---
## 核心能力
1. **虚拟化渲染**:通过自定义筛选逻辑实现仅渲染想要渲染的内容
2. **渲染劫持**:完全接管子元素的绘制流程
---
## 完整示例集
### 示例 1:默认渲染模式(等同普通容器)
```tsx
// 不传 render 参数时,自动渲染全部子元素
<container-custom>
<sprite x={0} render={drawBackground} />
<text x={20} y={20} text="Default Render" />
<text x={200} text="Click Me" />
</container-custom>
```
---
### 示例 2:部分渲染(仅显示可见区域)
```tsx
const render = (
canvas: MotaOffscreenCanvas2D,
children: RenderItem[],
transform: Transform
) => {
// 在 [0, 0, 200, 200] 之外的内容不渲染
children.forEach(child => {
const rect = child.getBoundingRect();
// 不在范围内的排除
if (
rect.right < 0 ||
rect.bottom < 0 ||
rect.left > 200 ||
rect.top > 200
)
return;
child.renderContent(canvas, transform);
});
};
<container-custom render={render}>
{/* 循环渲染 */}
{items.map((item, i) => (
<sprite x={i * 60} y={0} />
))}
</container-custom>;
```

View File

@ -1,202 +0,0 @@
# g-bezier 标签 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
BezierProps --> GraphicBaseProps --> BaseProps
click GraphicBaseProps "./GraphicBaseProps"
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface BezierProps extends GraphicBaseProps {
sx?: number; // 起点X坐标
sy?: number; // 起点Y坐标
cp1x?: number; // 第一控制点X坐标
cp1y?: number; // 第一控制点Y坐标
cp2x?: number; // 第二控制点X坐标
cp2y?: number; // 第二控制点Y坐标
ex?: number; // 终点X坐标
ey?: number; // 终点Y坐标
curve?: BezierParams; // 简写属性 [sx, sy, cp1x, cp1y, cp2x, cp2y, ex, ey]
}
```
---
## 核心属性说明
| 属性 | 类型 | 默认值 | 说明 |
| ------- | ------------------------------------------ | ------ | ------------------------------------- |
| `sx` | `number` | - | 曲线起点 X 坐标(单位:像素) |
| `sy` | `number` | - | 曲线起点 Y 坐标(单位:像素) |
| `cp1x` | `number` | - | 第一控制点 X 坐标(影响曲线起始方向) |
| `cp1y` | `number` | - | 第一控制点 Y 坐标 |
| `cp2x` | `number` | - | 第二控制点 X 坐标(影响曲线结束方向) |
| `cp2y` | `number` | - | 第二控制点 Y 坐标 |
| `ex` | `number` | - | 曲线终点 X 坐标 |
| `ey` | `number` | - | 曲线终点 Y 坐标 |
| `curve` | `[sx, sy, cp1x, cp1y, cp2x, cp2y, ex, ey]` | - | 简写属性:一次性定义全部坐标点 |
---
## 完整示例集
### 示例 1:基础三次贝塞尔曲线
```tsx
// 曲线默认仅描边,不需要单独设置 stroke 属性
<g-bezier
sx={100} // 起点 (100, 300)
sy={300}
cp1x={200} // 第一控制点 (200, 100)
cp1y={100}
cp2x={400} // 第二控制点 (400, 500)
cp2y={500}
ex={500} // 终点 (500, 300)
ey={300}
strokeStyle="#e74c3c"
strokeWidth={3}
/>
```
---
### 示例 2:虚线波浪线
```tsx
<g-bezier
curve={[50, 200, 150, 50, 250, 350, 350, 200]} // 简写属性定义
stroke={true}
strokeStyle="#3498db"
strokeWidth={2}
lineDash={[10, 5]} // 虚线样式
lineCap="round" // 圆角端点
/>
```
**曲线形态**:
- 起点 (50,200) → 第一控制点 (150,50)
- 第二控制点 (250,350) → 终点 (350,200)
- 形成"S"型波浪线
---
### 示例 3:动态流体效果
```tsx
import { ref } from 'vue';
const offset = ref(0);
// 每帧更新控制点位置
onTick(() => {
offset.value += 0.02;
});
<g-bezier
sx={100}
sy={400}
cp1x={200 + Math.sin(offset.value) * 30} // 水平波动
cp1y={300 + Math.cos(offset.value) * 50} // 垂直波动
cp2x={400}
cp2y={500}
ex={500}
ey={400}
strokeStyle={`hsl(${offset * 50}, 70%, 50%)`} // 变化的颜色
strokeWidth={4}
/>;
```
---
## 控制点行为说明
### 控制点影响示意图
```typescript
/*
(cp1)
▲
|
(start)●━━╋━━━━━━━━━━━┓
┃ ┃
┃ (cp2) ┃
┃ ▼ ┃
┗━━━━━━━●━━(end)
*/
```
- **第一控制点** (`cp1`):控制曲线起始方向的弯曲程度
- **第二控制点** (`cp2`):控制曲线结束方向的弯曲程度
### 特殊形态案例
| 控制点布局 | 曲线形态描述 |
| ------------------------------------ | ----------------- |
| `cp1`靠近起点,`cp2`靠近终点 | 近似直线 |
| `cp1`与`cp2`对称分布 | 形成对称波浪 |
| `cp1`在起点正上方,`cp2`在终点正下方 | 创建垂直"S"型曲线 |
---
## 高级用法示例
### 复杂路径组合
```tsx
// 组合多条贝塞尔曲线形成花瓣造型
<container x={400} y={300}>
{Array.from({ length: 5 }).map((_, i) => (
<g-bezier
key={i}
curve={[
0,
0, // 起点(中心)
Math.cos(angle) * 80, // cp1(外层控制点)
Math.sin(angle) * 80,
Math.cos(angle + Math.PI / 5) * 120, // cp2(花瓣尖端控制点)
Math.sin(angle + Math.PI / 5) * 120,
Math.cos(angle + Math.PI / 2.5) * 80, // 终点(对称点)
Math.sin(angle + Math.PI / 2.5) * 80
]}
fill
stroke
strokeStyle="#e84393"
fillStyle="rgba(232,67,147,0.3)"
rotate={((Math.PI * 2) / 5) * i} // 旋转复制
/>
))}
</container>
```
---
## 注意事项
1. **闭合路径**:
三次贝塞尔曲线默认不闭合,如需闭合需手动连接到起点:
```tsx
<g-bezier
curve={[100, 100, 200, 50, 300, 150, 100, 100]} // 终点回到起点
fill // 自动闭合填充
/>
```
2. **控制点极值**:
当控制点距离起点/终点过远时可能产生剧烈弯曲:
```tsx
// 可能产生非预期锐角
<g-bezier cp1x={sx + 500} .../>
```

View File

@ -1,182 +0,0 @@
# g-circle 标签 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
CircleProps --> GraphicBaseProps --> BaseProps
click GraphicBaseProps "./GraphicBaseProps"
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface CircleProps extends GraphicBaseProps {
radius?: number; // 圆的半径
start?: number; // 起始角度(单位:弧度)
end?: number; // 结束角度(单位:弧度)
circle?: CircleParams; // 简写属性 [x, y, radius, start?, end?],后两项要么都填,要么都不填
}
```
---
## 核心属性说明
| 属性 | 类型 | 默认值 | 说明 |
| -------- | ------------------------- | ------ | ---------------------------------------------------------- |
| `radius` | `number` | - | 圆的半径(单位:像素) |
| `start` | `number` | `0` | 起始角度(弧度),0 弧度 = 3 点钟方向(水平向右) |
| `end` | `number` | `2π` | 结束角度(弧度),默认完整圆 |
| `circle` | `[x, y, r, start?, end?]` | - | 简写属性:<br>`[圆心x, 圆心y, 半径, 起始角度?, 结束角度?]` |
---
## 完整示例集
### 示例 1:基础圆形(填充)
```tsx
<g-circle
x={100} // 圆心x坐标
y={100} // 圆心y坐标
radius={50} // 半径50px
fill // 启用填充
fillStyle="#ff7675" // 珊瑚红色
/>
```
---
### 示例 2:描边圆形
```tsx
<g-circle
circle={[300, 200, 60]} // 简写属性 [x,y,radius]
stroke // 启用描边
strokeStyle="#0984e3" // 蓝色描边
strokeWidth={5} // 5px宽描边
/>
```
---
### 示例 3:弓形(填充闭合)
```tsx
<g-circle
// 起始角度:90度(12点钟方向) 结束角度:180度(9点钟方向)
circle={[500, 300, 80, Math.PI / 2, Math.PI]}
fill
fillStyle="#55efc4" // 薄荷绿填充
/>
```
**角度说明**:
- 绘制方向:**顺时针**(从 12 点走向 9 点)
- 自动闭合路径形成扇形
---
### 示例 4:圆弧(非闭合)
```tsx
<g-circle
circle={[200, 400, 70, Math.PI / 4, Math.PI * 1.5]} // [x,y,r,start,end]
stroke // 仅描边
strokeStyle="#d63031" // 红色描边
strokeWidth={3}
/>
```
**路径特征**:
- 起始角度:45 度(右上对角线方向)
- 结束角度:270 度(12 点钟方向)
- 开环不闭合,形成月牙形弧线
---
## 角度系统详解
### 坐标系与方向
```typescript
// 0弧度基准点与绘制方向示意图
/*
Math.PI / 2 (90°)
|
|
Math.PI (180°) ——+—— 0 (0°)
|
|
Math.PI * 3 / 2 (270°)
*/
```
- **0 弧度基准**:3 点钟方向(与浏览器 Canvas API 完全一致)
- **绘制方向**:角度递增为顺时针方向(`start=0, end=Math.PI/2` 绘制右下四分之一圆)
### 特殊角度对照表
| 弧度值 | 角度值 | 方向 |
| ------------- | ------ | ------ |
| `0` | 0° | 正右 → |
| `Math.PI/2` | 90° | 正上 ↑ |
| `Math.PI` | 180° | 正左 ← |
| `3*Math.PI/2` | 270° | 正下 ↓ |
---
## 高级用法示例
### 动态进度环
```tsx
import { ref } from 'vue';
import { onTick } from '@motajs/render-vue';
const progress = ref(0);
// 每帧更新进度
onTick(() => {
progress.value += 0.01;
});
<g-circle
circle={[400, 400, 100]}
start={-Math.PI / 2} // 从12点开始
end={-Math.PI / 2 + progress.value * Math.PI * 2} // 顺时针增长
stroke
strokeStyle="#00b894"
strokeWidth={15}
lineCap="round" // 圆角端点
/>;
```
**效果**:
- 0%时从顶部开始
- 进度条顺时针增长
- 圆角端点消除锯齿
---
## 注意事项
1. **简写属性优先级**:
```tsx
// 谁最后设置用谁的
<g-circle
x={100} // 被覆盖
circle={[200, 300, 50]} // 实际生效坐标 (200,300)
/>
```

View File

@ -1,175 +0,0 @@
# g-ellipse 标签 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
EllipseProps --> GraphicBaseProps --> BaseProps
click GraphicBaseProps "./GraphicBaseProps"
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface EllipseProps extends GraphicBaseProps {
radiusX?: number; // 椭圆X轴半径
radiusY?: number; // 椭圆Y轴半径
start?: number; // 起始角度(单位:弧度)
end?: number; // 结束角度(单位:弧度)
ellipse?: EllipseParams; // 简写属性 [x, y, rx, ry, start?, end?]
}
```
---
## 核心属性说明
| 属性 | 类型 | 默认值 | 说明 |
| --------- | ------------------------------ | ------ | ------------------------------------------------------------------ |
| `radiusX` | `number` | - | 椭圆 X 轴半径(单位:像素) |
| `radiusY` | `number` | - | 椭圆 Y 轴半径(单位:像素) |
| `start` | `number` | `0` | 起始角度(弧度),0 弧度 = 3 点钟方向 |
| `end` | `number` | `2π` | 结束角度(弧度),默认完整椭圆 |
| `ellipse` | `[x, y, rx, ry, start?, end?]` | - | 简写属性:<br>`[圆心x, 圆心y, X半径, Y半径, 起始角度?, 结束角度?]` |
---
## 完整示例集
### 示例 1:基础椭圆(填充)
```tsx
<g-ellipse
ellipse={[200, 150, 100, 60]} // X轴半径100px Y轴半径60px
fill // 启用填充
fillStyle="#a55eea" // 紫色填充
/>
```
---
### 示例 2:描边椭圆
```tsx
<g-ellipse
ellipse={[400, 300, 80, 40]} // 简写属性 [x,y,rx,ry]
stroke // 启用描边
strokeStyle="#2d98da" // 蓝色描边
strokeWidth={3} // 3px宽描边
lineDash={[10, 5]} // 虚线样式
/>
```
---
### 示例 3:椭圆弓形(闭合)
```tsx
<g-ellipse
ellipse={[600, 200, 120, 80, Math.PI / 4, Math.PI * 1.25]}
fill
fillStyle="#fd9644" // 橙色填充
/>
```
**角度说明**:
- 绘制方向:**顺时针**(从 45 度到 225 度)
- 自动闭合路径形成扇形
- 若路径自相交,`evenodd` 规则会生成镂空
---
### 示例 4:椭圆弧线(非闭合)
```tsx
<g-ellipse
ellipse={[300, 400, 150, 50, -Math.PI / 2, Math.PI / 2]} // 从12点到6点
stroke
strokeStyle="#eb3b5a" // 红色描边
strokeWidth={5}
lineCap="round" // 圆角端点
/>
```
**路径特征**:
- 垂直方向椭圆弧(X 半径 > Y 半径)
- 起始角度:-90 度(12 点方向)
- 结束角度:90 度(6 点方向)
- 开环形成对称弧线
---
## 角度系统详解
### 坐标系与方向
```typescript
// 角度系统与圆形一致,但受半径比例影响:
/*
radiusY
↑
|
radiusX +---→
*/
```
- **0 弧度基准**:3 点钟方向(与浏览器 Canvas API 一致)
- **半径影响**:当 `radiusX ≠ radiusY` 时,相同角度对应的端点位置会拉伸
- **绘制方向**:角度递增为顺时针方向
### 特殊角度效果
| 参数组合 | 效果描述 |
| ---------------------------------- | ------------------------ |
| `radiusX=radiusY` | 退化为标准圆形 |
| `start=0, end=Math.PI` | 右半椭圆(水平方向半圆) |
| `start=Math.PI/2, end=3*Math.PI/2` | 上半椭圆(垂直方向半圆) |
---
## 高级用法示例
### 动态仪表盘
```tsx
import { ref } from 'vue';
const value = ref(0.3);
<g-ellipse
ellipse={[500, 500, 200, 100]}
start={-Math.PI / 2 - Math.PI / 4} // 起始角度:-135度(左上方)
end={-Math.PI / 2 - Math.PI / 4 + value.value * Math.PI * 1.5} // 按比例延伸
stroke
strokeStyle="#4b7bec"
strokeWidth={20}
lineCap="round"
/>;
```
**效果**:
- 椭圆弧仪表盘,从左上方向右侧延伸
- 进度值 `0.3` 时覆盖 30%路径
---
## 注意事项
1. **简写属性优先级**:
```tsx
// 谁最后被设置用谁的
<g-ellipse
radiusX={100} // 被覆盖
ellipse={[200, 200, 150, 80]} // 实际生效 rx=150, ry=80
/>
```

View File

@ -1,125 +0,0 @@
# g-line 标签 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
LineProps --> GraphicBaseProps --> BaseProps
click GraphicBaseProps "./GraphicBaseProps"
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface LineProps extends GraphicBaseProps {
x1?: number; // 起点X坐标
y1?: number; // 起点Y坐标
x2?: number; // 终点X坐标
y2?: number; // 终点Y坐标
line?: LineParams; // 简写属性 [x1, y1, x2, y2]
}
```
---
## 核心属性说明
| 属性 | 类型 | 默认值 | 说明 |
| ---------- | ----------------------------------- | -------- | ---------------------------------------------- |
| `x1` | `number` | - | 线段起点 X 坐标(单位:像素) |
| `y1` | `number` | - | 线段起点 Y 坐标(单位:像素) |
| `x2` | `number` | - | 线段终点 X 坐标(单位:像素) |
| `y2` | `number` | - | 线段终点 Y 坐标(单位:像素) |
| `line` | `[x1, y1, x2, y2]` | - | 简写属性:一次性定义起点和终点坐标 |
| `lineDash` | `number[]` | - | 虚线模式(如 `[5, 3]` 表示 5px 实线+3px 间隙) |
| `lineCap` | `"butt"` \| `"round"` \| `"square"` | `"butt"` | 线段端点样式 |
---
## 完整示例集
### 示例 1:基础实线
```tsx
// 线段默认就是仅描边,因此不需要单独设置 stroke 属性
<g-line
line={[100, 50, 300, 50]} // 起点坐标 (100, 50) 终点坐标 (300, 50)
strokeStyle="#2d98da" // 蓝色
strokeWidth={3} // 3px宽度
/>
```
---
### 示例 2:虚线线段
```tsx
<g-line
line={[50, 150, 400, 150]} // 简写属性定义起点终点
strokeStyle="#eb3b5a" // 红色
strokeWidth={2}
lineDash={[10, 5]} // 10px实线 + 5px间隙
lineCap="round" // 圆角端点
/>
```
**效果说明**:
- 水平红色虚线
- 线段端点呈圆形
---
### 示例 3:动态线段(动画)
```tsx
import { transitioned } from '@user/client-modules';
// 创建渐变
const x2 = transitioned(100, 2000, linear());
x2.set(400); // 终点横坐标从 100 变到 400
return () => (
<g-line
line={[100, 300, x2.ref.value, 300]}
strokeStyle="#10ac84"
strokeWidth={4}
/>
);
```
**动态效果**:
- 线段从 100px 位置向右延伸至 400px
- 2 秒完成动画
---
## 线段样式对照表
| 样式组合 | 效果图示 |
| --------------------- | ----------------- |
| `lineCap="butt"` | 平头端点:⎯ |
| `lineCap="round"` | 圆头端点:⭘―――――⭘ |
| `lineCap="square"` | 方头端点:▯―――――▯ |
| `lineDash=[20,5,5,5]` | 复杂虚线:━━⧀┄⧀┄ |
---
## 注意事项
1. **坐标系差异**:
线段坐标基于父容器坐标系,如需相对定位建议嵌套在`container`中:
```tsx
<container x={100} y={100}>
{/* 实际坐标为 (100,100)→(150,150) */}
<g-line line={[0, 0, 50, 50]} />
</container>
```

View File

@ -1,173 +0,0 @@
# g-path 标签 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
PathProps --> GraphicBaseProps --> BaseProps
click GraphicBaseProps "./GraphicBaseProps"
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface PathProps extends GraphicBaseProps {
path?: Path2D; // 自定义路径对象
}
```
---
## 核心属性说明
| 属性 | 类型 | 默认值 | 说明 |
| -------------- | -------------------------- | ----------- | -------------------------------------------------- |
| `path` | `Path2D` | - | 自定义矢量路径(支持多路径、贝塞尔曲线等复杂形状) |
| `fillRule` | `"nonzero"` \| `"evenodd"` | `"evenodd"` | 填充规则(影响路径重叠区域的渲染) |
| `actionStroke` | `boolean` | `false` | 设为 `true` 时,交互事件仅检测描边区域 |
---
## 完整示例集
### 示例 1:复杂星形路径
```tsx
// 创建五角星路径
const starPath = new Path2D();
for (let i = 0; i < 5; i++) {
const angle = (i * 2 * Math.PI) / 5 - Math.PI / 2;
const x = 100 + Math.cos(angle) * 50;
const y = 100 + Math.sin(angle) * 50;
if (i === 0) starPath.moveTo(x, y);
else starPath.lineTo(x, y);
}
starPath.closePath();
<g-path
x={200}
y={200}
path={starPath}
fill
stroke
fillStyle="#f1c40f"
fillRule="evenodd" // 使用奇偶环绕原则,使中心镂空
strokeStyle="#e67e22"
strokeWidth={3}
/>;
```
**效果说明**:
- 使用`evenodd`规则自动产生星形镂空效果
- 金色填充+橙色描边的五角星
---
### 示例 2:交互式描边检测
```tsx
import { ref } from 'vue';
const [clicked, setClicked] = useState(false);
const clicked = ref(false);
// 创建对话气泡路径
const bubblePath = new Path2D();
bubblePath.moveTo(50, 20);
bubblePath.quadraticCurveTo(25, 0, 0, 20);
bubblePath.quadraticCurveTo(25, 40, 50, 20);
bubblePath.rect(0, 20, 200, 100);
const click = () => void (clicked.value = !click.value);
<g-path
path={bubblePath}
fillStyle={clicked.value ? '#ffffff' : '#ecf0f1'}
strokeStyle="#bdc3c7"
strokeWidth={2}
actionStroke // 仅描边区域可交互
onClick={click}
/>;
```
**交互特性**:
- 点击描边区域切换填充颜色
- 内部区域不响应点击事件
---
### 示例 3:组合路径(齿轮造型)
```tsx
const gearPath = new Path2D();
// 主体圆形
gearPath.arc(100, 100, 80, 0, Math.PI * 2);
// 添加8个齿牙
for (let i = 0; i < 8; i++) {
const angle = ((Math.PI * 2) / 8) * i;
gearPath.moveTo(100 + Math.cos(angle) * 90, 100 + Math.sin(angle) * 90);
gearPath.lineTo(
100 + Math.cos(angle + Math.PI / 8) * 110,
100 + Math.sin(angle + Math.PI / 8) * 110
);
gearPath.lineTo(
100 + Math.cos(angle - Math.PI / 8) * 110,
100 + Math.sin(angle - Math.PI / 8) * 110
);
}
<g-path
path={gearPath}
fill
stroke
fillStyle="#2c3e50"
fillRule="nonzero" // 非零规则填充
strokeStyle="#34495e"
strokeWidth={5}
lineJoin="miter" // 尖角连接
/>;
```
---
## 高级用法示例
### SVG 路径转换
```tsx
// 将SVG路径转换为Path2D
const svgPath = 'M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80';
const path = new Path2D(svgPath);
<g-path
path={path}
stroke
strokeStyle="#e74c3c"
strokeWidth={3}
lineDash={[10, 5]}
lineCap="round"
/>;
```
---
## 注意事项
1. **路径闭合**:
```tsx
// 必须显式闭合路径才能正确填充
const path = new Path2D();
path.moveTo(0, 0);
path.lineTo(100, 0);
path.lineTo(100, 100);
path.closePath(); // 关键闭合操作
```

View File

@ -1,119 +0,0 @@
# g-quad 标签 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
QuadraticProps --> GraphicBaseProps --> BaseProps
click GraphicBaseProps "./GraphicBaseProps"
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface QuadraticProps extends GraphicBaseProps {
sx?: number; // 起点X坐标
sy?: number; // 起点Y坐标
cpx?: number; // 控制点X坐标
cpy?: number; // 控制点Y坐标
ex?: number; // 终点X坐标
ey?: number; // 终点Y坐标
curve?: QuadParams; // 简写属性 [sx, sy, cpx, cpy, ex, ey]
}
```
---
## 核心属性说明
| 属性 | 类型 | 默认值 | 说明 |
| ------- | ---------------------------- | ------ | --------------------------------------- |
| `sx` | `number` | - | 曲线起点 X 坐标(单位:像素) |
| `sy` | `number` | - | 曲线起点 Y 坐标(单位:像素) |
| `cpx` | `number` | - | 控制点 X 坐标(决定曲线弯曲方向和程度) |
| `cpy` | `number` | - | 控制点 Y 坐标 |
| `ex` | `number` | - | 曲线终点 X 坐标 |
| `ey` | `number` | - | 曲线终点 Y 坐标 |
| `curve` | `[sx, sy, cpx, cpy, ex, ey]` | - | 简写属性:一次性定义全部坐标点 |
---
## 完整示例集
### 示例 1:基础二次贝塞尔曲线
```tsx
<g-quad
sx={100} // 起点 (100, 300)
sy={300}
cpx={300} // 控制点 (300, 100)
cpy={100}
ex={500} // 终点 (500, 300)
ey={300}
strokeStyle="#2ecc71" // 绿色
strokeWidth={3}
/>
```
---
### 示例 2:虚线抛物线
```tsx
<g-quad
curve={[50, 400, 250, 100, 450, 400]} // 简写属性定义
strokeStyle="#f1c40f" // 黄色
strokeWidth={2}
lineDash={[15, 5]} // 长虚线样式
/>
```
**曲线形态**:
- 起点 (50,400) → 控制点 (250,100) → 终点 (450,400)
- 形成对称的类似抛物线形状的曲线
---
## 控制点行为说明
### 控制点影响示意图
```typescript
/*
(cpx,cpy)
●
/ \
/ \
(start) ●-----●(end)
*/
```
- **单控制点**:二次贝塞尔曲线仅有一个控制点,同时影响曲线的起始和结束方向
- **对称性**:控制点距离起点/终点的垂直距离越大,曲线弯曲越明显
### 特殊形态案例
| 控制点布局 | 曲线形态描述 |
| ------------------------ | ------------- |
| 控制点在起点终点连线中点 | 退化为直线 |
| 控制点在起点正上方 | 形成"U"型曲线 |
| 控制点在终点右侧 | 形成"C"型曲线 |
---
## 注意事项
1. **控制点极限值**:
当控制点与起点/终点距离过大时可能产生锐角:
```tsx
// 可能产生非预期的尖角形态
<g-quad cpx={sx + 1000} .../>
```

View File

@ -1,91 +0,0 @@
# g-rect 标签 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
RectProps --> GraphicBaseProps --> BaseProps
click GraphicBaseProps "./GraphicBaseProps"
click BaseProps "./BaseProps"
```
---
## 使用示例
### 示例 1:仅填充模式
```tsx
<g-rect
loc={[100, 100, 200, 150]} // x,y,width,height
fill
fillStyle="#fff"
/>
```
**效果**:
- 200x150 矩形
- 无描边效果
---
### 示例 2:仅描边模式
```tsx
<g-rect
loc={[400, 200, 180, 120]}
stroke
strokeStyle="rgba(0,0,0,0.8)"
strokeWidth={4}
actionStroke // 点击时仅描边区域响应
/>
```
**交互特性**:
- 4px 黑色半透明描边
- 鼠标悬停在描边区域才会触发事件
---
### 示例 3:填充 + 描边(默认顺序)
```tsx
<g-rect
loc={[50, 300, 150, 100]}
fill
stroke
fillStyle="#ffe66d"
strokeStyle="#2d3436"
strokeWidth={2}
/>
```
**渲染顺序**:
1. 填充黄色背景
2. 在填充层上绘制黑色描边
---
### 示例 4:强制先描边后填充
```tsx
<g-rect
loc={[300, 400, 200, 200]}
strokeAndFill
fillStyle="#a29bfe"
strokeStyle="#6c5ce7"
strokeWidth={8}
/>
```
**渲染顺序**:
1. 绘制紫色描边
2. 在描边层上填充浅紫色
**视觉效果**:描边被填充色覆盖一部分

View File

@ -1,167 +0,0 @@
# g-rectr 标签 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
RectRProps --> GraphicBaseProps --> BaseProps
click GraphicBaseProps "./GraphicBaseProps"
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface RectRProps extends GraphicBaseProps {
/**
* 圆形圆角参数 [左上, 右上, 右下, 左下]
* - 1个值:全角相同
* - 2个值:左上+右下 / 右上+左下
* - 3个值:左上 / 右上+左下 / 右下
* - 4个值:分别设置四个角 左上、右上、左下、右下
*/
circle?: RectRCircleParams;
/**
* 椭圆圆角参数 [x半径, y半径, ...]
* - 1组:全角相同
* - 2组:左上+右下 / 右上+左下
* - 3组:左上 / 右上+左下 / 右下
* - 4组:分别设置四个角 左上、右上、左下、右下
*/
ellipse?: RectREllipseParams;
}
```
---
## 核心行为规则
- **参数限制**:若圆角值超过 `width/height` 的 50% 或为负数,将自动修正:
- 负值 → 修正为 0
- 超过 50% → 修正为 50%
- **参数优先级**:`ellipse` 优先级高于 `circle`
---
## 完整示例集
### 示例 1:统一圆形圆角
```tsx
<g-rectr
loc={[100, 100, 300, 200]} // x,y,width,height
circle={[20]} // 所有角20px半径
fill
fillStyle="#3498db"
/>
```
---
### 示例 2:差异圆形圆角
```tsx
<g-rectr
loc={[500, 200, 250, 150]}
circle={[30, 15, 50, 0]} // 左上30px, 右上15px, 右下50px, 左下0px
stroke
strokeStyle="#2c3e50"
strokeWidth={4}
/>
```
---
### 示例 3:椭圆圆角
```tsx
<g-rectr
loc={[100, 400, 200, 100]}
ellipse={[30, 20, 10, 40]} // 左上+右下(30,20), 右上+左下(10,40)
fillStyle="#e74c3c"
fillRule="nonzero"
/>
```
---
### 示例 4:混合椭圆圆角
```tsx
<g-rectr
loc={[500, 400, 300, 200]}
ellipse={[
80,
50, // 左上:水平80px 垂直50px
40,
100, // 右上:水平40px 垂直100px
120,
30, // 右下:水平120px 垂直30px
60,
80 // 左下:水平60px 垂直80px
]}
fillStyle="#2ecc71"
strokeWidth={2}
/>
```
---
## 参数对照表
### 圆形圆角(circle)参数规则
| 参数数量 | 生效规则 |
| -------- | -------------------------------------------- |
| 1 | 全角相同:`[20] → [20,20,20,20]` |
| 2 | 对角对称:`[10,30] → [10,30,30,10]` |
| 3 | 左上/对角/右下:`[10,20,30] → [10,20,30,20]` |
| 4 | 独立设置四个角:`[10,20,30,40]` |
### 椭圆圆角(ellipse)参数规则
| 参数组数 | 生效规则 |
| -------- | ---------------------------------------------- |
| 1 | 全角相同:`[15,20] → 四角均为15x20` |
| 2 | 对角对称:`[10,5,20,10] → 左上+右下/右上+左下` |
| 3 | 左上/对角/右下:`[10,20,15,5,20,10]` |
| 4 | 独立设置四个角:`[10,20,15,25,20,30,5,10]` |
---
## 错误处理示例
```tsx
// 危险参数示例
<g-rectr
loc={[0, 0, 100, 50]}
circle={[-10, 200]} // 输入 [-10, 200]
stroke={true}
/>
```
**实际生效值**:
- 负值修正:`-10 → 0`
- 超限修正:`200 → min(200, 50/2=25) → 25px`
- 最终参数:`[0,25] → [0,25,25,0]`
---
## 最佳实践建议
1. **响应式圆角**:
```tsx
// 圆角随尺寸变化
<g-rectr
loc={[x, y, width.value, height]}
circle={[width.value * 0.1]} // 圆角为宽度的10%
/>
```

View File

@ -1,121 +0,0 @@
# icon 标签 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
IconProps --> BaseProps
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface IconProps extends BaseProps {
icon: AllNumbers | AllIds; // 图标ID或数字标识
frame?: number; // 显示指定帧(从0开始计数)
animate?: boolean; // 是否启用帧动画循环(默认false)
}
```
---
## 核心属性说明
| 属性 | 类型 | 默认值 | 说明 |
| --------- | -------------------- | -------- | ------------------------------------------------------ |
| `icon` | `number` \| `string` | **必填** | 图标资源标识符(对应素材库中的图块 ID 或预设数字编码) |
| `frame` | `number` | `0` | 指定显示的帧序号(当`animate=false`时生效) |
| `animate` | `boolean` | `false` | 启用自动播放帧动画(优先级高于`frame`参数) |
---
## 完整示例集
### 示例 1:静态显示指定帧
```tsx
// 显示图块ID为"greenSlime"的第3帧(索引从0开始)
<icon
loc={[100, 200]}
icon="greenSlime" // 图标资源ID
frame={2} // 显示第3帧
/>
```
---
### 示例 2:动态帧动画
```tsx
// 自动播放4帧循环动画
<icon
loc={[300, 150]} // x=300, y=150
icon={100} // 数字编码图标
animate // 启用自动播放
/>
```
**动画行为**:
- 播放图标自带的 4 帧动画序列(0→1→2→3→0...)
- 动画速度由素材预设帧率决定
---
### 示例 3:交互控制动画
```tsx
import { ref } from 'vue';
const animating = ref(false);
const click = () => void (animating.value = false);
// 点击切换动画状态
<icon
loc={[500, 300]}
icon="yellowDoor"
animate={animating.value}
frame={0} // 动画停止时显示第1帧
cursor="pointer"
onClick={click}
/>;
```
**交互逻辑**:
- 初始状态显示第 1 帧(门关闭)
- 点击后播放开门动画
---
## 帧动画系统规则
### 帧索引定义
```typescript
// 图块素材帧结构示例
/*
[0] [1] [2] [3]
+---+---+---+---+
| | | | | // 4帧水平排列的图块素材
+---+---+---+---+
*/
```
- **播放方向**:始终从 `0` 帧开始正向循环
- **循环模式**:播放到最后一帧后回到第 `0` 帧
### 参数限制
| 场景 | 系统行为 |
| ----------------------------- | ------------------------------------- |
| `frame` 超过最大帧数 | 报错 |
| `frame` 为负数 | 报错 |
| `animate=true` 时修改 `frame` | `frame` 参数被忽略,始终从 0 开始播放 |

View File

@ -1,103 +0,0 @@
# image 标签 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
ImageProps --> BaseProps
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface ImageProps extends BaseProps {
/** 必填 - 图片对象(CanvasImageSource 类型) */
image: CanvasImageSource;
}
```
---
## 核心功能
- **尺寸控制**:通过 `width/height` 或 `loc` 简写属性定义图片尺寸(默认 200x200)
- **像素风支持**:通过 `noanti=true` 禁用抗锯齿
---
## 使用示例
### 示例 1:基础图片显示
```tsx
const image = core.material.images.images['myimage.webp'];
// 显示 200x200 的默认尺寸图片
<image x={100} y={50} image={image} />;
```
**等效简写**:
```tsx
const image = core.material.images.images['myimage.webp'];
<image
loc={[100, 50]} // width/height 使用默认 200x200
image={image}
/>;
```
---
### 示例 2:自定义尺寸
```tsx
const image = core.material.images.images['myimage.webp'];
// 方式一:直接设置宽高
<image
x={300}
y={200}
width={150} // 覆盖默认宽度
height={80} // 覆盖默认高度
image={image}
/>;
// 方式二:通过 loc 简写属性
<image
loc={[500, 200, 120, 120]} // [x, y, width, height]
image={image}
/>;
```
---
### 示例 3:像素风渲染(禁用抗锯齿)
```tsx
const pixelImage = core.material.images.images['myimage.webp'];
// 硬核像素风格配置
<image
loc={[50, 50, 64, 64]}
image={pixelImage}
noanti // 关键配置:关闭抗锯齿
/>;
```
**效果说明**:
- 原始 32x32 像素图 → 放大为 64x64 像素
- 每个像素块保持锐利边缘
---
## 属性配置表
| 属性 | 类型 | 默认值 | 说明 |
| ------- | ------------------- | -------- | ------------------------------------------- |
| `image` | `CanvasImageSource` | **必填** | 图片资源(ImageBitmap/HTMLImageElement 等) |

View File

@ -1,148 +0,0 @@
# sprite 标签 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
SpriteProps --> BaseProps
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface SpriteProps extends BaseProps {
/**
* 自定义渲染函数
* @param canvas - 离屏画布对象
* @param transform - 当前元素相对于父元素的变换矩阵
*/
render?: (canvas: MotaOffscreenCanvas2D, transform: Transform) => void;
}
```
---
## 核心能力
通过 `render` 函数实现 **动态绘制**,可结合:
- 基础定位/变换参数(继承 `BaseProps`)
- 动画系统(`useAnimation`)
- 帧回调(`onTick`)
- 自定义图形绘制(路径/滤镜/混合模式)
**注意**,这个标签虽然非常基础,但是应该并不常用,因为很多内容都有对应的标签可以实现(例如线可以使用 `g-line` 标签等),因此如果你在考虑使用此标签,请确认你必须使用它,或是你的场景对性能非常敏感。
---
## 使用示例
以下的示例代码均应该在**组件内部**编写,哪里是组件内部请参考[指南](../../guide/ui/ui.md)。
### 示例 1:基础图形
```tsx
import { MotaOffscreenCanvas2D } from '@motajs/render-core';
// 绘制旋转了 45 度的彩色方块
const render = (canvas: MotaOffscreenCanvas2D) => {
const ctx = canvas.ctx;
ctx.fillStyle = 'rgba(255,0,0,0.8)';
ctx.strokeStyle = 'blue';
ctx.lineWidth = 3;
ctx.beginPath();
ctx.rect(0, 0, 200, 200);
ctx.fill();
ctx.stroke();
};
<sprite x={200} y={200} rotate={Math.PI / 4} render={render} />;
```
**效果**:
- 100x100 红色方块,中心点位于 (200,200)
- 45 度旋转,蓝色描边
- 80% 不透明度
---
### 示例 2:结合动画系统
```tsx
import { ref } from 'vue';
import { useAnimation } from '@motajs/render-vue';
// 平移动画 + 动态缩放
const [anim] = useAnimation();
anim.time(2000).move(100, 0).scale(1.5);
const loc = ref<ElementLocator>([0, 0]);
const scale = ref<ElementScaler>([1, 1]);
onTick(() => {
loc.value = [anim.x, anim.y];
scale.value = [anim.size, anim.size];
});
const render = canvas => {
const ctx = canvas.ctx;
ctx.rect(0, 0, 200, 200);
ctx.fill();
};
return () => <sprite loc={loc.value} scale={scale.value} render={render} />;
```
**效果**:
- 矩形横向放大 1.5 倍,横向位置移动 100px
- 2 秒线性动画
---
### 示例 3:交互事件 + 滤镜
```tsx
import { ref } from 'vue';
// 悬浮模糊
const filter = ref('none');
const enter = () => {
filter.value = 'blur(2px)';
};
const leave = () => {
filter.value = 'none';
};
return () => (
<sprite
x={300}
y={200}
cursor="pointer"
filter={filter.value}
render={}
onEnter={enter}
onLeave={leave}
/>
);
```
**效果**:
- 鼠标悬浮时添加模糊滤镜
- 鼠标悬浮显示指针光标
---
## 注意事项
1. **坐标系**:`render` 函数内使用 **局部坐标系**,锚点变换已自动处理
2. **循环更新**:避免在 `render` 中循环更新自身

View File

@ -1,160 +0,0 @@
# TextProps API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
TextProps --> BaseProps
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface TextProps extends BaseProps {
text?: string; // 显示的文字内容
fillStyle?: CanvasStyle; // 文字填充样式(颜色/渐变/图案)
strokeStyle?: CanvasStyle; // 文字描边样式
font?: Font; // 字体配置对象
strokeWidth?: number; // 描边宽度(单位:像素)
}
```
---
## 使用示例
### 1. 基本文本渲染
```tsx
import { Font } from '@motajs/render-style';
<text
loc={[100, 50]}
text="Hello World"
fillStyle="blue"
font={new Font('Arial', 24, 'px', 700)}
/>;
```
**效果**:
- 在 (100,50) 位置显示蓝色 "Hello World"
- 使用 24px 粗体 Arial 字体
- 无描边效果
---
### 2. 描边文字 + 填充组合
```tsx
import { Font } from '@motajs/render-style';
<text
loc={[200, 300]} // x=200, y=300
text="MOTA Engine"
fillStyle="gold"
strokeStyle="rgba(0,0,0,0.8)"
strokeWidth={2}
font={new Font('Verdana', 32, 'px', 900, true)} // 斜体
/>;
```
**效果**:
- 金色文字带黑色半透明描边
- 32px 加粗斜体 Verdana
- 2px 描边宽度
---
### 3. 动态更新文本
```tsx
import { ref } from 'vue';
import { Font } from '@motajs/render-style';
// Vue3 组件示例
const count = ref(0);
onTick(() => {
count.value++;
});
return () => (
<text
loc={[400, 100]}
text={`计时: ${count.value} 帧`}
fillStyle="#333"
font={new Font('Consolas', 28)}
/>
);
```
---
## 高级用法示例
### 文字路径动画
```tsx
import { ref } from 'vue';
import { Font, onTick } from '@motajs/render';
const offset = ref(0);
onTick(() => {
offset.value = (offset.value + 1) % 100;
});
<text
x={100 + Math.sin(offset.value * 0.1) * 50} // X轴波动
y={200 + offset.value}
text="动态文字"
fillStyle={`hsl(${offset.value * 3.6}, 80%, 50%)`} // 彩虹色
font={new Font('Comic Sans MS', 32)}
/>;
```
---
### 文字阴影 + 滤镜
```tsx
import { Font } from '@motajs/render-style';
<text
x={300}
y={400}
text="特效文字"
fillStyle="white"
font={new Font('Arial Black', 40)}
filter="drop-shadow(5px 5px 2px rgba(0,0,0,0.5)) blur(1px)"
strokeStyle="#333"
strokeWidth={1}
/>;
```
---
## 属性兼容性表
| 属性 | 是否继承 BaseProps | 动态更新支持 | 性能影响等级 |
| ------------- | ------------------ | ------------ | ------------ |
| `text` | 否 | ✔️ | 中 |
| `fillStyle` | 否 | ✔️ | 中 |
| `strokeStyle` | 否 | ✔️ | 中 |
| `font` | 否 | ✔️ | 高 |
| `strokeWidth` | 否 | ✔️ | 低 |
---
## 注意事项
1. 如果需要显示多行文本,考虑使用 [TextContent](../user-client-modules/组件%20TextContent.md)
2. 考虑到浏览器兼容性,不建议在颜色中填写一些新标准的语法,例如 `rgb(0.3, 0.6, 0.8 / 0.6)` `#rgba` 等

View File

@ -1,117 +0,0 @@
# winskin 标签 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
WinskinProps --> BaseProps
click BaseProps "./BaseProps"
```
---
## 接口定义
```typescript
interface WinskinProps extends BaseProps {
/**
* 窗口皮肤图片资源ID
*/
image: ImageIds;
/**
* 边框粗细
* - 设置为 32 时表示原始大小(16 像素宽度),默认为 32
* - 设为0时仅显示中心内容区
*/
borderSize?: number;
}
```
---
## 核心功能演示
### 示例 1:基础窗口皮肤
```tsx
// 使用默认边框(borderSize=32)
<container>
<winskin
loc={[100, 100, 400, 300]} // x,y,width,height
image="winskin.png" // 预加载的皮肤图片ID
/>
<text x={120} y={120} text="对话框标题" />
<text x={130} y={160} text="这里是正文内容区域..." />
</container>
```
---
### 示例 2:不同边框粗细对比
```tsx
// 细边框(borderSize=16)
<winskin loc={[50, 50, 200, 150]} image="winskin.png" borderSize={16} />;
// 粗边框(borderSize=32)
<winskin loc={[300, 50, 200, 150]} image="winskin.png" borderSize={32} />;
// 无边框(borderSize=0)
<winskin loc={[550, 50, 200, 150]} image="winskin.png" borderSize={0} />;
```
**效果差异**:
- 细边框:内容区域更大,适合信息密集场景
- 粗边框:装饰性更强,适合标题窗口
- 无边框:仅保留中心纹理,适合全屏背景
---
## 九宫格原理示意图
```typescript
/*
+-------------------+
| 1 top 2 | ← borderSize
| |
| |
left | 4 center 3 | right
| |
| |
| 5 bottom 6 |
+-------------------+
*/
```
---
## 高级用法示例
### 动态边框动画
```tsx
import { hyper } from 'mutate-animate';
import { transitioned } from '@user/client-modules';
import { onTick } from '@motajs/render-vue';
const border = transitioned(16, 1000, hyper('sin', 'in-out'));
onTick(() => {
if (border.value === 16) border.set(32);
if (border.value === 32) border.set(16)
})
<container>
<winskin
loc={[200, 300, 400, 300]}
image="winskin.png"
borderSize={border.ref.value} // 边框呼吸动画效果
composite="lighter" // 发光混合模式
/>
<text x={20} y={20} text="魔法结界" font={magicFont} />
</container>;
```

View File

@ -1,16 +0,0 @@
# @motajs/render
此模块包含如下模块的内容,可以直接引用:
- [@motajs/render-core](../motajs-render-core/)
- [@motajs/render-elements](../motajs-render-elements/)
- [@motajs/render-style](../motajs-render-style/)
- [@motajs/render-vue](../motajs-render-vue/)
引入示例:
```ts
import { Container } from '@motajs/render';
// 二者等价,不需要单独使用一个量来接收
import { Container } from '@motajs/render-core';
```

View File

@ -1,311 +0,0 @@
# Hotkey API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
```mermaid
graph LR
Hotkey --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
## 类描述
`Hotkey` 是按键系统的核心类,用于管理按键绑定、辅助键状态、按键分组及事件触发逻辑。继承自 `EventEmitter`,支持自定义事件监听。主要用于实现复杂的快捷键系统。
---
## 属性说明
| 属性名 | 类型 | 描述 |
| -------------- | ---------------------------- | -------------------------------------------- |
| `id` | `string` | 控制器的唯一标识符 |
| `name` | `string` | 控制器的显示名称 |
| `data` | `Record<string, HotkeyData>` | 存储所有已注册的按键配置 |
| `keyMap` | `Map<KeyCode, HotkeyData[]>` | 按键代码到配置的映射(支持多键绑定同一操作) |
| `enabled` | `boolean` | 当前控制器是否启用(默认 `false`) |
| `list`(静态) | `Hotkey[]` | 静态属性,存储所有已创建的控制器实例 |
---
## 构造方法
```typescript
function constructor(id: string, name: string): Hotkey;
```
- **参数**
- `id`: 控制器的唯一标识符
- `name`: 控制器的显示名称
**示例**
```typescript
const editorHotkey = new Hotkey('editor', '编辑器快捷键');
```
---
## 方法说明
### `register`
```typescript
function register(data: RegisterHotkeyData): this;
```
注册一个按键配置。
- **参数**
```typescript
interface RegisterHotkeyData {
id: string; // 按键唯一标识(可含数字后缀,如 "copy_1")
name: string; // 显示名称(如 "复制")
defaults: KeyCode; // 默认按键代码
ctrl?: boolean; // 是否默认需要 Ctrl 辅助键
shift?: boolean; // 是否默认需要 Shift 辅助键
alt?: boolean; // 是否默认需要 Alt 辅助键
}
```
**示例**
```typescript
editorHotkey.register({
id: 'copy',
name: '复制',
defaults: KeyCode.KeyC,
ctrl: true
});
```
---
### `realize`
```typescript
function realize(id: string, func: HotkeyFunc, config?: HotkeyEmitConfig): this;
```
为按键绑定触发逻辑。
- **参数**
- `id`: 目标按键 ID(无需后缀)
- `func`: 触发时执行的函数
- `config`: 触发类型配置(节流/超时等)
**示例**
```typescript
editorHotkey.realize(
'copy',
(id, key, ev) => {
console.log('执行复制操作');
},
{ type: 'down-throttle', throttle: 500 }
);
```
---
### `group`
```typescript
function group(id: string, name: string, keys?: RegisterHotkeyData[]): this;
```
创建按键分组,后续注册的按键自动加入该组。
- **参数**
- `id`: 分组唯一标识
- `name`: 分组显示名称
- `keys`: 可选,预注册的按键列表
---
### `set`
```typescript
function set(id: string, key: KeyCode, assist: number, emit?: boolean): void;
```
动态修改按键绑定。
- **参数**
- `id`: 目标按键 ID
- `key`: 新按键代码
- `assist`: 辅助键状态(二进制位:Ctrl=1<<0, Shift=1<<1, Alt=1<<2)
- `emit`: 是否触发 `set` 事件(默认 `true`)
---
### `when`
```typescript
function when(fn: () => boolean): this;
```
为当前作用域的按键绑定添加触发条件。
- **参数**
- `fn`: 条件函数,返回 `true` 时允许触发按键逻辑
**示例**
```typescript
// 仅在游戏处于运行状态时允许触发
controller.when(() => gameState === 'running');
```
---
### `enable`
```typescript
function enable(): void;
```
### `disable`
```typescript
function disable(): void;
```
启用/禁用整个按键控制器(禁用后所有按键事件将被忽略)。
**示例**
```typescript
// 暂停游戏时禁用按键
controller.disable();
```
---
### `use`
```typescript
function use(symbol: symbol): void;
```
切换当前作用域,后续 `realize` 方法绑定的逻辑将关联到该作用域。
- **参数**
- `symbol`: 唯一作用域标识符
---
### `dispose`
```typescript
function dispose(symbol?: symbol): void;
```
释放指定作用域及其绑定的所有按键逻辑。
- **参数**
- `symbol`(可选): 要释放的作用域(默认释放当前作用域)
**示例**
```typescript
const scope = Symbol();
controller.use(scope);
// ...绑定操作...
controller.dispose(scope); // 释放该作用域
```
---
### `emitKey`
```typescript
function emitKey(
key: KeyCode,
assist: number,
type: KeyEventType,
ev: KeyboardEvent
): boolean;
```
手动触发按键事件(可用于模拟按键操作)。
- **参数**
- `key`: 按键代码
- `assist`: 辅助键状态(二进制位:`Ctrl=1<<0`, `Shift=1<<1`, `Alt=1<<2`)
- `type`: 事件类型(`'up'` 或 `'down'`)
- `ev`: 原始键盘事件对象
- **返回值**
`true` 表示事件被成功处理,`false` 表示无匹配逻辑
**示例**
```typescript
// 模拟触发 Ctrl+S 保存操作
controller.emitKey(
KeyCode.KeyS,
1 << 0, // Ctrl 激活
'down',
new KeyboardEvent('keydown')
);
```
---
## 静态方法说明
### `Hotkey.get`
```typescript
function get(id: string): Hotkey | undefined;
```
**静态方法**:根据 ID 获取控制器实例。
---
## 事件说明
| 事件名 | 参数类型 | 触发时机 |
| --------- | --------------------------------------------------- | ---------------- |
| `set` | `[id: string, key: KeyCode, assist: number]` | 按键绑定被修改时 |
| `emit` | `[key: KeyCode, assist: number, type: KeyEmitType]` | 按键被触发时 |
| `press` | `[key: KeyCode]` | 按键被按下时 |
| `release` | `[key: KeyCode]` | 按键被释放时 |
**事件监听示例**
```typescript
gameKey.on('emit', (key, assist) => {
console.log(`按键 ${KeyCode[key]} 触发,辅助键状态:${assist}`);
});
```
---
## 总使用示例
::: code-group
```typescript [注册]
import { gameKey } from '@motajs/system-action';
gameKey.register({
id: 'jump',
name: '跳跃',
defaults: KeyCode.Space
});
```
```typescript [实现]
import { useKey } from '@motajs/render-vue';
const [gameKey] = useKey();
// 绑定跳跃逻辑
gameKey.realize('jump', () => {
player.jump();
});
```
:::

View File

@ -1,221 +0,0 @@
# Keyboard API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
```mermaid
graph LR
Keyboard --> EventEmitter
```
## 类描述
`Keyboard` 是虚拟键盘的核心类,用于管理动态按键布局、处理按键事件及辅助键状态。继承自 `EventEmitter`,支持自定义事件监听。
---
## 属性说明
| 属性名 | 类型 | 描述 |
| -------------- | ---------------- | ----------------------------------------------------------- |
| `id` | `string` | 键盘的唯一标识符 |
| `keys` | `KeyboardItem[]` | 当前键盘包含的按键列表(响应式数组) |
| `assist` | `number` | 辅助键状态(二进制位表示:Ctrl=1<<0, Shift=1<<1, Alt=1<<2) |
| `fontSize` | `number` | 按键文本字体大小(默认 18) |
| `list`(静态) | `Keyboard[]` | 静态属性,存储所有已创建的键盘实例 |
**KeyboardItem 结构**:
```typescript
interface KeyboardItem {
key: KeyCode; // 按键代码
text?: string; // 显示文本(可选)
x: number; // X 坐标
y: number; // Y 坐标
width: number; // 宽度
height: number; // 高度
}
```
---
## 构造方法
```typescript
function constructor(id: string): Keyboard;
```
- **参数**
- `id`: 键盘的唯一标识符
**示例**
```typescript
const numpad = new Keyboard('numpad');
```
---
## 方法说明
### `add`
```typescript
function add(item: KeyboardItem): Keyboard;
```
### `remove`
```typescript
function remove(item: KeyboardItem): Keyboard;
```
添加/移除按键,返回当前实例以便链式调用。
**示例**
```typescript
// 添加数字键 1
numpad.add({
key: KeyCode.Digit1,
text: '1',
x: 0,
y: 0,
width: 60,
height: 60
});
// 移除按键
numpad.remove(existingKey);
```
---
### `extend`
```typescript
function extend(
keyboard: Keyboard,
offsetX?: number,
offsetY?: number
): Keyboard;
```
继承其他键盘的按键布局并添加偏移量。
**示例**
```typescript
const extendedKB = new Keyboard('extended');
extendedKB.extend(numpad, 100, 0); // 向右偏移 100px
```
---
### `emitKey`
```typescript
function emitKey(key: KeyboardItem, index: number): void;
```
模拟触发按键事件(自动处理辅助键状态)。
---
### `createScope`
```typescript
function createScope(): symbol;
```
### `disposeScope`
```typescript
function disposeScope(): void;
```
管理事件监听作用域:
- `createScope`: 创建新作用域(返回唯一标识符)
- `disposeScope`: 释放当前作用域
---
### `withAssist`
```typescript
function withAssist(assist: number): symbol;
```
创建预设辅助键状态的作用域(如 `Ctrl+Shift`)。
---
### `Keyboard.get`
```typescript
function get(id: string): Keyboard | undefined;
```
**静态方法**:根据 ID 获取键盘实例。
---
## 事件说明
| 事件名 | 参数类型 | 触发时机 |
| -------------- | ------------------------- | ------------------ |
| `add` | `KeyboardItem` | 新增按键时 |
| `remove` | `KeyboardItem` | 移除按键时 |
| `extend` | `Keyboard` | 继承其他键盘布局时 |
| `emit` | `item, assist, index, ev` | 触发按键时 |
| `scopeCreate` | `symbol` | 创建作用域时 |
| `scopeDispose` | `symbol` | 释放作用域时 |
**事件监听示例**
```typescript
numpad.on('emit', (item, assist) => {
console.log(`按键 ${item.key} 触发,辅助键状态:${assist}`);
});
```
---
## 总使用示例
```typescript
import { KeyCode } from '@motajs/client-base';
import { Keyboard } from '@motajs/system-action';
// 创建数字键盘
const numpad = new Keyboard('numpad');
// 添加基础按键
numpad
.add({ key: KeyCode.Digit1, x: 0, y: 0, width: 60, height: 60 })
.add({ key: KeyCode.Digit2, x: 60, y: 0, width: 60, height: 60 });
// 添加功能键(带辅助状态)
const ctrlScope = numpad.withAssist(1 << 0); // Ctrl 激活
numpad.add({
key: KeyCode.KeyC,
text: '复制',
x: 120,
y: 0,
width: 120,
height: 60
});
// 监听复制键
numpad.on('emit', item => {
if (item.key === KeyCode.KeyC) {
console.log('执行复制操作');
}
});
// 触发按键
numpad.emitKey(numpad.keys[0], 0); // 模拟按下数字 1
// 获取键盘实例
const foundKB = Keyboard.get('numpad');
```

View File

@ -1,3 +0,0 @@
# @motajs/system-action
目录:

View File

@ -1,97 +0,0 @@
# GameUI API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
```mermaid
graph LR
GameUI --> IGameUI
```
_实现 `IGameUI` 接口_
## 接口描述
`IGameUI<C>` 是 UI 系统的核心接口,定义了 UI 实例的基础结构和静态操作方法。
---
## 属性说明
| 属性名 | 类型 | 描述 |
| -------------- | ---------------------------------- | ------------------------------------------------------------------- |
| `name` | `string` | 只读,UI 的唯一标识名称 |
| `component` | `C extends UIComponent` | 只读,关联的 Vue 组件实例 |
| `list`(静态) | `Map<string, GameUI<UIComponent>>` | 静态属性,存储所有已注册的 UI 实例,键为 `name`,值为 `GameUI` 实例 |
---
## 构造方法
### `consturctor`
```typescript
function constructor(name: string, component: C): GameUI;
```
- **参数**
- `name`: UI 的唯一标识名称
- `component`: 关联的 Vue 组件实例
**示例**
```typescript
import { defineComponent } from 'vue';
export const MyComponent = defineComponent(...);
// 创建 UI 实例并自动注册到静态列表
export const MyUI = new GameUI('my-ui', MyComponent);
```
---
## 方法说明
### `GameUI.get`
```typescript
function get<T extends UIComponent>(id: string): GameUI<T> | null;
```
**静态方法**:根据 UI 名称从静态列表获取实例。
- **参数**
- `id`: UI 的唯一标识名称
- **返回值**
匹配的 `GameUI` 实例,未找到时返回 `null`
**示例**
```typescript
// 获取名为 "home" 的 UI 实例
const ui = GameUI.get<MyComponent>('my-ui');
if (ui) {
console.log(ui.component); // 输出关联的 Vue 组件
}
```
---
## 总使用示例
```tsx
import { defineComponent } from 'vue';
import { GameUI } from '@motajs/system-ui';
// 定义组件
export const MyCom = defineComponent(() => {
return () => (
<container>
<text text="自定义组件 UI" />
</container>
);
});
// 定义 UI 实例
export const MyUI = new GameUI('my-ui', MyCom);
```

View File

@ -1,284 +0,0 @@
# UIController API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
```mermaid
graph LR
UIController --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
## 类描述
`UIController` 是 UI 控制系统的核心类,负责管理 UI 实例的显示栈、背景控制以及多种显示模式。继承自 `EventEmitter`,支持事件监听。想要编写 UI 请参考[深度指南](../../guide/ui/ui.md)。
---
## 属性说明
| 属性名 | 类型 | 描述 |
| --------------------- | ---------------------------- | --------------------------------------------------------------- |
| `stack` | `IUIInstance[]` (响应式数组) | 当前管理的 UI 实例栈 |
| `mode` | `UIMode` | UI 显示模式,默认为 `LastOnlyStack` |
| `background` | `IGameUI` | 背景 UI 的配置实例 |
| `backIns` | `ShallowRef<IUIInstance>` | 背景 UI 实例的响应式引用 |
| `showBack` | `ComputedRef<boolean>` | 当前是否显示背景(用户设置与系统状态共同决定) |
| `active`(只读) | `boolean` | 系统是否显示背景 UI(等价于 `sysShowBack.value`) |
| `controllers`(静态) | `Map<string, UIController>` | 静态属性,存储所有已创建的控制器实例,键为 `id`,值为控制器实例 |
---
## 构造方法
### `constructor`
```typescript
function constructor(id: string): UIController;
```
- **参数**
- `id`: 控制器的唯一标识符(若重复会触发警告日志)
**示例**
```typescript
const mainController = new UIController('main');
```
---
## 方法说明
### `render`
```typescript
function render(): VNode;
```
渲染 UI 容器组件(用于 Vue 挂载)。
**示例**
```tsx
import { defineComponent } from 'vue';
import { UIController } from '@motajs/system-ui';
export const myController = new UIController('my-controller');
export const MyCom = defineComponent(() => {
return () => <container>{myController.render()}</container>;
});
```
---
### `setBackground`
```typescript
function setBackground<T extends UIComponent>(
back: IGameUI<T>,
vBind: UIProps<T>
): void;
```
设置背景 UI 并初始化其实例。
- **参数**
- `back`: 背景 UI 配置实例
- `vBind`: 传递给背景组件的 Props 对象
**示例**
```typescript
import { BackgroundUI } from './background';
// 显示背景组件,并传入参数 theme='dark'
mainController.setBackground(BackgroundUI, { theme: 'dark' });
```
---
### `hideBackground`
```typescript
function hideBackground(): void;
```
隐藏背景 UI (不影响系统状态)。
---
### `showBackground`
```typescript
function showBackground(): void;
```
显示背景 UI(不影响系统状态)。
---
### `keep`
```typescript
function keep(): IKeepController;
```
维持背景显示(防闪烁),返回控制器对象:
```typescript
interface IKeepController {
safelyUnload(): void; // 安全卸载(仅在栈为空时关闭)
unload(): void; // 强制立即卸载
}
```
**示例**
```typescript
const keeper = mainController.keep();
// 执行某些操作后...
keeper.safelyUnload();
```
---
### `open`
```typescript
function open<T extends UIComponent>(
ui: IGameUI<T>,
vBind: UIProps<T>,
alwaysShow?: boolean
): IUIInstance<T>;
```
打开一个新 UI 实例并加入栈中。
- **参数**
- `ui`: UI 配置实例
- `vBind`: 组件 Props
- `alwaysShow`: 是否强制显示(默认 `false`)
- **返回值**
打开的 UI 实例,可以用于关闭等操作
**示例**
```typescript
import { MyUI } from './myUI';
const instance = mainController.open(MyUI, { param: 80 });
```
---
### `close`
```typescript
function close(ui: IUIInstance): void;
```
关闭指定 UI 实例(根据当前模式可能影响其他实例)。
---
### `closeAll`
```typescript
function closeAll(ui?: IGameUI): void;
```
关闭所有或指定类型的所有 UI 实例。
- **参数**
- `ui`(可选): 指定要关闭的 UI 类型,不填时表示关闭所有 UI
---
### `lastOnly`
```typescript
function lastOnly(stack?: boolean): void;
```
切换显示模式:仅显示最后一个 UI(可设置为栈模式)
---
### `showAll`
```typescript
function showAll(stack?: boolean): void;
```
切换显示模式:显示所有非隐藏 UI(可设置为栈模式)
---
### `showCustom`
```typescript
function showCustom(config: IUICustomConfig): void;
```
切换显示模式:使用自定义模式(需实现 `IUICustomConfig`),参考[指南](../../guide/ui/system.md#自定义显示模式)
---
### `UIController.getController`
```typescript
function getController(id: string): UIController | null;
```
**静态方法**:根据 ID 获取控制器实例。
**示例**
```typescript
const ctrl = UIController.getController('main');
```
---
## 事件说明
| 事件名 | 参数类型 | 触发时机 |
| ------- | ------------------------------- | ------------------ |
| `open` | `ui: IGameUI, ins: IUIInstance` | 新 UI 实例被打开时 |
| `close` | `ins: IUIInstance` | UI 实例被关闭时 |
**事件监听示例**
```typescript
mainController.on('open', (ui, ins) => {
console.log(`Opened UI: ${ui.name}`);
});
```
---
## 总使用示例
```typescript
import { BackgroundUI, DialogUI } from './myUI';
import { mainController } from '@user/client-modules';
// 事件监听
mainController.on('close', ins => {
console.log('UI closed:', ins.ui.name);
});
// 设置背景
mainController.setBackground(BackgroundUI, { color: '#333' });
// 打开 UI
const dialogIns = mainController.open(DialogUI, { title: '提示' });
// 切换显示模式,仅显示最后一个,启用栈模式
mainController.lastOnly(true);
// 关闭 UI
mainController.close(dialogIns);
```

View File

@ -1,121 +0,0 @@
# UIInstance API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
```mermaid
graph LR
UIInstance --> IUIInstance
```
_实现 `IUIInstance` 接口_
## 类描述
`UIInstance` 表示通过 `GameUI` 模板创建的具体 UI 实例,用于管理单个 UI 实例的状态和数据绑定。实现了 `IUIInstance` 接口。
---
## 属性说明
| 属性名 | 类型 | 描述 |
| ------------ | ------------ | -------------------------------------------------------- |
| `key` | `number` | 只读,实例的唯一标识(用于 Vue 的 `key` 属性) |
| `ui` | `IGameUI<C>` | 只读,关联的 UI 配置实例(即创建该实例的 `GameUI` 模板) |
| `vBind` | `UIProps<C>` | 只读,传递给 UI 组件的响应式 Props 对象 |
| `hidden` | `boolean` | 当前实例是否处于隐藏状态 |
| `alwaysShow` | `boolean` | 是否强制保持显示(不受显示模式影响) |
---
## 构造方法
```typescript
function constructor(
ui: IGameUI<C>,
vBind: UIProps<C>,
alwaysShow: boolean = false
): UIInstance;
```
- **参数**
- `ui`: 关联的 `GameUI` 配置实例
- `vBind`: 初始化的组件 Props 对象
- `alwaysShow`: 是否强制保持显示(默认 `false`)
**注意事项**:一般不需要手动创建 `UIInstance` 实例,请使用 [`UIController.open`](./UIController.md#open) 打开 UI 并创建实例。
---
## 方法说明
### `setVBind`
```typescript
function setVBind(data: Partial<Props<C>>, merge?: boolean): void;
```
更新组件的响应式 Props。
- **参数**
- `data`: 需要更新的数据(部分 Props)
- `merge`: 是否与现有数据合并(默认 `true`),若为 `false` 则完全覆盖
**示例**
```typescript
// 合并更新音量值
instance.setVBind({ volume: 60 });
// 覆盖所有 Props
instance.setVBind({ theme: 'dark' }, false);
```
---
### `hide`
```typescript
function hide(): void;
```
控制实例的显示状态(直接操作 `hidden` 属性)。
**示例**
```typescript
instance.hide(); // 隐藏 UI
setTimeout(() => instance.show(), 1000); // 1 秒后显示
```
---
### `show`
```typescript
function show(): void;
```
控制实例的显示状态(直接操作 `hidden` 属性)。
**示例**
```typescript
instance.show(); // 隐藏 UI
setTimeout(() => instance.show(), 1000); // 1 秒后显示
```
---
## 总使用示例
```typescript
import { myController, MyUI } from './myUI';
const myIns = myController.open(MyUI, { title: '警告' });
// 动态更新 props
myIns.setVBind({ title: '错误' });
// 设置显示状态
myIns.show();
```

View File

@ -1,3 +0,0 @@
# @motajs/system-ui
目录:

View File

@ -1,25 +0,0 @@
# @motajs/system
包含两个模块:
- [`@motajs/system-action`](../motajs-system-action/index.md)
- [`@motajs/system-ui`](../motajs-system-ui/index.md)
## 引入示例
```ts
import { gameKey, UIController } from '@motajs/system';
gameKey.register(...);
const myController = new UIController('my-controller');
```
等效于:
```ts
import { gameKey } from '@motajs/system-action';
import { UIController } from '@motajs/system-ui';
gameKey.register(...);
const myController = new UIController('my-controller');
```

View File

@ -1,3 +0,0 @@
# @motajs/types
目录:

View File

@ -1,142 +0,0 @@
# AudioDecoder API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 类描述
音频解码系统的核心抽象类,为不同音频格式提供统一的解码接口。主要处理浏览器原生不支持音频格式的解码任务(如 iOS 平台的 Ogg 格式)。
---
## 静态成员说明
### `decoderMap`
```typescript
declare const decoderMap: Map<AudioType, new () => AudioDecoder>;
```
解码器注册表,存储格式类型与解码器类的映射关系
---
## 静态方法说明
### `AudioDecoder.registerDecoder`
```typescript
function registerDecoder(
type: AudioType,
decoder: new () => AudioDecoder
): void;
```
注册自定义解码器到全局解码器系统
| 参数 | 类型 | 说明 |
| ------- | ------------------------ | -------------- |
| type | `AudioType` | 音频格式类型 |
| decoder | `new () => AudioDecoder` | 解码器构造函数 |
---
### `AudioDecoder.decodeAudioData`
```typescript
function decodeAudioData(
data: Uint8Array,
player: AudioPlayer
): Promise<AudioBuffer | null>;
```
核心解码入口方法,自动选择最佳解码方案
| 参数 | 类型 | 说明 |
| ------ | ------------- | ---------------- |
| data | `Uint8Array` | 原始音频字节数据 |
| player | `AudioPlayer` | 音频播放器实例 |
**处理流程**:
1. 通过文件头检测音频类型
2. 优先使用浏览器原生解码能力
3. 无原生支持时查找注册的自定义解码器
4. 返回标准 `AudioBuffer` 格式数据
---
## 抽象方法说明
### `abstract create`
```typescript
function create(): Promise<void>;
```
初始化解码器实例(需分配 WASM 内存等资源)
---
### `abstract destroy`
```typescript
function destroy(): void;
```
销毁解码器实例(需释放资源)
---
### `abstract decode`
```typescript
function decode(data: Uint8Array): Promise<IAudioDecodeData | undefined>;
```
流式解码方法(分块处理)
| 参数 | 类型 | 说明 |
| ---- | ------------ | ------------ |
| data | `Uint8Array` | 音频数据分块 |
---
### `abstract decodeAll`
```typescript
function decodeAll(data: Uint8Array): Promise<IAudioDecodeData | undefined>;
```
全量解码方法(单次处理完整文件)
---
### `abstract flush`
```typescript
function flush(): Promise<IAudioDecodeData | undefined>;
```
冲刷解码器缓冲区,获取残留数据
---
## 数据结构
### IAudioDecodeData
```typescript
interface IAudioDecodeData {
channelData: Float32Array[]; // 各声道 PCM 数据
samplesDecoded: number; // 已解码采样数
sampleRate: number; // 采样率 (Hz)
errors: IAudioDecodeError[]; // 解码错误集合
}
```
## 内置解码器
- `VorbisDecoder`: 解码 ogg vorbis 音频。
- `OpusDecoder`: 解码 ogg opus 音频。

View File

@ -1,207 +0,0 @@
# AudioEffect API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 类描述
音频处理管道的核心抽象类,为构建音频效果链提供基础框架。所有效果器通过输入/输出节点串联,形成可定制的音频处理流水线。
---
## 核心架构
音频播放流程:
```mermaid
graph LR
Source --> Effect1
Effect1 --> Effect2[...]
Effect2 --> GainNode
GainNode --> Destination
```
---
## 抽象成员说明
| 成员 | 类型 | 说明 |
| -------- | ----------- | -------------------------- |
| `input` | `AudioNode` | 效果器输入节点(必须实现) |
| `output` | `AudioNode` | 效果器输出节点(必须实现) |
---
## 核心方法说明
### `connect`
```typescript
function connect(target: IAudioInput, output?: number, input?: number): void;
```
连接至下游音频节点
| 参数 | 类型 | 说明 |
| ------ | ------------- | -------------------------- |
| target | `IAudioInput` | 目标效果器/节点 |
| output | `number` | 当前效果器输出通道(可选) |
| input | `number` | 目标效果器输入通道(可选) |
---
### `disconnect`
```typescript
function disconnect(
target?: IAudioInput,
output?: number,
input?: number
): void;
```
断开与下游节点的连接
---
### `abstract start`
```typescript
function start(): void;
```
效果器激活时调用(可用于初始化参数)
---
### `abstract end`
```typescript
function end(): void;
```
效果器停用时调用(可用于资源回收)
---
## 自定义效果器示例
### 混响效果器实现
```typescript
export class ReverbEffect extends AudioEffect {
private convolver: ConvolverNode;
private dryGain: GainNode;
private wetGain: GainNode;
constructor(ac: AudioContext) {
super(ac);
// 创建节点网络
this.dryGain = ac.createGain();
this.wetGain = ac.createGain();
this.convolver = ac.createConvolver();
// 定义输入输出
this.input = this.dryGain;
this.output = this.ac.createGain();
// 构建处理链
this.dryGain.connect(this.output);
this.dryGain.connect(this.convolver);
this.convolver.connect(this.wetGain);
this.wetGain.connect(this.output);
}
/** 设置混响强度 */
setMix(value: number) {
this.dryGain.gain.value = 1 - value;
this.wetGain.gain.value = value;
}
/** 加载脉冲响应 */
async loadImpulse(url: string) {
const response = await fetch(url);
const buffer = await this.ac.decodeAudioData(
await response.arrayBuffer()
);
this.convolver.buffer = buffer;
}
start() {
this.output.gain.value = 1;
}
end() {
this.output.gain.value = 0;
}
}
```
---
## 内置效果器说明
### StereoEffect(立体声控制)
```mermaid
graph LR
Input --> Panner[PannerNode]
Panner --> Output
```
- 控制声相/3D 空间定位
- 支持设置声音方位和位置
### VolumeEffect(音量控制)
```mermaid
graph LR
Input --> Gain[GainNode]
Gain --> Output
```
- 全局音量调节
- 支持实时音量渐变
### ChannelVolumeEffect(多声道控制)
```mermaid
graph LR
Input --> Splitter[ChannelSplitter]
Splitter --> Gain1
Splitter --> Gain2
Gain1 --> Merger
Gain2 --> Merger
Merger --> Output
```
- 6 声道独立音量控制
- 支持环绕声场调节
### DelayEffect(延迟效果)
```mermaid
graph LR
Input --> Delay[DelayNode]
Delay --> Output
```
- 基础延迟效果
- 精确到采样级的延迟控制
### EchoEffect(回声效果)
```mermaid
graph LR
Input --> Gain
Gain --> Delay
Delay --> Gain[反馈循环]
Gain --> Output
```
- 带反馈的延迟效果
- 自动渐弱回声处理
---

View File

@ -1,172 +0,0 @@
# AudioPlayer API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 类描述
音频系统的核心控制器,负责管理音频上下文、路由系统、效果器工厂和全局音频参数。支持多音轨管理和 3D 音频空间化配置。
```mermaid
graph LR
AudioPlayer --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---
## 核心架构
```mermaid
graph TD
Player[AudioPlayer] --> Sources[音频源工厂]
Player --> Effects[效果器工厂]
Player --> Routes[路由系统]
Player --> Listener[3D 听者配置]
```
---
## 属性说明
| 属性名 | 类型 | 说明 |
| ------------- | ------------------------- | ------------------------ |
| `ac` | `AudioContext` | Web Audio API 上下文实例 |
| `audioRoutes` | `Map<string, AudioRoute>` | 已注册的音频路由表 |
| `gain` | `GainNode` | 全局音量控制节点 |
---
## 方法说明
此处暂时只列出方法的简易说明。方法理解难度不高,如果需要可以自行查看代码以及其相关注释来查看如何使用。
### 音频源工厂方法
| 方法名 | 返回值 | 说明 |
| ----------------------- | -------------------- | ----------------------------- |
| `createSource(Source)` | `AudioSource` | 创建自定义音频源 |
| `createStreamSource()` | `AudioStreamSource` | 创建流式音频源(直播/长音频) |
| `createElementSource()` | `AudioElementSource` | 基于 HTML5 Audio 元素的音源 |
| `createBufferSource()` | `AudioBufferSource` | 基于 AudioBuffer 的静态音源 |
### 效果器工厂方法
| 方法名 | 返回值 | 说明 |
| ----------------------------- | --------------------- | ---------------------------- |
| `createEffect(Effect)` | `AudioEffect` | 创建自定义效果器 |
| `createVolumeEffect()` | `VolumeEffect` | 全局音量控制器 |
| `createStereoEffect()` | `StereoEffect` | 立体声场控制器 |
| `createChannelVolumeEffect()` | `ChannelVolumeEffect` | 多声道独立音量控制(6 声道) |
| `createDelayEffect()` | `DelayEffect` | 精确延迟效果器 |
| `createEchoEffect()` | `EchoEffect` | 回声效果器(带反馈循环) |
### 路由管理方法
| 方法名 | 参数 | 说明 |
| --------------------- | -------------------- | -------------- |
| `createRoute(source)` | `AudioSource` | 创建新播放路由 |
| `addRoute(id, route)` | `string, AudioRoute` | 注册命名路由 |
| `getRoute(id)` | `string` | 获取已注册路由 |
| `removeRoute(id)` | `string` | 移除指定路由 |
### 全局控制方法
| 方法名 | 参数 | 说明 |
| ------------------------------- | ------------------------ | -------------------- |
| `setVolume(volume)` | `number` (0.0-1.0) | 设置全局音量 |
| `getVolume()` | - | 获取当前全局音量 |
| `setListenerPosition(x,y,z)` | `number, number, number` | 设置听者 3D 空间坐标 |
| `setListenerOrientation(x,y,z)` | `number, number, number` | 设置听者朝向 |
| `setListenerUp(x,y,z)` | `number, number, number` | 设置听者头顶朝向 |
---
## 使用示例
### 基础音乐播放
```typescript
import { audioPlayer } from '@user/client-modules';
// 创建音频源(以音频缓冲为例)
const bgmSource = audioPlayer.createBufferSource();
// 创建播放路由
const bgmRoute = audioPlayer.createRoute(bgmSource);
// 添加效果链
bgmRoute.addEffect([
audioPlayer.createStereoEffect(),
audioPlayer.createVolumeEffect()
]);
// 播放控制
audioPlayer.play('bgm');
audioPlayer.pause('bgm');
```
### 3D 环境音效
```typescript
import { audioPlayer } from '@user/client-modules';
// 配置3D听者
audioPlayer.setListenerPosition(0, 0, 0); // 听者在原点
audioPlayer.setListenerOrientation(0, 0, -1); // 面朝屏幕内
// 创建环境音源
const ambientSource = audioPlayer.createBufferSource();
await ambientSource.setBuffer(/* 这里填写音频缓冲 */);
// 配置3D音效路由
const ambientRoute = audioPlayer.createRoute(ambientSource);
const stereo = audioPlayer.createStereoEffect();
stereo.setPosition(5, 2, -3); // 音源位于右前方高处
ambientRoute.addEffect(stereo);
// 循环播放
ambientRoute.setLoop(true);
audioPlayer.addRoute('ambient', ambientRoute);
audioPlayer.play('ambient');
```
---
## 生命周期管理
```mermaid
sequenceDiagram
participant User
participant AudioPlayer
participant AudioContext
User->>AudioPlayer: new AudioPlayer()
AudioPlayer->>AudioContext: 创建音频上下文
User->>AudioPlayer: createRoute()
AudioPlayer->>AudioRoute: 实例化路由
User->>AudioPlayer: play()
AudioPlayer->>AudioContext: 启动音频时钟
loop 播放周期
AudioPlayer->>AudioRoute: 更新状态
end
User->>AudioPlayer: stop()
AudioPlayer->>AudioRoute: 释放资源
AudioPlayer->>AudioContext: 关闭上下文
```
---
## 注意事项
1. **空间音频配置**
3D 效果需统一坐标系:
```txt
(0,0,0) 屏幕中心
X+ → 右
Y+ ↑ 上
Z+ ⊙ 朝向用户
```

View File

@ -1,221 +0,0 @@
# AudioRoute 音频播放路由 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 类描述
音频播放控制的核心类,负责管理音频源与效果器的连接关系,协调播放状态转换,并处理音频管线生命周期。
```mermaid
graph LR
AudioRoute --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---
## 属性说明
| 属性名 | 类型 | 说明 |
| ------------- | ------------------ | ------------------------------------------------ |
| `output` | `AudioNode` | 最终输出节点(继承自 IAudioOutput) |
| `effectRoute` | `AudioEffect[]` | 效果器链数组(按顺序存储已连接的效果器实例) |
| `endTime` | `number` | 淡出过渡时长(单位:秒),默认 0 |
| `status` | `AudioStatus` | 当前播放状态(见下方枚举定义) |
| `duration` | `number` (getter) | 音频总时长(单位:秒) |
| `currentTime` | `number` (get/set) | 当前播放进度(单位:秒),设置时会触发 seek 操作 |
---
### AudioStatus 枚举
```typescript
enum AudioStatus {
Playing, // 正在播放
Pausing, // 淡出暂停过程中
Paused, // 已暂停
Stoping, // 淡出停止过程中
Stoped // 已停止
}
```
---
## 方法说明
### `setEndTime`
```typescript
function setEndTime(time: number): void;
```
设置淡出过渡时长
| 参数 | 类型 | 说明 |
| ---- | -------- | ------------------------ |
| time | `number` | 淡出动画时长(单位:秒) |
---
### `onStart`
```typescript
function onStart(fn?: (route: AudioRoute) => void): void;
```
注册播放开始钩子函数
| 参数 | 类型 | 说明 |
| ---- | ----------------- | ------------------------ |
| `fn` | `(route) => void` | 播放开始时触发的回调函数 |
---
### `onEnd`
```typescript
function onEnd(fn?: (time: number, route: AudioRoute) => void): void;
```
注册播放结束钩子函数
| 参数 | 类型 | 说明 |
| ---- | --------------------------- | --------------------------------------------- |
| `fn` | `(duration, route) => void` | 淡出阶段开始时触发的回调,duration 为淡出时长 |
---
### `play`
```typescript
function play(when?: number = 0): Promise<void>;
```
启动/恢复音频播放
| 参数 | 类型 | 说明 |
| ------ | -------- | -------------------------------------- |
| `when` | `number` | 基于 AudioContext 时间的启动时刻(秒) |
---
### `pause`
```typescript
function pause(): Promise<void>;
```
触发暂停流程(执行淡出过渡)
---
### `resume`
```typescript
function resume(): void;
```
从暂停状态恢复播放(执行淡入过渡)
---
### `stop`
```typescript
function stop(): Promise<void>;
```
完全停止播放并释放资源
---
### `addEffect`
```typescript
function addEffect(effect: AudioEffect | AudioEffect[], index?: number): void;
```
添加效果器到处理链
| 参数 | 类型 | 说明 |
| -------- | ------------------ | ------------------------------ |
| `effect` | `AudioEffect`/数组 | 要添加的效果器实例 |
| `index` | `number` (可选) | 插入位置,负数表示从末尾倒计数 |
---
### `removeEffect`
```typescript
function removeEffect(effect: AudioEffect): void;
```
从处理链移除效果器
| 参数 | 类型 | 说明 |
| -------- | ------------- | ------------------ |
| `effect` | `AudioEffect` | 要移除的效果器实例 |
---
## 事件说明
| 事件名 | 参数 | 触发时机 |
| -------------- | ---- | ------------------ |
| `updateEffect` | - | 效果器链发生变更时 |
| `play` | - | 开始/恢复播放时 |
| `stop` | - | 完全停止播放后 |
| `pause` | - | 进入暂停状态后 |
| `resume` | - | 从暂停状态恢复时 |
---
## 总使用示例
```typescript
import { audioPlayer } from '@user/client-modules';
// 创建音频播放器和路由
const source = audioPlayer.createBufferSource();
const route = audioPlayer.createRoute(audioSource);
// 配置效果链
const stereo = audioPlayer.createStereoEffect();
const echo = audioPlayer.createEchoEffect();
const volume = audioPlayer.createVolumeEffect();
route.addEffect([stereo, echo], 0); // 插入到链首
route.addEffect(volume); // 音量控制放到链尾
// 播放暂停
await route.play();
await route.pause();
route.resume(); // 继续操作不是异步,不需要 await
await route.stop();
```
---
## 处理流程示意图
```mermaid
sequenceDiagram
participant User
participant AudioRoute
participant Effects
User->>AudioRoute: play()
AudioRoute->>Effects: 启动所有效果器
Effects-->>AudioRoute: 准备完成
AudioRoute->>Source: 开始播放
loop 播放中
AudioRoute->>Effects: 实时音频处理
end
User->>AudioRoute: pause()
AudioRoute->>Effects: 启动淡出过渡
Effects-->>AudioRoute: 过渡完成
AudioRoute->>Source: 暂停播放
```

View File

@ -1,184 +0,0 @@
# AudioSource API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 类描述
音频系统的源头抽象类,定义了音频播放的核心控制接口。支持多种音频源类型,包括流媒体、HTML 音频元素和静态音频缓冲。
```mermaid
graph LR
AudioPlayer --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---
## 抽象成员说明
| 成员 | 类型 | 说明 |
| ------------- | ----------- | ------------------------ |
| `output` | `AudioNode` | 音频输出节点(必须实现) |
| `duration` | `number` | 音频总时长(秒) |
| `currentTime` | `number` | 当前播放时间(秒) |
| `playing` | `boolean` | 播放状态标识 |
---
## 核心方法说明
### `abstract play`
```typescript
function play(when?: number): void;
```
启动音频播放时序
| 参数 | 类型 | 说明 |
| ---- | -------- | ----------------------------------------------- |
| when | `number` | 预定播放时间(基于 `AudioContext.currentTime`) |
---
### `abstract stop`
```typescript
function stop(): number;
```
停止播放并返回停止时刻
---
### `abstract connect`
```typescript
function connect(target: IAudioInput): void;
```
连接至音频处理管线
| 参数 | 类型 | 说明 |
| ------ | ------------- | ------------------- |
| target | `IAudioInput` | 下游处理节点/效果器 |
---
### `abstract setLoop`
```typescript
function setLoop(loop: boolean): void;
```
设置循环播放模式
---
## 事件系统
| 事件名 | 参数 | 触发时机 |
| ------ | ---- | -------------- |
| `play` | - | 开始播放时 |
| `end` | - | 自然播放结束时 |
---
## 自定义音频源示例
### 网络实时通话源
```typescript
class WebRTCAudioSource extends AudioSource {
private mediaStream: MediaStreamAudioSourceNode;
output: AudioNode;
constructor(ac: AudioContext, stream: MediaStream) {
super(ac);
this.mediaStream = ac.createMediaStreamSource(stream);
this.output = this.mediaStream;
}
get duration() {
return Infinity;
} // 实时流无固定时长
get currentTime() {
return this.ac.currentTime;
}
play() {
this.mediaStream.connect(this.output);
this.playing = true;
this.emit('play');
}
stop() {
this.mediaStream.disconnect();
this.playing = false;
return this.ac.currentTime;
}
connect(target: IAudioInput) {
this.output.connect(target.input);
}
setLoop() {} // 实时流不支持循环
}
// 使用示例
navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
const source = new WebRTCAudioSource(audioContext, stream);
source.connect(effectsChain);
source.play();
});
```
---
## 内置实现说明
### AudioStreamSource(流媒体源)
```mermaid
graph LR
Network[网络数据流] --> Buffer[缓冲区]
Buffer --> Decoder[音频解码器]
Decoder --> Output[实时音频节点]
```
- 支持渐进式加载
- 动态缓冲管理
- 适用于浏览器自身不支持的音频类型
### AudioElementSource(HTML 音频元素源)
```mermaid
graph LR
AudioTag[audio 元素] -->|音频流| Output[媒体元素源节点]
```
- 基于 HTML5 Audio 元素
- 支持跨域资源
- 自动处理音频格式兼容
### AudioBufferSource(静态音频缓冲源)
```mermaid
graph LR
File[音频文件] --> Decode[解码为 AudioBuffer]
Decode --> Output[缓冲源节点]
```
- 完整音频数据预加载
- 精确播放控制
- 支持内存音频播放
---
## 注意事项
1. **时间精度**
所有时间参数均以 `AudioContext.currentTime` 为基准,精度可达 0.01 秒

View File

@ -1,158 +0,0 @@
# BgmController API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
```mermaid
graph LR
BgmController --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
## 类描述
`BgmController` 是背景音乐系统的核心控制器,支持多 BGM 的加载、音量控制、渐变切换和播放状态管理。继承自 `EventEmitter`,提供完整的音频事件监听机制。
---
## 泛型说明
- `T extends string`: BGM 的唯一标识符类型(默认为项目预定义的 `BgmIds`)
---
## 属性说明
| 属性名 | 类型 | 描述 |
| ---------------- | --------- | ----------------------------------------- |
| `prefix` | `string` | BGM 资源路径前缀(默认 `bgms.`) |
| `playingBgm` | `T` | 当前正在播放的 BGM ID |
| `enabled` | `boolean` | 是否启用音频控制(默认 true) |
| `transitionTime` | `number` | 音频切换渐变时长(单位:毫秒,默认 2000) |
---
## 核心方法说明
### `setTransitionTime`
```typescript
function setTransitionTime(time: number): void;
```
设置所有 BGM 的渐变切换时长。
- **参数**
- `time`: 渐变时长(毫秒)
---
### `blockChange`
```typescript
function blockChange(): void;
```
### `unblockChange`
```typescript
function unblockChange(): void;
```
屏蔽/解除屏蔽 BGM 切换(用于特殊场景)。
---
### `setVolume`
```typescript
function setVolume(volume: number): void;
```
### `getVolume`
```typescript
function getVolume(): number;
```
控制全局音量(范围 0-1)。
---
### `setEnabled`
```typescript
function setEnabled(enabled: boolean): void;
```
启用/禁用整个 BGM 系统(禁用时停止所有播放)。
---
### `addBgm`
```typescript
function addBgm(id: T, url?: string): void;
```
加载并注册 BGM 资源。
- **参数**
- `id`: BGM 唯一标识
- `url`: 自定义资源路径(默认 `project/bgms/${id}`)
---
### `removeBgm`
```typescript
function removeBgm(id: T): void;
```
移除已注册的 BGM 资源。
---
### 播放控制方法
```typescript
function play(id: T, when?: number): void; // 播放指定 BGM(带渐变)
function pause(): void; // 暂停当前 BGM(保留进度)
function resume(): void; // 继续播放当前 BGM
function stop(): void; // 停止当前 BGM(重置进度)
```
---
## 事件说明
| 事件名 | 参数 | 触发时机 |
| -------- | ---- | ----------------- |
| `play` | `[]` | 开始播放新 BGM 时 |
| `pause` | `[]` | 暂停播放时 |
| `resume` | `[]` | 继续播放时 |
| `stop` | `[]` | 完全停止播放时 |
---
## 总使用示例
```typescript
import { bgmController } from '@user/client-modules';
// 设置全局参数
bgmCtrl.setTransitionTime(1500);
bgmCtrl.setVolume(0.8);
// 播放控制
bgmCtrl.play('battle.mp3'); // 播放战斗BGM
bgmCtrl.pause(); // 暂停(如打开菜单)
bgmCtrl.resume(); // 继续播放
bgmCtrl.play('boss_battle.mp3'); // 切换至BOSS战BGM
bgmCtrl.stop(); // 完全停止(如战斗结束)
// 事件监听
bgmCtrl.on('play', () => {
console.log('BGM 开始播放:', bgmCtrl.playingBgm);
});
```

View File

@ -1,147 +0,0 @@
# HeroKeyMover API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
## 类描述
`HeroKeyMover` 是勇士按键移动的核心控制器,负责将热键系统与勇士移动逻辑结合,实现基于键盘输入的连续移动控制。支持多方向优先级处理和移动中断机制。
---
## 属性说明
| 属性名 | 类型 | 描述 |
| ------------ | ----------- | ---------------------------------------- |
| `hotkey` | `Hotkey` | 关联的热键控制器实例 |
| `mover` | `HeroMover` | 勇士移动逻辑执行器 |
| `scope` | `symbol` | 当前移动触发的作用域(默认使用主作用域) |
| `hotkeyData` | `MoveKey` | 移动方向与热键的映射配置 |
---
## 构造方法
```typescript
function constructor(
hotkey: Hotkey,
mover: HeroMover,
config?: MoveKeyConfig
): HeroKeyMover;
```
- **参数**
- `hotkey`: 已配置的热键控制器实例
- `mover`: 勇士移动逻辑实例
- `config`: 自定义方向键映射配置(可选)
**默认按键映射**:
```typescript
const map = {
left: 'moveLeft',
right: 'moveRight',
up: 'moveUp',
down: 'moveDown'
};
```
---
## 方法说明
### `setScope`
```typescript
function setScope(scope: symbol): void;
```
设置当前移动控制的作用域(用于多场景隔离)。
- **参数**
- `scope`: 唯一作用域标识符
---
### `press`
```typescript
function press(dir: Dir): void;
```
触发指定方向的移动按键按下状态。
- **参数**
- `dir`: 移动方向(`'left' | 'right' | 'up' | 'down'`)
---
### `release`
```typescript
function release(dir: Dir): void;
```
解除指定方向的移动按键按下状态。
- **参数**
- `dir`: 要释放的移动方向
---
### `tryStartMove`
```typescript
function tryStartMove(): boolean;
```
尝试启动移动逻辑(自动根据当前方向键状态判断)。
- **返回值**
`true` 表示移动成功启动,`false` 表示条件不满足
---
### `endMove`
```typescript
function endMove(): void;
```
立即终止当前移动过程。
---
### `destroy`
```typescript
function destroy(): void;
```
销毁控制器实例(自动解除所有事件监听)。
---
## 总使用示例
```typescript
import { gameKey, mainScope } from '@motajs/system-action';
// 初始化移动控制器
const keyMover = new HeroKeyMover(
gameKey,
heroMover,
{ left: 'moveLeft', right: 'moveRight' } // 自定义部分按键映射
);
// 设置允许触发的作用域
keyMover.setScope(mainScope);
// 销毁控制器
keyMover.destroy();
```
## 移动优先级机制
1. **最后按下优先**:当同时按下多个方向键时,以后按下的方向为准
2. **队列延续**:在移动过程中持续检测按键状态,自动延续移动队列
3. **作用域隔离**:只有当前作用域匹配时才会响应按键事件

View File

@ -1,197 +0,0 @@
# SoundPlayer API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 类描述
音效管理核心类,提供短音频的加载、播放和空间化控制功能。推荐通过全局单例 `soundPlayer` 使用。
```mermaid
graph LR
AudioPlayer --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---
## 属性说明
| 属性名 | 类型 | 说明 |
| --------- | --------------------- | ---------------------- |
| `enabled` | `boolean` | 总开关状态(默认启用) |
| `buffer` | `Map<T, AudioBuffer>` | 已加载音效缓冲存储池 |
| `playing` | `Set<number>` | 当前活跃音效 ID 集合 |
| `gain` | `VolumeEffect` | 全局音量控制器 |
---
## 方法说明
### 基础控制
#### setEnabled
```typescript
function setEnabled(enabled: boolean): void;
```
启用/禁用音效系统(禁用时立即停止所有音效)
| 参数 | 类型 | 说明 |
| ------- | --------- | ------------ |
| enabled | `boolean` | 是否启用音效 |
---
#### setVolume / getVolume
```typescript
function setVolume(volume: number): void;
function getVolume(): number;
```
全局音量控制(范围 0.0~1.0)
---
### 资源管理
#### add
```typescript
async function add(id: T, data: Uint8Array): Promise<void>;
```
加载并缓存音效资源
| 参数 | 类型 | 说明 |
| ---- | ------------ | ---------------- |
| id | `T` | 音效唯一标识符 |
| data | `Uint8Array` | 原始音频字节数据 |
---
### 播放控制
#### play
```typescript
function play(
id: T,
position?: [number, number, number],
orientation?: [number, number, number]
): number;
```
播放指定音效(返回音效实例 ID)
| 参数 | 类型 | 默认值 | 说明 |
| ----------- | ----------- | --------- | ------------------------- |
| id | `T` | - | 音效标识符 |
| position | `[x, y, z]` | `[0,0,0]` | 3D 空间坐标(右手坐标系) |
| orientation | `[x, y, z]` | `[1,0,0]` | 声音传播方向向量 |
**坐标系说明**:
```txt
(0,0,0) 听者位置
X+ → 右
Y+ ↑ 上
Z+ ⊙ 朝向听者正前方
```
---
#### stop
```typescript
function stop(num: number): void;
```
停止指定音效实例
| 参数 | 类型 | 说明 |
| ---- | -------- | -------------------- |
| num | `number` | play() 返回的实例 ID |
---
#### stopAllSounds
```typescript
function stopAllSounds(): void;
```
立即停止所有正在播放的音效
---
## 使用示例
### 基础音效系统
```typescript
import { soundPlayer } from '@user/client-modules';
// 播放射击音效(右侧声场)
const shotId = soundPlayer.play('shoot', [2, 0, 0]);
// 播放爆炸音效(左后方)
soundPlayer.play('explosion', [-3, 0, -2], [-1, 0, -1]);
// 停止特定音效
soundPlayer.stop(shotId);
// 全局音量控制
soundPlayer.setVolume(0.7);
```
### 3D 环境音效
```typescript
// 汽车引擎循环音效
let engineSoundId = -1;
function startEngine() {
engineSoundId = soundPlayer.play('engine', [0, 0, -5]);
}
function updateCarPosition(x: number, z: number) {
const route = audioPlayer.getRoute(`sounds.${engineSoundId}`);
const stereo = route?.effectRoute[0] as StereoEffect;
stereo?.setPosition(x, 0, z);
}
```
---
## 生命周期管理
```mermaid
sequenceDiagram
participant User
participant SoundPlayer
participant AudioPlayer
User->>SoundPlayer: add('explosion', data)
SoundPlayer->>AudioPlayer: decodeAudioData()
AudioPlayer-->>SoundPlayer: AudioBuffer
User->>SoundPlayer: play('explosion')
SoundPlayer->>AudioPlayer: 创建路由/效果器
AudioPlayer-->>SoundPlayer: 音效ID
loop 播放周期
SoundPlayer->>AudioPlayer: 更新空间参数
end
User->>SoundPlayer: stop(id)
SoundPlayer->>AudioPlayer: 释放路由资源
```
---
## 注意事项
1. **实例数量限制**
同时播放音效建议不超过 32 个,可通过优先级系统管理

View File

@ -1,208 +0,0 @@
# StreamLoader API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
```mermaid
graph LR
StreamLoader --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
## 类描述
`StreamLoader` 是流式加载大文件的核心类,支持分块读取网络资源并通过事件机制传递数据。继承自 `EventEmitter`,实现 `IStreamController` 接口,提供流传输控制能力。
---
## 属性说明
| 属性名 | 类型 | 描述 |
| --------- | --------- | ---------------------- |
| `url` | `string` | 只读,要加载的资源 URL |
| `loading` | `boolean` | 当前是否处于加载状态 |
---
## 构造方法
```typescript
function constructor(url: string): StreamLoader;
```
- **参数**
- `url`: 要加载的资源地址
**示例**
```typescript
const loader = new StreamLoader('/api/large-file');
```
---
## 方法说明
### `pipe`
```typescript
function pipe(reader: IStreamReader): this;
```
将流数据管道传递给读取器对象。
- **参数**
- `reader`: 实现 `IStreamReader` 接口的对象
**示例**
```typescript
class MyReader implements IStreamReader {
async pump(data, done) {
console.log('收到数据块:', data);
}
// ... 还有一些其他需要实现的方法,参考总是用示例
}
loader.pipe(new MyReader());
```
---
### `start`
```typescript
function start(): Promise<void>;
```
启动流传输流程(自动处理分块读取与分发)。
---
### `cancel`
```typescript
function cancel(reason?: string): void;
```
终止当前流传输。
- **参数**
- `reason`: 终止原因描述(可选)
**示例**
```typescript
// 用户取消加载
loader.cancel('用户手动取消');
```
---
## 事件说明
| 事件名 | 参数类型 | 触发时机 |
| ------ | --------------------------------- | ------------------------ |
| `data` | `data: Uint8Array, done: boolean` | 每接收到一个数据块时触发 |
**事件监听示例**
```typescript
loader.on('data', (data, done) => {
if (done) console.log('传输完成');
});
```
---
## 相关接口说明
### IStreamReader
```typescript
export interface IStreamReader<T = any> {
/**
* 接受字节流流传输的数据
* @param data 传入的字节流数据,只包含本分块的内容
* @param done 是否传输完成
*/
pump(
data: Uint8Array | undefined,
done: boolean,
response: Response
): Promise<void>;
/**
* 当前对象被传递给加载流时执行的函数
* @param controller 传输流控制对象
*/
piped(controller: IStreamController<T>): void;
/**
* 开始流传输
* @param stream 传输流对象
* @param controller 传输流控制对象
*/
start(
stream: ReadableStream,
controller: IStreamController<T>,
response: Response
): Promise<void>;
/**
* 结束流传输
* @param done 是否传输完成,如果为 false 的话,说明可能是由于出现错误导致的终止
* @param reason 如果没有传输完成,那么表示失败的原因
*/
end(done: boolean, reason?: string): void;
}
```
- `pump`: 处理每个数据块
- `piped`: 当读取器被绑定到流时调用
- `start`: 流传输开始时调用
- `end`: 流传输结束时调用
---
## 总使用示例
```typescript
// 创建流加载器
const loader = new StreamLoader('/api/video-stream');
const videoElement = document.createElement('video');
// 实现自定义读取器
class VideoStreamReader implements IStreamReader {
async pump(data, done) {
if (data) videoElement.appendBuffer(data);
if (done) videoElement.play();
}
piped(controller) {
console.log('流传输管道连接成功');
}
start() {
console.log('开始流式加载');
}
end() {
console.log('流式加载结束');
}
}
const reader = new VideoStreamReader();
// 绑定读取器并启动
loader.pipe(reader);
loader.start();
// 监听进度
loader.on('data', (_, done) => {
if (!done) updateProgressBar();
});
// 错误处理
videoElement.onerror = () => loader.cancel('视频解码错误');
```

View File

@ -1,157 +0,0 @@
# TextContentParser API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
## 类描述
`TextContentParser` 是文字解析核心工具,用于处理文本排版、转义字符解析及动态样式管理。支持自动分词换行、图标嵌入和样式栈控制。
---
## 方法说明
### `parse`
```typescript
function parse(text: string, width: number): ITextContentRenderObject;
```
解析文本并生成渲染数据对象:
```typescript
interface ITextContentRenderObject {
lineHeights: number[]; // 每行高度
lineWidths: number[]; // 每行宽度
data: ITextContentRenderable[]; // 渲染元素集合
}
```
---
## 转义字符语法说明
### 1. 颜色控制 `\r[color]`
- **语法**:`\r[颜色值]`
- **栈模式**:支持嵌套,用`\r`恢复上一级颜色
- **颜色格式**:支持 CSS 颜色字符串
```typescript
// 示例:红→黄→红→默认
'\\r[red]危险!\\r[yellow]警告\\r恢复红色\\r默认';
```
### 2. 字号控制 `\c[size]`
- **语法**:`\c[字号(px)]`
- **栈模式**:用`\c`恢复上一级字号
```typescript
// 示例:24px→32px→24px
'普通\\c[24]标题\\c[32]超大标题\\c恢复';
```
### 3. 字体家族 `\g[family]`
- **语法**:`\g[字体名称]`
- **栈模式**:用`\g`恢复上一级字体
```typescript
'默认\\g[黑体]中文黑体\\g恢复默认';
```
### 4. 粗体切换 `\d`
- **语法**:`\d`(开关模式)
```typescript
'正常\\d粗体\\d正常';
```
### 5. 斜体切换 `\e`
- **语法**:`\e`(开关模式)
```typescript
'正常\\e斜体\\e正常';
```
### 6. 等待间隔 `\z[wait]`
- **语法**:`\z[等待字符数]`
- **计算规则**:`间隔时间 = 字符数 * 当前interval配置`
```typescript
'开始对话\\z[10](暂停500ms)继续';
```
### 7. 图标嵌入 `\i[icon]`
- **语法**:`\i[图标ID]`
- **图标规范**:需预加载到资源管理器
```typescript
'攻击\\i[sword]造成伤害';
```
### 8. 表达式 `${}`
- **语法**:与模板字符串语法一致,不过是在渲染的时候实时计算,而非字符串声明时计算
```typescript
'${core.status.hero.atk * 10}'; // 显示勇士攻击乘 10
'${core.status.hero.atk > 100 ? "高攻击" : "低攻击"}'; // 条件表达式
'${(() => { if (a > 10) return 100; else return 10; })()}'; // 嵌入函数
```
---
## 综合使用示例
### 战斗伤害提示
```typescript
const text =
'\\r[#ff0000]\\c[24]\\d敌人\\i[monster]对你造成\\c[32]\\r[yellow]500\\c\\r伤害!\\z[5]\\d\\e(按空格跳过)';
const result = parser.parse(text, 400);
/* 解析结果:
[
{ type: 'text', color: '#ff0000', size:24, bold:true, text:'敌人' },
{ type: 'icon', id:'monster' },
{ type: 'text', color:'#ff0000', size:24, text:'对你造成' },
{ type: 'text', color:'yellow', size:32, text:'500' },
{ type: 'text', color:'#ff0000', size:24, text:'伤害!' },
{ type: 'wait', duration:250 }, // 假设 interval=50
{ type: 'text', bold:false, italic:true, text:'(按空格跳过)' }
]
*/
```
### 多语言混合排版
```typescript
const multiLangText =
'\\g[Times New Roman]Hello\\g[宋体]你好\\i[globe]\\z[3]\\g切换为\\r[blue]Français';
// 效果:英文→中文+地球图标→等待→蓝色法文
```
---
## 注意事项
1. **转义字符格式**
- 必须使用 **双反斜杠**(`\\`)表示转义
- 错误示例:`\r[red]`(单反斜杠 `\r` 可能会被识别为换行)
- 正确示例:`\\r[red]`
2. **栈操作规则**
```typescript
// 颜色栈示例
'默认\\r[red]红\\r[blue]蓝\\r恢复红\\r恢复默认';
// 等效于:push(默认)→push(红)→push(蓝)→pop→pop
```

View File

@ -1,245 +0,0 @@
# TextContentTyper API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
```mermaid
graph LR
TextContentTyper --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
## 类描述
`TextContentTyper` 是文字逐字输出(打字机效果)的核心控制器,继承自 `EventEmitter`。用于管理文字排版、渲染时序及样式配置,支持动态修改文本内容和样式。
---
## 核心属性说明
| 属性名 | 类型 | 描述 |
| -------- | ----------------------- | ---------------------------------------------- |
| `config` | `Required<TyperConfig>` | 当前文字渲染配置(包含字体、行高、对齐等参数) |
| `parser` | `TextContentParser` | 文字解析器实例(负责分词、分行等底层处理) |
---
## 核心方法说明
### `constructor`
```typescript
function constructor(config: Partial<ITextContentConfig>): TextContentTyper;
```
初始化打字机实例,接受文字配置参数:
```typescript
interface ITextContentConfig {
/** 字体 */
font: Font;
/** 是否持续上一次的文本,开启后,如果修改后的文本以修改前的文本为开头,那么会继续播放而不会从头播放(暂未实现,后续更新) */
keepLast: boolean;
/** 打字机时间间隔,即两个字出现之间相隔多长时间 */
interval: number;
/** 行高 */
lineHeight: number;
/** 分词规则 */
wordBreak: WordBreak;
/** 文字对齐方式 */
textAlign: TextAlign;
/** 行首忽略字符,即不会出现在行首的字符 */
ignoreLineStart: Iterable<string>;
/** 行尾忽略字符,即不会出现在行尾的字符 */
ignoreLineEnd: Iterable<string>;
/** 会被分词规则识别的分词字符 */
breakChars: Iterable<string>;
/** 填充样式 */
fillStyle: CanvasStyle;
/** 描边样式 */
strokeStyle: CanvasStyle;
/** 线宽 */
strokeWidth: number;
/** 文字宽度,到达这么宽之后换行 */
width: number;
}
```
---
### `setConfig`
```typescript
function setConfig(config: Partial<ITextContentConfig>): void;
```
动态更新配置参数(支持部分更新)
---
### `setText`
```typescript
function setText(text: string): void;
```
设置要显示的文本内容(自动重置播放进度)
---
### `type`
```typescript
function type(): void;
```
启动逐字显示效果
---
### `typeAll`
```typescript
function typeAll(): void;
```
立即完整显示所有文字
---
### `setRender`
```typescript
function setRender(render: TyperFunction): void;
```
设置自定义渲染逻辑:
```typescript
type TyperFunction = (
data: TyperRenderable[], // 待渲染元素
typing: boolean // 是否正在播放中
) => void;
```
---
## 事件说明
| 事件名 | 参数 | 触发时机 |
| ----------- | ---- | ------------------ |
| `typeStart` | `[]` | 开始逐字显示时 |
| `typeEnd` | `[]` | 全部文字显示完成时 |
---
## 使用示例
### 基础用法 - 对话框文字
```typescript
// 初始化配置
const typer = new TextContentTyper({
font: new Font('黑体', 18),
interval: 50,
lineHeight: 1.2,
width: 400
});
// 设置文本内容
typer.setText(`「这是逐字显示的文字效果...
第二行会自动换行」`);
// 注册渲染逻辑
typer.setRender((elements, isTyping) => {
elements.forEach(element => {
if (element.type === TextContentType.Text) {
drawText(element.x, element.y, element.text);
}
});
});
// 开始播放
typer.type();
```
### 动态样式修改
```typescript
// 修改为红色斜体
typer.setConfig({
font: new Font('楷体', 20),
fillStyle: '#ff0000'
});
// 修改播放速度
typer.setConfig({ interval: 30 });
```
---
## 底层数据结构
### 渲染元素类型
```typescript
type TyperRenderable =
| TyperTextRenderable // 文本元素
| TyperIconRenderable // 图标元素
| TyperWaitRenderable; // 等待间隔
```
::: code-group
```ts [TyperTextRenderable]
interface TyperTextRenderable {
type: TextContentType.Text;
x: number;
y: number;
text: string;
font: string;
fillStyle: CanvasStyle;
strokeStyle: CanvasStyle;
/** 文字画到哪个索引 */
pointer: number;
/** 这段文字的总高度 */
height: number;
}
```
```ts [TyperIconRenderable]
interface TyperIconRenderable {
type: TextContentType.Icon;
x: number;
y: number;
width: number;
height: number;
renderable: RenderableData | AutotileRenderable;
}
```
```ts [TyperWaitRenderable]
interface TyperWaitRenderable {
type: TextContentType.Wait;
wait: number;
waited: number;
}
```
:::
---
## 注意事项
1. **性能优化**
当处理长文本(>1000 字)时,建议预调用 `parser.parse()` 进行分页
2. **坐标系统**
所有坐标基于初始化时设置的 `width` 参数进行相对计算
3. **动态修改限制**
在播放过程中修改配置可能导致渲染异常,建议在 `typeEnd` 事件后操作
4. **使用场景**
本接口的使用场景并不多,建议使用 `TextContent` 组件。如果必须使用的话,可以直接阅读源码来看一些实现细节。

View File

@ -1,166 +0,0 @@
# TextboxStore API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
```mermaid
graph LR
TextboxStore --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---
## 类描述
`TextboxStore` 是文本框的集中管理器,继承自 `EventEmitter`。所有 `Textbox` 组件实例化时会自动注册到该类的静态 `list` 中,支持通过 ID 精准控制特定文本框。
---
## 核心方法说明
### `TextboxStore.get`
```typescript
function get(id: string): TextboxStore | undefined;
```
**静态方法**:通过 ID 获取已注册的文本框控制器
- **参数**
`id`: 文本框的唯一标识符
- **返回值**
找到返回实例,否则返回 `undefined`
---
### `setText`
```typescript
function setText(text: string): void;
```
**动态更新文本内容**
- **特性**
- 自动重置打字机进度
- 触发重新排版计算
---
### `modify`
```typescript
function modify(data: Partial<TextboxProps>): void;
```
**动态修改文本框配置**
- **参数**
`data`: 需更新的属性(支持所有 `TextboxProps` 属性)
---
### `endType`
```typescript
function endType(): void;
```
**立即结束打字机动画**
- **特性**
- 强制显示全部文本
- 触发 `typeEnd` 事件
---
### `show`
```ts
function show(): void;
```
### `hide`
```ts
function hide(): void;
```
控制文本框的显示和隐藏。
---
## 使用示例
### 跨场景更新对话内容
```typescript
// 在剧情管理器中的调用
const updateChapterDialog = (chapterId: string) => {
const store = TextboxStore.get(`chapter_${chapterId}`);
store?.setText(getChapterText(chapterId));
store?.modify({ title: `第 ${chapterId} 章` });
};
```
### 紧急提示打断当前动画
```typescript
// 强制显示关键信息
const showEmergencyAlert = () => {
const alertBox = TextboxStore.get('system_alert');
alertBox?.setText('警告!基地即将爆炸!');
alertBox?.endType(); // 跳过打字动画
alertBox?.show();
};
```
### 动态样式调整
```typescript
// 根据昼夜切换对话框样式
const updateDialogStyle = (isNight: boolean) => {
TextboxStore.list.forEach(store => {
store.modify({
backColor: isNight ? '#1A1A32' : '#F0F0FF',
titleFill: isNight ? '#E6E6FA' : '#2F4F4F'
});
});
};
```
---
## 注意事项
1. **ID 管理规范**
建议显式指定可预测的 ID 格式:
```tsx
// 创建时指定可追踪 ID
<Textbox id={`npc_${npcId}_dialog`} ... />
```
2. **未找到实例处理**
调用前需做空值检测:
```typescript
const store = TextboxStore.get('custom_id');
if (!store) {
console.warn('文本框未注册: custom_id');
return;
}
```
3. **生命周期匹配**
在组件卸载时自动注销实例,请勿持有长期引用
4. **批量操作优化**
同时操作多个实例时建议使用迭代器:
```typescript
// 隐藏所有对话框
TextboxStore.list.forEach(store => store.hide());
```

View File

@ -1,147 +0,0 @@
# TipStore API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 类描述
`TipStore` 是提示框的集中管理器,提供全局访问和控制提示组件的能力。所有通过 `<Tip>` 组件注册的实例会自动加入静态 `list` 容器,支持通过 ID 精准控制特定提示框。
---
## 核心方法说明
### `TipStore.get`
```typescript
function get(id: string): TipStore | undefined;
```
**静态方法**:通过 ID 获取已注册的提示框控制器
| 参数 | 类型 | 必填 | 说明 |
| ---- | -------- | ---- | ---------------- |
| `id` | `string` | 是 | 提示框的唯一标识 |
**返回值**:找到返回实例,否则返回 `undefined`
---
### `TipStore.use`
```typescript
function use(id: string, data: TipExpose): TipStore;
```
**静态方法**:注册提示框实例到全局管理器(通常在组件内部使用)
| 参数 | 类型 | 必填 | 说明 |
| ------ | ----------- | ---- | ----------------------- |
| `id` | `string` | 是 | 提示框的唯一标识 |
| `data` | `TipExpose` | 是 | 来自 Tip 组件的暴露接口 |
---
### `drawTip`
```typescript
function drawTip(text: string, icon?: AllIds | AllNumbers): void;
```
**显示提示内容**(支持带图标的提示)
| 参数 | 类型 | 必填 | 说明 |
| ------ | ---------------------- | ---- | ------------------------------- |
| `text` | `string` | 是 | 提示文字内容 |
| `icon` | `AllIds \| AllNumbers` | 否 | 图标资源 ID(字符串或数字形式) |
**特性**:
- 自动触发淡入动画
- 3 秒无操作后自动淡出
- 重复调用会重置计时器
---
## 使用示例
### 基础提示
```typescript
// 获取预先注册的提示框
const tip = TipStore.get('item-get-tip');
// 显示纯文本提示
tip?.drawTip('获得金币 x100');
// 显示带图标的提示
tip?.drawTip('获得 传说之剑', 'legend_sword');
```
### 全局广播提示
```typescript
// 向所有提示框发送通知
TipStore.list.forEach(store => {
store.drawTip('系统将在5分钟后维护', 'warning');
});
```
### 动态内容提示
```typescript
// 组合动态内容
const showDamageTip = (damage: number) => {
TipStore.get('combat-tip')?.drawTip(
`造成 ${damage} 点伤害`,
damage > 1000 ? 'critical_hit' : 'normal_hit'
);
};
```
---
## 生命周期管理
### 组件注册流程
```tsx
// 在组件定义时注册实例
<Tip id="quest-tip" loc={[20, 20, 400, 40]}></Tip>;
// 在业务逻辑中调用
const showQuestComplete = () => {
TipStore.get('quest-tip')?.drawTip('任务「勇者的试炼」完成!');
};
```
---
## 注意事项
1. **自动清理机制**
组件卸载时自动注销实例,跨场景访问时需确保目标组件已挂载
2. **错误处理**
建议封装安全访问方法:
```typescript
const safeDrawTip = (id: string, text: string) => {
const instance = TipStore.get(id);
if (!instance) {
console.error(`Tip ${id} not registered`);
return;
}
instance.drawTip(text);
};
```
3. **动画队列**
连续调用时会中断当前动画,建议重要提示添加延迟:
```typescript
tip.drawTip('第一条提示');
setTimeout(() => {
tip.drawTip('第二条重要提示');
}, 3200); // 等待淡出动画结束
```

View File

@ -1,217 +0,0 @@
# WeatherController API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
```mermaid
graph LR
WeatherController --> IWeather
```
_实现 `IWeather` 接口_
## 类描述
`WeatherController` 是天气系统的核心控制器,支持动态管理多种天气效果(如雨、雪、雾等),可将天气效果绑定到任意渲染元素上,实现多场景独立天气控制。
---
## 属性说明
| 属性名 | 类型 | 描述 |
| -------------- | -------------------------------- | ----------------------------------------------------------------- |
| `id` | `string` | 只读,控制器的唯一标识符 |
| `active` | `Set<IWeather>` | 当前激活的天气实例集合 |
| `list`(静态) | `Map<string, Weather>` | 静态属性,存储所有注册的天气类型(键为天气 ID,值为天气构造函数) |
| `map`(静态) | `Map<string, WeatherController>` | 静态属性,存储所有控制器实例 |
---
## 构造方法
```typescript
function constructor(id: string): WeatherController;
```
- **参数**
- `id`: 控制器的标识符
## 方法说明
### `activate`
```typescript
function activate(id: string, level?: number): IWeather | undefined;
```
激活指定天气。
- **参数**
- `id`: 已注册的天气 ID
- `level`: 天气强度等级(可选)
---
### `bind`
```typescript
function bind(item?: RenderItem): void;
```
绑定/解绑渲染元素。
- **参数**
- `item`: 要绑定的渲染元素(不传则解绑)
---
### `deactivate`
```typescript
function deactivate(weather: IWeather): void;
```
关闭指定天气效果。
---
### `clearWeather`
```typescript
function clearWeather(): void;
```
清空所有天气效果。
---
### `getWeather`
```typescript
function getWeather<T extends IWeather = IWeather>(
weather: new (level?: number) => T
): T | null;
```
获取指定天气实例。
**示例**
```ts
import { RainWeather } from '@user/client-modules';
const rain = controller.getWeather(RainWeather);
```
---
### `destroy`
```typescript
function destroy(): void;
```
摧毁这个天气控制器,摧毁后不可继续使用。
---
## 静态方法说明
### `WeatherController.register`
```typescript
function register(id: string, weather: Weather): void;
```
**静态方法**:注册新的天气类型。
- **参数**
- `id`: 天气唯一标识(如 "rain")
- `weather`: 天气类(需实现 `IWeather` 接口)
---
### `WeatherController.get`
```typescript
function get(id: string): WeatherController | undefined;
```
- **参数**
- `id`: 要获得的控制器标识符
## 天气接口说明
```typescript
interface IWeather {
activate(item: RenderItem): void; // 初始化天气效果
frame(): void; // 每帧更新逻辑
deactivate(item: RenderItem): void; // 清除天气效果
}
```
---
## 内置天气
- `rain`: 下雨天气
## 总使用示例 实现滤镜天气效果
::: code-group
```typescript [定义天气]
// 定义灰度滤镜天气
class GrayFilterWeather implements IWeather {
private scale: number;
private now: number = 0;
private item?: RenderItem;
constructor(level: number = 5) {
this.scale = level / 10;
}
activate(item: RenderItem) {
// 添加灰度滤镜
item.filter = `grayscale(0)`;
this.item = item;
}
frame() {
// 动态调整滤镜强度(示例:正弦波动)
if (this.item) {
const intensity = ((Math.sin(Date.now() / 1000) + 1) * scale) / 2;
this.item.filter = `grayscale(${itensity})`;
}
}
deactivate(item: RenderItem) {
item.filter = `none`;
}
}
// 注册天气类型
WeatherController.register('gray-filter', GrayFilterWeather);
```
```tsx [使用天气]
import { defineComponent, onMounted } from 'vue';
import { Container } from '@motajs/render';
import { useWeather } from '@user/client-modules';
const MyCom = defineComponent(() => {
const [controller] = useWeather();
const root = ref<Container>();
onMounted(() => {
// 绑定天气的渲染元素
controller.bind(root.value);
// 激活天气效果
controller.activate('gray-filter', 5);
});
return () => <container ref={root}></container>;
});
```
:::

View File

@ -1,411 +0,0 @@
# 模块函数 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
## 钩子
### `onOrientationChange`
```typescript
function onOrientationChange(hook: OrientationHook): void;
```
监听屏幕方向变化事件。需要在组件内或 UI 内调用。
**参数**
- `hook`: 方向变化回调函数
```typescript
type OrientationHook = (
orientation: Orientation, // 当前方向
width: number, // 窗口宽度
height: number // 窗口高度
) => void;
```
**示例** - 响应式布局
```typescript
import { onOrientationChange, Orientation } from './use';
// 组件内
onOrientationChange((orient, width) => {
if (orient === Orientation.Portrait) {
// 竖屏模式
adjustMobileLayout(width);
} else {
// 横屏模式
resetDesktopLayout();
}
});
```
---
### `onLoaded`
```typescript
function onLoaded(hook: () => void): void;
```
在游戏核心资源加载完成后执行回调(若已加载则立即执行)。
---
## 过渡动画控制
### 通用接口
```typescript
interface ITransitionedController<T> {
readonly ref: Ref<T>; // 响应式引用
readonly value: T; // 当前值
set(value: T, time?: number): void; // 设置目标值
mode(timing: TimingFn): void; // 设置缓动曲线
setTime(time: number): void; // 设置默认时长
}
```
### `transitioned`
```typescript
function transitioned(
value: number, // 初始值
time: number, // 默认过渡时长(ms)
curve: TimingFn // 缓动函数(如 linear())
): ITransitionedController<number> | null;
```
创建数值渐变控制器(仅限组件内使用)。
**示例** - 旋转动画
```tsx
// Vue 组件内
const rotate = transitioned(0, 500, hyper('sin', 'out'));
// 触发动画
rotate.set(Math.PI, 800); // 800ms 内旋转到 180 度
// 模板中使用
<text rotate={rotate.ref.value} text="一些显示内容" />;
```
### `transitionedColor`
```typescript
function transitionedColor(
color: string, // 初始颜色(目前支持 #RGB/#RGBA/rgb()/rgba())
time: number, // 默认过渡时长(ms)
curve: TimingFn // 缓动函数
): ITransitionedController<string> | null;
```
创建颜色渐变控制器(仅限组件内使用)。
**示例** - 背景色过渡
```tsx
// Vue 组件内
const bgColor = transitionedColor('#fff', 300, linear());
// 触发颜色变化
bgColor.set('rgba(255, 0, 0, 0.5)'); // 渐变为半透明红色
// 模板中使用
<g-rect fillStyle={bgColor.ref.value} />;
```
---
### 注意事项
1. **组件生命周期**:过渡控制器必须在 Vue 组件内部创建,卸载时自动销毁
2. **性能优化**:避免在频繁触发的回调(如每帧渲染)中创建新控制器
3. **颜色格式**:`transitionedColor` 支持 HEX/RGB/RGBA,但不支持 HSL
4. **默认时长**:调用 `set()` 时不传时间参数则使用初始化时设置的时间
### 高级用法示例
#### 组合动画
```typescript
// 同时控制位置和透明度
const posX = transitioned(0, 500, linear());
const alpha = transitioned(1, 300, linear());
const moveAndFade = () => {
posX.set(200);
alpha.set(0);
};
// 组件卸载时自动清理动画资源
```
## 组件控制
### `getConfirm`
```typescript
function getConfirm(
controller: IUIMountable, // UI 控制器
text: string, // 确认内容
loc: ElementLocator, // 定位配置
width: number, // 对话框宽度(像素)
props?: Partial<ConfirmBoxProps> // 扩展配置
): Promise<boolean>;
```
---
#### 参数说明
| 参数名 | 类型 | 必填 | 描述 |
| ------------ | -------------------------- | ---- | ---------------------------------------------- |
| `controller` | `IUIMountable` | 是 | UI 控制器实例(通常从组件 props 获取) |
| `text` | `string` | 是 | 需要用户确认的文本内容 |
| `loc` | `ElementLocator` | 是 | 对话框位置配置(需包含 x,y 坐标及锚点) |
| `width` | `number` | 是 | 对话框宽度(像素),高度自动计算 |
| `props` | `Partial<ConfirmBoxProps>` | 否 | 扩展配置项(支持所有 ConfirmBox 组件的 props) |
---
#### 返回值
返回 `Promise<boolean>`:
- `true` 表示用户点击确认
- `false` 表示用户取消或关闭
---
#### 使用示例
##### 基础用法 - 删除确认
```tsx
import { defineComponent } from 'vue';
import { DefaultProps } from '@motajs/render';
import { GameUI } from '@motajs/system-ui';
// 在业务逻辑中调用,注意,组件需要使用 UI 控制器打开,它会自动传递 controller 参数
const MyCom = defineComponent<DefaultProps>(props => {
const handleDeleteItem = async (itemId: string) => {
const confirmed = await getConfirm(
props.controller, // 从组件 props 获取控制器
`确认删除 ID 为 ${itemId} 的项目吗?`,
[208, 208, void 0, void 0, 0.5, 0.5], // 居中显示
208
);
if (confirmed) {
api.deleteItem(itemId);
}
};
return () => (
<container>
{/* 假设有一个按钮在点击后触发上面的删除函数 */}
<text text="删除" onClick={() => handleDeleteItem(item.id)} />
</container>
);
});
export const MyUI = new GameUI('my-ui', MyCom);
```
##### 自定义按钮文本
```typescript
import { mainUIController } from '@user/client-modules';
// 注意,如果在 client-modules/render/ui 下编写代码,应该引入:
import { mainUIController } from './controller.ts';
// 修改确认/取消按钮文案
const result = await getConfirm(
// 传入主 UI 控制器也可以
mainUIController,
'切换场景将丢失未保存进度',
[208, 208, void 0, void 0, 0.5, 0.5],
320,
{
yesText: '继续切换',
noText: '留在当前',
selFill: '#e74c3c',
border: '#c0392b'
}
);
```
---
### `getChoice`
```typescript
function getChoice<T extends ChoiceKey = ChoiceKey>(
controller: IUIMountable, // UI 控制器
choices: ChoiceItem[], // 选项数组
loc: ElementLocator, // 定位配置
width: number, // 对话框宽度(像素)
props?: Partial<ChoicesProps> // 扩展配置
): Promise<T>;
```
#### 参数说明
| 参数名 | 类型 | 必填 | 描述 |
| ------------ | ----------------------- | ---- | ------------------------------------------- |
| `controller` | `IUIMountable` | 是 | UI 控制器实例(通常从组件 props 获取) |
| `choices` | `ChoiceItem[]` | 是 | 选项数组,格式为 `[key, text]` 的元组 |
| `loc` | `ElementLocator` | 是 | 对话框位置配置(需包含 x,y 坐标及锚点) |
| `width` | `number` | 是 | 对话框宽度(像素),高度自动计算 |
| `props` | `Partial<ChoicesProps>` | 否 | 扩展配置项(支持所有 Choices 组件的 props) |
#### 返回值
返回 `Promise<T>`:
- 解析为选中项的 `key` 值
#### 使用示例
##### 基础用法 - 难度选择
```typescript
import { getChoice, mainUIController } from '@user/client-modules';
// 写到异步函数里面
const selectedDifficulty = await getChoice(
mainUIController,
[
['easy', '新手模式'],
['normal', '普通模式'],
['hard', '困难模式']
],
[208, 208, void 0, void 0, 0.5, 0.5], // 居中显示
208,
{
title: '选择难度',
titleFont: new Font('黑体', 24)
}
);
// 判断选择的内容
if (selectedDifficulty === 'hard') {
applyHardcoreRules();
}
```
##### 分页支持 - 角色选择
```typescript
import { getChoice, mainUIController } from '@user/client-modules';
// 生成 200 个角色选项
const characterOptions = Array.from(
{ length: 200 },
(_, i) => [i, `角色 #${i + 1}`] as ChoiceItem
);
const chosenId = await getChoice(
mainUIController,
characterOptions,
[208, 208, void 0, void 0, 0.5, 0.5],
208,
{
maxHeight: 400, // 超过 400px 自动分页
winskin: 'winskin.png',
interval: 12
}
);
```
##### 动态样式配置
```typescript
import { getChoice, mainUIController } from '@user/client-modules';
// 自定义主题风格
const choiceResult = await getChoice(
mainUIController,
[
['light', '浅色主题'],
['dark', '深色主题'],
['oled', 'OLED 深黑']
],
[208, 208, void 0, void 0, 0.5, 0.5],
300,
{
color: 'rgba(30,30,30,0.9)',
border: '#4CAF50',
selFill: '#81C784',
titleFill: '#FFF59D'
}
);
```
### `waitbox`
```typescript
function waitbox<T>(
controller: IUIMountable,
loc: ElementLocator,
width: number,
promise: Promise<T>,
props?: Partial<WaitBoxProps<T>>
): Promise<T>;
```
#### 参数说明
| 参数名 | 类型 | 必填 | 默认值 | 描述 |
| ------------ | -------------------------- | ---- | ------ | ---------------------------------------------------- |
| `controller` | `IUIMountable` | 是 | - | UI 挂载控制器(通常传递父组件的 `props.controller`) |
| `loc` | `ElementLocator` | 是 | - | 定位参数 |
| `width` | `number` | 是 | - | 内容区域宽度(像素) |
| `promise` | `Promise<T>` | 是 | - | 要监视的异步操作 |
| `props` | `Partial<WaitBoxProps<T>>` | 否 | `{}` | 扩展配置项(继承 `Background` + `TextContent` 属性) |
---
#### 返回值
| 类型 | 说明 |
| ------------ | ----------------------------------------------------------------------------------- |
| `Promise<T>` | 与传入 `Promise` 联动的代理 `Promise`,在以下情况会 `reject`:原始 `Promise` 被拒绝 |
---
#### 使用示例
##### 等待网络请求
```typescript
// 获取用户数据
const userData = await waitbox(
props.controller,
[400, 300, void 0, void 0, 0.5, 0.5], // 居中定位
300,
fetch('/api/user'),
{
text: '加载用户信息...',
winskin: 'ui/loading_panel'
}
);
```
### 注意事项
1. **控制器有效性**
必须确保传入的 `controller` 已正确挂载且未销毁
2. **异步特性**
需使用 `await` 或 `.then()` 处理返回的 Promise
3. **定位系统**
Y 轴坐标基于 Canvas 坐标系(向下为正方向)
4. **额外参考**
- [组件 ConfirmBox](./组件%20ConfirmBox.md)
- [组件 Choices](./组件%20Choices.md)
- [组件 WaitBox](./组件%20WaitBox.md)

View File

@ -1,3 +0,0 @@
# @user/client-modules
目录:

View File

@ -1,46 +0,0 @@
# 图标组件 API
## Props 属性说明
| 属性名 | 类型 | 必填 | 描述 |
| ------ | ---------------- | ---- | ---------- |
| `loc` | `ElementLocator` | 是 | 图标定位符 |
图标比例固定,会自动根据传入的长宽缩放。
图标继承所有图形参数,参考[此文档](../motajs-render-vue/GraphicBaseProps.md)
## 图标列表
- `RollbackIcon`: 回退图标
- `RetweenIcon`: 回收图标
- `ViewMapIcon`: 浏览地图图标
- `DanmakuIcon`: 弹幕图标
- `ReplayIcon`: 回放图标
- `numpadIcon`: 数字键盘图标
- `PlayIcon`: 开始播放图标
- `PauseIcon`: 暂停播放图标
- `DoubleArrow`: 双箭头图标(向右)
- `StepForward`: 单步向前图标
- `SoundVolume`: 音量图标
- `Fullscreen`: 全屏图标
- `ExitFullscreen`: 退出全屏图标
- `ArrowLeftTailless`: 无尾巴左箭头图标
- `ArrowRightTailless`: 无尾巴右箭头图标
- `ArrowUpTailless`: 无尾巴上箭头图标
- `ArrowDownTailless`: 无尾巴下箭头图标
## 使用示例
```tsx
import { defineComponent } from 'vue';
import { RollbackIcon } from '@user/client-modules';
export const MyCom = defineComponent(() => {
return () => (
<container>
<RollbackIcon loc={[32, 32, 64, 64]} />
</container>
);
});
```

View File

@ -1,50 +0,0 @@
# Arrow 组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 核心特性
- **两点连线**:通过坐标点绘制任意方向箭头
- **头部定制**:可调节箭头尖端大小
- **样式控制**:支持颜色自定义
---
## Props 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| ------- | ---------------------------------- | ------ | ----------------------------------------- |
| `arrow` | `[number, number, number, number]` | 必填 | 箭头坐标 [起点 x, 起点 y, 终点 x, 终点 y] |
| `head` | `number` | `8` | 箭头头部尺寸(像素) |
| `color` | `CanvasStyle` | `#fff` | 箭头颜色 |
---
## 使用示例
### 基础箭头
```tsx
// 从 (50, 100) 到 (200, 300) 的基础箭头
<Arrow arrow={[50, 100, 200, 300]} />
```
### 定制样式
```tsx
// 红色粗箭头(头部尺寸12px)
<Arrow arrow={[120, 80, 320, 400]} head={12} color="#FF0000" lineWidth={3} />
```
### 虚线箭头
```tsx
// 带虚线效果的箭头
<Arrow
arrow={[0, 0, 400, 300]}
lineDash={[5, 3]} // 5px实线 + 3px间隔
color="gold"
/>
```

View File

@ -1,78 +0,0 @@
# Background 背景组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 核心特性
- **双样式模式**:支持图片皮肤或纯色填充
- **精准定位**:像素级坐标控制
- **静态呈现**:无内置动画的稳定背景层
---
## Props 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| --------- | ---------------- | -------- | ----------------------------- |
| `loc` | `ElementLocator` | **必填** | 背景定位 |
| `winskin` | `ImageIds` | - | 皮肤图片资源 ID(优先级最高) |
| `color` | `CanvasStyle` | `"#333"` | 填充颜色(无皮肤时生效) |
| `border` | `CanvasStyle` | `"#666"` | 边框颜色(无皮肤时生效) |
---
## 使用示例
### 图片皮肤模式
```tsx
// 使用预加载的UI背景图
<Background loc={[0, 0, 416, 416]} winskin="winskin.png" />
```
### 纯色模式
```tsx
// 自定义颜色背景
<Background
loc={[20, 20, 760, 560]}
color="gold"
border="rgba(255,255,255,0.2)"
/>
```
### 对话框组合
```tsx
// 对话框容器
<container loc={[200, 100, 400, 300]}>
<Background loc={[0, 0, 400, 300]} winskin="winskin.png" />
<text loc={[20, 20]} content="系统提示" font={titleFont} />
<text loc={[30, 60]} content="确认要离开吗?" font={contentFont} />
</container>
```
---
## 注意事项
1. **样式优先级**
同时指定参数时的生效顺序:
```tsx
// 以下配置仅生效 winskin
<Background winskin="bg_wood" color="#FF0000" />
```
2. **默认边框**
未指定 border 时的行为:
```tsx
// 无边框(指定为透明色)
<Background color="#222" border="transparent" />;
// 默认白色边框(当未指定任何参数时)
<Background />;
```

View File

@ -1,159 +0,0 @@
# Choices 选项框组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 组件特性
- **多选一机制**:从多个选项中选择一项
- **自动分页**:通过 `maxHeight` 控制分页
- **灵活样式**:支持图片背景/纯色背景 + 自定义字体
- **键盘导航**:方向键选择 + Enter 确认
- **动态内容**:支持异步加载选项数据
---
## Props 属性说明
```mermaid
graph LR
ConfirmBoxProps --> TextContentProps
click TextContentProps "./组件%20TextContent"
```
本组件完全继承 `TextContent` 组件的参数,参考 [组件 TextContent](./组件%20TextContent.md)
| 属性名 | 类型 | 默认值 | 描述 |
| ----------- | ---------------- | -------- | ------------------------------------- |
| `choices` | `ChoiceItem[]` | 必填 | 选项数组,格式为 `[key, text]` 的元组 |
| `loc` | `ElementLocator` | 必填 | 定位配置(需包含 x,y 坐标及锚点) |
| `width` | `number` | 必填 | 选项框宽度(像素) |
| `maxHeight` | `number` | `360` | 最大高度(超过时自动分页) |
| `text` | `string` | - | 主说明文本(显示在标题下方) |
| `title` | `string` | - | 标题文本 |
| `winskin` | `ImageIds` | - | 背景图片资源 ID(与 color 互斥) |
| `color` | `CanvasStyle` | `#333` | 背景颜色(未设置 winskin 时生效) |
| `border` | `CanvasStyle` | `gold` | 边框颜色/样式 |
| `selFont` | `Font` | 系统默认 | 选项文本字体 |
| `selFill` | `CanvasStyle` | `#fff` | 选项文本颜色 |
| `titleFont` | `Font` | 系统默认 | 标题字体 |
| `titleFill` | `CanvasStyle` | `gold` | 标题颜色 |
| `interval` | `number` | `16` | 选项间垂直间距(像素) |
---
## Events 事件说明
| 事件名 | 参数 | 触发时机 |
| -------- | ---------------- | ---------------------- |
| `choose` | `key: ChoiceKey` | 用户选择任意选项时触发 |
---
## 使用示例
### 基础用法 - 系统设置
```tsx
import { defineComponent } from 'vue';
import { Choices, ChoiceItem } from '@user/client-modules';
export const MyCom = defineComponent(() => {
const options: ChoiceItem[] = [
['low', '低画质'],
['medium', '中画质'],
['high', '高画质']
];
return () => (
<Choices
choices={options}
loc={[208, 208, void 0, void 0, 0.5, 0.5]}
width={208}
title="图形质量设置"
text="请选择适合您设备的画质等级"
// key 在这里是每个选项的第一个元素,即 low, medium, high
onChoose={key => console.log(`Choose ${key}.`)}
/>
);
});
```
### 分页处理 - 角色选择
```tsx
import { defineComponent } from 'vue';
import { Choices, ChoiceItem } from '@user/client-modules';
export const MyCom = defineComponent(() => {
// 生成 50 个角色选项
const characters: ChoiceItem[] = Array.from(
{ length: 50 },
(_, i) => [`char_${i}`, `角色 ${i + 1}`] as ChoiceItem
);
return () => (
<Choices
choices={characters}
loc={[208, 208, void 0, void 0, 0.5, 0.5]}
width={208}
maxHeight={400} // 高度超过 400px 自动分页
interval={12}
winskin="winskin.png"
// 粗体,20px 大小的 Verdana 字体
titleFont={new Font('Verdana', 20, 'px', 700)}
selFill="#4CAF50"
/>
);
});
```
### 动态内容 + 自定义样式
```tsx
import { defineComponent } from 'vue';
import { Choices, ChoiceItem } from '@user/client-modules';
import { onTick } from '@motajs/render';
export const MyCom = defineComponent(() => {
const dynamicOptions = ref<ChoiceItem[]>([]);
onTick(() => {
// 每帧生成随机选项名称
dynamicOptions.value = Array.from(
{ length: 50 },
(_, i) =>
[
`char_${i}`,
`随机数 ${Math.random().toFixed(8)}`
] as ChoiceItem
);
});
return () => (
<Choices
choices={dynamicOptions.value}
loc={[208, 208, void 0, void 0, 0.5, 0.5]}
width={208}
color="rgba(30,30,30,0.9)"
border="#607D8B"
title="选择随机数"
titleFill="#B2EBF2"
/>
);
});
```
---
## 注意事项
1. **选项键值唯一性**
每个选项的 `key` 必须唯一,否则可能引发不可预期行为
2. **分页计算规则**
分页依据 `maxHeight` 和字体大小自动计算,需确保字体大小一致
3. **使用更方便的函数**:多数情况下,你不需要使用本组件,使用包装好的函数往往会更加方便,参考 [`getChoice`](./functions.md#getchoice)

View File

@ -1,124 +0,0 @@
# ConfirmBox 确认框组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
## 组件特性
- **双选项支持**:是/否选择
- **灵活样式**:支持图片背景或纯色背景
- **键盘交互**:支持按键操作
- **自动布局**:根据内容动态计算高度
- **事件驱动**:提供明确的用户选择反馈
---
## Props 属性说明
```mermaid
graph LR
ConfirmBoxProps --> TextContentProps
click TextContentProps "./组件%20TextContent"
```
本组件完全继承 `TextContent` 组件的参数,参考 [组件 TextContent](./组件%20TextContent.md)
| 属性名 | 类型 | 默认值 | 描述 |
| ------------ | ---------------- | ------------ | --------------------------------- |
| `text` | `string` | 必填 | 显示的主文本内容 |
| `width` | `number` | 必填 | 确认框宽度(像素) |
| `loc` | `ElementLocator` | 必填 | 定位配置 |
| `winskin` | `ImageIds` | - | 背景图片资源 ID(与 color 互斥) |
| `color` | `CanvasStyle` | `'#333'` | 背景颜色(未设置 winskin 时生效) |
| `border` | `CanvasStyle` | `'gold'` | 边框颜色/样式 |
| `selFont` | `Font` | 系统默认字体 | 选项按钮字体 |
| `selFill` | `CanvasStyle` | `'#d48'` | 选项按钮文本颜色 |
| `yesText` | `string` | `'是'` | 确认按钮文本 |
| `noText` | `string` | `'否'` | 取消按钮文本 |
| `defaultYes` | `boolean` | `true` | 默认选中确认按钮 |
---
## Events 事件说明
| 事件名 | 参数 | 触发时机 |
| ------ | ---- | --------------------------- |
| `yes` | - | 用户选择确认时触发 |
| `no` | - | 用户选择取消或按 Esc 时触发 |
---
## 使用示例
### 基础用法 - 文本确认
```tsx
import { defineComponent } from 'vue';
import { ConfirmBox } from '@user/client-modules';
export const MyCom defineComponent(() => {
return () => (
<ConfirmBox
text="确定要保存当前进度吗?"
width={208}
loc={[208, 208, void 0, void 0, 0.5, 0.5]}
onYes={() => console.log('用户确认保存')}
onNo={() => console.log('用户取消保存')}
/>
);
});
```
### 图片背景 + 自定义按钮
```tsx
import { defineComponent } from 'vue';
import { ConfirmBox } from '@user/client-modules';
import { Font } from '@motajs/render';
export const MyCom = defineComponent(() => {
return () => (
<ConfirmBox
text="此操作不可逆,是否继续?"
width={208}
loc={[208, 208, void 0, void 0, 0.5, 0.5]}
// 背景使用 winskin
winskin="winskin.png"
yesText="确认删除"
noText="取消操作"
// 设置选项字体
selFont={new Font('Verdana')}
selFill="#f44"
/>
);
});
```
### 动态内容 + 编程控制
```tsx
import { defineComponent, computed } from 'vue';
import { ConfirmBox } from '@user/client-modules';
export const MyCom = defineComponent(() => {
const count = ref(0);
const myText = computed(() => `当前确认次数与取消次数差值:${count.value}`);
return () => (
<ConfirmBox
text={myText.value}
width={360}
loc={[208, 208, void 0, void 0, 0.5, 0.5]}
color="rgba(0,0,0,0.8)"
border="#4CAF50"
defaultYes={false}
onYes={() => void count.value++} // 每次确认次数加一
onNo={() => void count.value--} // 每次确认次数减一
/>
);
});
```
## 注意事项
1. **使用更方便的函数**:多数情况下,你不需要使用本组件,使用包装好的函数往往会更加方便,参考 [`getConfirm`](./functions.md#getconfirm)

View File

@ -1,85 +0,0 @@
# FloorSelector 楼层选择器组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
## 组件描述
楼层选择器组件用于在地图浏览或地图选择场景中切换不同楼层,其尺寸与内置状态栏组件匹配,适合在地图浏览时将状态栏替换为此组件。
---
## Props 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| -------- | ------------ | ------ | -------------------- |
| `floors` | `FloorIds[]` | 必填 | 可选择的楼层 ID 数组 |
| `now` | `number` | - | 当前选中的楼层索引 |
---
## Events 事件说明
| 事件名 | 参数类型 | 触发时机 |
| ------------ | ------------------------------------ | ---------------------- |
| `close` | - | 点击关闭按钮时触发 |
| `update` | `(floor: number, floorId: FloorIds)` | 当选中的楼层改变时触发 |
| `update:now` | `(value: number)` | v-model 双向绑定事件 |
---
## Slots 插槽说明
无插槽
---
## Exposed Methods 暴露方法
无暴露方法
---
## 使用示例
### 基础用法 - 地图浏览界面
```tsx
import { defineComponent, ref } from 'vue';
import { FloorSelector, STATUS_BAR_HEIGHT } from '@user/client-modules';
export const MapBrowserCom = defineComponent(() => {
const currentFloor = ref(0);
// 可用的楼层列表
const availableFloors = core.floorIds;
const handleFloorChange = (floorIndex: number, floorId: string) => {
console.log(`切换到楼层: ${floorId} (索引: ${floorIndex})`);
// 这里可以执行切换楼层的逻辑
};
const handleClose = () => {
console.log('关闭楼层选择器');
// 返回主界面或执行其他关闭逻辑
};
return () => (
<FloorSelector
loc={[0, 0, 180, STATUS_BAR_HEIGHT]}
floors={availableFloors}
v-model:now={currentFloor.value}
onUpdate={handleFloorChange}
onClose={handleClose}
/>
);
});
```
---
## 注意事项
1. **尺寸匹配**: 组件设计为与内置状态栏尺寸匹配,可直接替换
2. **索引基准**: 楼层索引从 0 开始
3. **内置集成**: 通常不需要直接使用,因为样板已内置完整的地图浏览界面
4. **倒序排列**: 楼层列表会自动倒序排列

View File

@ -1,113 +0,0 @@
# Input 输入框组件 API 文档
本文档由 `DeepSeek` 生成并微调。
## 组件描述
输入框组件用于接收用户的文本输入,支持单行和多行模式,提供边框样式自定义和实时/确认两种值变化事件。
---
## Props 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| ------------------------- | ------------------- | ------- | ----------------------------------------------------- |
| `placeholder` | `string` | - | 输入框的提示内容 |
| `value` | `string` | - | 输入框的值 |
| `multiline` | `boolean` | `false` | 是否是多行输入,多行输入时允许换行 |
| `border` | `string` | - | 边框颜色 |
| `circle` | `RectRCircleParams` | - | 边框圆角 |
| `borderWidth` | `number` | - | 边框宽度 |
| `pad` | `number` | - | 内边距 |
| 继承自 `TextContentProps` | - | - | [查看完整属性](./组件%20TextContent#Props%20属性说明) |
---
## Events 事件说明
| 事件名 | 参数类型 | 触发时机 |
| -------------- | ----------------- | ---------------------------------------- |
| `change` | `(value: string)` | 当输入框的值被确认时触发,例如失焦时 |
| `input` | `(value: string)` | 当输入框的值发生改变时触发,例如实时输入 |
| `update:value` | `(value: string)` | v-model 双向绑定事件 |
---
## Slots 插槽说明
无插槽
---
## Exposed Methods 暴露方法
无暴露方法
---
## 使用示例
### 基础用法 - 单行输入框
```tsx
import { defineComponent, ref } from 'vue';
import { Input } from '@user/client-modules';
export const MyCom = defineComponent(() => {
const inputValue = ref('');
const handleChange = (value: string) => {
console.log('输入确认:', value);
};
const handleInput = (value: string) => {
console.log('实时输入:', value);
};
return () => (
<Input
placeholder="请输入文本"
v-model={inputValue.value}
onChange={handleChange}
onInput={handleInput}
loc={[208, 208, 300, 40, 0.5, 0.5]}
border="#ccc"
borderWidth={1}
circle={[4]}
pad={8}
/>
);
});
```
### 多行文本输入
```tsx
import { defineComponent, ref } from 'vue';
import { Input } from '@user/client-modules';
export const MyCom = defineComponent(() => {
const multilineValue = ref('');
return () => (
<Input
multiline
placeholder="请输入多行文本..."
v-model={multilineValue.value}
loc={[208, 208, 300, 120, 0.5, 0.5]}
border="#007acc"
borderWidth={2}
circle={[8]}
pad={12}
/>
);
});
```
---
## 注意事项
1. **事件区别**:`input` 事件在每次输入时触发,`change` 事件在失焦或确认时触发
2. **多行模式**:启用 `multiline` 后支持换行输入,高度需要足够容纳多行文本
3. **样式继承**:支持从 `TextContentProps` 继承文本相关样式属性

View File

@ -1,315 +0,0 @@
# InputBox 输入对话框组件 API 文档
本文档由 `DeepSeek` 生成并微调。
## 组件描述
输入对话框组件是一个完整的弹出式输入界面,包含提示文本、输入框、确认和取消按钮。适用于需要用户输入文本的交互场景,提供了便捷的异步获取输入方法。
---
## Props 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| ------------------------- | ---------------- | -------- | ----------------------------------------------------- |
| `loc` | `ElementLocator` | 必填 | 输入框对话框的位置 |
| `input` | `InputProps` | - | 传递给内部 Input 组件的配置参数 |
| `winskin` | `ImageIds` | - | 窗口皮肤图片ID,用于对话框背景绘制 |
| `color` | `CanvasStyle` | - | 对话框背景颜色(未设置 winskin 时生效) |
| `border` | `CanvasStyle` | - | 对话框边框颜色(未设置 winskin 时生效) |
| `pad` | `number` | - | 对话框内部所有元素的内边距 |
| `inputHeight` | `number` | - | 内部输入框区域的高度 |
| `text` | `string` | - | 对话框顶部的提示文本 |
| `yesText` | `string` | `"确认"` | 确认按钮的显示文本 |
| `noText` | `string` | `"取消"` | 取消按钮的显示文本 |
| `selFont` | `Font` | - | 确认/取消按钮的字体样式 |
| `selFill` | `CanvasStyle` | - | 确认/取消按钮的文本颜色 |
| 继承自 `TextContentProps` | - | - | [查看完整属性](./组件%20TextContent#Props%20属性说明) |
---
## Events 事件说明
| 事件名 | 参数类型 | 触发时机 |
| -------------- | ----------------- | ------------------------------------------ |
| `confirm` | `(value: string)` | 当确认输入框的内容时触发 |
| `cancel` | `(value: string)` | 当取消时触发 |
| `change` | `(value: string)` | 继承自 Input 组件 - 输入框值被确认时触发 |
| `input` | `(value: string)` | 继承自 Input 组件 - 输入框值实时变化时触发 |
| `update:value` | `(value: string)` | 继承自 Input 组件 - v-model 双向绑定 |
---
## Slots 插槽说明
无插槽
---
## Exposed Methods 暴露方法
无暴露方法
---
## 工具函数
### `getInput(controller, text, loc, width, props?)`
弹出一个输入框并异步返回用户输入的结果。
**参数**
- `controller: IUIMountable` - UI 控制器
- `text: string` - 提示文本内容
- `loc: ElementLocator` - 确认框的位置
- `width: number` - 确认框的宽度
- `props?: InputBoxProps` - 额外的配置属性(可选)
**返回值**: `Promise<string>`
### `getInputNumber(controller, text, loc, width, props?)`
与 `getInput` 类似,但会将结果转换为数字。
**参数**: 同 `getInput`
**返回值**: `Promise<number>`
---
## 使用示例
### 基础用法 - 组件形式
```tsx
import { defineComponent, ref } from 'vue';
import { InputBox } from '@user/client-modules';
export const MyCom = defineComponent(() => {
const handleConfirm = (value: string) => {
console.log('用户输入:', value);
// 处理用户输入
};
const handleCancel = (value: string) => {
console.log('用户取消输入,最后值为:', value);
};
return () => (
<InputBox
text="请输入您的姓名:"
loc={[240, 240, 300, 180, 0.5, 0.5]}
input={{
placeholder: '在此输入姓名',
border: '#007acc',
borderWidth: 1,
circle: [4],
pad: 8
}}
color="#ffffff"
border="#cccccc"
borderWidth={2}
pad={16}
inputHeight={40}
yesText="确定"
noText="取消"
onConfirm={handleConfirm}
onCancel={handleCancel}
/>
);
});
```
### 使用 getInput 工具函数(推荐)
```tsx
import { defineComponent } from 'vue';
import { getInput, getInputNumber } from '@user/client-modules';
export const MyCom = defineComponent(props => {
const handleGetName = async () => {
// 获取文本输入
const name = await getInput(
props.controller,
'请输入您的姓名:',
[208, 208, void 0, void 0, 0.5, 0.5],
280,
{
input: {
placeholder: '姓名'
},
color: '#f8f8f8'
}
);
if (name) {
console.log('用户姓名:', name);
// 处理姓名
} else {
console.log('用户取消了输入');
}
};
const handleGetAge = async () => {
// 获取数字输入
const age = await getInputNumber(
props.controller,
'请输入您的年龄:',
[208, 208, void 0, void 0, 0.5, 0.5],
280
);
if (!isNaN(age)) {
console.log('用户年龄:', age);
// 处理年龄
}
};
return () => (
<container>
<text
loc={[240, 180, void 0, void 0, 0.5, 0.5]}
onClick={handleGetName}
text="输入姓名"
/>
<text
loc={[240, 220, void 0, void 0, 0.5, 0.5]}
onClick={handleGetAge}
text="输入年龄"
/>
</container>
);
});
```
### 带自定义样式的输入对话框
```tsx
import { defineComponent } from 'vue';
import { getInput } from '@user/client-modules';
export const StyledInputCom = defineComponent(props => {
const handleStyledInput = async () => {
const value = await getInput(
props.controller,
'请输入任务描述:',
[240, 240, void 0, void 0, 0.5, 0.5],
320,
{
text: '任务创建',
input: {
placeholder: '描述任务内容...',
multiline: true,
border: '#4CAF50',
borderWidth: 2,
circle: 8,
pad: 12
},
color: '#ffffff',
border: '#4CAF50',
borderWidth: 3,
pad: 20,
inputHeight: 80,
yesText: '创建',
noText: '取消',
selFill: '#4CAF50'
}
);
if (value) {
console.log('创建任务:', value);
}
};
return () => (
<text
loc={[240, 240, void 0, void 0, 0.5, 0.5]}
onClick={handleStyledInput}
text="创建新任务"
/>
);
});
```
### 游戏中的设置界面
```tsx
import { defineComponent } from 'vue';
import { getInput } from '@user/client-modules';
export const SettingsCom = defineComponent(props => {
const settings = ref({
playerName: '玩家',
serverIP: '127.0.0.1'
});
const changePlayerName = async () => {
const newName = await getInput(
props.controller,
'修改玩家名称:',
[240, 240, void 0, void 0, 0.5, 0.5],
280,
{
input: {
value: settings.value.playerName,
placeholder: '玩家名称',
border: '#FF9800',
borderWidth: 1
}
}
);
if (newName) {
settings.value.playerName = newName;
console.log('玩家名称已更新:', newName);
}
};
const changeServerIP = async () => {
const newIP = await getInput(
props.controller,
'修改服务器IP:',
[240, 240, void 0, void 0, 0.5, 0.5],
280,
{
input: {
value: settings.value.serverIP,
placeholder: '服务器IP地址',
border: '#2196F3',
borderWidth: 1
}
}
);
if (newIP) {
settings.value.serverIP = newIP;
console.log('服务器IP已更新:', newIP);
}
};
return () => (
<container loc={[240, 240, 300, 200, 0.5, 0.5]}>
<text
loc={[0, -40, void 0, void 0, 0.5, 0.5]}
onClick={changePlayerName}
text={`玩家名称: ${settings.value.playerName}`}
/>
<text
loc={[0, 0, void 0, void 0, 0.5, 0.5]}
onClick={changeServerIP}
text={`服务器IP: ${settings.value.serverIP}`}
/>
</container>
);
});
```
---
## 注意事项
1. **推荐使用工具函数**: `getInput` 和 `getInputNumber` 提供了更简洁的异步输入获取方式
2. **宽度设置**: 在使用工具函数时,高度由组件自动计算,只需指定宽度
3. **皮肤优先级**: 如果设置了 `winskin`,则 `color` 和 `border` 设置将失效
4. **异步处理**: 工具函数返回 Promise,需要使用 `await` 或 `.then()` 处理结果
5. **空值处理**: 用户取消输入时,`getInput` 返回空字符串,`getInputNumber` 返回 `NaN`

View File

@ -1,184 +0,0 @@
# List 列表组件 API 文档
本文档由 `DeepSeek` 生成并微调。
## 组件描述
列表组件用于展示可选择的项目列表,内置滚动条功能和选中项高亮效果。适用于菜单选择、内容导航、设置选项等场景。
---
## Props 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| ------------ | -------------------- | ------ | ------------------------------- |
| `list` | `[string, string][]` | 必填 | 列表内容,[id, 显示文本] 的数组 |
| `selected` | `string` | 必填 | 当前选中的项 ID |
| `loc` | `ElementLocator` | 必填 | 列表的位置和尺寸 |
| `lineHeight` | `number` | `18` | 每行的高度 |
| `font` | `Font` | - | 列表项的字体样式 |
| `winskin` | `ImageIds` | - | 使用 winskin 作为光标背景 |
| `color` | `CanvasStyle` | - | 使用指定样式作为光标背景 |
| `border` | `CanvasStyle` | - | 使用指定样式作为光标边框 |
| `alphaRange` | `[number, number]` | - | 选择图标的不透明度范围 |
---
## Events 事件说明
| 事件名 | 参数类型 | 触发时机 |
| ----------------- | ----------------- | ---------------------- |
| `update` | `(key: string)` | 当用户选中某一项时触发 |
| `update:selected` | `(value: string)` | v-model 双向绑定事件 |
---
## Slots 插槽说明
无插槽
---
## Exposed Methods 暴露方法
无暴露方法
---
## 使用示例
### 基础用法 - 简单列表
```tsx
import { defineComponent, ref } from 'vue';
import { List } from '@user/client-modules';
export const MyCom = defineComponent(() => {
const selectedItem = ref('item1');
// 列表数据:[id, 显示文本]
const listData = [
['item1', '第一项'],
['item2', '第二项'],
['item3', '第三项'],
['item4', '第四项']
];
const handleSelect = (key: string) => {
console.log('选中项:', key);
selectedItem.value = key;
};
return () => (
<List
list={listData}
v-model:selected={selectedItem.value}
loc={[0, 0, 100, 300, 0, 0]}
selected={selectedItem.value}
onUpdate={handleSelect}
/>
);
});
```
### 带样式的列表
```tsx
import { defineComponent, ref } from 'vue';
import { List } from '@user/client-modules';
export const StyledListCom = defineComponent(() => {
const selected = ref('opt2');
const options = [
['opt1', '开始游戏'],
['opt2', '游戏设置'],
['opt3', '帮助文档'],
['opt4', '关于我们']
];
return () => (
<List
list={options}
v-model:selected={selected.value}
loc={[0, 0, 100, 300, 0, 0]}
lineHeight={24}
color="#e3f2fd"
border="#2196f3"
borderWidth={1}
/>
);
});
```
### 使用皮肤图片的列表
```tsx
import { defineComponent, ref } from 'vue';
import { List } from '@user/client-modules';
export const SkinnedListCom = defineComponent(() => {
const currentSelection = ref('cat');
const animalList = [
['cat', '猫咪'],
['dog', '小狗'],
['bird', '小鸟'],
['fish', '小鱼']
];
const handleUpdate = key => {
const item = animalList.find(item => item[0] === key)?.[1];
currentSelection.value = key;
console.log('选择了:', item);
};
return () => (
<List
list={animalList}
selected={currentSelection.value}
loc={[0, 0, 100, 300, 0, 0]}
winskin="winskin.png"
lineHeight={20}
onUpdate={handleUpdate}
/>
);
});
```
### 长列表滚动示例
```tsx
import { defineComponent, ref } from 'vue';
import { List } from '@user/client-modules';
export const ScrollListCom = defineComponent(() => {
const selected = ref('item5');
// 创建长列表数据
const longList = Array.from({ length: 20 }, (_, i) => [
`item${i + 1}`,
`列表项 ${i + 1}`
]);
return () => (
<List
list={longList}
v-model:selected={selected.value}
loc={[0, 0, 100, 300, 0, 0]}
lineHeight={20}
color="#fff3e0"
border="#ff9800"
/>
);
});
```
---
## 注意事项
1. **数据格式**: `list` 属性需要 `[id, text]` 格式的二维数组
2. **选中状态**: `selected` 需要与列表项中的 id 匹配
3. **滚动支持**: 自动显示滚动条
4. **样式优先级**: 如果设置了 `winskin`,则 `color` 和 `border` 设置将失效

View File

@ -1,226 +0,0 @@
# ListPage 列表页面组件 API 文档
本文档由 `DeepSeek` 生成并微调。
## 组件描述
列表页面组件结合了列表选择和内容展示功能,左侧显示可选项列表,右侧显示选中项的详细内容。适用于说明文档、设置界面、内容导航等场景。
---
## Props 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| ------------------ | ---------------- | ------- | ---------------------------------------------- |
| `loc` | `ElementLocator` | 必填 | 组件整体位置和尺寸 |
| `basis` | `number` | - | 列表区域所占比例 |
| `right` | `boolean` | `false` | 列表是否排列在右侧 |
| `close` | `boolean` | `false` | 是否显示关闭按钮 |
| `closeLoc` | `ElementLocator` | - | 关闭按钮的位置(相对于组件定位) |
| 继承自 `ListProps` | - | - | [查看完整属性](./组件%20List#Props%20属性说明) |
---
## Events 事件说明
| 事件名 | 参数类型 | 触发时机 |
| ----------------- | ----------------- | ------------------------------------ |
| `close` | - | 当用户点击关闭按钮时触发 |
| `update` | `(key: string)` | 继承自 List - 当用户选中某一项时触发 |
| `update:selected` | `(value: string)` | 继承自 List - v-model 双向绑定事件 |
---
## Slots 插槽说明
### `default`
接收当前选中的 key 并返回对应的内容
**参数**
- `key: string` 当前选中的项 ID
### 具名插槽
以列表项 ID 为名称的具名插槽,用于定义每个选项对应的详细内容
---
## 使用示例
### 基础用法 - 说明文档界面
```tsx
import { defineComponent, ref } from 'vue';
import { ListPage } from '@user/client-modules';
export const HelpCom = defineComponent(() => {
const selected = ref('intro');
const helpTopics = [
['intro', '功能介绍'],
['usage', '使用方法'],
['settings', '设置说明'],
['faq', '常见问题']
];
return () => (
<ListPage
list={helpTopics}
v-model:selected={selected.value}
loc={[208, 208, 400, 300, 0.5, 0.5]}
basis={0.3}
>
{{
// 使用具名插槽定义每个选项的内容
intro: () => (
<container>
<text text="这里是最新版本的功能介绍..." loc={[0, 0]} />
<text text="欢迎使用本系统" loc={[0, 40]} />
</container>
),
usage: () => (
<container>
<text text="使用方法指南" loc={[0, 0]} />
<text text="1. 点击左侧菜单选择功能" loc={[0, 40]} />
<text text="2. 在右侧查看详细说明" loc={[0, 80]} />
</container>
),
settings: () => <text text="设置说明内容..." loc={[0, 0]} />,
faq: () => <text text="常见问题解答..." loc={[0, 0]} />
}}
</ListPage>
);
});
```
### 使用默认插槽
```tsx
import { defineComponent, ref } from 'vue';
import { ListPage } from '@user/client-modules';
export const SimpleCom = defineComponent(() => {
const selected = ref('item1');
const items = [
['item1', '选项一'],
['item2', '选项二'],
['item3', '选项三']
];
return () => (
<ListPage
list={items}
v-model:selected={selected.value}
loc={[208, 208, 350, 250, 0.5, 0.5]}
>
{key => (
<container>
<text
text={`当前选中: ${items.find(item => item[0] === key)?.[1]}`}
loc={[0, 0]}
/>
<text text={`ID: ${key}`} loc={[0, 30]} />
</container>
)}
</ListPage>
);
});
```
### 带关闭按钮的弹窗
```tsx
import { defineComponent, ref } from 'vue';
import { ListPage } from '@user/client-modules';
export const ModalCom = defineComponent(props => {
const selected = ref('weapon');
const gameItems = [
['weapon', '武器'],
['armor', '防具'],
['potion', '药水'],
['material', '材料']
];
const handleClose = () => {
props.controller.close(props.instance);
console.log('关闭物品栏');
};
return () => (
<ListPage
list={gameItems}
v-model:selected={selected.value}
loc={[208, 208, 400, 320, 0.5, 0.5]}
close
// 设定关闭按钮的位置
closeLoc={[0, 300]}
basis={0.35}
onClose={handleClose}
>
{{
weapon: () => (
<container>
<text text="武器列表" loc={[0, 0]} />
<text text="• 长剑" loc={[0, 30]} />
<text text="• 弓箭" loc={[0, 60]} />
<text text="• 法杖" loc={[0, 90]} />
</container>
),
armor: () => <text text="防具装备信息..." loc={[0, 0]} />,
potion: () => <text text="药水效果说明..." loc={[0, 0]} />,
material: () => <text text="合成材料列表..." loc={[0, 0]} />
}}
</ListPage>
);
});
```
### 列表在右侧的布局
```tsx
import { defineComponent, ref } from 'vue';
import { ListPage } from '@user/client-modules';
export const RightListCom = defineComponent(() => {
const selected = ref('profile');
const menuItems = [
['profile', '个人资料'],
['security', '安全设置'],
['privacy', '隐私设置'],
['notifications', '通知设置']
];
return () => (
<ListPage
list={menuItems}
v-model:selected={selected.value}
loc={[240, 240, 500, 280, 0.5, 0.5]}
right
basis={0.4}
>
{key => (
<container>
<text text="显示一些内容..." loc={[0, 60]} />
<text text="这里是详细的设置内容..." loc={[0, 0]} />
</container>
)}
</ListPage>
);
});
```
---
## 注意事项
1. **插槽使用**: 可以使用具名插槽(以列表项 ID 为名)或默认插槽来定义内容
2. **布局控制**: 通过 `basis` 控制列表区域比例,`right` 控制列表位置
3. **关闭功能**: 设置 `close` 为 `true` 显示关闭按钮,通过 `closeLoc` 自定义位置
4. **事件处理**: `close` 事件需要手动处理界面关闭逻辑
5. **内容更新**: 切换列表选项时,右侧内容会自动更新为对应插槽的内容

View File

@ -1,192 +0,0 @@
# Page 分页组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
## 组件描述
分页组件用于将大量内容分割为多个独立页面展示,支持通过编程控制或用户交互进行页面切换。适用于存档界面、多步骤表单等场景。
---
## Props 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| -------------- | ---------------- | ----------------- | -------------------------------- |
| `pages` | `number` | 必填 | 总页数 |
| `loc` | `ElementLocator` | 必填 | 页码组件定位配置(坐标系及位置) |
| `font` | `Font` | `Font.defaults()` | 页码文本字体配置(可选) |
| `hideIfSingle` | `boolean` | `false` | 当总页数为 1 时是否隐藏页码组件 |
---
## Events 事件说明
| 事件名 | 参数类型 | 触发时机 |
| ------------ | ---------------- | ------------------------------- |
| `pageChange` | `(page: number)` | 当前页码变化时触发(从 0 开始) |
---
## Slots 插槽说明
### `default`
接收当前页码(从 0 开始)并返回需要渲染的内容
**参数**
- `page: number` 当前页码索引(0-based)
---
## Exposed Methods 暴露方法
| 方法名 | 参数 | 返回值 | 描述 |
| ------------ | --------------- | -------- | --------------------------------------------------- |
| `changePage` | `page: number` | `void` | 跳转到指定页码(0-based,自动约束在有效范围内) |
| `movePage` | `delta: number` | `void` | 基于当前页码进行偏移切换(如 +1 下一页,-1 上一页) |
| `now` | - | `number` | 获取当前页码索引(0-based) |
---
## 使用示例
### 基础用法 - 多页文本展示
```tsx
import { defineComponent } from 'vue';
import { Page, PageExpose } from '@user/client-modules';
export const MyCom = defineComponent(() => {
return () => (
<Page pages={3} loc={[208, 208, 208, 208, 0.5, 0.5]}>
{page => (
<text
text={`第 ${page + 1} 页内容`}
loc={[104, 104, void 0, void 0, 0.5, 0.5]}
/>
)}
</Page>
);
});
```
### 监听页面修改
```tsx
import { defineComponent, ref } from 'vue';
import { Page, PageExpose } from '@user/client-modules';
export const MyCom = defineComponent(() => {
// 示例数据
const pages = [
{ content: '第一页内容' },
{ content: '第二页内容' },
{ content: '第三页内容' }
];
// 分页组件引用
const pageRef = ref<PageExpose>();
// 页码变化回调
const handlePageChange = (currentPage: number) => {
// 可以使用参数获得当前页码,加一是因为页码是从 0 开始的
console.log(`当前页码:${currentPage + 1}`);
// 或者也可以使用 Page 组件的接口获得当前页码
console.log(`当前页码:${pageRef.value!.now() + 1}`);
};
return () => (
<Page
pages={pages.length}
loc={[208, 208, 208, 208, 0.5, 0.5]} // 游戏画面居中
onPageChange={handlePageChange}
ref={pageRef}
>
{page => <text text={pages[page].content} />}
</Page>
);
});
```
### 动态配置示例
```tsx
import { defineComponent, ref } from 'vue';
import { Page, PageExpose } from '@user/client-modules';
// 带统计面板的复杂分页
export const MyCom = defineComponent(() => {
const dataPages = [
/* 复杂数据结构 */
];
// 暴露方法实现翻页逻辑
const pageRef = ref<PageExpose>();
const jumpToAnalysis = () => pageRef.value?.changePage(3); // 1-based
return () => (
<container>
{/* 分页内容 */}
<Page
pages={dataPages.length}
loc={[208, 208, 208, 208, 0.5, 0.5]}
hideIfSingle // 如果只有一个页面,那么隐藏底部的页码显示
ref={pageRef}
>
{page => (
<container>
{/* 这里面可以写一些复杂的渲染内容,或者单独写成一个组件,把页码作为参数传入 */}
<text text="渲染内容" />
<g-rect loc={[50, 50, 100, 50]} stroke />
</container>
)}
</Page>
{/* 自定义跳转按钮 */}
<text
loc={[108, 180, void 0, void 0, 0.5, 1]} // 左右居中,靠下对齐
onClick={jumpToAnalysis}
text="跳转到分析页"
/>
</container>
);
});
```
### 边缘检测示例
```tsx
import { defineComponent, ref } from 'vue';
// 边界处理逻辑
export const MyCom = defineComponent(() => {
const pageRef = ref<PageExpose>();
// 自定义边界提示
const handleEdge = () => {
const current = pageRef.value?.now() ?? 0;
const total = pageRef.value?.pages ?? 0;
// 到达边界时提示(可以换成其他提示方式)
if (current === 0) core.drawTip('已经是第一页');
if (current === total - 1) core.drawTip('已经是最后一页');
};
return () => (
<Page
pages={8}
ref={pageRef}
onPageChange={handleEdge}
loc={[208, 208, 208, 208, 0.5, 0.5]}
>
{page => <text text={`第${page}页`} />}
</Page>
);
});
```
---
## 注意事项
1. **自动约束**:切换页码时会自动约束在 `[0, pages-1]` 范围内

View File

@ -1,107 +0,0 @@
# Progress 组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 核心特性
- **动态进度显示**:支持 0.0~1.0 范围的进度可视化
- **双色样式分离**:可分别定制已完成/未完成部分样式
- **精准定位**:支持像素级坐标控制
- **平滑过渡**:数值变化自动触发重绘
---
## Props 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| ------------ | ---------------- | -------- | --------------------- |
| `loc` | `ElementLocator` | **必填** | 进度条容器坐标 |
| `progress` | `number` | **必填** | 当前进度值(0.0~1.0) |
| `success` | `CanvasStyle` | `green` | 已完成部分填充样式 |
| `background` | `CanvasStyle` | `gray` | 未完成部分填充样式 |
| `lineWidth` | `number` | `2` | 进度条线宽(像素) |
---
## 使用示例
### 基础用法
```tsx
import { defineComponent, ref } from 'vue';
import { Progress } from '@user/client-modules';
import { onTick } from '@motajs/render';
export const MyCom = defineComponent(() => {
// 创建响应式进度值
const loadingProgress = ref(0);
// 模拟进度更新
onTick(() => {
if (loadingProgress.value < 1) {
loadingProgress.value += 0.002;
}
});
return () => (
<Progress
loc={[20, 20, 200, 8]} // x=20, y=20, 宽200px, 高8px
progress={loadingProgress.value}
/>
);
});
```
### 自定义样式
```tsx
// 自定义进度条的已完成和未完成部分的样式
<Progress
loc={[50, 100, 300, 12]}
progress={0.65}
success="rgb(54, 255, 201)"
background="rgba(255,255,255,0.2)"
lineWidth={6}
/>
```
### 垂直进度条
```tsx
// 通过旋转容器实现垂直效果,注意锚点的使用
<container rotation={-Math.PI / 2} loc={[100, 200, 150, 8, 0.5, 0.5]}>
<Progress loc={[0, 0, 150, 8]} progress={0.8} success="#FF5722" />
</container>
```
---
## 动画效果实现
### 平滑过渡示例
```tsx
import { transitioned } from '@user/client-modules';
import { pow } from 'mutate-animate';
const progressValue = transitioned(0, 2000, pow(2, 'out'));
progressValue.set(1); // 2秒内完成二次曲线平滑过渡
return () => (
<Progress loc={[0, 0, 400, 10]} progress={progressValue.ref.value} />
);
```
---
## 注意事项
1. **坐标系统**
实际渲染高度由 `loc[3]` 参数控制,会自动上下居中:
```tsx
// 情况1:显式指定高度为8px
<Progress loc={[0, 0, 200, 8]} />
```

View File

@ -1,129 +0,0 @@
# Scroll 滚动组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
## 组件特性
- **虚拟滚动**:自动裁剪可视区域外元素
- **双模式支持**:垂直/水平滚动(默认垂直)
- **性能优化**:动态计算可视区域,支持万级元素流畅滚动
- **编程控制**:支持精准定位滚动位置
---
## Props 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| ---------- | ---------------- | ------- | ------------------------------------------------- |
| `hor` | `boolean` | `false` | 启用水平滚动模式 |
| `noscroll` | `boolean` | `false` | 是否不显示滚动条,可用于一些特殊场景 |
| `loc` | `ElementLocator` | 必填 | 滚动容器定位配置 |
| `padEnd` | `number` | `0` | 滚动到底部/右侧的额外留白(用于修正自动计算误差) |
---
## Exposed Methods 暴露方法
| 方法名 | 参数 | 返回值 | 描述 |
| ----------------- | --------------------------------- | -------- | --------------------------------------------------- |
| `scrollTo` | `position: number, time?: number` | `void` | 滚动到指定位置(单位:像素),time 为过渡时间(ms) |
| `getScrollLength` | - | `number` | 获取最大可滚动距离(单位:像素) |
---
## Slots 插槽说明
### `default`
接收滚动内容,**必须直接包含可渲染元素**
⚠️ 禁止嵌套 container 包裹,推荐平铺结构:
```tsx
// ✅ 正确写法
<Scroll>
<item />
<item />
<item />
</Scroll>;
// ❌ 错误写法(影响虚拟滚动计算)
<Scroll>
<container>
// 会导致整体被视为单个元素
<item />
<item />
</container>
</Scroll>;
```
---
## 使用示例
### 基础垂直滚动
```tsx
import { defineComponent } from 'vue';
export const MyCom = defineComponent(() => {
const list = Array(200).fill(0);
return () => (
<Scroll loc={[208, 208, 208, 208, 0.5, 0.5]}>
{list.map((_, index) => (
<text key={index} text={index.toString()} />
))}
</Scroll>
);
});
```
### 水平滚动 + 编程控制
```tsx
import { defineComponent, ref, onMounted } from 'vue';
export const MyCom = defineComponent(() => {
const list = Array(200).fill(0);
const scrollRef = ref<ScrollExpose>();
// 滚动水平 100 像素位置,动画时长 500 毫秒
onMounted(() => {
scrollRef.value?.scrollTo(100, 500);
});
return () => (
<Scroll hor loc={[208, 208, 208, 208, 0.5, 0.5]} ref={scrollRef}>
{list.map((_, index) => (
<text key={index} text={index.toString()} />
))}
</Scroll>
);
});
```
---
## 性能优化指南
### 1. 替代方案建议
⚠️ **当子元素数量 > 1000 时**,推荐改用分页组件:
```tsx
// 使用 Page 组件处理超大数据集
<Page pages={Math.ceil(data.length / 50)}>
{page => renderChunk(data.slice(page * 50, (page + 1) * 50))}
</Page>
```
### 2. 缓存建议
如果子元素数量较多,建议给 `Scroll` 组件的所有子元素添加 `nocache` 标记:
```tsx {2}
<Scroll>
<item nocache />
{/* 更多内容 */}
</Scroll>
```

View File

@ -1,160 +0,0 @@
# ScrollText 组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 核心特性
- **自动滚动**:支持设定滚动速度的纵向滚动效果
- **长文本支持**:内置高性能文本渲染引擎
- **精准控制**:提供播放/暂停/调速等操作接口
- **智能布局**:自动计算文本高度和滚动距离
---
## Props 属性说明
```mermaid
graph LR
ScrollTextProps --> TextContentProps
ScrollTextProps --> ScrollProps
click TextContentProps "./组件%20TextContent"
click ScrollProps "./组件%20Scroll"
```
完全继承 `TextContent` 组件和 `Scroll` 组件的参数和事件。
| 属性名 | 类型 | 默认值 | 描述 |
| ------- | ---------------- | ------ | --------------------------- |
| `speed` | `number` | 必填 | 滚动速度(像素/秒) |
| `width` | `number` | 必填 | 文本区域固定宽度(像素) |
| `loc` | `ElementLocator` | 必填 | 容器定位 [x,y,width,height] |
| `pad` | `number` | `16` | 首行前空白距离(像素) |
---
## 事件说明
| 事件名 | 参数 | 触发时机 |
| ----------- | ---- | -------------------- |
| `scrollEnd` | - | 滚动到文本末尾时触发 |
---
## Exposed Methods 暴露方法
| 方法名 | 参数 | 返回值 | 描述 |
| ---------- | --------------- | ------ | --------------------------- |
| `pause` | - | void | 暂停滚动 |
| `resume` | - | void | 继续滚动 |
| `setSpeed` | `speed: number` | void | 动态调整滚动速度(像素/秒) |
| `rescroll` | - | void | 立即重置到起始位置重新滚动 |
---
## 使用示例
### 基础滚动
```tsx
import { defineComponent } from 'vue';
import { ScrollText } from '@user/client-modules';
export const MyCom = defineComponent(() => {
const longText = '序幕\n'.repeat(100) + '——全剧终——';
return () => (
<ScrollText
text={longText}
speed={80} // 每秒滚动80像素
width={416} // 文本区域宽度
loc={[0, 0, 416, 416]} // 容器位置和尺寸
fillStyle="#E6E6FA" // 薰衣草色文字
/>
);
});
```
### 动态控制
```tsx
import { defineComponent, ref } from 'vue';
import { ScrollText } from '@user/client-modules';
export const MyCom = defineComponent(() => {
const longText = '序幕\n'.repeat(100) + '——全剧终——';
const scrollRef = ref<ScrollTextExpose>();
// 暂停/恢复控制
const toggleScroll = () => {
if (scrollRef.value?.isPaused) {
scrollRef.value.resume();
} else {
scrollRef.value?.pause();
}
};
// 速度控制
const accelerate = () => {
scrollRef.value?.setSpeed(200);
};
return () => (
<ScrollText
ref={scrollRef}
text={longText}
speed={100}
width={416}
loc={[0, 0, 416, 416]}
onScrollEnd={() => console.log('滚动结束')}
/>
);
});
```
### 复杂排版
```tsx
const staffText =
'\\c[32]====制作人员====\\c\n\n' +
'\\r[#FFD700]总监督\\r\t\t张三\n' +
'\\r[#00FF00]美术指导\\r\\t李四\n' +
'\\i[logo]\n' +
'特别感谢:某某公司';
<ScrollText
text={staffText}
speed={120}
width={720}
loc={[40, 40, 720, 560]}
pad={40} // 顶部留白
font={new Font('黑体', 24)}
lineHeight={8} // 行间距
interval={0} // 禁用打字机效果
/>;
```
---
## 注意事项
1. **容器尺寸**
实际可滚动区域计算公式:
```
可视高度 = loc[3](容器高度)
滚动距离 = 文本总高度 + pad(首行前空白)
```
2. **速度控制**
推荐速度范围 50-200 像素/秒
3. **组合动画**
可与容器变换配合实现复杂效果:
```tsx
<container rotation={-5} alpha={0.9}>
<ScrollText />
</container>
```

View File

@ -1,77 +0,0 @@
# Selection 组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 核心特性
- **动态高亮**:自动呼吸动画效果
- **双样式模式**:支持图片皮肤或纯色样式
- **精准定位**:像素级坐标控制
- **透明度动画**:可定制不透明度变化范围
---
## Props 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| ------------ | ------------------ | -------------- | --------------------------------- |
| `loc` | `ElementLocator` | **必填** | 光标定位 |
| `winskin` | `ImageIds` | - | 图片资源 ID(优先级最高) |
| `color` | `CanvasStyle` | `#ddd` | 填充颜色(无皮肤时生效) |
| `border` | `CanvasStyle` | `gold` | 边框颜色(无皮肤时生效) |
| `alphaRange` | `[number, number]` | `[0.25, 0.55]` | 不透明度波动范围 [最小值, 最大值] |
---
## 使用示例
### 图片皮肤模式
```tsx
// 使用预加载的游戏皮肤资源
<Selection
loc={[120, 80, 160, 24]}
winskin="winskin.png"
alphaRange={[0.4, 1.0]}
/>
```
---
### 纯色模式
```tsx
// 自定义颜色方案
<Selection
loc={[20, 240, 200, 32]}
color="rgba(0,128,255,0.2)" // 填充颜色
border="#00BFFF" // 边框颜色
alphaRange={[0.5, 0.9]}
/>
```
---
## 注意事项
1. **样式优先级**
同时指定 `winskin` 和颜色参数时:
```tsx
// 以下配置将忽略 color/border 参数
<Selection winskin="winskin.png" color="red" border="blue" />
```
2. **动画速度**
呼吸动画固定为 2000ms/周期,暂不支持自定义时长
3. **点击反馈**
建议配合事件系统实现点击效果:
```tsx
<container onClick={handleClick}>
<Selection />
<text />
</container>
```

View File

@ -1,184 +0,0 @@
# TextContent 文本组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 核心特性
- **自动布局**:根据宽度自动换行
- **样式控制**:支持动态修改字体/颜色/描边
- **打字机效果**:逐字显示支持
- **动态高度**:自适应或固定高度模式
---
## Props 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| ----------------- | ------------- | ----------------- | ------------------------------ |
| `text` | `string` | - | 显示文本(支持转义字符) |
| `width` | `number` | 必填 | 文本区域宽度(像素) |
| `fill` | `boolean` | `true` | 是否对文字填充 |
| `stroke` | `boolean` | `false` | 是否对文字描边 |
| `font` | `Font` | 系统默认字体 | 字体配置对象 |
| `lineHeight` | `number` | `0` | 行间距(像素) |
| `interval` | `number` | `50` | 打字机字符间隔(ms) |
| `autoHeight` | `boolean` | `false` | 是否根据内容自动调整高度 |
| `fillStyle` | `CanvasStyle` | `#fff` | 文字填充颜色 |
| `strokeStyle` | `CanvasStyle` | `#000` | 文字描边颜色 |
| `strokeWidth` | `number` | `1` | 描边宽度 |
| `textAlign` | `TextAlign` | `TextAlign.Left` | 文字对齐方式 |
| `wordBreak` | `WordBreak` | `WordBreak.Space` | 文本分词原则,将会影响换行表现 |
| `breakChars` | `string` | - | 会被分词规则识别的分词字符 |
| `ignoreLineStart` | `string` | - | 不允许出现在行首的字符 |
| `ignoreLineEnd` | `string` | - | 不允许出现在行尾的字符 |
---
## 事件说明
| 事件名 | 参数 | 触发时机 |
| -------------- | ---------------- | ------------------ |
| `typeStart` | - | 开始逐字显示时 |
| `typeEnd` | - | 全部文字显示完成时 |
| `updateHeight` | `height: number` | 文本高度变化时 |
---
## Exposed Methods 暴露方法
| 方法名 | 参数 | 返回值 | 描述 |
| ----------- | ---- | -------- | ---------------------------- |
| `retype` | - | `void` | 从头开始重新打字 |
| `showAll` | - | `void` | 立刻结束打字机,显示所有文字 |
| `getHeight` | - | `number` | 获得当前文本的高度 |
---
## 使用示例
### 基础用法 - 对话文本
```tsx
import { defineComponent } from 'vue';
import { TextContent } from '@user/client-modules';
import { Font } from '@motajs/render';
export const MyCom = defineComponent(() => {
return () => (
<TextContent
text="这是基础文本内容,会自动换行排版"
width={200} // 最大宽度,达到这个宽度会自动换行
font={new Font('宋体', 18)}
fillStyle="#333333" // 黑色字体
onTypeEnd={() => console.log('显示完成')} // 打字机结束后执行
/>
);
});
```
### 自定义样式 + 描边效果
```tsx
import { defineComponent } from 'vue';
import { TextContent } from '@user/client-modules';
import { Font } from '@motajs/render';
export const MyCom = defineComponent(() => {
return () => (
<TextContent
text="\\r[#FFD700]金色描边文字"
width={300}
font={new Font('黑体', 24)}
stroke // 设为填充+描边格式,如果仅描边需要设置 fill={false}
strokeStyle="#8B4513" // 描边颜色
strokeWidth={2} // 描边宽度
lineHeight={8} // 行间距,8 像素
interval={30} // 打字机间隔
/>
);
});
```
### 动态内容更新
```tsx
import { defineComponent, ref } from 'vue';
import { TextContent } from '@user/client-modules';
export const MyCom = defineComponent(() => {
const dynamicText = ref('初始内容');
setTimeout(() => {
dynamicText.value = '更新后的内容\\z[5]带暂停效果';
}, 2000);
return () => (
<TextContent
text={dynamicText.value}
width={500}
autoHeight
onUpdateHeight={h => console.log('当前高度:', h)} // 当高度发生变化时触发
/>
);
});
```
### 禁用动画效果
```tsx
import { defineComponent } from 'vue';
import { TextContent } from '@user/client-modules';
export const MyCom = defineComponent(() => {
return () => (
<TextContent
text="立即显示所有内容"
width={350}
interval={0} // 设置为0禁用逐字效果
showAll // 立即显示全部
fillStyle="rgba(0,128,0,0.8)"
/>
);
});
```
### 多语言复杂排版
```tsx
import { defineComponent } from 'vue';
import { TextContent } from '@user/client-modules';
export const MyCom = defineComponent(() => {
const complexText =
'\\g[Times New Roman]Hello\\g[宋体] 你好 \\i[flag]\\n' +
'\\r[#FF5733]Multi\\r[#3498db]-\\r[#2ECC71]Color\\r\\n' +
'\\c[18]Small\\c[24]Size\\c[30]Changes';
return () => (
<TextContent
text={complexText}
width={600}
interval={25}
onTypeStart={() => console.log('开始渲染复杂文本')}
/>
);
});
```
---
## 转义字符示例
```tsx
// 颜色/字体/图标综合使用
const styledText =
'\\r[#FF0000]警告!\\g[方正粗宋]\\c[24]' +
'\\i[warning_icon]发现异常\\z[10]\\n' +
'请立即处理\\r\\g\\c';
<TextContent text={styledText} width={450} interval={40} />;
```
转义字符具体用法参考 [TextContentParser](./TextContentParser.md#转义字符语法说明)

View File

@ -1,173 +0,0 @@
# Textbox 对话框组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
本文档描述在 `TextContent` 基础上扩展的对话框组件,专为剧情对话、系统提示等场景设计,支持背景、标题等装饰元素。
---
## 特有属性说明
```mermaid
graph LR
TextboxProps --> TextContentProps
click TextContentProps "./组件%20TextContent"
```
| 属性名 | 类型 | 默认值 | 描述 |
| -------------- | ------------- | -------------- | ------------------------------------- |
| `backColor` | `CanvasStyle` | `#222` | 背景颜色(与 `winskin` 互斥) |
| `winskin` | `ImageIds` | - | 背景图片资源 ID(优先于 `backColor`) |
| `padding` | `number` | `8` | 内容区域与边框的内边距(像素) |
| `title` | `string` | - | 标题文本内容 |
| `titleFont` | `Font` | `18px Verdana` | 标题字体配置 |
| `titleFill` | `CanvasStyle` | `gold` | 标题文字颜色 |
| `titleStroke` | `CanvasStyle` | `transparent` | 标题描边颜色 |
| `titlePadding` | `number` | `8` | 标题在其背景的间距(像素) |
---
## 事件说明
```mermaid
graph LR
TextboxEmits --> TextContentEmits
click TextContentEmits "./组件%20TextContent"
```
完全继承 `TextContent` 的事件。
---
## Exposed Methods 暴露方法
| 方法名 | 参数 | 返回值 | 描述 |
| --------- | ---- | ------ | ---------------------------- |
| `retype` | - | `void` | 从头开始重新打字 |
| `showAll` | - | `void` | 立刻结束打字机,显示所有文字 |
| `show` | - | `void` | 显示这个文本框 |
| `hide` | - | `void` | 隐藏这个文本框 |
---
## Slots 插槽说明
### default
背景插槽,传入后可以自定义背景
```tsx
// 例如使用一张图片作为背景
<Textbox>
<container>
<image image="myImage.png" />
</container>
</Textbox>
```
### title
标题背景插槽,自定义标题背景
```tsx
// 与 default 一起使用
<Textbox>
{{
// 背景图
default: () => <image image="myImage.png" />,
// 标题背景图
title: () => <g-rectr circle={[4]} fill />
}}
</Textbox>
```
## 使用示例
### 基础对话框
```tsx
import { defineComponent } from 'vue';
import { Textbox } from '@user/client-modules';
export const MyCom = defineComponent(() => {
return () => (
<Textbox
title="NPC对话"
winskin="winskin.png" // 背景 winskin
padding={12} // 文字内边距
width={416} // 最大宽度,超过换行,自动减去内边距
titleFont={new Font('楷体', 22)} // 标题字体
titleFill="#FFD700" // 标题填充样式
/>
);
});
```
### 纯色背景 + 复杂标题
```tsx
import { defineComponent } from 'vue';
import { Textbox } from '@user/client-modules';
export const MyCom = defineComponent(() => {
return () => (
<Textbox
title="国王的旨意" // 标题内容
backColor="rgba(0,0,0,0.8)" // 背景色,使用半透明黑色
padding={16}
width={416}
titlePadding={10} // 标题的内边距
titleFont={new Font('华文行楷', 24)}
titleStroke="#8B4513" // 标题描边样式
titleFill="#FFFFFF"
/>
);
});
```
### 动态标题交互
```tsx
import { defineComponent } from 'vue';
import { Textbox, TextbosExpose } from '@user/client-modules';
export const MyCom = defineComponent(() => {
const currentTitle = ref<string>();
// 点击按钮切换标题
const toggleTitle = () => {
currentTitle.value += 1;
};
return () => (
<container>
<Textbox
ref={dialogRef}
title={currentTitle.value.toString()}
winskin="winskin.png"
padding={10}
width={416}
titleFill="#FF4444"
/>
<text text="点击切换标题" onClick={toggleTitle} />
</container>
);
});
```
---
## 布局结构示意图
```mermaid
graph TB
Dialog[对话框] --> Background[背景层]
Dialog --> Title[标题层]
Dialog --> Content[内容层]
Background -->|winskin/backColor| 渲染背景
Title -->|title 配置| 标题文本
Content -->|padding 控制| 文字内容
```

View File

@ -1,119 +0,0 @@
# Thumbnail 地图缩略图组件 API 文档
本文档由 `DeepSeek` 生成并微调。
## 组件描述
地图缩略图组件用于在游戏界面中显示当前楼层的迷你地图,可展示地图布局、角色位置、伤害区域等信息。适用于小地图显示、地图预览等场景。
---
## Props 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| ---------- | ---------------- | ------ | -------------------------------------- |
| `loc` | `ElementLocator` | 必填 | 缩略图的位置和尺寸 |
| `floorId` | `FloorIds` | 必填 | 楼层 ID |
| `padStyle` | `CanvasStyle` | - | 缩略图填充样式 |
| `map` | `Block[]` | - | 楼层信息 |
| `hero` | `HeroStatus` | - | 角色信息 |
| `damage` | `boolean` | - | 是否显示地图伤害 |
| `all` | `boolean` | - | 是否完全展示地图(false 时只显示部分) |
| `noHD` | `boolean` | - | 是否使用高清模式 |
| `size` | `number` | - | 缩略图的比例(1 表示与实际地图一致) |
---
## Events 事件说明
无事件
---
## Slots 插槽说明
无插槽
---
## Exposed Methods 暴露方法
无暴露方法
---
## 使用示例
### 基础用法 - 显示当前楼层缩略图
```tsx
import { defineComponent } from 'vue';
import { Thumbnail } from '@user/client-modules';
export const MiniMapCom = defineComponent(() => {
return () => (
<Thumbnail
loc={[400, 50, 120, 120, 1, 0]}
floorId="main_floor"
padStyle="#2c3e50"
size={0.1}
/>
);
});
```
### 带角色位置的小地图
```tsx
import { defineComponent } from 'vue';
import { Thumbnail } from '@user/client-modules';
export const GameHUDCom = defineComponent(props => {
const heroStatus: HeroStatus = {
// 角色状态信息
loc: { x: 100, y: 150 }
// ... 其他角色属性
};
return () => (
<container loc={[400, 50, 150, 150, 1, 0]}>
<Thumbnail
loc={[0, 0, 150, 150, 0.5, 0.5]}
floorId="dungeon_1"
hero={heroStatus}
padStyle="#34495e"
damage
size={0.08}
/>
<text text="小地图" loc={[0, 0]} />
</container>
);
});
```
### 完整地图预览
```tsx
import { defineComponent } from 'vue';
import { Thumbnail } from '@user/client-modules';
export const MapPreviewCom = defineComponent(() => {
return () => (
<Thumbnail
loc={[240, 240, 300, 300, 0.5, 0.5]}
floorId="boss_arena"
all
padStyle="#1a1a1a"
size={0.3}
/>
);
});
```
---
## 注意事项
1. **楼层标识**: `floorId` 必须与游戏中的楼层标识匹配
2. **比例控制**: `size` 参数控制缩略图与实际地图的比例关系
3. **显示范围**: `all` 为 false 时,大地图只会显示当前可视区域

View File

@ -1,65 +0,0 @@
# Tip 组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
## 参数说明(Props)
| 参数名 | 类型 | 默认值 | 说明 |
| -------- | ------------------ | -------- | ---------------------------------------- |
| `loc` | `ElementLocator` | 必填 | 容器基础定位参数 [x,y,width,height] |
| `pad` | `[number, number]` | `[4,4]` | 图标与文字的边距配置 [水平边距,垂直边距] |
| `corner` | `number` | `4` | 圆角矩形的圆角半径 |
| `id` | `string` | 自动生成 | 提示框唯一标识(需全局唯一) |
## 暴露接口(Expose)
| 方法名 | 参数 | 返回值 | 说明 |
| --------- | ----------------------------------------------- | ------ | --------------------------------------------------- |
| `drawTip` | `text: string`<br>`icon?: AllIds \| AllNumbers` | `void` | 显示带图标的提示文本(图标支持字符串 ID 或数字 ID) |
## 使用示例
```tsx
import { defineComponent } from 'vue';
import { Tip } from './tip';
// 在游戏界面中定义提示组件
export const MyCom = defineComponent(() => {
return () => (
<container>
<Tip
loc={[32, 32, 280, 40]}
pad={[8, 4]}
corner={8}
id="global-tip"
></Tip>
</container>
);
});
// 在业务代码中调用提示,使用 TipStore 类
const tip = TipStore.get('global-tip');
tip?.drawTip('宝箱已解锁!', 'chest_icon');
```
## 特性说明
1. **自动布局**:
- 根据图标尺寸自动计算容器宽度
- 文字垂直居中显示
- 图标与文字间距自动适配
2. **动画效果**:
- 默认带有 500ms 双曲正弦缓动的淡入动画
- 3 秒无操作后自动淡出
- 支持通过`alpha`参数自定义过渡效果
## 注意事项
1. **全局单例**:建议通过 `TipStore` 进行全局管理,避免重复创建
2. **ID 唯一性**:未指定 `id` 时会自动生成格式为 `@default-tip-数字` 的标识
3. **自动隐藏**:调用 `drawTip` 后 3 秒自动隐藏,连续调用会重置计时
4. **性能优化**:使用 `lodash` 的 `debounce` 进行隐藏操作防抖
5. **动画配置**:可通过修改 `hyper('sin', 'in-out')` 参数调整动画曲线

View File

@ -1,104 +0,0 @@
# WaitBox 等待框组件 API 文档
本文档由 `DeepSeek R1` 模型生成并微调。
---
## 核心特性
- **Promise 绑定**:自动监控 `Promise` 状态
- **复合式组件**:集成背景+文字+加载动画
- **双重控制**:支持自动/手动完成等待
- **动态布局**:根据内容自动计算高度
---
## 组件定位
> 💡 更推荐使用 `waitbox` 工具函数,该组件主要用于需要深度定制的场景。参考 [此文档](./functions.md#waitbox)。
---
## Props 属性说明
| 属性名 | 类型 | 必填 | 描述 |
| --------- | ---------------- | ---- | ----------------------- |
| `promise` | `Promise<T>` | 否 | 要监控的 `Promise` 对象 |
| `loc` | `ElementLocator` | 是 | 容器定位 |
| `width` | `number` | 是 | 内容区域宽度(像素) |
| `text` | `string` | 否 | 等待提示文字 |
| `pad` | `number` | `16` | 文字与边缘间距 |
### 继承属性
- 支持所有 `Background` 背景属性
- 支持所有 `TextContent` 文本属性
---
## 事件说明
| 事件名 | 参数 | 触发时机 |
| --------- | ---- | -------------------------- |
| `resolve` | `T` | `Promise` 完成时返回结果值 |
---
## Exposed Methods 暴露方法
| 方法名 | 参数 | 描述 |
| --------- | --------- | ---------------------------- |
| `resolve` | `data: T` | 手动完成等待(立即触发事件) |
---
## 使用示例
### 基础组件用法
```tsx
// 等待网络请求
const fetchPromise = fetchData();
<WaitBox
promise={fetchPromise}
loc={[208, 208, void 0, void 0, 0.5, 0.5]} // 居中定位
width={208}
text="加载中..."
winskin="ui/loading_bg"
font={new Font('黑体', 18)}
onResolve={data => console.log('收到数据:', data)}
/>;
```
### 手动控制示例
```tsx
const waitRef = ref<WaitBoxExpose<number>>();
// 手动结束等待
const forceComplete = () => {
waitRef.value?.resolve(Date.now());
};
return () => (
<WaitBox
ref={waitRef}
loc={[100, 100, 400, 200]}
width={360}
text="点击按钮继续"
color="rgba(0,0,0,0.7)"
></WaitBox>
);
```
---
## 注意事项
1. **推荐用法**
90% 场景应使用 `waitbox` 函数,以下情况才需要直接使用组件:
- 需要永久显示的等待界面
- 需要组合复杂子组件
- 需要复用同一个等待实例

Some files were not shown because too many files have changed in this diff Show More