唯杰地图 logo唯杰地图
VJMAP
EN

shortcuts

vjmapext/references/drawing/shortcuts.md 4.6 KB124 行
原文

本文回答:快捷键 —— setShortcuts / getShortcuts / getDefaultShortcuts / setModeToggleShortcut(已对照 vjmapext.d.ts 与运行时核实)。

一、方向:动作 → 键位(不是「键位 → 命令」)

ShortcutMap 的键是内置动作名,值是按键串:

interface ShortcutMap {
  modeToggle?: string | null;   // edit ↔ browse 切换
  selectAll?: string | null;
  undo?: string | null;
  redo?: string | null;
  delete?: string | null;
  nudgeUp?: string | null;      // 微移(像素)
  nudgeDown?: string | null;
  nudgeLeft?: string | null;
  nudgeRight?: string | null;
  rotateLeft?: string | null;   // 选中实体旋转
  rotateRight?: string | null;
  scaleUp?: string | null;      // 选中实体缩放
  scaleDown?: string | null;
  copy?: string | null;
  cut?: string | null;
  paste?: string | null;
  cancel?: string | null;       // 取消输入/清选集
  confirm?: string | null;      // 确认/结束当前输入
  repeatCommand?: string | null; // 重复上一条命令
}

vjmapext.getDefaultShortcuts() 的默认值(顶层函数;MapCadLayer 实例上无此方法):

{
  modeToggle: 'ctrl+shift+e',
  selectAll: 'ctrl+a',
  undo: 'ctrl+z',  redo: 'ctrl+y',
  delete: 'delete',
  nudgeUp: 'ctrl+arrowup',  nudgeDown: 'ctrl+arrowdown',
  nudgeLeft: 'ctrl+arrowleft', nudgeRight: 'ctrl+arrowright',
  rotateLeft: 'ctrl+[',  rotateRight: 'ctrl+]',
  scaleUp: 'ctrl+.',     scaleDown: 'ctrl+,',
  copy: 'ctrl+c',  cut: 'ctrl+x',  paste: 'ctrl+v',
  cancel: 'escape', confirm: 'enter',
  repeatCommand: null,     // 默认未绑;可用 confirm(enter) 之外自配
}

⚠️ 没有「字母键启动命令」体系('l'→'LINE'、'co'→'COPY' 这类 AutoCAD 别名在本库不存在——handleKeyDown 只匹配上表动作)。要给命令加速键,自己监听容器 keydown 再 executeCommand('LINE')。

二、读取 / 覆盖

const all = mapcadLayer.getShortcuts();          // ShortcutMap(动作→键位)
mapcadLayer.setShortcuts({ undo: 'ctrl+z', redo: 'ctrl+shift+z' });
mapcadLayer.setShortcuts({ nudgeUp: null });     // 传 null = 禁用该动作键位
mapcadLayer.setModeToggleShortcut('ctrl+e');     // 等效 setShortcuts({modeToggle:'ctrl+e'})

setShortcuts 是按动作合并(Partial),不是整表替换。

三、键位串格式

ctrl+ / shift+ / alt+  +  主键
  • 修饰键无序敏感(内部拆 + 后按 ctrl/shift/alt 归一);主键取最后一段,e.key.toLowerCase() 比对。
  • 主键例:z、a、delete、escape、enter、arrowup、[、]、,、.。⚠️ 空格无法绑定:比对的是 e.key.toLowerCase(),空格键的 e.key 是 ' ',写 'space' 永不匹配(' ' 也会被 trim 成空串);空格只在 confirm 里被硬编码兜底(e.key === ' ')。
  • 不支持 meta、f1~f12 外的功能键可试但看浏览器;多字符序列键(co)不支持。

四、键盘触发流程

keydown(地图容器聚焦时)→ InputManager.handleKeyDown
  → 逐个 matchShortcut(事件, shortcuts.动作)
    → 命中即 preventDefault + 执行对应内置动作

要生效 canvas 必须先聚焦:

mapcadLayer.getMapContainer()?.focus();

五、禁用某个快捷键

mapcadLayer.setShortcuts({ undo: null });   // 动作→null 即禁用

六、全局 vs canvas 作用域

快捷键只在地图容器监听。要在整页生效自己加全局监听:

window.addEventListener('keydown', e => {
  if (e.ctrlKey && e.key === 's') { e.preventDefault(); /* save */ }
});

七、和浏览器默认冲突

浏览器吞 处理
Ctrl+S e.preventDefault() 拦截
Ctrl+W / Ctrl+T 无法拦截,别占
F5 / F11 / Ctrl+N 浏览器保留,别占

八、常见坑

  1. canvas 没聚焦 → 按键无效;addControl 后手动 focus()。
  2. 输入框里触发 → 全局 input 聚焦时按键仍会进容器监听(若在容器内);给业务 input 加 e.stopPropagation()。
  3. Ctrl+Z 不 undo:焦点问题,或 undoManager 无可撤销项。
  4. 想给 repeatCommand 绑键:默认 null,如 setShortcuts({ repeatCommand: 'enter' })——但注意 enter 已是 confirm;选一个就行。
  5. 误以为支持命令别名:'co' 这类多键序列没有;字母热键启动命令要自己写 keydown。

相关