Files
bim_engine/docs/components/漫游控制面板组件-WalkControlPanel.md

595 lines
17 KiB
Markdown
Raw Normal View History

2025-12-25 19:08:26 +08:00
# 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 |