Skip to content

输入作用域与指针会话 ​

键盘作用域 ​

InputScope通过id和priority参与统一分发。数值越大越先收到按键;返回true表示已消费,返回false或不返回则允许后续处理。

成员作用
id当前作用域唯一标识
priority优先级
onKeyDown(event)按下处理
onKeyUp(event)松开处理
onBlur()焦点丢失后复位按住状态

宿主使用editor.registerInputScope(scope);插件使用ctx.registerInputScope(scope),两者均返回注销函数。

ts
import type { SkyNoteEditor } from '@skynote/editor';

/** 面板打开时注册,关闭或卸载时调用返回的注销函数。 */
export function registerPanelEscape(editor: SkyNoteEditor<HTMLElement>, closePanel: () => void): () => void {
  return editor.registerInputScope({
    id: 'example/panel',
    priority: 2000,
    onKeyDown(event) {
      if (event.isComposing || event.keyCode === 229 || event.key !== 'Escape') return false;
      event.preventDefault();
      closePanel();
      return true;
    }
  });
}

示例只应在面板打开期间注册,关闭或卸载后注销。同一面板不要每次渲染重复注册。优先级2000是本示例的宿主选择,不是所有业务都必须使用的值。

输入法与焦点 ​

CanvasKeyboardEvent提供key/code、修饰键、isComposing、可选keyCode及preventDefault/stopPropagation。组合输入期间不能触发画布命令;对于中文拼音,也要考虑keyCode === 229。

文本编辑作用域优先处理输入,不能因为用户在编辑标题时按了Tab,就让导图新增主题。画布失焦时可能收不到keyup,空格平移等按住状态必须在onBlur清理。

指针协作 ​

插件通过registerPointerHooks(hooks, priority?)接收onPointerDown/Move/Up/Cancel/Leave、onContextMenu和onWheel。世界/屏幕坐标来自归一化事件与宿主桥接,不直接依赖window事件。

排他的拖动、框选或绘制应认领pointer session;观察到已被其他功能认领时停止竞争。认领与宿主指针捕获是相关但不同的职责:前者协调插件,后者让离开元素的后续指针事件仍可到达。

结束与取消 ​

结束原因必须处理的内容
PointerUp提交或完成本次动作,释放临时状态
PointerCancel浏览器、系统或设备中断,撤除半完成预览
PointerLeave让依赖悬停位置的提示和标识失效
onBlur / 宿主切换复位按住键和依赖旧宿主的瞬态资源
插件卸载注销钩子,取消任务,清除覆盖层

右键发生在左键拖动过程中时,不一定产生新的pointerdown。绘制中的“右键取消”应处理onContextMenu;宿主调用dispatchContextMenu(point)返回true时,表示插件已消费,不再弹出宿主菜单。

可组合的画布能力,从一个想法开始。