mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-04-11 15:47:06 +08:00
feat: 自动创建API文档目录
This commit is contained in:
parent
1294c5f1ca
commit
3581e2604b
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[titleA] ?? 0) - (weight[titleB] ?? 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();
|
||||
}
|
||||
});
|
338
docs/.vitepress/apiSidebar.ts
Normal file
338
docs/.vitepress/apiSidebar.ts
Normal file
@ -0,0 +1,338 @@
|
||||
import { DefaultTheme } from 'vitepress';
|
||||
|
||||
export default [
|
||||
{
|
||||
"text": "目录",
|
||||
"link": "/api/"
|
||||
},
|
||||
{
|
||||
"text": "motajs-client",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-client/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-client-base",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "KeyCode",
|
||||
"link": "/api/motajs-client-base/KeyCode.md"
|
||||
},
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-client-base/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-common",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "Logger",
|
||||
"link": "/api/motajs-common/Logger.md"
|
||||
},
|
||||
{
|
||||
"text": "函数",
|
||||
"link": "/api/motajs-common/functions.md"
|
||||
},
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-common/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-legacy-client",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-legacy-client/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-legacy-common",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-legacy-common/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-legacy-system",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-legacy-system/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-legacy-ui",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-legacy-ui/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-render",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-render/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-render-core",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "Container",
|
||||
"link": "/api/motajs-render-core/Container.md"
|
||||
},
|
||||
{
|
||||
"text": "ContainerCustom",
|
||||
"link": "/api/motajs-render-core/ContainerCustom.md"
|
||||
},
|
||||
{
|
||||
"text": "Event",
|
||||
"link": "/api/motajs-render-core/Event.md"
|
||||
},
|
||||
{
|
||||
"text": "GL2",
|
||||
"link": "/api/motajs-render-core/GL2.md"
|
||||
},
|
||||
{
|
||||
"text": "GL2Program",
|
||||
"link": "/api/motajs-render-core/GL2Program.md"
|
||||
},
|
||||
{
|
||||
"text": "MotaOffscreenCanvas2D",
|
||||
"link": "/api/motajs-render-core/MotaOffscreenCanvas2D.md"
|
||||
},
|
||||
{
|
||||
"text": "MotaRenderer",
|
||||
"link": "/api/motajs-render-core/MotaRenderer.md"
|
||||
},
|
||||
{
|
||||
"text": "RenderAdapter",
|
||||
"link": "/api/motajs-render-core/RenderAdapter.md"
|
||||
},
|
||||
{
|
||||
"text": "RenderItem",
|
||||
"link": "/api/motajs-render-core/RenderItem.md"
|
||||
},
|
||||
{
|
||||
"text": "Shader",
|
||||
"link": "/api/motajs-render-core/Shader.md"
|
||||
},
|
||||
{
|
||||
"text": "ShaderProgram",
|
||||
"link": "/api/motajs-render-core/ShaderProgram.md"
|
||||
},
|
||||
{
|
||||
"text": "Sprite",
|
||||
"link": "/api/motajs-render-core/Sprite.md"
|
||||
},
|
||||
{
|
||||
"text": "Transform",
|
||||
"link": "/api/motajs-render-core/Transform.md"
|
||||
},
|
||||
{
|
||||
"text": "函数",
|
||||
"link": "/api/motajs-render-core/functions.md"
|
||||
},
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-render-core/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-render-elements",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "BlockCacher",
|
||||
"link": "/api/motajs-render-elements/BlockCacher.md"
|
||||
},
|
||||
{
|
||||
"text": "Camera",
|
||||
"link": "/api/motajs-render-elements/Camera.md"
|
||||
},
|
||||
{
|
||||
"text": "CameraAnimation",
|
||||
"link": "/api/motajs-render-elements/CameraAnimation.md"
|
||||
},
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-render-elements/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-render-style",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-render-style/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-render-vue",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-render-vue/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-system",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-system/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-system-action",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-system-action/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-system-ui",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-system-ui/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "motajs-types",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/motajs-types/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "user-client-modules",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/user-client-modules/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "user-data-base",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/user-data-base/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "user-data-fallback",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/user-data-fallback/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "user-data-state",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/user-data-state/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "user-data-utils",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/user-data-utils/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "user-entry-client",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/user-entry-client/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "user-entry-data",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/user-entry-data/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "user-legacy-plugin-client",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/user-legacy-plugin-client/index.md"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "user-legacy-plugin-data",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "主页",
|
||||
"link": "/api/user-legacy-plugin-data/index.md"
|
||||
}
|
||||
]
|
||||
}
|
||||
] as DefaultTheme.SidebarItem[];
|
@ -1,5 +1,6 @@
|
||||
import { defineConfig } from 'vitepress';
|
||||
import { MermaidMarkdown, MermaidPlugin } from 'vitepress-plugin-mermaid';
|
||||
import api from './apiSidebar';
|
||||
|
||||
// https://vitepress.dev/reference/site-config
|
||||
export default defineConfig({
|
||||
@ -69,306 +70,7 @@ export default defineConfig({
|
||||
'/api/': [
|
||||
{
|
||||
text: 'API 列表',
|
||||
items: [
|
||||
{ text: '目录', link: '/api/' },
|
||||
{
|
||||
text: '@motajs/client',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: '主页', link: '/api/motajs-client/' }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/client-base',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/motajs-client-base/'
|
||||
},
|
||||
{
|
||||
text: 'KeyCode',
|
||||
link: '/api/motajs-client-base/KeyCode'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/common',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: '主页', link: '/api/motajs-common/' },
|
||||
{
|
||||
text: '函数',
|
||||
link: '/api/motajs-common/functions'
|
||||
},
|
||||
{
|
||||
text: 'Logger',
|
||||
link: '/api/motajs-common/Logger'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/legacy-client',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/motajs-legacy-client/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/legacy-common',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/motajs-legacy-common/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/legacy-system',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/motajs-legacy-system/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/legacy-ui',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: '主页', link: '/api/motajs-legacy-ui/' }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/render',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: '主页', link: '/api/motajs-render/' }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/render-core',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/motajs-render-core/'
|
||||
},
|
||||
{
|
||||
text: '函数',
|
||||
link: '/api/motajs-render-core/functions'
|
||||
},
|
||||
{
|
||||
text: '交互事件',
|
||||
link: '/api/motajs-render-core/Event'
|
||||
},
|
||||
{
|
||||
text: 'MotaOffscreenCanvas2D',
|
||||
link: '/api/motajs-render-core/MotaOffscreenCanvas2D'
|
||||
},
|
||||
{
|
||||
text: 'Transform',
|
||||
link: '/api/motajs-render-core/Transform'
|
||||
},
|
||||
{
|
||||
text: 'RenderItem',
|
||||
link: '/api/motajs-render-core/RenderItem'
|
||||
},
|
||||
{
|
||||
text: 'Container',
|
||||
link: '/api/motajs-render-core/Container'
|
||||
},
|
||||
{
|
||||
text: 'ContainerCustom',
|
||||
link: '/api/motajs-render-core/ContainerCustom'
|
||||
},
|
||||
{
|
||||
text: 'Sprite',
|
||||
link: '/api/motajs-render-core/Sprite'
|
||||
},
|
||||
{
|
||||
text: 'MotaRenderer',
|
||||
link: '/api/motajs-render-core/MotaRenderer'
|
||||
},
|
||||
{
|
||||
text: 'GL2',
|
||||
link: '/api/motajs-render-core/GL2'
|
||||
},
|
||||
{
|
||||
text: 'GL2Program',
|
||||
link: '/api/motajs-render-core/GL2Program'
|
||||
},
|
||||
{
|
||||
text: 'RenderAdapter',
|
||||
link: '/api/motajs-render-core/RenderAdapter'
|
||||
},
|
||||
{
|
||||
text: 'Shader',
|
||||
link: '/api/motajs-render-core/Shader'
|
||||
},
|
||||
{
|
||||
text: 'ShaderProgram',
|
||||
link: '/api/motajs-render-core/ShaderProgram'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/render-elements',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/motajs-render-elements/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/render-style',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/motajs-render-style/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/render-vue',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/motajs-render-vue/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/system',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: '主页', link: '/api/motajs-system/' }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/system-action',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/motajs-system-action/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/system-ui',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: '主页', link: '/api/motajs-system-ui/' }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@motajs/types',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: '主页', link: '/api/motajs-types/' }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@user/client-modules',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/user-client-modules/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@user/data-base',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/user-data-base/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@user/data-fallback',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/user-data-fallback/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@user/data-state',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/user-data-state/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@user/data-utils',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/user-data-utils/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@user/entry-client',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/user-entry-client/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@user/entry-data',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/user-entry-data/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@user/legacy-plugin-client',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/user-legacy-plugin-client/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '@user/legacy-plugin-data',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: '主页',
|
||||
link: '/api/user-legacy-plugin-data/'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
items: api
|
||||
}
|
||||
]
|
||||
},
|
||||
|
367
docs/api/motajs-render-elements/BlockCacher.md
Normal file
367
docs/api/motajs-render-elements/BlockCacher.md
Normal file
@ -0,0 +1,367 @@
|
||||
# BlockCacher API 文档
|
||||
|
||||
本文档由 `DeepSeek R1` 模型生成并微调。
|
||||
|
||||
---
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
BlockCacher --> 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();
|
||||
```
|
384
docs/api/motajs-render-elements/Camera.md
Normal file
384
docs/api/motajs-render-elements/Camera.md
Normal file
@ -0,0 +1,384 @@
|
||||
# Camera API 文档
|
||||
|
||||
本文档由 `DeepSeek R1` 模型生成并微调。
|
||||
|
||||
---
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
Camera --> 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; // 纵向缩放比
|
||||
}
|
||||
```
|
199
docs/api/motajs-render-elements/CameraAnimation.md
Normal file
199
docs/api/motajs-render-elements/CameraAnimation.md
Normal file
@ -0,0 +1,199 @@
|
||||
# CameraAnimation API 文档
|
||||
|
||||
本文档由 `DeepSeek R1` 模型生成并微调。
|
||||
|
||||
---
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
CameraAnimation --> 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;
|
||||
```
|
@ -14,7 +14,7 @@
|
||||
"lines": "tsx script/lines.ts packages packages-user",
|
||||
"build:packages": "vue-tsx --noEmit && tsx script/build-packages.ts",
|
||||
"build:game": "vue-tsx --noEmit && tsx script/build-game.ts",
|
||||
"docs:dev": "vitepress dev docs",
|
||||
"docs:dev": "concurrently -k -n 'SIDEBAR,VITEPRESS' -c 'blue,green' \"tsx docs/.vitepress/api.ts\" \"vitepress dev docs\"",
|
||||
"docs:build": "vitepress build docs",
|
||||
"docs:preview": "vitepress preview docs"
|
||||
},
|
||||
@ -59,6 +59,7 @@
|
||||
"@vitejs/plugin-vue-jsx": "^4.1.2",
|
||||
"chokidar": "^3.6.0",
|
||||
"compressing": "^1.10.1",
|
||||
"concurrently": "^9.1.2",
|
||||
"eslint": "^9.22.0",
|
||||
"eslint-plugin-prettier": "^5.2.3",
|
||||
"eslint-plugin-vue": "^9.33.0",
|
||||
|
@ -137,7 +137,7 @@ export class BlockCacher<
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空指定索引的缓存,与 {@link clearCache} 不同的是,这里会直接清空对应索引的缓存,而不是指定分块的缓存(分块->void)
|
||||
* 清空指定索引的缓存,与 {@link clearCache} 不同的是,这里会直接清空对应索引的缓存,而不是指定分块的缓存(元素->void)
|
||||
*/
|
||||
clearCacheByIndex(index: number) {
|
||||
const item = this.cache.get(index);
|
||||
@ -303,10 +303,7 @@ export interface ICanvasCacheItem extends IBlockCacheable {
|
||||
}
|
||||
|
||||
export class CanvasCacheItem implements ICanvasCacheItem {
|
||||
constructor(
|
||||
public canvas: MotaOffscreenCanvas2D,
|
||||
public symbol: number
|
||||
) {}
|
||||
constructor(public canvas: MotaOffscreenCanvas2D, public symbol: number) {}
|
||||
|
||||
destroy(): void {
|
||||
this.canvas.delete();
|
||||
|
@ -80,7 +80,7 @@ export class Camera extends EventEmitter<CameraEvent> {
|
||||
});
|
||||
|
||||
const ca = Camera.cameraMap.get(item);
|
||||
if (ca && !ca.enabled) {
|
||||
if (ca && ca.enabled) {
|
||||
logger.warn(22);
|
||||
}
|
||||
}
|
||||
@ -371,40 +371,40 @@ interface CameraAnimationBase {
|
||||
start: number;
|
||||
}
|
||||
|
||||
interface TranslateAnimation extends CameraAnimationBase {
|
||||
export interface TranslateAnimation extends CameraAnimationBase {
|
||||
type: 'translate';
|
||||
timing: TimingFn;
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
interface TranslateAsAnimation extends CameraAnimationBase {
|
||||
export interface TranslateAsAnimation extends CameraAnimationBase {
|
||||
type: 'translateAs';
|
||||
timing: TimingFn<2>;
|
||||
time: number;
|
||||
}
|
||||
|
||||
interface RotateAnimation extends CameraAnimationBase {
|
||||
export interface RotateAnimation extends CameraAnimationBase {
|
||||
type: 'rotate';
|
||||
timing: TimingFn;
|
||||
angle: number;
|
||||
time: number;
|
||||
}
|
||||
|
||||
interface ScaleAnimation extends CameraAnimationBase {
|
||||
export interface ScaleAnimation extends CameraAnimationBase {
|
||||
type: 'scale';
|
||||
timing: TimingFn;
|
||||
scale: number;
|
||||
time: number;
|
||||
}
|
||||
|
||||
type CameraAnimationData =
|
||||
export type CameraAnimationData =
|
||||
| TranslateAnimation
|
||||
| TranslateAsAnimation
|
||||
| RotateAnimation
|
||||
| ScaleAnimation;
|
||||
|
||||
interface CameraAnimationExecution {
|
||||
export interface CameraAnimationExecution {
|
||||
data: CameraAnimationData[];
|
||||
animation: Animation;
|
||||
}
|
||||
|
@ -123,6 +123,9 @@ importers:
|
||||
compressing:
|
||||
specifier: ^1.10.1
|
||||
version: 1.10.1
|
||||
concurrently:
|
||||
specifier: ^9.1.2
|
||||
version: 9.1.2
|
||||
eslint:
|
||||
specifier: ^9.22.0
|
||||
version: 9.22.0
|
||||
@ -2831,6 +2834,10 @@ packages:
|
||||
resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
cliui@8.0.1:
|
||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
clone-buffer@1.0.0:
|
||||
resolution: {integrity: sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==}
|
||||
engines: {node: '>= 0.10'}
|
||||
@ -2922,6 +2929,11 @@ packages:
|
||||
resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==}
|
||||
engines: {'0': node >= 6.0}
|
||||
|
||||
concurrently@9.1.2:
|
||||
resolution: {integrity: sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
confbox@0.1.8:
|
||||
resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
|
||||
|
||||
@ -3634,6 +3646,10 @@ packages:
|
||||
resolution: {integrity: sha512-MtjsmYiCXcYDDrGqtNbeIYdAl85n+5mSv2r3FbzER/YV3ZILw4HNNIw34HuV5pyl0jzs6GFYU1VHVEefhgcNHQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
get-caller-file@2.0.5:
|
||||
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
|
||||
engines: {node: 6.* || 8.* || >= 10.*}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -4920,6 +4936,10 @@ packages:
|
||||
resolution: {integrity: sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
require-from-string@2.0.2:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -4998,6 +5018,9 @@ packages:
|
||||
rw@1.3.3:
|
||||
resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==}
|
||||
|
||||
rxjs@7.8.2:
|
||||
resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
|
||||
|
||||
safe-buffer@5.1.2:
|
||||
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
|
||||
|
||||
@ -5063,6 +5086,10 @@ packages:
|
||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
shell-quote@1.8.2:
|
||||
resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
shiki@2.5.0:
|
||||
resolution: {integrity: sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==}
|
||||
|
||||
@ -5291,6 +5318,10 @@ packages:
|
||||
tr46@0.0.3:
|
||||
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||
|
||||
tree-kill@1.2.2:
|
||||
resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
|
||||
hasBin: true
|
||||
|
||||
trim-lines@3.0.1:
|
||||
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
|
||||
|
||||
@ -5710,6 +5741,10 @@ packages:
|
||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
||||
engines: {node: '>=0.4'}
|
||||
|
||||
y18n@5.0.8:
|
||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
yallist@3.1.1:
|
||||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
||||
|
||||
@ -5720,6 +5755,14 @@ packages:
|
||||
resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
yargs-parser@21.1.1:
|
||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yargs@17.7.2:
|
||||
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yazl@2.5.1:
|
||||
resolution: {integrity: sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==}
|
||||
|
||||
@ -8300,6 +8343,12 @@ snapshots:
|
||||
|
||||
cli-spinners@2.9.2: {}
|
||||
|
||||
cliui@8.0.1:
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 7.0.0
|
||||
|
||||
clone-buffer@1.0.0: {}
|
||||
|
||||
clone-stats@0.0.1: {}
|
||||
@ -8377,6 +8426,16 @@ snapshots:
|
||||
readable-stream: 3.6.2
|
||||
typedarray: 0.0.6
|
||||
|
||||
concurrently@9.1.2:
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
lodash: 4.17.21
|
||||
rxjs: 7.8.2
|
||||
shell-quote: 1.8.2
|
||||
supports-color: 8.1.1
|
||||
tree-kill: 1.2.2
|
||||
yargs: 17.7.2
|
||||
|
||||
confbox@0.1.8: {}
|
||||
|
||||
confbox@0.2.1: {}
|
||||
@ -9210,6 +9269,8 @@ snapshots:
|
||||
ast-module-types: 6.0.1
|
||||
node-source-walk: 7.0.1
|
||||
|
||||
get-caller-file@2.0.5: {}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
@ -10620,6 +10681,8 @@ snapshots:
|
||||
|
||||
replace-ext@2.0.0: {}
|
||||
|
||||
require-directory@2.1.1: {}
|
||||
|
||||
require-from-string@2.0.2: {}
|
||||
|
||||
requirejs-config-file@4.0.0:
|
||||
@ -10706,6 +10769,10 @@ snapshots:
|
||||
|
||||
rw@1.3.3: {}
|
||||
|
||||
rxjs@7.8.2:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
safe-buffer@5.1.2: {}
|
||||
|
||||
safe-buffer@5.2.1: {}
|
||||
@ -10761,6 +10828,8 @@ snapshots:
|
||||
|
||||
shebang-regex@3.0.0: {}
|
||||
|
||||
shell-quote@1.8.2: {}
|
||||
|
||||
shiki@2.5.0:
|
||||
dependencies:
|
||||
'@shikijs/core': 2.5.0
|
||||
@ -10998,6 +11067,8 @@ snapshots:
|
||||
|
||||
tr46@0.0.3: {}
|
||||
|
||||
tree-kill@1.2.2: {}
|
||||
|
||||
trim-lines@3.0.1: {}
|
||||
|
||||
trim-newlines@4.1.1: {}
|
||||
@ -11441,12 +11512,26 @@ snapshots:
|
||||
|
||||
xtend@4.0.2: {}
|
||||
|
||||
y18n@5.0.8: {}
|
||||
|
||||
yallist@3.1.1: {}
|
||||
|
||||
yallist@4.0.0: {}
|
||||
|
||||
yargs-parser@20.2.9: {}
|
||||
|
||||
yargs-parser@21.1.1: {}
|
||||
|
||||
yargs@17.7.2:
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
escalade: 3.2.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 21.1.1
|
||||
|
||||
yazl@2.5.1:
|
||||
dependencies:
|
||||
buffer-crc32: 0.2.13
|
||||
|
Loading…
Reference in New Issue
Block a user