Files
bim_engine/docs/components/walk-control-panel.md
2025-12-25 19:08:26 +08:00

17 KiB

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 构造函数

constructor(options: WalkControlPanelOptions = {})

参数:

  • options: WalkControlPanelOptions - 漫游控制面板配置选项(可选)

WalkControlPanelOptions 定义:

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-bgtheme.panelBackground
    • --bim-walk-btn-hovertheme.componentHover
    • --bim-walk-btn-activetheme.componentActive
    • --bim-primary-colortheme.primary
    • --bim-primary-hovertheme.primaryHover
    • --bim-icon-colortheme.icon
    • --bim-text-colortheme.textPrimary
    • --bim-divider-colortheme.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 结构

<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
  • :disabledopacity: 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 图标:

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 使用的翻译键

// 翻译键路径
'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 基本使用

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 外部控制状态

// 外部设置平面图激活状态
walkPanel.setPlanViewActive(true);

// 外部设置路径模式激活状态
walkPanel.setPathModeActive(true);

// 获取当前状态
const state = walkPanel.getState();
console.log('当前模式:', state.mode);
console.log('当前速度:', state.speed);

10. 实现细节(供 AI 重现)

10.1 状态管理

组件内部维护一个状态对象 WalkControlState:

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

export type WalkControlMode = 'none' | 'path' | 'walk';

11.2 CharacterModel

export type CharacterModel = 'office-male' | 'construction-worker';

11.3 WalkMode

export type WalkMode = 'walk' | 'run';

11.4 WalkControlState

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