Files
OneOS1.2/.agents/skills/canvas-workspace/references/canvas-read-write.md
王冕 af29b26fe8 Sync OneOS workspace with new prototypes, annotations, and Gitea remote fix.
Add vehicle-h2-fee-ledger, customer-management, lease and self-operated ledgers, annotation sources, agent skills, and vite annotation runtime support. Update vehicle management, contract templates, and lease contract flows.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 15:27:23 +08:00

4.6 KiB
Raw Blame History

画布读写能力参考

面向使用 Skill 的 Agent优先读写本地 .excalidraw 文件。用户指定画布名或画布链接时,直接定位本地画布文件;不要使用 axhub-make canvas CLI。

快速判断

目标 做法
读取画布元素、批注、节点信息 直接读 .excalidraw
修改画布内容 直接改 .excalidraw
从用户给的画布链接定位元素 从链接提取画布名和元素 ID再读文件
获取画布截图 优先使用已有 canvas-assets 截图;需要当前浏览器画布时用全局截图 API

文件位置

常见路径:

src/prototypes/<prototype-name>/canvas.excalidraw
src/prototypes/<prototype-name>/canvas-assets/embed-<elementId>.png

.excalidraw 是 JSON。主要关注

  • elements:所有画布元素。
  • files:嵌入图片数据或图片元信息。
  • appState.gridSize:整理/对齐时参考。

读取画布

读取过程以本地 JSON 为准。

最常用字段:

字段 用途
id 元素唯一标识,链接定位和截图文件名会用到
type 元素类型,如 textimageembeddablearrow
x / y / width / height 位置和尺寸
isDeleted 为 true 时跳过
link 嵌入节点链接
customData 批注、标题、截图地址等 Axhub 扩展信息
fileId 图片元素对应的 files[fileId]

识别常见节点:

类型 判断方式
原型节点 type == "embeddable"customData.resourceType == "prototype",或 link/previewUrl 指向原型
文档节点 type == "embeddable"customData.type == "axhub-doc"customData.resourceType == "doc"
主题节点 type == "embeddable"customData.resourceType == "theme"customData.type == "axhub-theme"
Drawio 节点 type == "image"customData.type == "axhub-drawio"
图片元素 type == "image"
批注元素 customData.annotation 有值

Axhub 节点字段见 axhub-nodes.md

CLI

没有画布专用 CLI。读取元素、节点和批注时仍以 .excalidraw 文件为准;需要截图时,优先使用已有 canvas-assets 截图或浏览器页面能力。

浏览器截图 API

Excalidraw 官方暴露的是导出工具方法,例如 exportToBlobexportToCanvasexportToSvg不是当前画布实例的一键截图命令。Axhub 在浏览器里的当前画布实例上封装了全局截图 API

await window.__AXHUB_EXCALIDRAW_CAPTURE__.captureCanvas()
await window.__AXHUB_EXCALIDRAW_CAPTURE__.captureElement('<elementId>')

两个方法都返回:

{
  blob: Blob
  dataUrl: string
  width?: number
  height?: number
  elementIds: string[]
}

可选参数:

{
  exportBackground?: boolean
  exportPadding?: number
  maxWidthOrHeight?: number
  mimeType?: string
  quality?: number
  width?: number
  height?: number
}

默认导出 PNG、带背景、16px padding。captureCanvas() 导出当前画布所有未删除元素;captureElement(elementId) 只导出指定未删除元素。该能力只在画布页面打开并完成初始化后可用。

从链接定位

用户可能给一个带节点 ID 的画布链接。处理步骤:

  1. 从 URL 中提取画布名和元素 ID。
  2. 找到对应 .excalidraw 文件。
  3. elements 中找同 ID 元素。
  4. 如果是原型节点,预览截图通常在 canvas-assets/embed-<elementId>.png
  5. 如果是图片元素,按 fileIdfiles[fileId]
  6. 如果是嵌入节点,结合 customData.resourceTypecustomData.previewUrlcustomData.screenshotUrl 判断资源来源。

写入画布

直接修改 .excalidrawelements 数组。

添加元素

追加到 elements。必须有唯一 id,推荐沿用现有格式:<timestamp>-<random>

修改元素

更新目标字段后,同时更新:

  • version 加 1
  • versionNonce 换成新的随机整数
  • updated 设为当前毫秒时间戳

删除元素

默认直接从 elements 中移除。不要为了删除而设置 isDeleted: true,这会让画布文件持续膨胀。

如果遇到历史遗留的 isDeleted: true 元素,读取时跳过;整理画布时可以一并移除。

关系检查

修改连接、容器、分组时检查引用是否仍然存在:

  • boundElements
  • containerId
  • startBinding / endBinding
  • groupIds

热更新

保存 .excalidraw 后,打开中的画布会通过热更新同步。完成画布写入时,交付说明里标明画布文件路径和改动内容。