shortcuts
本文回答:快捷键 ——
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 |
浏览器保留,别占 |
八、常见坑
- canvas 没聚焦 → 按键无效;addControl 后手动
focus()。 - 输入框里触发 → 全局 input 聚焦时按键仍会进容器监听(若在容器内);给业务 input 加
e.stopPropagation()。 - Ctrl+Z 不 undo:焦点问题,或
undoManager无可撤销项。 - 想给
repeatCommand绑键:默认null,如setShortcuts({ repeatCommand: 'enter' })——但注意enter已是confirm;选一个就行。 - 误以为支持命令别名:
'co'这类多键序列没有;字母热键启动命令要自己写 keydown。
相关
- 命令注册 → custom-command
- 执行命令 → execute-command
- 撤销 → undo-redo
- 模式切换 → mode