# 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
1X
``` ### 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 = { '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 |