手机像素画板的核心输入是触控,大屏和二合一设备却能提供键盘、鼠标和滚轮。把桌面快捷键原封不动搬到手机上,只会让界面多出一套无用设置;反过来完全忽略键盘,又会让大屏编辑效率很低。bitArt 的处理方式是把快捷键配置持久化,但只在大屏布局且开关允许时响应;鼠标滚轮则仍归到画布视口逻辑,围绕当前光标缩放。

++快捷键配置可以保存,但响应范围必须受布局约束++
快捷键实现最常见的问题有两个。第一,直接在页面里判断 keyCode,随着撤销、导出、工具切换和弹窗关闭不断增加,代码很快无法维护;第二,在设置弹窗、项目命名输入框或素材库打开时仍响应 B、E、S 等单键,用户输入文本会意外切换工具或触发导出。
++按键解析和命令执行为什么要拆开++
键盘和鼠标应该增强现有工作流,而不是制造另一套编辑器状态。所有输入最终仍要回到同一份工具、历史和视口规则。

++按键先解析成动作,再决定怎样执行++
KeyboardShortcutService 维护动作列表、默认绑定、格式化显示、冲突移除和查找。EditorShortcutActionService 则负责根据 KeyEvent 更新 Ctrl、Shift 状态,判断是否处于大屏、是否正在录制快捷键、是否允许单键,再返回 actionId。真正的执行交给工作流:工具动作映射到 activeTool,缩放动作映射到视口,关闭动作按叠层优先级处理。
默认方案既支持 Ctrl+Z、Ctrl+Y、Ctrl+Shift+Z 这类组合,也支持 B、E、F、P、M 等工具键。冲突分配时 withAssignedShortcut 会从其他动作移除相同绑定,避免一个按键同时触发两个命令。
默认快捷键只是配置数据,真正是否响应还需要后续的布局和面板状态判断。
static createDefaultShortcuts(): KeyboardShortcutSettings {
const result: KeyboardShortcutSettings = {};
result.undo = [KeyboardShortcutService.createBinding(KeyCode.KEYCODE_Z, true, false)];
result.redo = [KeyboardShortcutService.createBinding(KeyCode.KEYCODE_Y, true, false),
KeyboardShortcutService.createBinding(KeyCode.KEYCODE_Z, true, true)];
result.pencil = [KeyboardShortcutService.createBinding(KeyCode.KEYCODE_B, false, false)];
result.eraser = [KeyboardShortcutService.createBinding(KeyCode.KEYCODE_E, false, false)];
result.fill = [KeyboardShortcutService.createBinding(KeyCode.KEYCODE_F, false, false)];
result.closeOverlay = [KeyboardShortcutService.createBinding(KeyCode.KEYCODE_ESCAPE, false, false)];
return result;
}
++单键快捷键要避开正在输入文字的面板++
按键处理先更新修饰键状态,再忽略仅有 Ctrl 或 Shift 的事件;随后根据事件和回退状态判断组合键。若正在录制快捷键,普通按键会被转成新的 binding;否则用 findActionId 搜索匹配项。对于不带 Ctrl 与 Shift 的动作,还要调用 canUseSingleKeyShortcuts,确保没有新建、项目管理、设置、颜色、主菜单、历史或素材面板处于打开状态。
if (!EditorShortcutActionService.isLargeScreenShortcutEnabled(state.largeScreenLayout,
state.keyboardShortcutsEnabled)) {
const result = EditorShortcutActionService.createResult(state, false);
result.shortcutCtrlDown = false;
result.shortcutShiftDown = false;
return result;
}
const actionId = KeyboardShortcutService.findActionId(nextState.keyboardShortcuts, event.keyCode,
ctrlPressed, shiftPressed);
if (!ctrlPressed && !shiftPressed && actionId !== 'closeOverlay' &&
!EditorShortcutActionService.canUseSingleKeyShortcuts(nextState)) return createResult(nextState, false);

++输入会话状态与快捷键配置分开保存++
快捷键状态包含开关、绑定表、正在编辑的动作和修饰键按下状态。它是项目可保存配置,但当前 Ctrl/Shift 按下状态是瞬态 UI 状态,不能持久化。大屏条件不满足时服务返回未处理结果,同时清理修饰键状态,手机界面不会因为外接键盘残留状态而出现异常。
快捷键绑定可以随项目保存,按下 Ctrl 或 Shift 则只属于当前输入会话,离开事件后不应残留。
static withAssignedShortcut(settings: KeyboardShortcutSettings, actionId: string,
binding: KeyboardShortcutBinding): KeyboardShortcutSettings {
const normalized = KeyboardShortcutService.normalizeShortcuts(settings);
const result: KeyboardShortcutSettings = {};
for (const currentActionId of KeyboardShortcutService.ACTIONS.map((item) => item.id)) {
const sourceBindings = normalized[currentActionId] ? normalized[currentActionId] : [];
result[currentActionId] = currentActionId === actionId ? [KeyboardShortcutService.cloneBinding(binding)] :
KeyboardShortcutService.removeMatchingBindings(sourceBindings, binding);
}
return result;
}

++大屏输入最容易和文本编辑冲突的情况++
- 不要在所有窗口尺寸下响应单键快捷键,手机和文本输入面板必须有明确保护。
- 重新绑定一个按键时要从其他动作移除冲突,不能让查找顺序决定谁"碰巧获胜"。
- Ctrl、Shift 等修饰键需要有回退状态,不能只依赖某些设备不一定提供的事件查询接口。
鼠标和键盘不是另一套编辑器。它们最终仍调用已有的工具状态、撤销历史和视口约束。这样用户用 B 切到画笔、用滚轮缩放、用 Esc 关闭选区时,不会走出触控路径之外的分叉逻辑。输入方式增加了,数据源和业务规则没有增加。
++键盘输入先尊重当前焦点++
快捷键测试要把焦点场景列在第一位。先在画布空闲状态按 B、E、F、Ctrl+Z,再打开项目重命名、设置输入框、颜色输入框和素材面板重复按同一组键。正确结果不是所有地方都响应,而是只有没有文本输入和覆盖层的工作区响应单键。Esc 可以按叠层优先级关闭当前最高层界面,但也不能越过用户正在编辑的重要输入。
鼠标滚轮还要与快捷键分开验证。它不应因为某个快捷键被禁用就失效,而应始终由视口判断当前缩放和边界。在大屏用光标指向一处像素后滚动,目标像素应尽量留在指针下方;切回手机布局时,键盘动作停止,触控和视口规则仍保持原有行为。这样多输入设备共存时才不会出现一方覆盖另一方的意外。

++怎样确认快捷键只在正确场景响应++
快捷键检查需要在面板打开和布局切换时重复按键,确认保护条件真的生效。
-
在大屏布局下验证 Ctrl+Z、Ctrl+Y、Ctrl+Shift+Z、保存、导出和常用工具键。
-
打开设置、项目管理、颜色弹窗、素材库和文本输入后按 B、E、S,确认不会误触发单键命令。
-
重新给两个动作分配相同按键,确认旧动作的绑定被移除且格式化显示正确。
-
切换到手机布局或关闭快捷键开关,确认按键不再修改编辑器状态;滚轮缩放仍受视口边界约束。
快捷键与鼠标检查记录
大屏开启时组合键与工具键可用
输入和弹窗打开时单键不误触发
重新绑定自动去除冲突
手机布局或关闭开关时快捷键保持无副作用

++快捷键功能的使用边界++
当前快捷键覆盖编辑器主动作,不尝试复刻桌面绘图软件的全部组合键、宏录制或系统级全局热键。它的目标是在键盘可用的大屏上减少常见操作的重复点击,同时不破坏手机上的触控主路径。
这一篇的重点是把键盘和鼠标接入现有编辑器规则,而不是另起一套行为。至此,11 到 22 篇补齐了工具、项目、素材和大屏输入这些支线,后续若继续扩展,更适合围绕新能力或真实设备回归再开新的系列。