From 7fef0df1e69df259c32ac726ce1a71c0f383cf13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=20=E5=81=A5=E8=B5=9F?= <923596930@qq.com> Date: Tue, 23 Sep 2025 11:22:49 +0800 Subject: [PATCH] =?UTF-8?q?docs=EF=BC=9Arender/components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client-modules/src/action/move.ts | 17 +++++++++++ .../src/render/components/choices.tsx | 28 +++++++++++++++++++ .../src/render/components/input.tsx | 23 +++++++++++++++ .../src/render/components/scroll.tsx | 1 + .../src/render/components/textbox.tsx | 10 +++++++ .../src/render/components/textboxTyper.ts | 5 ++++ .../src/render/components/thumbnail.tsx | 5 ++++ .../src/render/components/tip.tsx | 4 +++ pnpm-lock.yaml | 2 ++ 9 files changed, 95 insertions(+) diff --git a/packages-user/client-modules/src/action/move.ts b/packages-user/client-modules/src/action/move.ts index 7e97704..49372b4 100644 --- a/packages-user/client-modules/src/action/move.ts +++ b/packages-user/client-modules/src/action/move.ts @@ -44,6 +44,7 @@ export class HeroKeyMover { down: data[config?.down ?? 'moveDown'] }; + // 静止时尝试启动移动 this.ticker.add(() => { if (!this.moving) { if (this.pressedKey.size > 0) { @@ -56,6 +57,10 @@ export class HeroKeyMover { }); } + /** + * 按键移动 + * @param code 按键码 + */ private onPressKey = (code: KeyCode) => { if (core.isReplaying() || !core.isPlaying()) return; core.waitHeroToStop(); @@ -65,6 +70,10 @@ export class HeroKeyMover { else if (code === this.hotkeyData.down.key) this.press('down'); }; + /** + * 释放按键 + * @param code 按键码 + */ private onReleaseKey = (code: KeyCode) => { if (code === this.hotkeyData.left.key) this.release('left'); else if (code === this.hotkeyData.right.key) this.release('right'); @@ -135,18 +144,26 @@ export class HeroKeyMover { this.controller?.stop(); } + /** + * 移动结束 + */ private onStepEnd = () => { const con = this.controller; if (!con) return; + + // 被禁止操作时 if (core.status.lockControl) { con.stop(); return; } + + // 未移动时 if (!this.moving) { con.stop(); return; } + // 尝试移动 if (this.pressedKey.size > 0) { if (con.queue.length === 0) { con.push({ type: 'dir', value: this.moveDir }); diff --git a/packages-user/client-modules/src/render/components/choices.tsx b/packages-user/client-modules/src/render/components/choices.tsx index 57459c9..32cc2f5 100644 --- a/packages-user/client-modules/src/render/components/choices.tsx +++ b/packages-user/client-modules/src/render/components/choices.tsx @@ -9,17 +9,29 @@ import { useKey } from '../use'; import { sleep } from 'mutate-animate'; export interface ConfirmBoxProps extends DefaultProps, TextContentProps { + /** 确认框的提示文本内容 */ text: string; + /** 确认框对话框的宽度 */ width: number; + /** 确认框对话框的位置 */ loc: ElementLocator; + /** 确认/取消按钮的字体样式 */ selFont?: Font; + /** 确认/取消按钮的文本颜色 */ selFill?: CanvasStyle; + /** 对话框内部所有元素的内边距 */ pad?: number; + /** 确认按钮的显示文本,默认为"确认" */ yesText?: string; + /** 取消按钮的显示文本,默认为"取消" */ noText?: string; + /** 窗口皮肤图片ID,用于对话框背景绘制 */ winskin?: ImageIds; + /** 是否默认选中确认按钮 */ defaultYes?: boolean; + /** 对话框背景颜色,当未设置 winskin 时生效 */ color?: CanvasStyle; + /** 对话框边框颜色,当未设置 winskin 时生效 */ border?: CanvasStyle; } @@ -198,21 +210,37 @@ export type ChoiceItem = [ ]; export interface ChoicesProps extends DefaultProps, TextContentProps { + /** 选项数组 */ choices: ChoiceItem[]; + /** 选择框对话框的位置 */ loc: ElementLocator; + /** 选择框对话框的宽度 */ width: number; + /** 选择框的最大高度,超过时将分页显示 */ maxHeight?: number; + /** 选择框的提示文本内容 */ text?: string; + /** 选择框的标题文本 */ title?: string; + /** 窗口皮肤图片ID,用于对话框背景绘制 */ winskin?: ImageIds; + /** 对话框背景颜色,当未设置 winskin 时生效 */ color?: CanvasStyle; + /** 对话框边框颜色,当未设置 winskin 时生效 */ border?: CanvasStyle; + /** 选项文本的字体样式 */ selFont?: Font; + /** 选项文本的颜色 */ selFill?: CanvasStyle; + /** 标题文本的字体样式 */ titleFont?: Font; + /** 标题文本的颜色 */ titleFill?: CanvasStyle; + /** 对话框内部所有元素的内边距 */ pad?: number; + /** 选项之间的垂直间隔 */ interval?: number; + /** 默认选中的选项索引 */ selected?: number; } diff --git a/packages-user/client-modules/src/render/components/input.tsx b/packages-user/client-modules/src/render/components/input.tsx index 42c822f..68e1eca 100644 --- a/packages-user/client-modules/src/render/components/input.tsx +++ b/packages-user/client-modules/src/render/components/input.tsx @@ -146,6 +146,7 @@ export const Input = defineComponent( const renderer = MotaRenderer.get('render-main'); const canvas = renderer?.getCanvas(); if (!canvas) return; + const chain: RenderItem[] = []; let now: RenderItem | undefined = root.value; if (!now) return; @@ -153,6 +154,8 @@ export const Input = defineComponent( chain.unshift(now); now = now.parent; } + + // 应用内边距偏移. const { clientLeft, clientTop } = canvas; const trans = new Transform(); trans.translate(clientLeft, clientTop); @@ -163,8 +166,11 @@ export const Input = defineComponent( trans.multiply(item.transform); } trans.translate(padding.value, padding.value); + + // 构建CSS transform的matrix字符串 const [a, b, , c, d, , e, f] = trans.mat; const str = `matrix(${a},${b},${c},${d},${e},${f})`; + const w = width.value * core.domStyle.scale; const h = height.value * core.domStyle.scale; const font = props.font ?? Font.defaults(); @@ -237,17 +243,29 @@ export const Input = defineComponent( ); export interface InputBoxProps extends TextContentProps { + /** 输入框对话框的位置 */ loc: ElementLocator; + /** 传递给内部 Input 组件的配置参数,用于自定义输入行为 */ input?: InputProps; + /** 窗口皮肤图片ID,用于对话框背景绘制 */ winskin?: ImageIds; + /** 对话框背景颜色,当未设置 winskin 时生效 */ color?: CanvasStyle; + /** 对话框边框颜色,当未设置 winskin 时生效 */ border?: CanvasStyle; + /** 对话框内部所有元素的内边距 */ pad?: number; + /** 内部输入框区域的高度 */ inputHeight?: number; + /** 对话框顶部的提示文本 */ text?: string; + /** 确认按钮的显示文本,默认为"确认" */ yesText?: string; + /** 取消按钮的显示文本,默认为"取消" */ noText?: string; + /** 确认/取消按钮的字体样式 */ selFont?: Font; + /** 确认/取消按钮的文本颜色 */ selFill?: CanvasStyle; } @@ -505,6 +523,11 @@ export function getInput( /** * 与 `getInput` 类似,不过会将结果转为数字。用法参考 {@link getInput} + * @param controller UI 控制器 + * @param text 确认文本内容 + * @param loc 确认框的位置 + * @param width 确认框的宽度 + * @param props 额外的 props,参考 {@link ConfirmBoxProps} */ export async function getInputNumber( controller: IUIMountable, diff --git a/packages-user/client-modules/src/render/components/scroll.tsx b/packages-user/client-modules/src/render/components/scroll.tsx index 00c522e..cf684a8 100644 --- a/packages-user/client-modules/src/render/components/scroll.tsx +++ b/packages-user/client-modules/src/render/components/scroll.tsx @@ -54,6 +54,7 @@ export interface ScrollExpose { export interface ScrollProps extends DefaultProps { loc: ElementLocator; hor?: boolean; + /** 是否不允许滚动 */ noscroll?: boolean; /** * 滚动到最下方(最右方)时的填充大小,如果默认的高度计算方式有误, diff --git a/packages-user/client-modules/src/render/components/textbox.tsx b/packages-user/client-modules/src/render/components/textbox.tsx index da6bb6f..8557899 100644 --- a/packages-user/client-modules/src/render/components/textbox.tsx +++ b/packages-user/client-modules/src/render/components/textbox.tsx @@ -500,18 +500,28 @@ export const Textbox = defineComponent< }, textboxOptions); interface TextboxStoreEmits { + /** 结束打字机动画的回调函数 */ endType: () => void; + /** 隐藏文本框的回调函数 */ hide: () => void; + /** 显示文本框的回调函数 */ show: () => void; + /** 更新文本框配置的回调函数 */ update: (value: TextboxProps) => void; + /** 设置显示文本的回调函数 */ setText: (text: string) => void; } interface TextboxStoreEvent { + /** 文本框配置更新事件,传递更新后的配置值 */ update: [value: TextboxProps]; + /** 文本框显示事件 */ show: []; + /** 文本框隐藏事件 */ hide: []; + /** 打字机开始打字事件 */ typeStart: []; + /** 打字机结束打字事件 */ typeEnd: []; } diff --git a/packages-user/client-modules/src/render/components/textboxTyper.ts b/packages-user/client-modules/src/render/components/textboxTyper.ts index 36fee77..4d00417 100644 --- a/packages-user/client-modules/src/render/components/textboxTyper.ts +++ b/packages-user/client-modules/src/render/components/textboxTyper.ts @@ -75,10 +75,15 @@ interface TyperConfig extends ITextContentConfig { } interface ParserStatus { + /** 画布填充描边样式 */ fillStyle: CanvasStyle; + /** 描边样式 */ fontFamily: string; + /** 字体大小 */ fontSize: number; + /** 是否斜体 */ fontItalic: boolean; + /** 字体粗细 */ fontWeight: number; } diff --git a/packages-user/client-modules/src/render/components/thumbnail.tsx b/packages-user/client-modules/src/render/components/thumbnail.tsx index d850ef6..00312ca 100644 --- a/packages-user/client-modules/src/render/components/thumbnail.tsx +++ b/packages-user/client-modules/src/render/components/thumbnail.tsx @@ -8,10 +8,15 @@ import { defineComponent, ref, watch } from 'vue'; import { SetupComponentOptions } from '@motajs/system-ui'; export interface ThumbnailProps extends SpriteProps { + /** 缩略图的位置 */ loc: ElementLocator; + /** 楼层 ID */ floorId: FloorIds; + /** 缩略图填充样式 */ padStyle?: CanvasStyle; + /** 楼层信息 */ map?: Block[]; + /** 角色信息 */ hero?: HeroStatus; // configs damage?: boolean; diff --git a/packages-user/client-modules/src/render/components/tip.tsx b/packages-user/client-modules/src/render/components/tip.tsx index 97310eb..d5c5eaa 100644 --- a/packages-user/client-modules/src/render/components/tip.tsx +++ b/packages-user/client-modules/src/render/components/tip.tsx @@ -8,9 +8,13 @@ import { texture } from '../elements'; import { SetupComponentOptions } from '@motajs/system-ui'; export interface TipProps extends DefaultProps { + /** 显示的位置 */ loc: ElementLocator; + /** 边距 */ pad?: [number, number]; + /** 圆角 */ corner?: number; + /** 显示的图标 */ id?: string; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 039eb06..5de67fd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -402,6 +402,8 @@ importers: packages-user/types: {} + packages/animate: {} + packages/client: dependencies: '@motajs/client-base':