Babylon 编辑器快捷键小记
一、最终代码(带满屏注释)
// Babylon.js 键盘事件枚举
import { KeyboardEventTypes } from "@babylonjs/core";
// 全局事件总线(mitt)
import { emitter } from "../../utils/EventBus";
// 编辑器系统,内部有 keyboardController
import type { EditorSystem } from "../EditorSystem";/*** 快捷键管理器* 职责:* 1. 监听键盘事件* 2. 根据规则分发事件到 EventBus* 3. 支持单键 & Ctrl+? 组合键*/
export class ShortCutsManager {// 编辑器引用,主要用来拿 keyboardControllerprivate _editorSystem: EditorSystem;/*** 单键映射* key -> EventName*/private _shortcutDictionary: ShortcutDictionary = {q: "selectMode",w: "moveMode",e: "rotateMode",r: "scaleMode",delete: "openDeleteConfirm"};/*** Ctrl+? 组合键映射* 仅记录“字母部分”,判断时再加前缀 "Control"*/private _ctrlShortcutDictionary: ShortcutDictionary = {s: "saveScene", // Ctrl+So: "openScene", // Ctrl+On: "newScene", // Ctrl+Nz: "undo", // Ctrl+Zy: "redo" // Ctrl+Y};constructor(editorSystem: EditorSystem) {this._editorSystem = editorSystem;this._init();}/** 初始化:注册键盘事件 */private _init(): void {const keyboardController = this._editorSystem.keyboardController;if (!keyboardController) {console.error("GlobalKeyboardController is not initialized.");return;}// 监听所有 KEYDOWN 事件keyboardController.addListener(KeyboardEventTypes.KEYDOWN, () => {// 当前按下的单个字符(已转成小写)const onlyKey = keyboardController.pressedSingleNormalKey?.trim().toLowerCase();if (!onlyKey) return; // 没按字符键直接返回// ---------- 组合键优先 ----------if (keyboardController.isModifierKeysCombined(["Control"])) {const eventName = this._ctrlShortcutDictionary[onlyKey];if (eventName) {emitter.emit(eventName);return; // 命中组合键后不再走单键}}// ---------- 单键 ----------const eventName = this._shortcutDictionary[onlyKey];if (eventName) {emitter.emit(eventName);}});}
}/** 字典类型:string -> string */
interface ShortcutDictionary {[key: string]: string;
}
二、怎么用
任意地方监听
import { emitter } from '@/utils/EventBus';emitter.on('undo', () => console.log('撤销'));
emitter.on('saveScene', () => scene.save());