一键导入
obsidian-plugin-excalidraw
生成符合当前 Excalidraw JSON Schema 的白板文件(.excalidraw),支持形状、智能连线、文本绑定、Obsidian 内部链接。兼容 Obsidian Excalidraw 插件 2.0+,用于绘制架构图、流程图、思维导图。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
生成符合当前 Excalidraw JSON Schema 的白板文件(.excalidraw),支持形状、智能连线、文本绑定、Obsidian 内部链接。兼容 Obsidian Excalidraw 插件 2.0+,用于绘制架构图、流程图、思维导图。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Captures learnings, errors, and corrections to enable continuous improvement. Use when: (1) A command or operation fails unexpectedly, (2) User corrects Claude ('No, that's wrong...', 'Actually...'), (3) User requests a capability that doesn't exist, (4) An external API or tool fails, (5) Claude realizes its knowledge is outdated or incorrect, (6) A better approach is discovered for a recurring task. Also review learnings before major tasks.
Extract clean markdown content from web pages using Defuddle CLI, removing clutter and navigation to save tokens. Use instead of WebFetch when the user provides a URL to read or analyze, for online documentation, articles, blog posts, or any standard web page. Do NOT use for URLs ending in .md — those are already markdown, use WebFetch directly.
Use when starting any conversation - establishes how to find and use skills, requiring Skill tool invocation before ANY response including clarifying questions
Use when you have a spec or requirements for a multi-step task, before touching code
Wrapper skill for the add-skill CLI. Installs skills from arbitrary GitHub repos for OpenCode/Claude/Codex.
A fast Rust-based headless browser automation CLI with Node.js fallback that enables AI agents to navigate, click, type, and snapshot pages via structured commands.
| name | obsidian-plugin-excalidraw |
| description | 生成符合当前 Excalidraw JSON Schema 的白板文件(.excalidraw),支持形状、智能连线、文本绑定、Obsidian 内部链接。兼容 Obsidian Excalidraw 插件 2.0+,用于绘制架构图、流程图、思维导图。 |
Excalidraw 文件为 JSON 格式,扩展名 .excalidraw。必须包含以下顶级字段:
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [],
"appState": {
"gridSize": 20,
"viewBackgroundColor": "#ffffff",
"theme": "light",
"currentItemFontFamily": 1,
"exportBackground": true,
"viewModeEnabled": false
},
"files": {}
}
警告:如果elements中引用了图片(type: "image"),必须在files对象中提供对应的二进制数据(DataURL),否则打开文件会导致插件崩溃或无限加载。
渲染顺序:elements数组索引 0 为最底层,N 为最顶层
gridSize:强制对齐网格
files:仅在涉及图片嵌入时使用,否则为空对象
关键约束:
elements 数组顺序决定。
大部分元素对象包含以下字段,部分字段为类型特定或可选:
| 字段 | 类型/值域 | 默认值 | 严格约束说明 |
|---|---|---|---|
id | string | - | 全局唯一。 |
type | enum | - | 见下方类型详解。 |
x, y | float | - | 建议取整以防抗锯齿模糊。 |
width, height | float | - | 必须 > 0。 |
angle | float | 0 | 弧度制 (0 ~ 2π)。顺时针旋转。 |
strokeColor | hex | "#1e1e1e" | 避免纯黑(#000)。 |
backgroundColor | hex | "transparent" | 支持 8位 Hex 透明度 (e.g. #ff000080)。 |
fillStyle | enum | "solid" | "hachure", "cross-hatch", "solid", "zigzag" |
strokeWidth | int | 1 | 1(细), 2(标准), 4(粗)。 |
strokeStyle | enum | "solid" | "solid", "dashed", "dotted" |
roughness | int | 1 | 0(几何), 1(手绘), 2(素描)。 |
opacity | int | 100 | 0-100。 |
groupIds | string[] | [] | 属于哪个分组。用于把多个元素编组(类似 Ctrl+G),移动/删除时整体操作。严格逻辑:同一个组内的所有元素必须拥有完全相同的group ID字符串。生成时一般为空,除非需要批量移动的复合图形。复制元素时需同时复制group ID。 |
roundness | object | null | 见下方详细对象结构。 |
seed | int | random | 正整数(建议 100000 ~ 999999999),用于确定手绘抖动的随机种子,保证渲染一致性。 |
version | int | 1 | 每次修改自增。生成时默认为 1。 |
versionNonce | int | random | 0 ~ 2^32-1。 |
isDeleted | bool | false | 若为 true,Obsidian 将不渲染该元素。 |
boundElements | array | [] | 关键:用于双向绑定。 |
updated | int | time | 毫秒时间戳。 |
link | string | null | Obsidian 内部链接格式。 |
locked | bool | false | 是否锁定。 |
frameId | `string | null` | null |
重要说明:
示例
{
"id": "unique-string",
"type": "...",
"x": 100,
"y": 100,
"width": 120,
"height": 80,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"seed": 123456789,
"version": 1,
"versionNonce": 987654321,
"isDeleted": false,
"updated": 1735689600000,
"link": null,
"locked": false
}
坐标计算公式(避免亚像素模糊):
x = Math.round(targetX)y = Math.round(targetY)width = Math.ceil(targetWidth)height = Math.ceil(targetHeight)文本居中公式(严苛版):
textElement.x = container.x + (container.width - textElement.width) / 2;
textElement.y = container.y + (container.height - textElement.height) / 2;
容器类 (Rectangle, Ellipse, Diamond)
圆角规则 (roundness):
roundness: nullroundness: { "type": 1 } (PROPORTIONAL_RADIUS / LEGACY) - 旧版格式roundness: { "type": 2 } (ADAPTIVE_RADIUS) - 当前标准建议值,最平滑,无需 valueroundness: { "type": 3, "value": 20 } (FIXED_RADIUS) - 配合 value 使用,提供特定像素的圆角注意:在2024年后的版本中,菱形(Diamond)也支持roundness对象。
{
"type": "rectangle",
"roundness": null
}
圆角选项:
roundness: nullroundness: { "type": 1, "value": 20 }roundness: { "type": 2 }{
"type": "diamond",
"roundness": null
}
菱形圆角选项:
roundness: nullroundness: { "type": 2 }roundness: { "type": 3, "value": 10 }注意:在2024年后的版本中,菱形也支持roundness对象。
{
"type": "ellipse",
"roundness": null
}
注意:x, y 为外接矩形左上角。
极高风险项,文本是渲染最容易出错的部分。必须严格遵循以下计算
{
"type": "text",
"fontSize": 20,
"fontFamily": 1,
"lineHeight": 1.25,
"text": "第一行\n第二行",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": "box-1",
"baseline": 18,
"width": 60,
"height": 45
}
文本元素说明:
fontFamily:1=Virgil(手绘), 2=Helvetica(无衬线), 3=Cascadia(代码字体)。Obsidian 插件通常不支持其他值。lineHeight:必须提供,否则多行文本对齐会乱。text:必须显式包含 \n,Excalidraw 不会自动换行。verticalAlign:"top", "middle", "bottom" (仅当 containerId 不为 null 时生效)。baseline:计算值,对于多行文本,仍然是第一行的基线高度。width:必须预计算文本实际宽度。height:必须包含所有行高之和。绑定规则(严格):
文本元素重要说明:
Baseline 计算公式 (近似值):
警告:不要依赖硬编码的 baseline 近似值!实际场景中(多行文本、verticalAlign 不同、lineHeight 变化)都会导致明显偏移。
强烈建议:
箭头坐标是相对坐标体系。
{
"type": "arrow",
"x": 100,
"y": 100,
"width": 150,
"height": 50,
"angle": 0,
"points": [
[0, 0],
[150, 0]
],
"lastCommittedPoint": [150, 0],
"startArrowhead": null,
"endArrowhead": "triangle",
"startBinding": {
"elementId": "rect-1",
"focus": 0,
"gap": 8
},
"endBinding": {
"elementId": "rect-2",
"focus": 0,
"gap": 8
},
"strokeSharpness": "round"
}
箭头元素说明:
type:"arrow" 或 "line"(直线,无默认箭头样式)。x, y:起点基准坐标。width, height:由points计算出的包围盒(必须正确)。points:
lastCommittedPoint:必须等于points最后一项,始终与points数组的最后一个元素保持一致。startArrowhead:有效值:"arrow", "triangle", "dot", "bar", "diamond", "circle", "triangle_filled", "arrow_filled", null。endArrowhead:默认值:null(无箭头);常用:"triangle"(尖头)、"arrow"(经典箭头)。focus:-1 ~ 1,0=中心最稳定。gap:必填,推荐4~12,避免默认间距过大。strokeSharpness:"round"(圆角折线/贝塞尔感)、"sharp"(直折角)。说明:
常用推荐组合:
"files": { "fileId": { "type": "image/png", "data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==" } }
**图片文件说明**:
- `type`:必须准确,与DataURL的mimeType一致。
- `data`:Base64编码的图片数据,格式为data:image/{format};base64,{data}。
**注意**:"type"字段的mimeType必须与DataURL中的mimeType完全一致,否则可能导致图片无法加载。
- **freedraw**:type: "freedraw",points: [[x,y], ...](绝对坐标),用于手绘路径。
**说明**:以上类型覆盖90%架构图/流程图/思维导图场景,其余类型可参考Excalidraw导出JSON。
#### 6. 双向绑定握手协议 (The Binding Handshake)
**核心原则**:在 Excalidraw 中,绑定必须是双向声明的。任何一方缺失都会导致“假绑定”(视觉接触但拖动分离)。
**双向绑定规则**:
- **容器 -> 成员**:容器(Rectangle/Ellipse/Diamond/Frame)的 boundElements 数组内必须包含对象:{"id": "member-id", "type": "text" | "arrow"}。
- **成员 -> 容器**:
- 文本需设置 containerId: "container-id"。
- 箭头需设置 startBinding 或 endBinding。
**严苛警告**:
- 如果容器被 isDeleted: true,但其绑定的文本 isDeleted: false,Obsidian 会渲染一个漂浮在原地的文本。必须级联删除。
- 箭头指向容器时,容器的 boundElements 必须包含箭头的 ID,否则箭头不会跟随容器移动。
##### 场景 A:文本放入矩形 (Text inside Rectangle)
1. **矩形侧**:`boundElements` 必须包含文本 ID。
JSON
"id": "rect-1", "boundElements": [ { "id": "text-1", "type": "text" } ]
2. **文本侧**:`containerId` 必须指向矩形 ID。
JSON
"id": "text-1", "containerId": "rect-1"
3. **坐标对齐**:文本的 `x, y` 必须经过计算,使其位于矩形中心(或指定的 align 位置)。
##### 场景 B:箭头连接矩形 (Arrow connects Rectangles)
1. **箭头侧**:声明 `startBinding` 或 `endBinding`。
JSON
"startBinding": { "elementId": "rect-1", "focus": 0, "gap": 8 }
2. **矩形侧**:`boundElements` 必须包含箭头 ID。
JSON
"boundElements": [ { "id": "text-1", "type": "text" }, { "id": "arrow-1", "type": "arrow" } ]
##### 推荐文件格式
**优先使用 `.excalidraw` 文件格式**,这是纯JSON格式,兼容性最好,不易出错:
- **文件扩展名**:`.excalidraw`
- **文件内容**:纯JSON格式,无任何额外内容
- **格式要求**:严格遵循以下结构
```json
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [],
"appState": {},
"files": {}
}
重要说明:
.excalidraw.md 格式,因为AI生成compressed-json结构容易出错.excalidraw 是Excalidraw的原生格式,兼容性最好生成规范:
"link": "[[Note]]""link": "[[Note|显示别名]]""link": "[[Note#Heading]]""link": "[[Note#^block-id]]""link": "[[Folder/Note#Section|^alias]]""link": "exec:脚本名"(用于执行 Obsidian 脚本)file:// 或 obsidian://,直接写 WikiLink。"customData": {
"someKey": "someValue"
}
建议:暗色主题下优先使用 #2e2e2e 作为 strokeColor,提高可读性。
暗色主题推荐搭配:
推荐文件格式:Diagram.excalidraw(纯 JSON)
优势:
嵌入语法
Markdown
![[Diagram.excalidraw]] <!-- 可编辑画布 -->
![[Diagram.excalidraw|600]] <!-- 指定宽度 -->
![[Diagram.excalidraw|600x400]] <!-- 宽高 -->
重要提示:
.excalidraw.md 格式,因为AI生成compressed-json结构容易出错.excalidraw 文件,以获得最佳的兼容性和可靠性内部链接(link 字段) 支持 [[Note]], [[Note#heading]], [[Note|alias]], [[Note#^block]]
\n?rect-1,但 rect-1 的 boundElements 里没有箭头 ID?(修正:必须双向添加)。x: 100.3333333?(修正:除 angle 外,尽量 Math.round() 坐标,提升渲染性能)。strokeColor 有足够对比度)。水平节点间距 180–250px,垂直 120–180px
字体:标题 28–36px,正文 20px,注释 16px
fillStyle: "solid"(推荐)、"hachure"(手绘斜线)、"cross-hatch"
roughness: 1(标准),0(锐利),2(极粗)
生成时:先容器 → 文本 → 箭头(保证绑定顺序)
使用当前时间戳 + 递增小偏移作为 updated
双向绑定必做:
focus 参数计算建议(-1 ~ 1):
gap 参数建议:
0:箭头端点紧贴容器边缘(可能穿模)。
8~12:最佳视觉间隙(推荐值)。
15:箭头太远,显得松散。
points / width / height 计算(生成时必须正确):
创建顺序: 先创建所有容器 → 再创建箭头(绑定依赖容器已存在 ID)。 文本绑定同理:容器先,文本后。
常见绑定失败调试(添加到“常见错误与调试”):
版本兼容性:基于 Excalidraw JSON v2 + Obsidian Excalidraw 插件 2.0+(2025 年最新)。
当使用 AI 生成 Excalidraw JSON 文件时,必须严格遵守以下约束,以防止解析错误:
// 或 /* */ 注释。... 或 (其余内容同上),必须输出完整的、合法的 JSON 对象。"x": - 这种非法格式。负数必须带有前导数字(如 -0.5 而不是 -.5)。json ... 之间,且上方必须有完整的 YAML Frontmatter 区。在生成或修改 Excalidraw 文件后,请检查以下项目,以避免常见错误:
JSON 语法错误:
版本差异:
绑定关系复杂性:
必填字段缺失:
严格遵循 JSON 规范:
版本兼容策略:
version: 2 格式简化绑定关系:
必填字段检查:
id:唯一标识符type:元素类型x, y:坐标位置width, height:尺寸seed:随机种子version:版本号versionNonce:版本随机数updated:时间戳调试技巧:
使用模板文件:
版本标记:
兼容性测试:
错误处理:
通过遵循以上解决方案,可以确保生成的 Excalidraw 文件在当前版本中正常显示,同时保持向前兼容性。