Skip to content

小地图 API ​

MinimapPlugin从@skynote/plugins-basic根入口导入,负责概览数据与导航,不自带DOM、Canvas绘制或面板。接入示例与产品表现见小地图指南。

构造与启用 ​

new MinimapPlugin()没有配置参数,安装后默认关闭。将实例传入Editor的plugins,完成安装和宿主挂载,再调用setEnabled(true)。不要重复调用install;由引擎完成装配与卸载。

ts
import { SkyNoteEditor } from '@skynote/editor';
import { LeaferAdapter } from '@skynote/renderer-leafer';
import { MinimapPlugin, type MinimapSnapshot } from '@skynote/plugins-basic';

export function mountMinimapExample(
  container: HTMLElement,
  draw: (snapshot: MinimapSnapshot | null) => void
): { editor: SkyNoteEditor<HTMLElement>; minimap: MinimapPlugin; destroy: () => void } {
  const minimap = new MinimapPlugin();
  const editor = new SkyNoteEditor<HTMLElement>({ renderer: new LeaferAdapter(), plugins: [minimap] });
  let frame: number | undefined;
  const unsubscribe = minimap.subscribe(() => {
    if (frame !== undefined) return;
    frame = requestAnimationFrame(() => {
      frame = undefined;
      draw(minimap.getSnapshot({ width: 224, height: 144 }));
    });
  });
  function destroy(): void {
    unsubscribe();
    if (frame !== undefined) cancelAnimationFrame(frame);
    editor.destroy();
  }
  try {
    editor.mount(container);
    editor.createNode({ nodeType: 'sticky', x: 0, y: 0, options: { text: '从这里开始' } });
    editor.fitContent();
    minimap.setEnabled(true);
    return { editor, minimap, destroy };
  } catch (error) {
    destroy();
    throw error;
  }
}

示例使用224×144 CSS像素的绘制区域。修改区域尺寸时,绘制、读取快照和指针导航必须传入同一组实际尺寸。宿主可按设备像素比放大绘图缓冲区,但API仍使用CSS像素。

状态、订阅与快照 ​

成员 / 签名参数、返回与行为
isNavigating: boolean是否存在当前导航会话,不等于面板是否打开
setEnabled(enabled: boolean): void启闭概览;改变状态时清除内容缓存、焦点和导航状态并发送通知;关闭后停止场景收集
setFocused(focused: boolean): void同步小地图表面的键盘焦点;失焦会结束导航;未启用或未安装时不会进入获焦状态
subscribe(listener: () => void): () => void无参数的失效通知,返回解绑函数;注册时不立即调用;宿主收到通知后重新读取快照
getSnapshot(size: MinimapSize): MinimapSnapshot | null未安装、未启用或宽高不为正时为null;维护期间仍可返回快照,但disabled为true

通知可能来自文档、布局、选区、主题或视口变化;用requestAnimationFrame合并绘制,不在每次通知中创建另一套完整渲染器。宿主需要初次绘制时主动读取,或在订阅后启用。快照和集合按只读数据消费,不修改其内容。

类型与坐标约定 ​

类型字段
MinimapSize只读width/height: number,小地图绘制区域CSS像素尺寸
MinimapProjection只读scale/x/y: number,世界坐标到小地图像素的缩放与平移
MinimapNodeid: string、bounds: RectBounds(世界坐标)、container: boolean
MinimapConnectorid: string、points: readonly Point[]、bounds: RectBounds,均为世界几何
MinimapContentnodes、connectors只读数组;bounds: RectBounds | null为空内容时可为null

MinimapSnapshot还包含:

字段类型与说明
contentMinimapContent,可见节点与连线路由的几何示意
projectionMinimapProjection,内容和视口共用的投影;导航中使用会话开始时的投影
viewportRectBounds,主画布当前可视区域的世界矩形
themeCanvasTheme,绘制时使用的主题
selectedNodes/selectedConnectorsReadonlySet<string>,当前选区ID
navigatingboolean,是否存在导航会话
disabledboolean,当前维护冻结状态;不是文档只读标记

世界点映射公式为mapX = worldX * scale + x、mapY = worldY * scale + y;逆变换先减平移再除scale。所有传入导航的point都是相对小地图绘制区域的CSS像素坐标,不能直接使用页面clientX/clientY或世界坐标。

指针导航 ​

方法 / 签名说明
beginNavigation(pointerId: number, point: Point, size: MinimapSize): boolean快照不可用、维护冻结或已有导航时返回false;成功时记录投影并立即导航,返回true
moveNavigation(pointerId: number, point: Point): void仅移动匹配pointerId的会话,其他指针被忽略
endNavigation(pointerId: number): void结束匹配指针的导航;不是该指针则不执行
cancelNavigation(): void结束当前导航并通知重绘;不会把视口恢复到拖动前的位置
zoomAt(point: Point, size: MinimapSize, factor: number): void以对应世界点为锚缩放;factor须为有限正数;快照不可用、冻结或导航中不执行
panBy(x: number, y: number): void按主画布屏幕像素增量导航,视口平移量分别减去x/y;未启用、未安装、冻结或导航中不执行

点在视口框内时保留抓取偏移,拖动不会突然跳到框中心;点击框外时以点击点为中心导航。导航只更新会话视口,不产生文档或撤销历史。只读文档仍允许导航,维护冻结则不允许。

宿主只在beginNavigation返回true后捕获对应指针,PointerUp结束并释放捕获,PointerCancel、失焦和卸载时取消。主画布工具、缩放、尺寸或文档替换等变化可能提前结束会话;宿主不能仅凭“之前返回过true”继续显示抓取态,应读取isNavigating或最新快照。

键盘接入 ​

小地图表面获焦时调用setFocused(true),失焦调用false,并将键盘按下、抬起和失焦通过宿主InputScope桥接分发。

按键行为
方向键每次40像素导航;按住Shift时160像素
+ / = / -按1.2倍或其倒数缩放,导航手势中不缩放
Esc结束当前导航,不回滚此前视口变化

不要额外绑定一套绕过输入作用域的全局document快捷键。键盘接入协议见InputScope。

投影函数与常量 ​

导出说明
MINIMAP_PLUGIN_ID@skynote/plugins-basic/minimap,用于识别实例,不是额外的包导入子路径
MINIMAP_MIN_VIEWPORT_WIDTH50 CSS像素,最小视口映射宽度
fitMinimap(content: RectBounds | null, viewport: RectBounds, size: MinimapSize): MinimapProjection纯投影计算,先容纳内容与视口,再用最小视口宽度约束整体映射

纯函数调用方提供有效、有限的边界和正尺寸,不将其当作不可信数据的校验器。正常绘制优先使用getSnapshot返回的projection,尤其导航中不能自行换算另一套投影。最小视口约束作用于内容与视口的整体映射,高度保持主视口比例;触及约束时可能裁切远处内容。

关闭与销毁 ​

关闭面板时调用setFocused(false)、setEnabled(false),释放宿主指针捕获并取消待执行绘制帧;不再需要通知时调用subscribe返回的解绑函数。销毁整张画布由Editor.destroy完成,不手动调用插件unmount。

引擎卸载插件时会清空内容、导航和监听器并关闭插件;宿主仍负责自己的DOM监听、绘图资源与异步任务。示例不代表完整小地图UI或大场景帧率已经验收。

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