当前位置: 首页 > ds >正文

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());
http://www.xdnf.cn/news/19886.html

相关文章:

  • 零构建的快感!dagger.js 与 React Hooks 实现对比,谁更优雅?
  • Python OpenCV图像处理与深度学习:Python OpenCV DNN模块深度学习与图像处理
  • 线程安全问题及解决方案
  • 163起融资,梅卡曼德融资额夺冠,钉钉、百度智能云10周年,汉桑科技IPO| 2025年8月人工智能投融资观察 · 极新月报
  • Android --- 搭建JNI框架
  • % g++ *.cpp ...: fatal error: ‘opencv2/opencv.hpp‘ file not found 1
  • 数论常见公式定理大全
  • 无需服务器,免费、快捷的一键部署前端 vue React代码--PinMe
  • 嵌入式学习 51单片机基础
  • 《微服务协作实战指南:构建全链路稳健性的防御体系》
  • AR技术赋能风电运维:精准、高效、智能
  • 算法模板(Java版)_非负整数的高精度运算
  • 【论文阅读】Jet-Nemotron: 高效语言模型与后神经网络架构搜索
  • 研发团队缺乏统一文档模板怎么办
  • 服务器的监控和管理手段有哪些?
  • 【LeetCode牛客数据结构】单链表的应用——环形链表及链表分割问题详解
  • 【Python3教程】Python3高级篇之多线程
  • Chrome浏览器调用ActiveX控件之allWebOffice在线编辑控件
  • 记录收入最高的一次私活 选号网,需要大量卖号的人可能需要,比如游戏脚本批量跑的号
  • 电脑配置不足怎么办,告别硬件束缚,川翔云电脑
  • 从Oracle到PostgreSQL的数据库迁移
  • MySQL中binlog、redolog与undolog的不同之处解析
  • 传统大数据 Hadoop 和 云原生湖仓 Databend 对比
  • Spring MVC + JSP 项目的配置流程,适合传统 Java Web 项目开发
  • LangGraph 重要注意事项和常见问题
  • 猫头虎AI分享:无需OCR,基于ColQwen2、Qwen2.5和Weaviate对PDF进行多模态RAG的解决方案
  • 基于STM32的居家养老健康安全检测系统
  • 中文分词器之结巴分词
  • GPT-Realtime 弹幕TTS API 低延迟集成教程
  • leetcode111. 二叉树的最小深度