docs: @motajs/render 的大部分文档

This commit is contained in:
unanmed 2025-03-31 23:19:55 +08:00
parent 4343da6fe0
commit 0df879298e
38 changed files with 2798 additions and 17 deletions

View File

@ -45,7 +45,7 @@ function generateSidebar(): void {
items.sort((a, b) => {
const titleA = a.text ?? '';
const titleB = b.text ?? '';
return (weight[titleA] ?? 0) - (weight[titleB] ?? 0);
return (weight[titleB] ?? 0) - (weight[titleA] ?? 0);
});
sidebar.push({

View File

@ -9,6 +9,9 @@
```mermaid
graph LR
Container --> RenderItem --> EventEmitter
click RenderItem "./RenderItem"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
## 属性说明

View File

@ -9,6 +9,10 @@
```mermaid
graph LR
ContainerCustom --> Container --> RenderItem --> EventEmitter
click Container "./Container"
click RenderItem "./RenderItem"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---

View File

@ -8,8 +8,10 @@
```mermaid
graph LR
EventEmitter --> RenderItem
RenderItem --> GL2
GL2 --> RenderItem --> EventEmitter
click RenderItem "./RenderItem"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---

View File

@ -11,6 +11,8 @@
```mermaid
graph LR
GL2Program --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---

View File

@ -9,6 +9,8 @@
```mermaid
graph LR
MotaOffscreenCanvas2D --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---

View File

@ -8,9 +8,11 @@
```mermaid
graph LR
EventEmitter --> RenderItem
RenderItem --> Container
Container --> MotaRenderer
MotaRenderer --> Container --> RenderItem --> EventEmitter
click Container "./Container"
click RenderItem "./RenderItem"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---

View File

@ -6,7 +6,7 @@
```mermaid
graph LR
RenderAdapter --> 无继承关系
RenderAdapter --> 无继承关系
```
_RenderAdapter 为独立类无父类或子类。_

View File

@ -11,6 +11,8 @@
```mermaid
graph LR
RenderItem --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---

View File

@ -3,6 +3,10 @@
```mermaid
graph LR
Shader --> GL2 --> RenderItem --> EventEmitter
click GL2 "./GL2"
click RenderItem "./RenderItem"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
用法同 [GL2](./GL2.md)

View File

@ -3,6 +3,9 @@
```mermaid
graph LR
ShaderProgram --> GL2Program --> EventEmitter
click GL2Program "./GL2Program"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
用法同 [GL2Program](./GL2Program.md)

View File

@ -9,6 +9,9 @@
```mermaid
graph LR
Sprite --> RenderItem --> EventEmitter
click RenderItem "./RenderItem"
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---

View File

@ -9,6 +9,8 @@
```mermaid
graph LR
Transform --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
---

View File

@ -6,7 +6,9 @@
```mermaid
graph LR
BlockCacher --> EventEmitter
BlockCacher --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
_继承自 `EventEmitter<BlockCacherEvent>`支持事件监听。_

View File

@ -6,7 +6,9 @@
```mermaid
graph LR
Camera --> EventEmitter
Camera --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
_继承自 `EventEmitter<CameraEvent>`支持事件监听。_

View File

@ -6,7 +6,9 @@
```mermaid
graph LR
CameraAnimation --> EventEmitter
CameraAnimation --> EventEmitter
click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter"
```
_继承自 `EventEmitter<CameraAnimationEvent>`支持事件监听。_

View 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
});
```

View 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)

View 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` 属性来启用缓存,避免频繁的复杂图形绘制。

View 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 设计,不可用于其他框架环境

View 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可能触发浏览器纹理限制

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

View 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} .../>
```

View 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)
/>
```

View 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
/>
```

View 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>
```

View 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(); // 关键闭合操作
```

View 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} .../>
```

View 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. 在描边层上填充浅紫色
**视觉效果**:描边被填充色覆盖一部分

View 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%
/>
```

View 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 开始播放 |

View 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 等) |

View 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` 中循环更新自身

View 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`

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

View File

@ -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": "concurrently -k -n 'SIDEBAR,VITEPRESS' -c 'blue,green' \"tsx docs/.vitepress/api.ts\" \"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"
},

View File

@ -54,8 +54,8 @@ export class Font implements IFontConfig {
}
/**
* 使
* @param fallback
* 使
* @param fallback
*/
addFallback(...fallback: Font[]) {
this.fallbacks.push(...fallback);
@ -63,9 +63,9 @@ export class Font implements IFontConfig {
}
private build() {
return `${
this.italic ? 'italic ' : ''
} ${this.weight} ${this.size}${this.sizeUnit} ${this.family}`;
return `${this.italic ? 'italic ' : ''} ${this.weight} ${this.size}${
this.sizeUnit
} ${this.family}`;
}
private getFallbackFont(used: Set<Font>) {

View File

@ -194,7 +194,7 @@ export interface EllipseProps extends GraphicPropsBase {
end?: number;
/**
* `[圆心 x 坐标,圆心 y 坐标x半径y半径起始角度终止角度]` x, y, radiusX, radiusY, start, end
*
*
*/
ellipse?: EllipseParams;
}