Babylon 编辑器快捷键小记

一、最终代码(带满屏注释)

TypeScript 复制代码
// 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 {
  // 编辑器引用,主要用来拿 keyboardController
  private _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+S
    o: "openScene", // Ctrl+O
    n: "newScene",  // Ctrl+N
    z: "undo",      // Ctrl+Z
    y: "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;
}

二、怎么用

任意地方监听

TypeScript 复制代码
import { emitter } from '@/utils/EventBus';

emitter.on('undo', () => console.log('撤销'));
emitter.on('saveScene', () => scene.save());
相关推荐
猫头虎1 天前
Claude Code 永动机:ralph-loop 无限循环迭代插件详解(安装 / 原理 / 最佳实践 / 避坑)
ide·人工智能·langchain·开源·编辑器·aigc·编程技术
爱吃汽的小橘1 天前
ZYNQ入门指南:ARM+FPGA开发全解析
编辑器
环黄金线HHJX.1 天前
《QuantumTuan ⇆ QT:Qt》
人工智能·qt·算法·编辑器·量子计算
LingRannn1 天前
【vim 中如何替换】
编辑器·vim·excel
山峰哥1 天前
3000字深度解析:SQL调优如何让数据库查询效率提升10倍
java·服务器·数据库·sql·性能优化·编辑器
环黄金线HHJX.1 天前
拼音字母量子编程PQLAiQt架构”这一概念。结合上下文《QuantumTuan ⇆ QT:Qt》
开发语言·人工智能·qt·编辑器·量子计算
早日退休!!!1 天前
GCC与LLVM编译器深度解析:核心原理与差异对比(小白向)
c++·编辑器
ttod_qzstudio2 天前
Babylon.js:MirrorTexture平面反射的科学与艺术
babylonjs·mirrortexture
冬奇Lab2 天前
【Cursor进阶实战·06】MCP生态:让AI突破编辑器边界
人工智能·编辑器·ai编程
环黄金线HHJX.2 天前
【MCP: Tuan编程 + Qt架构 + QoS - 量子-经典混合计算管理控制平台】
ide·人工智能·qt·编辑器·量子计算