name: json-canvas description: 创建和编辑JSON Canvas文件(.canvas),包含节点、边、组和连接。当处理.canvas文件、创建视觉画布、思维导图、流程图,或用户提到Obsidian中的Canvas文件时使用。
JSON Canvas 技能
此技能使Claude Code能够创建和编辑用于Obsidian和其他应用的有效JSON Canvas文件(.canvas)。
概述
JSON Canvas 是一种用于无限画布数据的开放文件格式。Canvas文件使用.canvas扩展名,并包含遵循JSON Canvas Spec 1.0的有效JSON。
文件结构
一个canvas文件包含两个顶级数组:
{
"nodes": [],
"edges": []
}
nodes(可选):节点对象数组edges(可选):连接节点的边对象数组
节点
节点是放置在画布上的对象。有四种节点类型:
text- 包含Markdown的文本内容file- 引用文件或附件link- 外部URLgroup- 其他节点的视觉容器
Z-Index 排序
节点按z-index在数组中排序:
- 第一个节点 = 底层(显示在其他节点下方)
- 最后一个节点 = 顶层(显示在其他节点上方)
通用节点属性
所有节点共享这些属性:
| 属性 | 必需 | 类型 | 描述 |
|---|---|---|---|
id |
是 | 字符串 | 节点的唯一标识符 |
type |
是 | 字符串 | 节点类型:text、file、link 或 group |
x |
是 | 整数 | X位置(像素) |
y |
是 | 整数 | Y位置(像素) |
width |
是 | 整数 | 宽度(像素) |
height |
是 | 整数 | 高度(像素) |
color |
否 | canvasColor | 节点颜色(参见颜色部分) |
文本节点
文本节点包含Markdown内容。
{
"id": "6f0ad84f44ce9c17",
"type": "text",
"x": 0,
"y": 0,
"width": 400,
"height": 200,
"text": "# 你好世界
这是 **Markdown** 内容。"
}
| 属性 | 必需 | 类型 | 描述 |
|---|---|---|---|
text |
是 | 字符串 | 带有Markdown语法的纯文本 |
文件节点
文件节点引用文件或附件(图像、视频、PDF、笔记等)。
{
"id": "a1b2c3d4e5f67890",
"type": "file",
"x": 500,
"y": 0,
"width": 400,
"height": 300,
"file": "附件/图表.png"
}
{
"id": "b2c3d4e5f6789012",
"type": "file",
"x": 500,
"y": 400,
"width": 400,
"height": 300,
"file": "笔记/项目概述.md",
"subpath": "#实施"
}
| 属性 | 必需 | 类型 | 描述 |
|---|---|---|---|
file |
是 | 字符串 | 系统内文件路径 |
subpath |
否 | 字符串 | 链接到标题或块(以#开头) |
链接节点
链接节点显示外部URL。
{
"id": "c3d4e5f678901234",
"type": "link",
"x": 1000,
"y": 0,
"width": 400,
"height": 200,
"url": "https://obsidian.md"
}
| 属性 | 必需 | 类型 | 描述 |
|---|---|---|---|
url |
是 | 字符串 | 外部URL |
组节点
组节点是用于组织其他节点的视觉容器。
{
"id": "d4e5f6789012345a",
"type": "group",
"x": -50,
"y": -50,
"width": 1000,
"height": 600,
"label": "项目概述",
"color": "4"
}
{
"id": "e5f67890123456ab",
"type": "group",
"x": 0,
"y": 700,
"width": 800,
"height": 500,
"label": "资源",
"background": "附件/背景.png",
"backgroundStyle": "cover"
}
| 属性 | 必需 | 类型 | 描述 |
|---|---|---|---|
label |
否 | 字符串 | 组的文本标签 |
background |
否 | 字符串 | 背景图像路径 |
backgroundStyle |
否 | 字符串 | 背景渲染样式 |
背景样式
| 值 | 描述 |
|---|---|
cover |
填充节点的整个宽度和高度 |
ratio |
保持背景图像的宽高比 |
repeat |
在两个方向上重复图像作为图案 |
边
边是连接节点的线。
{
"id": "f67890123456789a",
"fromNode": "6f0ad84f44ce9c17",
"toNode": "a1b2c3d4e5f67890"
}
{
"id": "0123456789abcdef",
"fromNode": "6f0ad84f44ce9c17",
"fromSide": "right",
"fromEnd": "none",
"toNode": "b2c3d4e5f6789012",
"toSide": "left",
"toEnd": "arrow",
"color": "1",
"label": "导致"
}
| 属性 | 必需 | 类型 | 默认 | 描述 |
|---|---|---|---|---|
id |
是 | 字符串 | - | 边的唯一标识符 |
fromNode |
是 | 字符串 | - | 连接起始的节点ID |
fromSide |
否 | 字符串 | - | 边起始的边 |
fromEnd |
否 | 字符串 | none |
边起始的形状 |
toNode |
是 | 字符串 | - | 连接结束的节点ID |
toSide |
否 | 字符串 | - | 边结束的边 |
toEnd |
否 | 字符串 | arrow |
边结束的形状 |
color |
否 | canvasColor | - | 线条颜色 |
label |
否 | 字符串 | - | 边的文本标签 |
边值
| 值 | 描述 |
|---|---|
top |
节点的顶部边 |
right |
节点的右侧边 |
bottom |
节点的底部边 |
left |
节点的左侧边 |
末端形状
| 值 | 描述 |
|---|---|
none |
无端点形状 |
arrow |
箭头端点 |
颜色
canvasColor 类型可以通过两种方式指定:
十六进制颜色
{
"color": "#FF0000"
}
预设颜色
{
"color": "1"
}
| 预设 | 颜色 |
|---|---|
"1" |
红色 |
"2" |
橙色 |
"3" |
黄色 |
"4" |
绿色 |
"5" |
青色 |
"6" |
紫色 |
注意:预设的特定颜色值故意未定义,允许应用使用自己的品牌颜色。
完整示例
简单画布带文本和连接
{
"nodes": [
{
"id": "8a9b0c1d2e3f4a5b",
"type": "text",
"x": 0,
"y": 0,
"width": 300,
"height": 150,
"text": "# 主要想法
这是核心概念。"
},
{
"id": "1a2b3c4d5e6f7a8b",
"type": "text",
"x": 400,
"y": -100,
"width": 250,
"height": 100,
"text": "## 支持点 A
详情在此。"
},
{
"id": "2b3c4d5e6f7a8b9c",
"type": "text",
"x": 400,
"y": 100,
"width": 250,
"height": 100,
"text": "## 支持点 B
更多详情。"
}
],
"edges": [
{
"id": "3c4d5e6f7a8b9c0d",
"fromNode": "8a9b0c1d2e3f4a5b",
"fromSide": "right",
"toNode": "1a2b3c4d5e6f7a8b",
"toSide": "left"
},
{
"id": "4d5e6f7a8b9c0d1e",
"fromNode": "8a9b0c1d2e3f4a5b",
"fromSide": "right",
"toNode": "2b3c4d5e6f7a8b9c",
"toSide": "left"
}
]
}
带组的项目板
{
"nodes": [
{
"id": "5e6f7a8b9c0d1e2f",
"type": "group",
"x": 0,
"y": 0,
"width": 300,
"height": 500,
"label": "待办事项",
"color": "1"
},
{
"id": "6f7a8b9c0d1e2f3a",
"type": "group",
"x": 350,
"y": 0,
"width": 300,
"height": 500,
"label": "进行中",
"color": "3"
},
{
"id": "7a8b9c0d1e2f3a4b",
"type": "group",
"x": 700,
"y": 0,
"width": 300,
"height": 500,
"label": "已完成",
"color": "4"
},
{
"id": "8b9c0d1e2f3a4b5c",
"type": "text",
"x": 20,
"y": 50,
"width": 260,
"height": 80,
"text": "## 任务 1
实施功能 X"
},
{
"id": "9c0d1e2f3a4b5c6d",
"type": "text",
"x": 370,
"y": 50,
"width": 260,
"height": 80,
"text": "## 任务 2
审查 PR #123",
"color": "2"
},
{
"id": "0d1e2f3a4b5c6d7e",
"type": "text",
"x": 720,
"y": 50,
"width": 260,
"height": 80,
"text": "## 任务 3
~~设置 CI/CD~~"
}
],
"edges": []
}
带文件和链接的研究画布
{
"nodes": [
{
"id": "1e2f3a4b5c6d7e8f",
"type": "text",
"x": 300,
"y": 200,
"width": 400,
"height": 200,
"text": "# 研究主题
## 关键问题
- X 如何影响 Y?
- 含义是什么?",
"color": "5"
},
{
"id": "2f3a4b5c6d7e8f9a",
"type": "file",
"x": 0,
"y": 0,
"width": 250,
"height": 150,
"file": "文献/论文 A.pdf"
},
{
"id": "3a4b5c6d7e8f9a0b",
"type": "file",
"x": 0,
"y": 200,
"width": 250,
"height": 150,
"file": "笔记/会议笔记.md",
"subpath": "#关键见解"
},
{
"id": "4b5c6d7e8f9a0b1c",
"type": "link",
"x": 0,
"y": 400,
"width": 250,
"height": 100,
"url": "https://example.com/research"
},
{
"id": "5c6d7e8f9a0b1c2d",
"type": "file",
"x": 750,
"y": 150,
"width": 300,
"height": 250,
"file": "附件/图表.png"
}
],
"edges": [
{
"id": "6d7e8f9a0b1c2d3e",
"fromNode": "2f3a4b5c6d7e8f9a",
"fromSide": "right",
"toNode": "1e2f3a4b5c6d7e8f",
"toSide": "left",
"label": "支持"
},
{
"id": "7e8f9a0b1c2d3e4f",
"fromNode": "3a4b5c6d7e8f9a0b",
"fromSide": "right",
"toNode": "1e2f3a4b5c6d7e8f",
"toSide": "left",
"label": "告知"
},
{
"id": "8f9a0b1c2d3e4f5a",
"fromNode": "4b5c6d7e8f9a0b1c",
"fromSide": "right",
"toNode": "1e2f3a4b5c6d7e8f",
"toSide": "left",
"toEnd": "arrow",
"color": "6"
},
{
"id": "9a0b1c2d3e4f5a6b",
"fromNode": "1e2f3a4b5c6d7e8f",
"fromSide": "right",
"toNode": "5c6d7e8f9a0b1c2d",
"toSide": "left",
"label": "可视化"
}
]
}
流程图
{
"nodes": [
{
"id": "a0b1c2d3e4f5a6b7",
"type": "text",
"x": 200,
"y": 0,
"width": 150,
"height": 60,
"text": "**开始**",
"color": "4"
},
{
"id": "b1c2d3e4f5a6b7c8",
"type": "text",
"x": 200,
"y": 100,
"width": 150,
"height": 60,
"text": "步骤 1:
收集数据"
},
{
"id": "c2d3e4f5a6b7c8d9",
"type": "text",
"x": 200,
"y": 200,
"width": 150,
"height": 80,
"text": "**决策**
数据是否有效?",
"color": "3"
},
{
"id": "d3e4f5a6b7c8d9e0",
"type": "text",
"x": 400,
"y": 200,
"width": 150,
"height": 60,
"text": "处理数据"
},
{
"id": "e4f5a6b7c8d9e0f1",
"type": "text",
"x": 0,
"y": 200,
"width": 150,
"height": 60,
"text": "请求新数据",
"color": "1"
},
{
"id": "f5a6b7c8d9e0f1a2",
"type": "text",
"x": 400,
"y": 320,
"width": 150,
"height": 60,
"text": "**结束**",
"color": "4"
}
],
"edges": [
{
"id": "a6b7c8d9e0f1a2b3",
"fromNode": "a0b1c2d3e4f5a6b7",
"fromSide": "bottom",
"toNode": "b1c2d3e4f5a6b7c8",
"toSide": "top"
},
{
"id": "b7c8d9e0f1a2b3c4",
"fromNode": "b1c2d3e4f5a6b7c8",
"fromSide": "bottom",
"toNode": "c2d3e4f5a6b7c8d9",
"toSide": "top"
},
{
"id": "c8d9e0f1a2b3c4d5",
"fromNode": "c2d3e4f5a6b7c8d9",
"fromSide": "right",
"toNode": "d3e4f5a6b7c8d9e0",
"toSide": "left",
"label": "是",
"color": "4"
},
{
"id": "d9e0f1a2b3c4d5e6",
"fromNode": "c2d3e4f5a6b7c8d9",
"fromSide": "left",
"toNode": "e4f5a6b7c8d9e0f1",
"toSide": "right",
"label": "否",
"color": "1"
},
{
"id": "e0f1a2b3c4d5e6f7",
"fromNode": "e4f5a6b7c8d9e0f1",
"fromSide": "top",
"fromEnd": "none",
"toNode": "b1c2d3e4f5a6b7c8",
"toSide": "left",
"toEnd": "arrow"
},
{
"id": "f1a2b3c4d5e6f7a8",
"fromNode": "d3e4f5a6b7c8d9e0",
"fromSide": "bottom",
"toNode": "f5a6b7c8d9e0f1a2",
"toSide": "top"
}
]
}
ID 生成
节点和边的ID必须是唯一字符串。Obsidian生成16字符十六进制ID:
"id": "6f0ad84f44ce9c17"
"id": "a3b2c1d0e9f8g7h6"
"id": "1234567890abcdef"
此格式是16字符小写十六进制字符串(64位随机值)。
布局指南
定位
- 坐标可以为负(画布无限延伸)
x向右增加y向下增加- 位置指节点的左上角
推荐尺寸
| 节点类型 | 建议宽度 | 建议高度 |
|---|---|---|
| 小文本 | 200-300 | 80-150 |
| 中等文本 | 300-450 | 150-300 |
| 大文本 | 400-600 | 300-500 |
| 文件预览 | 300-500 | 200-400 |
| 链接预览 | 250-400 | 100-200 |
| 组 | 可变 | 可变 |
间距
- 在组内留出20-50px内边距
- 节点间间隔50-100px以提高可读性
- 对齐节点到网格(10或20的倍数)以获得更清晰的布局
验证规则
- 所有
id值必须在节点和边中唯一 fromNode和toNode必须引用现有的节点ID- 每种节点类型的必需字段必须存在
type必须是以下之一:text、file、link、groupbackgroundStyle必须是以下之一:cover、ratio、repeatfromSide、toSide必须是以下之一:top、right、bottom、leftfromEnd、toEnd必须是以下之一:none、arrow- 颜色预设必须是
"1"到"6"或有效的十六进制颜色