mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-06-28 05:07:59 +08:00
Merge 45c1d8c952
into 820dc5bf4c
This commit is contained in:
commit
8883eca285
2
.github/workflows/page.yml
vendored
2
.github/workflows/page.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
||||
run: |
|
||||
npm i -g pnpm@7.27.0
|
||||
pnpm i
|
||||
pnpm build-gh
|
||||
pnpm build
|
||||
|
||||
# 执行部署
|
||||
- name: 部署
|
||||
|
18
.gitignore
vendored
18
.gitignore
vendored
@ -35,4 +35,20 @@ index.cjs
|
||||
!public/swap/*.h5save
|
||||
_bundle
|
||||
out
|
||||
dist-resource
|
||||
dist-resource
|
||||
_temp
|
||||
dam1.png
|
||||
dam2.png
|
||||
dam3.png
|
||||
dam4.png
|
||||
meeting.md
|
||||
|
||||
*.csv
|
||||
script/special.ts
|
||||
script/people.ts
|
||||
user.ts
|
||||
.antlr
|
||||
graph.svg
|
||||
docs/.vitepress/cache
|
||||
docs/.vitepress/dist
|
||||
docs/.vitepress/apiSidebar.ts
|
||||
|
12
.madgerc
Normal file
12
.madgerc
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"fileExtensions": [
|
||||
"ts",
|
||||
"tsx"
|
||||
],
|
||||
"tsConfig": "./tsconfig.json",
|
||||
"detectiveOptions": {
|
||||
"ts": {
|
||||
"skipTypeImports": true
|
||||
}
|
||||
}
|
||||
}
|
@ -5,4 +5,12 @@ public/project/floors/*.js
|
||||
public/project/items.js
|
||||
public/project/floors/*.js
|
||||
public/project/maps.js
|
||||
script/**/*.js
|
||||
public/project/icons.js
|
||||
public/project/enemys.js
|
||||
public/_server/**/*.js
|
||||
script/**/*.js
|
||||
public/editor.html
|
||||
keyCodes.ts
|
||||
src/core/main/setting.ts
|
||||
src/core/fx/shadow.ts
|
||||
dist/
|
13
.prettierrc
Normal file
13
.prettierrc
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"tabWidth": 4,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"quoteProps": "as-needed",
|
||||
"bracketSpacing": true,
|
||||
"vueIndentScriptAndStyle": false,
|
||||
"arrowParens": "avoid",
|
||||
"trailingComma": "none",
|
||||
"endOfLine": "auto"
|
||||
}
|
8
.vscode/extensions.json
vendored
8
.vscode/extensions.json
vendored
@ -1,3 +1,9 @@
|
||||
{
|
||||
"recommendations": ["Vue.volar"]
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"vue.volar",
|
||||
"slevesque.shader",
|
||||
"tobermory.es6-string-html"
|
||||
]
|
||||
}
|
||||
|
178
LICENSE
178
LICENSE
@ -1,21 +1,165 @@
|
||||
MIT License
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (c) 2023 unanmed
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
|
3
components.d.ts
vendored
3
components.d.ts
vendored
@ -7,7 +7,9 @@ export {}
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
export interface GlobalComponents {
|
||||
AButton: typeof import('ant-design-vue/es')['Button']
|
||||
ADivider: typeof import('ant-design-vue/es')['Divider']
|
||||
AInput: typeof import('ant-design-vue/es')['Input']
|
||||
AProgress: typeof import('ant-design-vue/es')['Progress']
|
||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||
@ -17,6 +19,7 @@ declare module '@vue/runtime-core' {
|
||||
BoxAnimate: typeof import('./src/components/boxAnimate.vue')['default']
|
||||
Colomn: typeof import('./src/components/colomn.vue')['default']
|
||||
EnemyOne: typeof import('./src/components/enemyOne.vue')['default']
|
||||
Minimap: typeof import('./src/components/minimap.vue')['default']
|
||||
Scroll: typeof import('./src/components/scroll.vue')['default']
|
||||
}
|
||||
}
|
||||
|
97
docs/.vitepress/api.ts
Normal file
97
docs/.vitepress/api.ts
Normal file
@ -0,0 +1,97 @@
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import chokidar from 'chokidar';
|
||||
import { DefaultTheme } from 'vitepress';
|
||||
|
||||
const apiDir = path.resolve('./docs/api');
|
||||
const sidebarConfigPath = path.resolve('./docs/.vitepress/apiSidebar.ts');
|
||||
|
||||
const weight: Record<string, number> = {
|
||||
主页: 10,
|
||||
函数: 5
|
||||
};
|
||||
|
||||
function generateSidebar(): void {
|
||||
const sidebar: DefaultTheme.SidebarItem[] = [
|
||||
{ text: '目录', link: '/api/' }
|
||||
];
|
||||
|
||||
// 遍历 api 目录,查找 package 目录
|
||||
const packages = fs
|
||||
.readdirSync(apiDir)
|
||||
.filter(pkg => fs.statSync(path.join(apiDir, pkg)).isDirectory());
|
||||
|
||||
packages.forEach(pkg => {
|
||||
const pkgPath = path.join(apiDir, pkg);
|
||||
const files = fs
|
||||
.readdirSync(pkgPath)
|
||||
.filter(file => file.endsWith('.md'));
|
||||
|
||||
const items: DefaultTheme.SidebarItem[] = files.map(file => {
|
||||
const filePath = `api/${pkg}/${file}`;
|
||||
const fileName = path.basename(file, '.md');
|
||||
|
||||
return {
|
||||
text:
|
||||
fileName === 'index'
|
||||
? '主页'
|
||||
: fileName === 'functions'
|
||||
? '函数'
|
||||
: fileName,
|
||||
link: `/${filePath.replace(/\\/g, '/')}` // 兼容 Windows 路径
|
||||
};
|
||||
});
|
||||
|
||||
items.sort((a, b) => {
|
||||
const titleA = a.text ?? '';
|
||||
const titleB = b.text ?? '';
|
||||
return (weight[titleB] ?? 0) - (weight[titleA] ?? 0);
|
||||
});
|
||||
|
||||
sidebar.push({
|
||||
text: pkg,
|
||||
collapsed: true,
|
||||
items
|
||||
});
|
||||
});
|
||||
|
||||
// 生成 sidebar.ts
|
||||
const sidebarContent = `import { DefaultTheme } from 'vitepress';
|
||||
|
||||
export default ${JSON.stringify(
|
||||
sidebar,
|
||||
null,
|
||||
4
|
||||
)} as DefaultTheme.SidebarItem[];`;
|
||||
fs.writeFileSync(sidebarConfigPath, sidebarContent);
|
||||
console.log('✅ Sidebar 配置已更新');
|
||||
}
|
||||
|
||||
// 初次运行
|
||||
generateSidebar();
|
||||
|
||||
// 监听文件变动
|
||||
chokidar
|
||||
.watch(apiDir, { ignoreInitial: true })
|
||||
.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, details) => {
|
||||
if (event === 'rename') {
|
||||
console.log(`🔄 文件或文件夹重命名: ${path}`);
|
||||
generateSidebar();
|
||||
}
|
||||
});
|
119
docs/.vitepress/config.ts
Normal file
119
docs/.vitepress/config.ts
Normal file
@ -0,0 +1,119 @@
|
||||
import { defineConfig } from 'vitepress';
|
||||
import { MermaidMarkdown, MermaidPlugin } from 'vitepress-plugin-mermaid';
|
||||
import api from './apiSidebar';
|
||||
|
||||
// https://vitepress.dev/reference/site-config
|
||||
export default defineConfig({
|
||||
title: 'HTML5 魔塔样板 V2.B',
|
||||
description: 'HTML5 魔塔样板 V2.B 帮助文档',
|
||||
base: '/_docs/',
|
||||
markdown: {
|
||||
math: true,
|
||||
config(md) {
|
||||
md.use(MermaidMarkdown);
|
||||
}
|
||||
},
|
||||
themeConfig: {
|
||||
// https://vitepress.dev/reference/default-theme-config
|
||||
outline: [2, 3],
|
||||
nav: [
|
||||
{ text: '主页', link: '/' },
|
||||
{ text: '指南', link: '/guide/diff' },
|
||||
{ text: 'API', link: '/api/' },
|
||||
{ text: '错误代码', link: '/logger/' }
|
||||
],
|
||||
sidebar: {
|
||||
'/guide/': [
|
||||
{
|
||||
text: '深度指南',
|
||||
items: [
|
||||
{ text: '差异说明', link: '/guide/diff' },
|
||||
{ text: '系统说明', link: '/guide/system' },
|
||||
{ text: '代码编写', link: '/guide/coding' },
|
||||
{
|
||||
text: 'UI 系统',
|
||||
collapsed: false,
|
||||
items: [
|
||||
{ text: 'UI 编写', link: '/guide/ui' },
|
||||
{ text: 'UI 优化', link: '/guide/ui-perf' },
|
||||
{ text: 'UI 系统', link: '/guide/ui-system' },
|
||||
{ text: 'UI 元素', link: '/guide/ui-elements' },
|
||||
{ text: 'UI 常见问题', link: '/guide/ui-faq' }
|
||||
]
|
||||
},
|
||||
{ text: '音频系统', link: '/guide/audio' }
|
||||
]
|
||||
}
|
||||
],
|
||||
'/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
|
||||
}
|
||||
]
|
||||
},
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/unanmed/HumanBreak' }
|
||||
],
|
||||
search: {
|
||||
provider: 'local',
|
||||
options: {
|
||||
locales: {
|
||||
zh: {
|
||||
translations: {
|
||||
button: {
|
||||
buttonText: '搜索文档',
|
||||
buttonAriaLabel: '搜索文档'
|
||||
},
|
||||
modal: {
|
||||
noResultsText: '无法找到相关结果',
|
||||
resetButtonTitle: '清除查询条件',
|
||||
footer: {
|
||||
selectText: '选择',
|
||||
navigateText: '切换'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
locales: {
|
||||
root: {
|
||||
lang: 'zh',
|
||||
label: '中文'
|
||||
}
|
||||
},
|
||||
vite: {
|
||||
plugins: [MermaidPlugin()],
|
||||
optimizeDeps: {
|
||||
include: ['mermaid']
|
||||
},
|
||||
ssr: {
|
||||
noExternal: ['mermaid']
|
||||
}
|
||||
}
|
||||
});
|
7
docs/.vitepress/theme.css
Normal file
7
docs/.vitepress/theme.css
Normal file
@ -0,0 +1,7 @@
|
||||
.mermaid {
|
||||
max-width: 600px; /* 限制最大宽度 */
|
||||
max-height: 400px; /* 限制最大高度 */
|
||||
overflow: auto; /* 允许滚动以防止超出 */
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
32
docs/api/index.md
Normal file
32
docs/api/index.md
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
lang: zh-CN
|
||||
---
|
||||
|
||||
# API 列表
|
||||
|
||||
- [@motajs/client](./motajs-client) 渲染层代码
|
||||
- [@motajs/client-base](./motajs-client-base) 渲染层底层代码
|
||||
- [@motajs/common](./motajs-common) 渲染层和数据层通用代码
|
||||
- [@motajs/legacy-client](./motajs-legacy-client) 遗留渲染层代码
|
||||
- [@motajs/legacy-common](./motajs-legacy-common) 遗留通用代码
|
||||
- [@motajs/legacy-data](./motajs-legacy-data) 遗留数据层代码
|
||||
- [@motajs/legacy-system](./motajs-legacy-system) 遗留渲染层系统代码
|
||||
- [@motajs/legacy-ui](./motajs-legacy-ui) 遗留 UI 相关代码
|
||||
- [@motajs/render](./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) 渲染系统 vue 支持代码
|
||||
- [@motajs/system](./motajs-system) 渲染层系统代码
|
||||
- [@motajs/system-action](./motajs-system-action) 渲染层交互系统代码
|
||||
- [@motajs/system-ui](./motajs-system-ui) 渲染层 UI 系统代码
|
||||
- [@motajs/types](./motajs-types) 渲染层类型代码
|
||||
- [@user/client-modules](./user-client-modules) 用户渲染层主要代码
|
||||
- [@user/data-base](./user-data-base) 用户数据层底层代码
|
||||
- [@user/data-fallback](./user-data-fallback) 用户数据层向后兼容代码
|
||||
- [@user/data-state](./user-data-state) 用户数据层状态代码
|
||||
- [@user/data-utils](./user-data-utils) 用户数据层工具代码
|
||||
- [@user/entry-client](./user-entry-client) 用户渲染层入口
|
||||
- [@user/entry-data](./user-entry-data) 用户数据层入口
|
||||
- [@user/legacy-plugin-client](./user-legacy-plugin-client) 用户遗留渲染层代码
|
||||
- [@user/legacy-plugin-data](./user-legacy-plugin-data) 用户遗留数据层代码
|
3
docs/api/motajs-client-base/KeyCode.md
Normal file
3
docs/api/motajs-client-base/KeyCode.md
Normal file
@ -0,0 +1,3 @@
|
||||
# KeyCode
|
||||
|
||||
参考 `monaco-editor` 文档 [KeyCode](https://microsoft.github.io/monaco-editor/docs.html#enums/KeyCode.html)
|
5
docs/api/motajs-client-base/index.md
Normal file
5
docs/api/motajs-client-base/index.md
Normal file
@ -0,0 +1,5 @@
|
||||
# @motajs/client-base
|
||||
|
||||
目录:
|
||||
|
||||
- [KeyCode](./KeyCode.md)
|
13
docs/api/motajs-client/index.md
Normal file
13
docs/api/motajs-client/index.md
Normal file
@ -0,0 +1,13 @@
|
||||
# @motajs/client
|
||||
|
||||
`@motajs/client` 包含多个模块:
|
||||
|
||||
- [`@motajs/client-base`](../motajs-client-base/)
|
||||
|
||||
示例:
|
||||
|
||||
```ts
|
||||
import { KeyCode } from '@motajs/client';
|
||||
|
||||
const { KeyCOde } = Mota.require('@motajs/client');
|
||||
```
|
212
docs/api/motajs-common/Logger.md
Normal file
212
docs/api/motajs-common/Logger.md
Normal file
@ -0,0 +1,212 @@
|
||||
# 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();
|
||||
```
|
24
docs/api/motajs-common/functions.md
Normal file
24
docs/api/motajs-common/functions.md
Normal file
@ -0,0 +1,24 @@
|
||||
# @motajs/common 函数
|
||||
|
||||
## `sleep`
|
||||
|
||||
```ts
|
||||
function sleep(time: number): Promise<void>;
|
||||
```
|
||||
|
||||
#### 描述
|
||||
|
||||
创建一个等待指定时长的异步。
|
||||
|
||||
#### 参数
|
||||
|
||||
- `time`: 等待时长
|
||||
|
||||
#### 使用示例
|
||||
|
||||
```ts
|
||||
async function myFunc() {
|
||||
await sleep(1000);
|
||||
// 这后面的内容会在 1 秒之后执行
|
||||
}
|
||||
```
|
11
docs/api/motajs-common/index.md
Normal file
11
docs/api/motajs-common/index.md
Normal file
@ -0,0 +1,11 @@
|
||||
# @motajs/common
|
||||
|
||||
目录:
|
||||
|
||||
- [函数](./functions.md)
|
||||
|
||||
---
|
||||
|
||||
类目录:
|
||||
|
||||
- [Logger](./Logger.md)
|
3
docs/api/motajs-legacy-client/index.md
Normal file
3
docs/api/motajs-legacy-client/index.md
Normal file
@ -0,0 +1,3 @@
|
||||
# @motajs/legacy-client
|
||||
|
||||
目录:
|
120
docs/api/motajs-legacy-common/Patch.md
Normal file
120
docs/api/motajs-legacy-common/Patch.md
Normal file
@ -0,0 +1,120 @@
|
||||
# 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;
|
||||
});
|
||||
}
|
||||
```
|
3
docs/api/motajs-legacy-common/index.md
Normal file
3
docs/api/motajs-legacy-common/index.md
Normal file
@ -0,0 +1,3 @@
|
||||
# @motajs/legacy-common
|
||||
|
||||
目录:
|
3
docs/api/motajs-legacy-system/index.md
Normal file
3
docs/api/motajs-legacy-system/index.md
Normal file
@ -0,0 +1,3 @@
|
||||
# @motajs/legacy-system
|
||||
|
||||
目录:
|
3
docs/api/motajs-legacy-ui/index.md
Normal file
3
docs/api/motajs-legacy-ui/index.md
Normal file
@ -0,0 +1,3 @@
|
||||
# @motajs/legacy-ui
|
||||
|
||||
目录:
|
121
docs/api/motajs-render-core/Container.md
Normal file
121
docs/api/motajs-render-core/Container.md
Normal file
@ -0,0 +1,121 @@
|
||||
# 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); // 自动触发重新排序
|
||||
```
|
71
docs/api/motajs-render-core/ContainerCustom.md
Normal file
71
docs/api/motajs-render-core/ContainerCustom.md
Normal file
@ -0,0 +1,71 @@
|
||||
# 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);
|
||||
});
|
||||
});
|
||||
```
|
201
docs/api/motajs-render-core/Event.md
Normal file
201
docs/api/motajs-render-core/Event.md
Normal file
@ -0,0 +1,201 @@
|
||||
# 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} />;
|
||||
```
|
||||
|
||||
:::
|
151
docs/api/motajs-render-core/GL2.md
Normal file
151
docs/api/motajs-render-core/GL2.md
Normal file
@ -0,0 +1,151 @@
|
||||
# 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 功能
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 总使用示例
|
||||
|
||||
暂时没有。
|
188
docs/api/motajs-render-core/GL2Program.md
Normal file
188
docs/api/motajs-render-core/GL2Program.md
Normal file
@ -0,0 +1,188 @@
|
||||
# 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);
|
||||
}
|
||||
```
|
311
docs/api/motajs-render-core/MotaOffscreenCanvas2D.md
Normal file
311
docs/api/motajs-render-core/MotaOffscreenCanvas2D.md
Normal file
@ -0,0 +1,311 @@
|
||||
# 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` 而非直接调用此构造函数。
|
||||
|
||||
---
|
||||
|
||||
## 方法说明
|
||||
|
||||
### `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);
|
||||
```
|
174
docs/api/motajs-render-core/MotaRenderer.md
Normal file
174
docs/api/motajs-render-core/MotaRenderer.md
Normal file
@ -0,0 +1,174 @@
|
||||
# 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();
|
||||
});
|
||||
```
|
230
docs/api/motajs-render-core/RenderAdapter.md
Normal file
230
docs/api/motajs-render-core/RenderAdapter.md
Normal file
@ -0,0 +1,230 @@
|
||||
# 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();
|
||||
```
|
477
docs/api/motajs-render-core/RenderItem.md
Normal file
477
docs/api/motajs-render-core/RenderItem.md
Normal file
@ -0,0 +1,477 @@
|
||||
# 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` 模型生成并微调。
|
||||
|
||||
---
|
12
docs/api/motajs-render-core/Shader.md
Normal file
12
docs/api/motajs-render-core/Shader.md
Normal file
@ -0,0 +1,12 @@
|
||||
# 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)
|
11
docs/api/motajs-render-core/ShaderProgram.md
Normal file
11
docs/api/motajs-render-core/ShaderProgram.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Shader 类 API 文档
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
ShaderProgram --> GL2Program --> EventEmitter
|
||||
|
||||
click GL2Program "./GL2Program"
|
||||
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
|
||||
```
|
||||
|
||||
用法同 [GL2Program](./GL2Program.md)
|
121
docs/api/motajs-render-core/Sprite.md
Normal file
121
docs/api/motajs-render-core/Sprite.md
Normal file
@ -0,0 +1,121 @@
|
||||
# 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);
|
||||
```
|
332
docs/api/motajs-render-core/Transform.md
Normal file
332
docs/api/motajs-render-core/Transform.md
Normal file
@ -0,0 +1,332 @@
|
||||
# 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);
|
||||
```
|
119
docs/api/motajs-render-core/functions.md
Normal file
119
docs/api/motajs-render-core/functions.md
Normal file
@ -0,0 +1,119 @@
|
||||
# 函数 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 --> 矩阵变换
|
||||
```
|
1
docs/api/motajs-render-core/index.md
Normal file
1
docs/api/motajs-render-core/index.md
Normal file
@ -0,0 +1 @@
|
||||
# @motajs/render-core
|
369
docs/api/motajs-render-elements/BlockCacher.md
Normal file
369
docs/api/motajs-render-elements/BlockCacher.md
Normal file
@ -0,0 +1,369 @@
|
||||
# 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();
|
||||
```
|
386
docs/api/motajs-render-elements/Camera.md
Normal file
386
docs/api/motajs-render-elements/Camera.md
Normal file
@ -0,0 +1,386 @@
|
||||
# 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; // 纵向缩放比
|
||||
}
|
||||
```
|
201
docs/api/motajs-render-elements/CameraAnimation.md
Normal file
201
docs/api/motajs-render-elements/CameraAnimation.md
Normal file
@ -0,0 +1,201 @@
|
||||
# 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;
|
||||
```
|
3
docs/api/motajs-render-elements/index.md
Normal file
3
docs/api/motajs-render-elements/index.md
Normal file
@ -0,0 +1,3 @@
|
||||
# @motajs/render-elements
|
||||
|
||||
目录:
|
186
docs/api/motajs-render-style/Font.md
Normal file
186
docs/api/motajs-render-style/Font.md
Normal file
@ -0,0 +1,186 @@
|
||||
# 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
|
||||
});
|
||||
```
|
3
docs/api/motajs-render-style/index.md
Normal file
3
docs/api/motajs-render-style/index.md
Normal file
@ -0,0 +1,3 @@
|
||||
# @motajs/render-style
|
||||
|
||||
目录:
|
134
docs/api/motajs-render-vue/BaseProps.md
Normal file
134
docs/api/motajs-render-vue/BaseProps.md
Normal file
@ -0,0 +1,134 @@
|
||||
# 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)
|
167
docs/api/motajs-render-vue/GraphicBaseProps.md
Normal file
167
docs/api/motajs-render-vue/GraphicBaseProps.md
Normal file
@ -0,0 +1,167 @@
|
||||
# GraphicBaseProps API 文档
|
||||
|
||||
本文档由 `DeepSeek R1` 模型生成并微调。
|
||||
|
||||
---
|
||||
|
||||
## 接口定义
|
||||
|
||||
```typescript
|
||||
interface GraphicBaseProps extends BaseProps {
|
||||
/** 是否填充(默认 false) */
|
||||
fill?: boolean;
|
||||
/** 是否描边(默认 false) */
|
||||
stroke?: boolean;
|
||||
/** 强制先描边后填充(优先级最高,默认 false) */
|
||||
strokeAndFill?: boolean;
|
||||
/** 填充规则(默认 "evenodd") */
|
||||
fillRule?: CanvasFillRule;
|
||||
/** 填充样式(颜色/渐变/图案) */
|
||||
fillStyle?: CanvasStyle;
|
||||
/** 描边样式(颜色/渐变/图案) */
|
||||
strokeStyle?: CanvasStyle;
|
||||
/** 交互时是否仅检测描边区域(默认 false) */
|
||||
actionStroke?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心属性说明
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
| --------------- | ----------------------------------------------- | ----------- | -------------------------------------------------------------- |
|
||||
| `fill` | `boolean` | `false` | 启用填充(需设置 `fillStyle`) |
|
||||
| `stroke` | `boolean` | `false` | 启用描边(需设置 `strokeStyle` 和 `strokeWidth`) |
|
||||
| `strokeAndFill` | `boolean` | `false` | 强制先描边后填充(覆盖 `fill` 和 `stroke` 的设置) |
|
||||
| `fillRule` | `"nonzero"` \| `"evenodd"` | `"evenodd"` | 填充路径计算规则(影响复杂图形的镂空效果) |
|
||||
| `fillStyle` | `string` \| `CanvasGradient` \| `CanvasPattern` | - | 填充样式(支持 CSS 颜色、渐变对象等) |
|
||||
| `strokeStyle` | `string` \| `CanvasGradient` \| `CanvasPattern` | - | 描边样式 |
|
||||
| `actionStroke` | `boolean` | `false` | 设为 `true` 时,交互事件仅响应描边区域(需配合 `stroke` 使用) |
|
||||
|
||||
---
|
||||
|
||||
## 使用示例(以矩形为例)
|
||||
|
||||
### 示例 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. 在描边层上填充浅紫色
|
||||
**视觉效果**:描边被填充色覆盖一部分
|
||||
|
||||
---
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 交互增强技巧
|
||||
|
||||
```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"
|
||||
strokeWidth={3}
|
||||
onEnter={enter}
|
||||
onLeave={leave}
|
||||
/>;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **样式覆盖顺序**:
|
||||
`strokeAndFill` 会强制按 **描边 → 填充** 顺序渲染,忽略 `fill` 和 `stroke` 的独立设置。
|
||||
|
||||
2. **路径闭合规则**:
|
||||
`fillRule="evenodd"` 适用于以下场景:
|
||||
|
||||
```tsx
|
||||
// 五角星镂空效果
|
||||
<path
|
||||
fill={true}
|
||||
fillRule="evenodd"
|
||||
path={starPath} // 交替重叠的路径
|
||||
/>
|
||||
```
|
||||
|
||||
3. **性能问题**:
|
||||
多数情况下,图形的性能很好,不需要单独优化,但是如果你使用 `path` 标签,且内容复杂,建议添加 `cache` 属性来启用缓存,避免频繁的复杂图形绘制。
|
149
docs/api/motajs-render-vue/functions.md
Normal file
149
docs/api/motajs-render-vue/functions.md
Normal file
@ -0,0 +1,149 @@
|
||||
# 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 设计,不可用于其他框架环境
|
3
docs/api/motajs-render-vue/index.md
Normal file
3
docs/api/motajs-render-vue/index.md
Normal file
@ -0,0 +1,3 @@
|
||||
# @motajs/render-vue
|
||||
|
||||
目录:
|
139
docs/api/motajs-render-vue/标签 container.md
Normal file
139
docs/api/motajs-render-vue/标签 container.md
Normal file
@ -0,0 +1,139 @@
|
||||
# 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/Scroll.md)或[分页](../user-client-modules/Page.md)组件。
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **缓存失效条件**:当任意子元素及自身发生变化时,将会自动触发更新
|
||||
2. **嵌套层级**:推荐使用容器嵌套提高缓存能力,但是并建议不嵌套过多
|
||||
3. **子元素更新**:修改容器子元素时会触发整个容器的缓存重建
|
||||
4. **内存管理**:超大缓存容器(如 4096x4096)可能触发浏览器纹理限制
|
88
docs/api/motajs-render-vue/标签 custom-container.md
Normal file
88
docs/api/motajs-render-vue/标签 custom-container.md
Normal file
@ -0,0 +1,88 @@
|
||||
# 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>;
|
||||
```
|
202
docs/api/motajs-render-vue/标签 g-bezier.md
Normal file
202
docs/api/motajs-render-vue/标签 g-bezier.md
Normal file
@ -0,0 +1,202 @@
|
||||
# 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} .../>
|
||||
```
|
182
docs/api/motajs-render-vue/标签 g-circle.md
Normal file
182
docs/api/motajs-render-vue/标签 g-circle.md
Normal file
@ -0,0 +1,182 @@
|
||||
# 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)
|
||||
/>
|
||||
```
|
175
docs/api/motajs-render-vue/标签 g-ellipse.md
Normal file
175
docs/api/motajs-render-vue/标签 g-ellipse.md
Normal file
@ -0,0 +1,175 @@
|
||||
# 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
|
||||
/>
|
||||
```
|
125
docs/api/motajs-render-vue/标签 g-line.md
Normal file
125
docs/api/motajs-render-vue/标签 g-line.md
Normal file
@ -0,0 +1,125 @@
|
||||
# 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>
|
||||
```
|
173
docs/api/motajs-render-vue/标签 g-path.md
Normal file
173
docs/api/motajs-render-vue/标签 g-path.md
Normal file
@ -0,0 +1,173 @@
|
||||
# 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(); // 关键闭合操作
|
||||
```
|
119
docs/api/motajs-render-vue/标签 g-quad.md
Normal file
119
docs/api/motajs-render-vue/标签 g-quad.md
Normal file
@ -0,0 +1,119 @@
|
||||
# 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} .../>
|
||||
```
|
91
docs/api/motajs-render-vue/标签 g-rect.md
Normal file
91
docs/api/motajs-render-vue/标签 g-rect.md
Normal file
@ -0,0 +1,91 @@
|
||||
# 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. 在描边层上填充浅紫色
|
||||
**视觉效果**:描边被填充色覆盖一部分
|
167
docs/api/motajs-render-vue/标签 g-rectr.md
Normal file
167
docs/api/motajs-render-vue/标签 g-rectr.md
Normal file
@ -0,0 +1,167 @@
|
||||
# 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%
|
||||
/>
|
||||
```
|
121
docs/api/motajs-render-vue/标签 icon.md
Normal file
121
docs/api/motajs-render-vue/标签 icon.md
Normal file
@ -0,0 +1,121 @@
|
||||
# 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 开始播放 |
|
103
docs/api/motajs-render-vue/标签 image.md
Normal file
103
docs/api/motajs-render-vue/标签 image.md
Normal file
@ -0,0 +1,103 @@
|
||||
# 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 等) |
|
148
docs/api/motajs-render-vue/标签 sprite.md
Normal file
148
docs/api/motajs-render-vue/标签 sprite.md
Normal file
@ -0,0 +1,148 @@
|
||||
# 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.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` 中循环更新自身
|
160
docs/api/motajs-render-vue/标签 text.md
Normal file
160
docs/api/motajs-render-vue/标签 text.md
Normal file
@ -0,0 +1,160 @@
|
||||
# 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/TextContent.md)
|
||||
2. 考虑到浏览器兼容性,不建议在颜色中填写一些新标准的语法,例如 `rgb(0.3, 0.6, 0.8 / 0.6)` `#rgba` 等
|
117
docs/api/motajs-render-vue/标签 winskin.md
Normal file
117
docs/api/motajs-render-vue/标签 winskin.md
Normal file
@ -0,0 +1,117 @@
|
||||
# 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>;
|
||||
```
|
16
docs/api/motajs-render/index.md
Normal file
16
docs/api/motajs-render/index.md
Normal file
@ -0,0 +1,16 @@
|
||||
# @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';
|
||||
// 二者等价,不需要单独使用一个量来接收,注意与 @motajs/client 引入方式区分
|
||||
import { Container } from '@motajs/render-core';
|
||||
```
|
311
docs/api/motajs-system-action/Hotkey.md
Normal file
311
docs/api/motajs-system-action/Hotkey.md
Normal file
@ -0,0 +1,311 @@
|
||||
# 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
|
||||
editorHotkey.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();
|
||||
});
|
||||
```
|
||||
|
||||
:::
|
221
docs/api/motajs-system-action/Keyboard.md
Normal file
221
docs/api/motajs-system-action/Keyboard.md
Normal file
@ -0,0 +1,221 @@
|
||||
# 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');
|
||||
```
|
3
docs/api/motajs-system-action/index.md
Normal file
3
docs/api/motajs-system-action/index.md
Normal file
@ -0,0 +1,3 @@
|
||||
# @motajs/system-action
|
||||
|
||||
目录:
|
97
docs/api/motajs-system-ui/GameUI.md
Normal file
97
docs/api/motajs-system-ui/GameUI.md
Normal file
@ -0,0 +1,97 @@
|
||||
# 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);
|
||||
```
|
284
docs/api/motajs-system-ui/UIController.md
Normal file
284
docs/api/motajs-system-ui/UIController.md
Normal file
@ -0,0 +1,284 @@
|
||||
# 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.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);
|
||||
```
|
121
docs/api/motajs-system-ui/UIInstance.md
Normal file
121
docs/api/motajs-system-ui/UIInstance.md
Normal file
@ -0,0 +1,121 @@
|
||||
# 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();
|
||||
```
|
3
docs/api/motajs-system-ui/index.md
Normal file
3
docs/api/motajs-system-ui/index.md
Normal file
@ -0,0 +1,3 @@
|
||||
# @motajs/system-ui
|
||||
|
||||
目录:
|
25
docs/api/motajs-system/index.md
Normal file
25
docs/api/motajs-system/index.md
Normal file
@ -0,0 +1,25 @@
|
||||
# @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');
|
||||
```
|
3
docs/api/motajs-types/index.md
Normal file
3
docs/api/motajs-types/index.md
Normal file
@ -0,0 +1,3 @@
|
||||
# @motajs/types
|
||||
|
||||
目录:
|
142
docs/api/user-client-modules/AudioDecoder.md
Normal file
142
docs/api/user-client-modules/AudioDecoder.md
Normal file
@ -0,0 +1,142 @@
|
||||
# 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 音频。
|
207
docs/api/user-client-modules/AudioEffect.md
Normal file
207
docs/api/user-client-modules/AudioEffect.md
Normal file
@ -0,0 +1,207 @@
|
||||
# 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
|
||||
```
|
||||
|
||||
- 带反馈的延迟效果
|
||||
- 自动渐弱回声处理
|
||||
|
||||
---
|
172
docs/api/user-client-modules/AudioPlayer.md
Normal file
172
docs/api/user-client-modules/AudioPlayer.md
Normal file
@ -0,0 +1,172 @@
|
||||
# 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+ ⊙ 朝向用户
|
||||
```
|
221
docs/api/user-client-modules/AudioRoute.md
Normal file
221
docs/api/user-client-modules/AudioRoute.md
Normal file
@ -0,0 +1,221 @@
|
||||
# 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: 暂停播放
|
||||
```
|
184
docs/api/user-client-modules/AudioSource.md
Normal file
184
docs/api/user-client-modules/AudioSource.md
Normal file
@ -0,0 +1,184 @@
|
||||
# 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 秒
|
158
docs/api/user-client-modules/BgmController.md
Normal file
158
docs/api/user-client-modules/BgmController.md
Normal file
@ -0,0 +1,158 @@
|
||||
# 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);
|
||||
});
|
||||
```
|
147
docs/api/user-client-modules/HeroKeyMover.md
Normal file
147
docs/api/user-client-modules/HeroKeyMover.md
Normal file
@ -0,0 +1,147 @@
|
||||
# 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. **作用域隔离**:只有当前作用域匹配时才会响应按键事件
|
197
docs/api/user-client-modules/SoundPlayer.md
Normal file
197
docs/api/user-client-modules/SoundPlayer.md
Normal file
@ -0,0 +1,197 @@
|
||||
# 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 个,可通过优先级系统管理
|
208
docs/api/user-client-modules/StreamLoader.md
Normal file
208
docs/api/user-client-modules/StreamLoader.md
Normal file
@ -0,0 +1,208 @@
|
||||
# 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('视频解码错误');
|
||||
```
|
157
docs/api/user-client-modules/TextContentParser.md
Normal file
157
docs/api/user-client-modules/TextContentParser.md
Normal file
@ -0,0 +1,157 @@
|
||||
# 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
|
||||
```
|
245
docs/api/user-client-modules/TextContentTyper.md
Normal file
245
docs/api/user-client-modules/TextContentTyper.md
Normal file
@ -0,0 +1,245 @@
|
||||
# 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` 组件。如果必须使用的话,可以直接阅读源码来看一些实现细节。
|
166
docs/api/user-client-modules/TextboxStore.md
Normal file
166
docs/api/user-client-modules/TextboxStore.md
Normal file
@ -0,0 +1,166 @@
|
||||
# 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());
|
||||
```
|
147
docs/api/user-client-modules/TipStore.md
Normal file
147
docs/api/user-client-modules/TipStore.md
Normal file
@ -0,0 +1,147 @@
|
||||
# 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); // 等待淡出动画结束
|
||||
```
|
217
docs/api/user-client-modules/WeatherController.md
Normal file
217
docs/api/user-client-modules/WeatherController.md
Normal file
@ -0,0 +1,217 @@
|
||||
# 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>;
|
||||
});
|
||||
```
|
||||
|
||||
:::
|
410
docs/api/user-client-modules/functions.md
Normal file
410
docs/api/user-client-modules/functions.md
Normal file
@ -0,0 +1,410 @@
|
||||
# 模块函数 API 文档
|
||||
|
||||
本文档由 `DeepSeek R1` 模型生成并微调。
|
||||
|
||||
## 钩子
|
||||
|
||||
### `onOrientationChange`
|
||||
|
||||
```typescript
|
||||
function onOrientationChange(hook: OrientationHook): void;
|
||||
```
|
||||
|
||||
监听屏幕方向变化事件。
|
||||
**参数**
|
||||
|
||||
- `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)
|
3
docs/api/user-client-modules/index.md
Normal file
3
docs/api/user-client-modules/index.md
Normal file
@ -0,0 +1,3 @@
|
||||
# @user/client-modules
|
||||
|
||||
目录:
|
37
docs/api/user-client-modules/图标组件.md
Normal file
37
docs/api/user-client-modules/图标组件.md
Normal file
@ -0,0 +1,37 @@
|
||||
# 图标组件 API
|
||||
|
||||
## Props 属性说明
|
||||
|
||||
| 属性名 | 类型 | 必填 | 描述 |
|
||||
| ------ | ---------------- | ---- | ---------- |
|
||||
| `loc` | `ElementLocator` | 是 | 图标定位符 |
|
||||
|
||||
图标比例固定,会自动根据传入的长宽缩放。
|
||||
|
||||
## 图标列表
|
||||
|
||||
- `RollbackIcon`: 回退图标
|
||||
- `RetweenIcon`: 回收图标
|
||||
- `ViewMapIcon`: 浏览地图图标
|
||||
- `DanmakuIcon`: 弹幕图标
|
||||
- `ReplayIcon`: 回放图标
|
||||
- `numpadIcon`: 数字键盘图标
|
||||
- `PlayIcon`: 开始播放图标
|
||||
- `PauseIcon`: 暂停播放图标
|
||||
- `DoubleArrow`: 双箭头图标(向右)
|
||||
- `StepForward`: 单步向前图标
|
||||
|
||||
## 使用示例
|
||||
|
||||
```tsx
|
||||
import { defineComponent } from 'vue';
|
||||
import { RollbackIcon } from '@user/client-modules';
|
||||
|
||||
export const MyCom = defineComponent(() => {
|
||||
return () => (
|
||||
<container>
|
||||
<RollbackIcon loc={[32, 32, 64, 64]} />
|
||||
</container>
|
||||
);
|
||||
});
|
||||
```
|
50
docs/api/user-client-modules/组件 Arrow.md
Normal file
50
docs/api/user-client-modules/组件 Arrow.md
Normal file
@ -0,0 +1,50 @@
|
||||
# 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"
|
||||
/>
|
||||
```
|
78
docs/api/user-client-modules/组件 Background.md
Normal file
78
docs/api/user-client-modules/组件 Background.md
Normal file
@ -0,0 +1,78 @@
|
||||
# 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 />;
|
||||
```
|
159
docs/api/user-client-modules/组件 Choices.md
Normal file
159
docs/api/user-client-modules/组件 Choices.md
Normal file
@ -0,0 +1,159 @@
|
||||
# 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)
|
124
docs/api/user-client-modules/组件 ConfirmBox.md
Normal file
124
docs/api/user-client-modules/组件 ConfirmBox.md
Normal file
@ -0,0 +1,124 @@
|
||||
# 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)
|
192
docs/api/user-client-modules/组件 Page.md
Normal file
192
docs/api/user-client-modules/组件 Page.md
Normal file
@ -0,0 +1,192 @@
|
||||
# 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]` 范围内
|
107
docs/api/user-client-modules/组件 Progress.md
Normal file
107
docs/api/user-client-modules/组件 Progress.md
Normal file
@ -0,0 +1,107 @@
|
||||
# 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]} />
|
||||
```
|
118
docs/api/user-client-modules/组件 Scroll.md
Normal file
118
docs/api/user-client-modules/组件 Scroll.md
Normal file
@ -0,0 +1,118 @@
|
||||
# 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>
|
||||
```
|
160
docs/api/user-client-modules/组件 ScrollText.md
Normal file
160
docs/api/user-client-modules/组件 ScrollText.md
Normal file
@ -0,0 +1,160 @@
|
||||
# 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>
|
||||
```
|
77
docs/api/user-client-modules/组件 Selection.md
Normal file
77
docs/api/user-client-modules/组件 Selection.md
Normal file
@ -0,0 +1,77 @@
|
||||
# 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>
|
||||
```
|
184
docs/api/user-client-modules/组件 TextContent.md
Normal file
184
docs/api/user-client-modules/组件 TextContent.md
Normal file
@ -0,0 +1,184 @@
|
||||
# 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#转义字符语法说明)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user