初始化
This commit is contained in:
@@ -438,6 +438,13 @@ interface IBimComponent {
|
||||
- `button-group.md` - ButtonGroup 组件详细文档
|
||||
- `engine.md` - Engine 组件详细文档
|
||||
- `tab.md` - Tab 组件详细文档
|
||||
- `tree.md` - Tree 组件详细文档
|
||||
- `menu.md` - Menu 组件详细文档
|
||||
- `right-key.md` - RightKey 组件详细文档
|
||||
- `collapse.md` - Collapse 组件详细文档
|
||||
- `description.md` - Description 组件详细文档
|
||||
- `measure-panel.md` - MeasurePanel 组件详细文档
|
||||
- `walk-control-panel.md` - WalkControlPanel 组件详细文档
|
||||
|
||||
#### 文档内容结构
|
||||
每个组件文档包含以下部分:
|
||||
@@ -537,9 +544,10 @@ const dialog = engine.dialog.create({
|
||||
| `BimMenu` | `src/components/menu/index.ts` | 通用菜单列表 | `IBimComponent` |
|
||||
| `BimTree` | `src/components/tree/index.ts` | 通用树形组件 | `IBimComponent` |
|
||||
| `BimTab` | `src/components/tab/index.ts` | 固定标签页组件 | `IBimComponent` |
|
||||
| `BimCollapse` | `src/components/collapse/index.ts` | 折叠面板组件 | `IBimComponent` |
|
||||
| `BimDescription` | `src/components/description/index.ts` | 描述列表组件 (Key-Value) | `IBimComponent` |
|
||||
| `MeasurePanel` | `src/components/measure-panel/index.ts` | 测量面板组件(仅 UI) | `IBimComponent` |
|
||||
| `BimCollapse` | `src/components/collapse/index.ts` | 折叠面板组件 | `IBimComponent` |
|
||||
| `BimDescription` | `src/components/description/index.ts` | 描述列表组件 (Key-Value) | `IBimComponent` |
|
||||
| `MeasurePanel` | `src/components/measure-panel/index.ts` | 测量面板组件(仅 UI) | `IBimComponent` |
|
||||
| `WalkControlPanel` | `src/components/walk-control-panel/index.ts` | 漫游控制面板组件 | `IBimComponent` |
|
||||
|
||||
### 4.3 服务类清单
|
||||
|
||||
@@ -548,7 +556,20 @@ const dialog = engine.dialog.create({
|
||||
| `ThemeManager` | `src/services/theme.ts` | 主题管理 | 单例 |
|
||||
| `LocaleManager` | `src/services/locale.ts` | 语言管理 | 单例 |
|
||||
|
||||
### 4.4 事件总线定义
|
||||
### 4.4 工具类清单
|
||||
|
||||
| 工具名称 | 文件路径 | 功能 | 文档路径 |
|
||||
| -------------- | ---------------------------- | ------------------------------ | ----------------------------- |
|
||||
| `IconManager` | `src/utils/icon-manager.ts` | 统一管理所有 SVG 图标资源 | `docs/utils/icon-manager.md` |
|
||||
|
||||
**IconManager 说明**:
|
||||
- 提供 `getIcon(name: string): string` 函数
|
||||
- 所有组件通过该函数获取 SVG 图标字符串
|
||||
- 支持默认图标回退机制
|
||||
- 图标使用 `currentColor` 以支持主题颜色
|
||||
- 详细说明见 `docs/utils/icon-manager.md`
|
||||
|
||||
### 4.5 事件总线定义
|
||||
|
||||
#### 事件类型 (`EngineEvents`)
|
||||
|
||||
@@ -643,7 +664,7 @@ this.on('ui:open-dialog', (payload) => {
|
||||
});
|
||||
```
|
||||
|
||||
### 4.5 核心基类
|
||||
### 4.6 核心基类
|
||||
|
||||
| 类名 | 文件路径 | 功能 | 继承/实现 |
|
||||
| -------------- | --------------------------- | -------------- | ------------------- |
|
||||
@@ -653,9 +674,9 @@ this.on('ui:open-dialog', (payload) => {
|
||||
|
||||
---
|
||||
|
||||
## 4.6 国际化实现指南
|
||||
## 4.7 国际化实现指南
|
||||
|
||||
### 4.6.1 国际化的重要性
|
||||
### 4.7.1 国际化的重要性
|
||||
|
||||
**所有用户可见的文本都必须支持国际化,这是强制要求。**
|
||||
|
||||
@@ -663,7 +684,7 @@ this.on('ui:open-dialog', (payload) => {
|
||||
- 所有 UI 文本必须通过翻译函数获取
|
||||
- 严禁在代码中硬编码任何语言的文本
|
||||
|
||||
### 4.6.2 国际化实现方式
|
||||
### 4.7.2 国际化实现方式
|
||||
|
||||
#### 步骤 1: 在翻译字典中添加键值
|
||||
|
||||
@@ -758,7 +779,7 @@ export class MyComponent implements IBimComponent {
|
||||
}
|
||||
```
|
||||
|
||||
### 4.6.3 国际化注意事项
|
||||
### 4.7.3 国际化注意事项
|
||||
|
||||
#### ✅ 必须做的
|
||||
|
||||
@@ -831,7 +852,7 @@ export class MyComponent implements IBimComponent {
|
||||
- 组件必须响应语言切换
|
||||
- 不能只在初始化时设置文本
|
||||
|
||||
### 4.6.4 国际化最佳实践
|
||||
### 4.7.4 国际化最佳实践
|
||||
|
||||
#### 翻译键的组织结构
|
||||
|
||||
@@ -939,7 +960,7 @@ export class MyDialog implements IBimComponent {
|
||||
};
|
||||
```
|
||||
|
||||
### 4.6.5 国际化检查清单
|
||||
### 4.7.5 国际化检查清单
|
||||
|
||||
在开发新功能时,确保:
|
||||
|
||||
|
||||
594
docs/components/walk-control-panel.md
Normal file
594
docs/components/walk-control-panel.md
Normal file
@@ -0,0 +1,594 @@
|
||||
# WalkControlPanel 组件详细文档
|
||||
|
||||
> 本文档详细描述 WalkControlPanel 组件的实现细节,包括 API、UI 结构、逻辑流程等,供 AI 根据文档重现组件。
|
||||
|
||||
---
|
||||
|
||||
## 1. 组件概述
|
||||
|
||||
### 1.1 基本信息
|
||||
- **组件名称**: `WalkControlPanel`
|
||||
- **文件路径**: `src/components/walk-control-panel/index.ts`
|
||||
- **类型定义**: `src/components/walk-control-panel/types.ts`
|
||||
- **样式文件**: `src/components/walk-control-panel/index.css`
|
||||
- **实现接口**: `IBimComponent`
|
||||
- **用途**: 渲染漫游控制面板,提供平面图切换、路径漫游、人物漫游三种模式,以及速度、重力、碰撞、角色模型、行走模式等设置。
|
||||
- **特点**: 纯 UI 组件,通过回调函数通知外部状态变化,支持主题和国际化。
|
||||
|
||||
### 1.2 在 SDK 中的位置
|
||||
- WalkControlPanel 组件通常由 `WalkControlManager` 管理(如果存在)
|
||||
- 也可以单独实例化并挂载到任何容器中
|
||||
- 用于 3D 场景的漫游控制界面
|
||||
|
||||
---
|
||||
|
||||
## 2. 组件类 API 文档
|
||||
|
||||
### 2.1 构造函数
|
||||
|
||||
```typescript
|
||||
constructor(options: WalkControlPanelOptions = {})
|
||||
```
|
||||
|
||||
**参数**:
|
||||
- `options`: `WalkControlPanelOptions` - 漫游控制面板配置选项(可选)
|
||||
|
||||
**WalkControlPanelOptions 定义**:
|
||||
```typescript
|
||||
interface WalkControlPanelOptions {
|
||||
/** 平面图切换回调 */
|
||||
onPlanViewToggle?: (isActive: boolean) => void;
|
||||
/** 路径漫游模式切换回调 */
|
||||
onPathModeToggle?: (isActive: boolean) => void;
|
||||
/** 漫游模式切换回调 */
|
||||
onWalkModeToggle?: (isActive: boolean) => void;
|
||||
/** 速度变化回调 */
|
||||
onSpeedChange?: (speed: number) => void;
|
||||
/** 重力切换回调 */
|
||||
onGravityToggle?: (enabled: boolean) => void;
|
||||
/** 碰撞切换回调 */
|
||||
onCollisionToggle?: (enabled: boolean) => void;
|
||||
/** 角色模型变化回调 */
|
||||
onCharacterModelChange?: (model: CharacterModel) => void;
|
||||
/** 行走模式变化回调 */
|
||||
onWalkModeChange?: (mode: WalkMode) => void;
|
||||
/** 退出回调 */
|
||||
onExit?: () => void;
|
||||
|
||||
/** 默认速度 (1-10) */
|
||||
defaultSpeed?: number;
|
||||
/** 默认重力状态 */
|
||||
defaultGravity?: boolean;
|
||||
/** 默认碰撞状态 */
|
||||
defaultCollision?: boolean;
|
||||
/** 默认角色模型 */
|
||||
defaultCharacterModel?: CharacterModel;
|
||||
/** 默认行走模式 */
|
||||
defaultWalkMode?: WalkMode;
|
||||
}
|
||||
```
|
||||
|
||||
**行为**:
|
||||
- 创建面板 DOM 结构
|
||||
- 保存配置选项
|
||||
- 初始化状态
|
||||
|
||||
### 2.2 公共方法
|
||||
|
||||
#### `init(): void`
|
||||
初始化组件(实现 `IBimComponent` 接口)
|
||||
|
||||
**功能**:
|
||||
- 创建并渲染 DOM 结构
|
||||
- 订阅语言变更:`localeManager.subscribe()`
|
||||
- 订阅主题变更:`themeManager.subscribe()`
|
||||
- 更新初始视图状态
|
||||
|
||||
#### `setTheme(theme: ThemeConfig): void`
|
||||
设置主题(实现 `IBimComponent` 接口)
|
||||
|
||||
**参数**:
|
||||
- `theme`: `ThemeConfig`
|
||||
|
||||
**功能**:
|
||||
- 将主题颜色映射到 CSS 变量:
|
||||
- `--bim-walk-control-bg` ← `theme.panelBackground`
|
||||
- `--bim-walk-btn-hover` ← `theme.componentHover`
|
||||
- `--bim-walk-btn-active` ← `theme.componentActive`
|
||||
- `--bim-primary-color` ← `theme.primary`
|
||||
- `--bim-primary-hover` ← `theme.primaryHover`
|
||||
- `--bim-icon-color` ← `theme.icon`
|
||||
- `--bim-text-color` ← `theme.textPrimary`
|
||||
- `--bim-divider-color` ← `theme.border`
|
||||
- 以及其他速度控制、下拉框相关的主题变量
|
||||
|
||||
#### `setLocales(): void`
|
||||
设置语言(实现 `IBimComponent` 接口)
|
||||
|
||||
**功能**:
|
||||
- 更新速度标签文本:`t('walkControl.speed')`
|
||||
- 更新复选框标签:`t('walkControl.gravity')`, `t('walkControl.collision')`
|
||||
- 更新角色模型下拉框选项和标签
|
||||
- 更新行走模式下拉框选项和标签
|
||||
- 更新退出按钮文本:`t('walkControl.exit')`
|
||||
|
||||
#### `destroy(): void`
|
||||
销毁组件(实现 `IBimComponent` 接口)
|
||||
|
||||
**功能**:
|
||||
- 取消语言和主题订阅
|
||||
- 从 DOM 中移除自身元素
|
||||
|
||||
#### `setPlanViewActive(active: boolean): void`
|
||||
设置平面图按钮激活状态
|
||||
|
||||
**参数**:
|
||||
- `active`: boolean - 是否激活
|
||||
|
||||
**功能**:
|
||||
- 更新内部状态
|
||||
- 更新按钮视觉状态
|
||||
|
||||
#### `setPathModeActive(active: boolean): void`
|
||||
设置路径模式按钮激活状态
|
||||
|
||||
**参数**:
|
||||
- `active`: boolean - 是否激活
|
||||
|
||||
**功能**:
|
||||
- 更新模式状态
|
||||
- 更新按钮视觉状态
|
||||
- 路径模式激活时禁用重力和碰撞选项
|
||||
|
||||
#### `getState(): WalkControlState`
|
||||
获取当前状态
|
||||
|
||||
**返回**: `WalkControlState` - 当前控制面板状态的副本
|
||||
|
||||
---
|
||||
|
||||
## 3. 分化组件说明
|
||||
|
||||
**WalkControlPanel 没有子类或分化组件**。
|
||||
|
||||
---
|
||||
|
||||
## 4. Manager API 文档
|
||||
|
||||
目前 WalkControlPanel 没有专门的 Manager,通常由使用方直接创建和管理。
|
||||
未来可以创建 `WalkControlManager` 来统一管理该组件的实例。
|
||||
|
||||
---
|
||||
|
||||
## 5. UI 详细描述
|
||||
|
||||
### 5.1 DOM 结构
|
||||
|
||||
```html
|
||||
<div class="walk-control-panel">
|
||||
<!-- 左侧按钮区 -->
|
||||
<div class="walk-control-left">
|
||||
<button class="walk-icon-btn walk-icon-btn-plan-view [active]">
|
||||
[平面图 SVG图标]
|
||||
</button>
|
||||
<button class="walk-icon-btn walk-icon-btn-path [active]">
|
||||
[路径 SVG图标]
|
||||
</button>
|
||||
<button class="walk-icon-btn walk-icon-btn-walk [active]">
|
||||
[漫游 SVG图标]
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 分割线 -->
|
||||
<div class="walk-divider"></div>
|
||||
|
||||
<!-- 中间设置区 -->
|
||||
<div class="walk-control-settings">
|
||||
<!-- 速度控件(路径模式显示) -->
|
||||
<div class="walk-speed-control">
|
||||
<label class="walk-speed-label">速度</label>
|
||||
<div class="walk-speed-group">
|
||||
<button class="walk-speed-btn">-</button>
|
||||
<div class="walk-speed-display">1X</div>
|
||||
<button class="walk-speed-btn">+</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 角色模型选择(漫游模式显示) -->
|
||||
<div class="walk-select-wrapper walk-select-wrapper-character-model">
|
||||
<label class="walk-select-label">角色模型</label>
|
||||
<select class="walk-select walk-select-character-model">
|
||||
<option value="construction-worker">建筑工人</option>
|
||||
<option value="office-male">办公室男性</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- 行走模式选择(漫游模式显示) -->
|
||||
<div class="walk-select-wrapper walk-select-wrapper-walk-mode">
|
||||
<label class="walk-select-label">行走模式</label>
|
||||
<select class="walk-select walk-select-walk-mode">
|
||||
<option value="walk">行走</option>
|
||||
<option value="run">奔跑</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- 重力复选框 -->
|
||||
<label class="walk-checkbox-wrapper walk-checkbox-gravity">
|
||||
<input type="checkbox" class="walk-checkbox" [disabled]>
|
||||
<span class="walk-checkbox-label">重力</span>
|
||||
</label>
|
||||
|
||||
<!-- 碰撞复选框 -->
|
||||
<label class="walk-checkbox-wrapper walk-checkbox-collision">
|
||||
<input type="checkbox" class="walk-checkbox" [disabled]>
|
||||
<span class="walk-checkbox-label">碰撞</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- 分割线 -->
|
||||
<div class="walk-divider"></div>
|
||||
|
||||
<!-- 右侧退出按钮 -->
|
||||
<button class="walk-exit-btn">退出</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
### 5.2 CSS 类名和样式
|
||||
|
||||
#### `.walk-control-panel` (根容器)
|
||||
- `display: flex`, `align-items: center`
|
||||
- `gap: 20px`, `padding: 8px 16px`
|
||||
- `background`: `var(--bim-walk-control-bg)`
|
||||
- `border-radius: 8px`
|
||||
- `user-select: none`
|
||||
|
||||
#### `.walk-icon-btn` (左侧图标按钮)
|
||||
- `width: 48px`, `height: 48px`
|
||||
- `padding: 8px` (实际图标 32x32)
|
||||
- `display: flex`, `align-items: center`, `justify-content: center`
|
||||
- `background: transparent`
|
||||
- `border: 2px solid transparent`, `border-radius: 6px`
|
||||
- `cursor: pointer`, `transition: all 0.2s`
|
||||
- `color`: `var(--bim-icon-color)`
|
||||
|
||||
#### `.walk-icon-btn:hover`
|
||||
- `background`: `var(--bim-walk-btn-hover)`
|
||||
|
||||
#### `.walk-icon-btn.active`
|
||||
- `background`: `var(--bim-walk-btn-active)`
|
||||
|
||||
#### `.walk-icon-btn svg`
|
||||
- `width: 32px`, `height: 32px`
|
||||
|
||||
#### `.walk-divider` (分割线)
|
||||
- `width: 1px`, `height: 40px`
|
||||
- `background`: `var(--bim-divider-color)`
|
||||
- `flex-shrink: 0`
|
||||
|
||||
#### `.walk-speed-control` (速度控件)
|
||||
- `display: flex`, `align-items: center`, `gap: 12px`
|
||||
|
||||
#### `.walk-speed-btn` (速度按钮)
|
||||
- `width: 32px`, `height: 32px`
|
||||
- `background`: `var(--bim-speed-btn-bg)`
|
||||
- `border: none`, `border-radius: 4px`
|
||||
- `cursor: pointer`
|
||||
- `:disabled` 时 `opacity: 0.5`, `cursor: not-allowed`
|
||||
|
||||
#### `.walk-checkbox-wrapper` (复选框包装)
|
||||
- `display: flex`, `align-items: center`, `gap: 8px`
|
||||
- `cursor: pointer`
|
||||
|
||||
#### `.walk-select-wrapper` (下拉框包装)
|
||||
- `display: flex`, `align-items: center`, `gap: 8px`
|
||||
|
||||
#### `.walk-exit-btn` (退出按钮)
|
||||
- `padding: 10px 24px`
|
||||
- `background`: `var(--bim-primary-color)`
|
||||
- `border: none`, `border-radius: 6px`
|
||||
- `color: #fff`, `font-size: 14px`, `font-weight: 600`
|
||||
- `cursor: pointer`, `transition: all 0.2s`
|
||||
|
||||
---
|
||||
|
||||
## 6. 逻辑流程详细描述
|
||||
|
||||
### 6.1 初始化流程 (`init`)
|
||||
|
||||
1. **创建面板**(`createPanel`):
|
||||
- 创建根容器 `.walk-control-panel`
|
||||
- 创建左侧按钮区(`createLeftButtons`)
|
||||
- 创建中间设置区(`createSettingsContainer`)
|
||||
- 创建右侧退出按钮(`createExitButton`)
|
||||
- 组装各部分并添加分割线
|
||||
|
||||
2. **订阅变更**:
|
||||
- 订阅语言变更:`localeManager.subscribe(() => this.setLocales())`
|
||||
- 订阅主题变更:`themeManager.subscribe((theme) => this.setTheme(theme))`
|
||||
|
||||
3. **初始设置**:
|
||||
- 调用 `setLocales()` 设置初始文本
|
||||
- 调用 `setTheme()` 应用当前主题
|
||||
- 调用 `updateSettingsView()` 根据初始模式显示/隐藏控件
|
||||
|
||||
### 6.2 模式切换流程
|
||||
|
||||
#### 模式类型
|
||||
- `'none'`: 无模式
|
||||
- `'path'`: 路径漫游模式
|
||||
- `'walk'`: 人物漫游模式
|
||||
|
||||
#### 模式切换逻辑 (`setMode`)
|
||||
1. **保存旧模式**:用于触发关闭事件
|
||||
|
||||
2. **触发旧模式关闭事件**:
|
||||
- 如果从 `'walk'` 切换出去,触发 `onWalkModeToggle(false)`
|
||||
- 如果从 `'path'` 切换出去,触发 `onPathModeToggle(false)`
|
||||
|
||||
3. **更新模式状态**:`this.state.mode = newMode`
|
||||
|
||||
4. **特殊处理**:
|
||||
- 路径模式时:禁用重力和碰撞复选框,并设置为 false
|
||||
- 其他模式:启用重力和碰撞复选框
|
||||
|
||||
5. **更新视图**:
|
||||
- `updateButtonStates()`: 更新按钮激活状态
|
||||
- `updateSettingsView()`: 显示/隐藏相应的设置控件
|
||||
- `updateSpeedButtonStates()`: 更新速度按钮禁用状态
|
||||
|
||||
### 6.3 设置视图更新 (`updateSettingsView`)
|
||||
|
||||
根据当前模式动态显示/隐藏控件:
|
||||
|
||||
**漫游模式 (`'walk'`)**:
|
||||
- 隐藏速度控件
|
||||
- 显示角色模型选择
|
||||
- 显示行走模式选择
|
||||
- 显示重力复选框
|
||||
- 显示碰撞复选框
|
||||
|
||||
**路径模式 (`'path'`)** 或 **无模式 (`'none'`)**:
|
||||
- 显示速度控件
|
||||
- 隐藏角色模型选择
|
||||
- 隐藏行走模式选择
|
||||
- 显示重力复选框
|
||||
- 显示碰撞复选框
|
||||
|
||||
### 6.4 图标管理
|
||||
|
||||
使用统一的图标管理器 (`icon-manager.ts`) 获取 SVG 图标:
|
||||
|
||||
```typescript
|
||||
private getIconSVG(type: string): string {
|
||||
const icons: Record<string, string> = {
|
||||
'plan-view': getIcon('地图'), // 平面图/鸟瞰
|
||||
'path': getIcon('地图'), // 路径漫游
|
||||
'walk': getIcon('漫游') // 人物漫游
|
||||
};
|
||||
return icons[type] || '';
|
||||
}
|
||||
```
|
||||
|
||||
**重要**: 所有按钮图标尺寸统一为 32x32,与 toolbar 底部工具栏保持一致。
|
||||
|
||||
---
|
||||
|
||||
## 7. 国际化支持
|
||||
|
||||
### 7.1 使用的翻译键
|
||||
|
||||
```typescript
|
||||
// 翻译键路径
|
||||
'walkControl.speed' // 速度标签
|
||||
'walkControl.gravity' // 重力标签
|
||||
'walkControl.collision' // 碰撞标签
|
||||
'walkControl.characterModel.label' // 角色模型标签
|
||||
'walkControl.characterModel.constructionWorker' // 建筑工人
|
||||
'walkControl.characterModel.officeMale' // 办公室男性
|
||||
'walkControl.walkMode.label' // 行走模式标签
|
||||
'walkControl.walkMode.walk' // 行走
|
||||
'walkControl.walkMode.run' // 奔跑
|
||||
'walkControl.exit' // 退出按钮
|
||||
```
|
||||
|
||||
### 7.2 实现方式
|
||||
- 使用 `src/services/locale.ts` 中的 `t()` 函数
|
||||
- 组件初始化时订阅语言变更,变更发生时更新所有文本 (`setLocales`)
|
||||
- 动态创建的下拉框选项也使用 `t()` 函数获取翻译文本
|
||||
|
||||
---
|
||||
|
||||
## 8. 主题支持
|
||||
|
||||
### 8.1 变量映射
|
||||
|
||||
在 `setTheme` 中设置内联样式变量:
|
||||
- `--bim-walk-control-bg`: 面板背景色
|
||||
- `--bim-walk-btn-hover`: 按钮悬停背景
|
||||
- `--bim-walk-btn-active`: 按钮激活背景
|
||||
- `--bim-primary-color`: 主色(退出按钮)
|
||||
- `--bim-primary-hover`: 主色悬停
|
||||
- `--bim-icon-color`: 图标颜色
|
||||
- `--bim-text-color`: 文本颜色
|
||||
- `--bim-divider-color`: 分割线颜色
|
||||
- `--bim-speed-group-bg`: 速度组背景
|
||||
- `--bim-speed-btn-bg`: 速度按钮背景
|
||||
- `--bim-speed-btn-hover`: 速度按钮悬停
|
||||
- `--bim-select-bg`: 下拉框背景
|
||||
- `--bim-select-border`: 下拉框边框
|
||||
- `--bim-select-option-bg`: 下拉框选项背景
|
||||
|
||||
---
|
||||
|
||||
## 9. 使用示例
|
||||
|
||||
### 9.1 基本使用
|
||||
|
||||
```typescript
|
||||
import { WalkControlPanel } from './components/walk-control-panel';
|
||||
|
||||
// 创建实例
|
||||
const walkPanel = new WalkControlPanel({
|
||||
defaultSpeed: 1,
|
||||
defaultGravity: false,
|
||||
defaultCollision: false,
|
||||
onPlanViewToggle: (isActive) => {
|
||||
console.log('平面图模式:', isActive);
|
||||
},
|
||||
onPathModeToggle: (isActive) => {
|
||||
console.log('路径模式:', isActive);
|
||||
// 启用/禁用路径漫游功能
|
||||
},
|
||||
onWalkModeToggle: (isActive) => {
|
||||
console.log('漫游模式:', isActive);
|
||||
// 启用/禁用人物漫游功能
|
||||
},
|
||||
onSpeedChange: (speed) => {
|
||||
console.log('速度:', speed);
|
||||
// 更新漫游速度
|
||||
},
|
||||
onGravityToggle: (enabled) => {
|
||||
console.log('重力:', enabled);
|
||||
},
|
||||
onCollisionToggle: (enabled) => {
|
||||
console.log('碰撞:', enabled);
|
||||
},
|
||||
onCharacterModelChange: (model) => {
|
||||
console.log('角色模型:', model);
|
||||
},
|
||||
onWalkModeChange: (mode) => {
|
||||
console.log('行走模式:', mode);
|
||||
},
|
||||
onExit: () => {
|
||||
console.log('退出漫游');
|
||||
// 销毁面板,退出漫游模式
|
||||
}
|
||||
});
|
||||
|
||||
// 初始化
|
||||
walkPanel.init();
|
||||
|
||||
// 挂载到 DOM
|
||||
document.body.appendChild(walkPanel.element);
|
||||
```
|
||||
|
||||
### 9.2 外部控制状态
|
||||
|
||||
```typescript
|
||||
// 外部设置平面图激活状态
|
||||
walkPanel.setPlanViewActive(true);
|
||||
|
||||
// 外部设置路径模式激活状态
|
||||
walkPanel.setPathModeActive(true);
|
||||
|
||||
// 获取当前状态
|
||||
const state = walkPanel.getState();
|
||||
console.log('当前模式:', state.mode);
|
||||
console.log('当前速度:', state.speed);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 实现细节(供 AI 重现)
|
||||
|
||||
### 10.1 状态管理
|
||||
|
||||
组件内部维护一个状态对象 `WalkControlState`:
|
||||
|
||||
```typescript
|
||||
private state: WalkControlState = {
|
||||
mode: 'none', // 当前模式
|
||||
isPlanViewActive: false, // 平面图是否激活
|
||||
speed: 1, // 移动速度 1-10
|
||||
gravity: false, // 重力是否启用
|
||||
collision: false, // 碰撞是否启用
|
||||
characterModel: 'construction-worker', // 角色模型
|
||||
walkMode: 'walk' // 行走模式
|
||||
};
|
||||
```
|
||||
|
||||
状态变更时:
|
||||
1. 更新内部状态
|
||||
2. 更新 UI 视觉效果
|
||||
3. 触发对应的回调函数
|
||||
|
||||
### 10.2 模式互斥逻辑
|
||||
|
||||
三个按钮(平面图、路径、漫游)中:
|
||||
- **平面图**是独立的开关,不影响模式
|
||||
- **路径**和**漫游**是互斥的,激活一个会关闭另一个
|
||||
- 点击已激活的模式按钮会关闭该模式(回到 `'none'`)
|
||||
|
||||
### 10.3 路径模式的特殊处理
|
||||
|
||||
当进入路径模式时:
|
||||
1. 自动禁用并取消勾选重力和碰撞
|
||||
2. 禁用重力和碰撞复选框(设置 `disabled` 属性)
|
||||
3. 退出路径模式时重新启用这两个复选框
|
||||
|
||||
### 10.4 速度控制
|
||||
|
||||
- 速度范围: 1-10
|
||||
- 减速按钮在速度为 1 时禁用
|
||||
- 加速按钮在速度为 10 时禁用
|
||||
- 速度显示格式: `${speed}X`
|
||||
|
||||
### 10.5 下拉框动态创建
|
||||
|
||||
角色模型和行走模式的下拉框选项在 `setLocales()` 中动态创建:
|
||||
1. 清空现有选项:`select.innerHTML = ''`
|
||||
2. 创建新选项,使用 `t()` 获取翻译文本
|
||||
3. 根据当前状态设置选中项
|
||||
|
||||
这样可以确保语言切换时下拉框文本也会更新。
|
||||
|
||||
---
|
||||
|
||||
## 11. 类型定义
|
||||
|
||||
### 11.1 WalkControlMode
|
||||
```typescript
|
||||
export type WalkControlMode = 'none' | 'path' | 'walk';
|
||||
```
|
||||
|
||||
### 11.2 CharacterModel
|
||||
```typescript
|
||||
export type CharacterModel = 'office-male' | 'construction-worker';
|
||||
```
|
||||
|
||||
### 11.3 WalkMode
|
||||
```typescript
|
||||
export type WalkMode = 'walk' | 'run';
|
||||
```
|
||||
|
||||
### 11.4 WalkControlState
|
||||
```typescript
|
||||
export interface WalkControlState {
|
||||
mode: WalkControlMode;
|
||||
isPlanViewActive: boolean;
|
||||
speed: number;
|
||||
gravity: boolean;
|
||||
collision: boolean;
|
||||
characterModel: CharacterModel;
|
||||
walkMode: WalkMode;
|
||||
}
|
||||
```
|
||||
|
||||
### 11.5 WalkControlPanelOptions
|
||||
见 2.1 节
|
||||
|
||||
---
|
||||
|
||||
## 12. 文件清单
|
||||
|
||||
- `src/components/walk-control-panel/index.ts`: 组件核心逻辑
|
||||
- `src/components/walk-control-panel/index.css`: 组件样式
|
||||
- `src/components/walk-control-panel/types.ts`: 类型定义
|
||||
|
||||
---
|
||||
|
||||
## 13. 更新记录
|
||||
|
||||
| 日期 | 修改内容 | 修改人 |
|
||||
| ---------- | ----------------------------------------- | ------------ |
|
||||
| 2025-12-25 | 创建漫游控制面板组件文档,集成图标管理器 | AI Assistant |
|
||||
423
docs/utils/icon-manager.md
Normal file
423
docs/utils/icon-manager.md
Normal file
@@ -0,0 +1,423 @@
|
||||
# Icon Manager 图标管理器文档
|
||||
|
||||
> 本文档详细描述 Icon Manager 图标管理工具的实现细节,包括 API、使用方式、图标清单等,供 AI 根据文档重现功能。
|
||||
|
||||
---
|
||||
|
||||
## 1. 工具概述
|
||||
|
||||
### 1.1 基本信息
|
||||
- **工具名称**: `IconManager`
|
||||
- **文件路径**: `src/utils/icon-manager.ts`
|
||||
- **导出函数**: `getIcon(name: string): string`
|
||||
- **用途**: 统一管理所有 SVG 图标资源,提供通过名称获取图标的接口
|
||||
- **特点**: 单一职责,简单易用,支持默认图标回退
|
||||
|
||||
### 1.2 设计目标
|
||||
- **统一管理**: 所有图标集中在一个文件中管理,避免重复和不一致
|
||||
- **简化使用**: 通过简单的函数调用获取图标,无需在各处重复 SVG 代码
|
||||
- **类型安全**: SVG 作为字符串存储,可直接用于 innerHTML 或图标属性
|
||||
- **容错机制**: 当请求的图标不存在时,返回默认图标而不是报错
|
||||
|
||||
---
|
||||
|
||||
## 2. API 文档
|
||||
|
||||
### 2.1 getIcon 函数
|
||||
|
||||
```typescript
|
||||
function getIcon(name: string): string
|
||||
```
|
||||
|
||||
**参数**:
|
||||
- `name`: string - 图标名称(中文)
|
||||
|
||||
**返回值**:
|
||||
- string - SVG 图标的完整字符串
|
||||
|
||||
**行为**:
|
||||
1. 从 `ICONS` 对象中查找对应名称的图标
|
||||
2. 如果找到,返回该图标的 SVG 字符串
|
||||
3. 如果未找到,在控制台输出警告并返回默认图标
|
||||
|
||||
**示例**:
|
||||
```typescript
|
||||
import { getIcon } from '../../utils/icon-manager';
|
||||
|
||||
// 获取测量图标
|
||||
const measureIcon = getIcon('测量');
|
||||
|
||||
// 获取不存在的图标(会返回默认图标并警告)
|
||||
const unknownIcon = getIcon('不存在的图标');
|
||||
// 控制台输出: [IconManager] Icon "不存在的图标" not found, using default icon
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 图标清单
|
||||
|
||||
### 3.1 来自 assets 的图标 (48x48)
|
||||
|
||||
这些图标从 `src/assets/` 目录中的 SVG 文件简化而来,用于 toolbar 和主要功能按钮:
|
||||
|
||||
| 图标名称 | 用途 | 原始文件 |
|
||||
|---------|------|----------|
|
||||
| 测量 | 测量工具 | 测量.svg |
|
||||
| 地图 | 地图视图/平面图 | 地图.svg |
|
||||
| 框选放大 | 框选缩放 | 框选放大.svg |
|
||||
| 漫游 | 漫游模式 | 漫游.svg |
|
||||
| 目录树 | 构件树 | 目录树.svg |
|
||||
| 剖切 | 剖切菜单 | 剖切.svg |
|
||||
| 剖切盒 | 剖切盒 | 剖切盒.svg |
|
||||
| 全屏 | 全屏模式 | 全屏.svg |
|
||||
| 设置 | 设置面板 | 设置.svg |
|
||||
| 拾曲面剖切 | 拾取曲面剖切 | 拾曲面剖切.svg |
|
||||
| 轴向剖切 | 轴向剖切 | 轴向剖切.svg |
|
||||
| 主视角 | 主视角/首页 | 主视角.svg |
|
||||
| 文档 | 文档/属性 | 地图 – 1.svg |
|
||||
|
||||
### 3.2 测量相关图标 (32x32)
|
||||
|
||||
用于测量面板的各种测量方式:
|
||||
|
||||
| 图标名称 | 用途 |
|
||||
|---------|------|
|
||||
| 标高 | 标高测量 |
|
||||
| 距离 | 距离测量 |
|
||||
| 最小距离 | 最小距离测量 |
|
||||
| 激光边距 | 激光边距测量 |
|
||||
| 角度 | 角度测量 |
|
||||
| 坡度 | 坡度测量 |
|
||||
| 体积 | 体积测量 |
|
||||
| 空间体积 | 空间体积测量 |
|
||||
|
||||
### 3.3 通用图标 (24x24)
|
||||
|
||||
常用的 UI 图标:
|
||||
|
||||
| 图标名称 | 用途 |
|
||||
|---------|------|
|
||||
| close | 关闭 |
|
||||
| check | 勾选/确认 |
|
||||
| warning | 警告 |
|
||||
| error | 错误 |
|
||||
| success | 成功 |
|
||||
| plus | 加号/新增 |
|
||||
| minus | 减号/删除 |
|
||||
| arrowUp | 向上箭头 |
|
||||
| arrowDown | 向下箭头 |
|
||||
| arrowLeft | 向左箭头 |
|
||||
| arrowRight | 向右箭头 |
|
||||
| search | 搜索 |
|
||||
| refresh | 刷新 |
|
||||
| delete | 删除 |
|
||||
| edit | 编辑 |
|
||||
| save | 保存 |
|
||||
| expand | 展开 |
|
||||
| collapse | 收起 |
|
||||
|
||||
### 3.4 默认图标
|
||||
|
||||
| 图标名称 | 用途 |
|
||||
|---------|------|
|
||||
| default | 当请求的图标不存在时返回 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 使用场景
|
||||
|
||||
### 4.1 在按钮配置中使用
|
||||
|
||||
```typescript
|
||||
import { getIcon } from '../../../utils/icon-manager';
|
||||
|
||||
export const createMeasureButton = (engine: BimEngine): ButtonConfig => {
|
||||
return {
|
||||
id: 'measure',
|
||||
groupId: 'group-1',
|
||||
type: 'button',
|
||||
label: 'toolbar.measure',
|
||||
icon: getIcon('测量'), // 使用图标管理器
|
||||
onClick: () => {
|
||||
engine.measure?.show();
|
||||
}
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### 4.2 在组件中使用
|
||||
|
||||
```typescript
|
||||
import { getIcon } from '../../utils/icon-manager';
|
||||
|
||||
export class WalkControlPanel implements IBimComponent {
|
||||
private getIconSVG(type: string): string {
|
||||
const icons: Record<string, string> = {
|
||||
'plan-view': getIcon('地图'),
|
||||
'path': getIcon('地图'),
|
||||
'walk': getIcon('漫游')
|
||||
};
|
||||
return icons[type] || '';
|
||||
}
|
||||
|
||||
private createIconButton(type: string, onClick: () => void): HTMLButtonElement {
|
||||
const btn = document.createElement('button');
|
||||
btn.className = `walk-icon-btn walk-icon-btn-${type}`;
|
||||
btn.innerHTML = this.getIconSVG(type);
|
||||
btn.addEventListener('click', onClick);
|
||||
return btn;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 在树节点中使用
|
||||
|
||||
```typescript
|
||||
import { getIcon } from '../../utils/icon-manager';
|
||||
|
||||
const treeData: TreeNodeConfig[] = [
|
||||
{
|
||||
id: 'level-1',
|
||||
label: '一层',
|
||||
icon: getIcon('目录树'),
|
||||
children: [...]
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. SVG 简化规范
|
||||
|
||||
### 5.1 简化原则
|
||||
|
||||
从 assets 目录中的 SVG 文件简化时,遵循以下原则:
|
||||
|
||||
1. **保留核心路径**:只保留 `<path>` 元素及其 `d` 属性
|
||||
2. **移除冗余属性**:删除 `<defs>`, `<clipPath>`, `<style>`, `<g>` 等非必要元素
|
||||
3. **保持颜色属性**:保留 `fill="currentColor"` 以支持主题颜色
|
||||
4. **统一尺寸**:根据用途设置合适的 `viewBox` 和 `width/height`
|
||||
5. **简化变换**:如果有 `transform`,尽量简化或合并到路径中
|
||||
|
||||
### 5.2 简化示例
|
||||
|
||||
**原始 SVG (从 assets/测量.svg)**:
|
||||
```xml
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48" viewBox="0 0 48 48">
|
||||
<defs>
|
||||
<clipPath id="clip-path">
|
||||
<rect width="48" height="48" fill="none"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="测量" clip-path="url(#clip-path)">
|
||||
<path d="M0,28.207H3.429v3.526H44.571V28.207H48v7.052H0ZM0,3.526v14.1a3.478,3.478,0,0,0,3.429,3.526H6.857V17.629h3.429v3.526h3.429V17.629h3.429v3.526h3.429V10.578H24V21.155h3.429V17.629h3.429v3.526h3.429V17.629h3.429v3.526h3.429V10.578h3.429V21.155A3.478,3.478,0,0,0,48,17.629V3.526A3.478,3.478,0,0,0,44.571,0H3.429A3.478,3.478,0,0,0,0,3.526Z" transform="translate(0 5.456)" fill="#000"/>
|
||||
</g>
|
||||
</svg>
|
||||
```
|
||||
|
||||
**简化后 (在 icon-manager.ts 中)**:
|
||||
```typescript
|
||||
测量: '<svg width="48" height="48" viewBox="0 0 48 48"><path fill="currentColor" d="M0,28.207H3.429v3.526H44.571V28.207H48v7.052H0ZM0,3.526v14.1a3.478,3.478,0,0,0,3.429,3.526H6.857V17.629h3.429v3.526h3.429V17.629h3.429v3.526h3.429V10.578H24V21.155h3.429V17.629h3.429v3.526h3.429V17.629h3.429v3.526h3.429V10.578h3.429V21.155A3.478,3.478,0,0,0,48,17.629V3.526A3.478,3.478,0,0,0,44.571,0H3.429A3.478,3.478,0,0,0,0,3.526Z" transform="translate(0 5.456)"/></svg>',
|
||||
```
|
||||
|
||||
**关键变化**:
|
||||
- 移除了 `xmlns`, `xmlns:xlink`, `<defs>`, `<clipPath>`, `<g>` 等
|
||||
- 将 `fill="#000"` 改为 `fill="currentColor"` 以支持主题
|
||||
- 保留了核心的 `<path>` 和 `viewBox`
|
||||
|
||||
---
|
||||
|
||||
## 6. 图标尺寸规范
|
||||
|
||||
### 6.1 尺寸分类
|
||||
|
||||
根据使用场景,图标分为三种尺寸:
|
||||
|
||||
1. **48x48**: 主要功能按钮(toolbar、工具栏)
|
||||
2. **32x32**: 测量工具图标
|
||||
3. **24x24**: 通用 UI 图标(关闭、展开等)
|
||||
|
||||
### 6.2 与 CSS 的配合
|
||||
|
||||
图标尺寸在 CSS 中可以被覆盖:
|
||||
|
||||
```css
|
||||
/* Toolbar 按钮图标 */
|
||||
.opt-btn-icon svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 漫游控制面板按钮图标 */
|
||||
.walk-icon-btn svg {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
```
|
||||
|
||||
实际显示尺寸由 CSS 控制,SVG 的 `width` 和 `height` 属性主要用于:
|
||||
1. 定义默认尺寸
|
||||
2. 计算宽高比
|
||||
3. 作为 `viewBox` 的参考
|
||||
|
||||
---
|
||||
|
||||
## 7. 添加新图标
|
||||
|
||||
### 7.1 添加流程
|
||||
|
||||
1. **准备 SVG 文件**:
|
||||
- 将新图标文件放到 `src/assets/` 目录
|
||||
- 或直接获取 SVG 代码
|
||||
|
||||
2. **简化 SVG**:
|
||||
- 按照 5.1 节的简化原则处理 SVG
|
||||
- 确保 `fill="currentColor"` 以支持主题
|
||||
- 设置合适的尺寸
|
||||
|
||||
3. **添加到 ICONS 对象**:
|
||||
```typescript
|
||||
const ICONS: Record<string, string> = {
|
||||
// ... 现有图标
|
||||
新图标名称: '<svg width="48" height="48" viewBox="0 0 48 48"><path fill="currentColor" d="..."/></svg>',
|
||||
};
|
||||
```
|
||||
|
||||
4. **使用新图标**:
|
||||
```typescript
|
||||
const icon = getIcon('新图标名称');
|
||||
```
|
||||
|
||||
### 7.2 命名规范
|
||||
|
||||
- **使用中文名称**:便于理解和维护
|
||||
- **描述功能**:名称应清晰描述图标用途
|
||||
- **避免重复**:检查是否已存在类似图标
|
||||
|
||||
**推荐命名**:
|
||||
- ✅ 好的命名: `测量`, `地图`, `全屏`, `剖切盒`
|
||||
- ❌ 不好的命名: `icon1`, `svg2`, `btn_icon`
|
||||
|
||||
---
|
||||
|
||||
## 8. 实现细节(供 AI 重现)
|
||||
|
||||
### 8.1 核心数据结构
|
||||
|
||||
```typescript
|
||||
const ICONS: Record<string, string> = {
|
||||
// key: 图标名称(中文)
|
||||
// value: SVG 字符串(完整的 <svg>...</svg>)
|
||||
};
|
||||
```
|
||||
|
||||
### 8.2 获取逻辑
|
||||
|
||||
```typescript
|
||||
export function getIcon(name: string): string {
|
||||
const icon = ICONS[name];
|
||||
|
||||
if (!icon) {
|
||||
console.warn(`[IconManager] Icon "${name}" not found, using default icon`);
|
||||
return ICONS.default;
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
```
|
||||
|
||||
**关键点**:
|
||||
1. 简单的字典查找
|
||||
2. 未找到时返回默认图标而不是 `undefined`
|
||||
3. 在控制台输出警告信息,便于调试
|
||||
|
||||
### 8.3 为什么不使用枚举?
|
||||
|
||||
设计选择:使用字符串而不是 TypeScript 枚举
|
||||
|
||||
**原因**:
|
||||
1. **简化使用**:直接传中文字符串,更直观
|
||||
2. **灵活性**:可以动态添加图标而不需要修改类型定义
|
||||
3. **国际化友好**:中文名称与 UI 文案保持一致
|
||||
4. **降低耦合**:使用方不需要导入枚举类型
|
||||
|
||||
---
|
||||
|
||||
## 9. 与主题系统的配合
|
||||
|
||||
### 9.1 currentColor 属性
|
||||
|
||||
所有图标使用 `fill="currentColor"`,这样图标颜色会继承父元素的 `color` 属性:
|
||||
|
||||
```typescript
|
||||
测量: '<svg width="48" height="48" viewBox="0 0 48 48"><path fill="currentColor" d="..."/></svg>',
|
||||
```
|
||||
|
||||
### 9.2 在 CSS 中控制颜色
|
||||
|
||||
```css
|
||||
.opt-btn-icon {
|
||||
color: var(--bim-icon-color, #ccc);
|
||||
}
|
||||
|
||||
.opt-btn-icon svg {
|
||||
fill: currentColor; /* 继承父元素的 color */
|
||||
}
|
||||
```
|
||||
|
||||
### 9.3 主题变更时的自动适配
|
||||
|
||||
当主题颜色变更时,只需更新 CSS 变量,所有图标会自动适配新颜色:
|
||||
|
||||
```typescript
|
||||
// 在 setTheme 中
|
||||
element.style.setProperty('--bim-icon-color', theme.icon ?? '#ccc');
|
||||
// 所有使用 currentColor 的图标自动更新颜色
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 最佳实践
|
||||
|
||||
### 10.1 使用建议
|
||||
|
||||
**✅ 推荐做法**:
|
||||
```typescript
|
||||
// 在组件顶部导入
|
||||
import { getIcon } from '../../utils/icon-manager';
|
||||
|
||||
// 在需要时调用
|
||||
const icon = getIcon('测量');
|
||||
button.innerHTML = icon;
|
||||
```
|
||||
|
||||
**❌ 避免做法**:
|
||||
```typescript
|
||||
// 不要在组件中硬编码 SVG
|
||||
const icon = '<svg>...</svg>'; // 不推荐
|
||||
|
||||
// 不要重复定义相同的图标
|
||||
const myIcon = '<svg>...</svg>'; // 应该使用 getIcon()
|
||||
```
|
||||
|
||||
### 10.2 性能考虑
|
||||
|
||||
- **字符串查找很快**:`ICONS` 对象的查找是 O(1) 操作
|
||||
- **无需缓存**:图标字符串很小,不需要额外的缓存机制
|
||||
- **按需使用**:只在需要时调用 `getIcon()`,不需要预加载所有图标
|
||||
|
||||
### 10.3 维护建议
|
||||
|
||||
1. **定期整理**:删除不再使用的图标
|
||||
2. **统一风格**:新增图标应与现有图标风格一致
|
||||
3. **文档同步**:添加新图标时更新本文档的图标清单
|
||||
4. **命名规范**:使用清晰、一致的中文命名
|
||||
|
||||
---
|
||||
|
||||
## 11. 更新记录
|
||||
|
||||
| 日期 | 修改内容 | 修改人 |
|
||||
| ---------- | ----------------------------------------- | ------------ |
|
||||
| 2025-12-25 | 创建图标管理器,整合所有 SVG 图标资源 | AI Assistant |
|
||||
| 2025-12-25 | 添加"文档"图标,替换所有 toolbar 按钮图标 | AI Assistant |
|
||||
Reference in New Issue
Block a user