name: json-canvas category: document-processing description: 创建和编辑 JSON Canvas 文件(.canvas),包含节点、边、组和连接。当处理 .canvas 文件、创建可视化画布、思维导图、流程图,或用户提到 Obsidian 中的 Canvas 文件时使用。
JSON Canvas
此技能使 Claude Code 能够创建和编辑有效的 JSON Canvas 文件(.canvas),遵循 JSON Canvas 规范 1.0。
概述
JSON Canvas 是一种用于无限画布数据的开放文件格式。Canvas 文件使用 .canvas 扩展名,并包含遵循 JSON Canvas 规范 1.0 的有效 JSON。
何时使用此技能
- 在 Obsidian 中创建或编辑 .canvas 文件
- 构建可视化思维导图或流程图
- 创建项目板或规划文档
- 通过连接视觉化组织笔记
- 构建带有链接内容的图表
文件结构
一个 canvas 文件包含两个顶级数组:
{
"nodes": [],
"edges": []
}
nodes(可选):节点对象数组edges(可选):连接节点的边对象数组
节点
节点是放置在画布上的对象。有四种节点类型:
text- 包含 Markdown 的文本内容file- 引用文件或附件link- 外部 URLgroup- 其他节点的视觉容器
Z-索引顺序
第一个节点 = 底层(显示在其他节点下方) 最后一个节点 = 顶层(显示在其他节点上方)
通用节点属性
| 属性 | 必填 | 类型 | 描述 |
|---|---|---|---|
id |
是 | 字符串 | 节点的唯一标识符 |
type |
是 | 字符串 | 节点类型:text、file、link 或 group |
x |
是 | 整数 | X 位置(像素) |
y |
是 | 整数 | Y 位置(像素) |
width |
是 | 整数 | 宽度(像素) |
height |
是 | 整数 | 高度(像素) |
color |
否 | canvasColor | 节点颜色(参见颜色部分) |
文本节点
文本节点包含 Markdown 内容。
{
"id": "text1",
"type": "text",
"x": 0,
"y": 0,
"width": 300,
"height": 150,
"text": "# 标题
这是 **Markdown** 内容。"
}
文件节点
文件节点引用文件或附件(图像、视频、PDF、笔记等)。
| 属性 | 必填 | 类型 | 描述 |
|---|---|---|---|
file |
是 | 字符串 | 系统内文件路径 |
subpath |
否 | 字符串 | 链接到标题或块(以 # 开头) |
{
"id": "file1",
"type": "file",
"x": 350,
"y": 0,
"width": 400,
"height": 300,
"file": "Notes/My Note.md",
"subpath": "#Heading"
}
链接节点
链接节点显示外部 URL。
{
"id": "link1",
"type": "link",
"x": 0,
"y": 200,
"width": 300,
"height": 150,
"url": "https://example.com"
}
组节点
组节点是用于组织其他节点的视觉容器。
| 属性 | 必填 | 类型 | 描述 |
|---|---|---|---|
label |
否 | 字符串 | 组的文本标签 |
background |
否 | 字符串 | 背景图像路径 |
backgroundStyle |
否 | 字符串 | 背景渲染样式 |
背景样式
| 值 | 描述 |
|---|---|
cover |
填充节点的整个宽度和高度 |
ratio |
保持背景图像的纵横比 |
repeat |
在两个方向上重复图像作为图案 |
{
"id": "group1",
"type": "group",
"x": -50,
"y": -50,
"width": 800,
"height": 500,
"label": "项目想法",
"color": "4"
}
边
边是连接节点的线。
| 属性 | 必填 | 类型 | 默认 | 描述 |
|---|---|---|---|---|
id |
是 | 字符串 | - | 边的唯一标识符 |
fromNode |
是 | 字符串 | - | 连接起始的节点 ID |
fromSide |
否 | 字符串 | - | 边起始的侧边 |
fromEnd |
否 | 字符串 | none |
边起点的形状 |
toNode |
是 | 字符串 | - | 连接结束的节点 ID |
toSide |
否 | 字符串 | - | 边结束的侧边 |
toEnd |
否 | 字符串 | arrow |
边终点的形状 |
color |
否 | canvasColor | - | 线颜色 |
label |
否 | 字符串 | - | 边的文本标签 |
侧边值
| 值 | 描述 |
|---|---|
top |
节点的顶部边缘 |
right |
节点的右侧边缘 |
bottom |
节点的底部边缘 |
left |
节点的左侧边缘 |
终点形状
| 值 | 描述 |
|---|---|
none |
无终点形状 |
arrow |
箭头终点 |
{
"id": "edge1",
"fromNode": "text1",
"fromSide": "right",
"toNode": "file1",
"toSide": "left",
"toEnd": "arrow",
"label": "引用"
}
颜色
canvasColor 类型支持十六进制颜色和预设选项。
十六进制颜色
{
"color": "#FF0000"
}
预设颜色
| 预设 | 颜色 |
|---|---|
"1" |
红色 |
"2" |
橙色 |
"3" |
黄色 |
"4" |
绿色 |
"5" |
青色 |
"6" |
紫色 |
预设的具体颜色值有意未定义,允许应用程序使用自己的品牌颜色。
完整示例
简单画布带文本和连接
{
"nodes": [
{
"id": "idea1",
"type": "text",
"x": 0,
"y": 0,
"width": 250,
"height": 100,
"text": "# 主要想法
核心概念在这里"
},
{
"id": "idea2",
"type": "text",
"x": 350,
"y": -50,
"width": 200,
"height": 80,
"text": "## 支持点 1
详细信息..."
},
{
"id": "idea3",
"type": "text",
"x": 350,
"y": 100,
"width": 200,
"height": 80,
"text": "## 支持点 2
更多细节..."
}
],
"edges": [
{
"id": "e1",
"fromNode": "idea1",
"fromSide": "right",
"toNode": "idea2",
"toSide": "left",
"toEnd": "arrow"
},
{
"id": "e2",
"fromNode": "idea1",
"fromSide": "right",
"toNode": "idea3",
"toSide": "left",
"toEnd": "arrow"
}
]
}
项目板带组
{
"nodes": [
{
"id": "todo-group",
"type": "group",
"x": 0,
"y": 0,
"width": 300,
"height": 400,
"label": "待办事项",
"color": "1"
},
{
"id": "progress-group",
"type": "group",
"x": 350,
"y": 0,
"width": 300,
"height": 400,
"label": "进行中",
"color": "3"
},
{
"id": "done-group",
"type": "group",
"x": 700,
"y": 0,
"width": 300,
"height": 400,
"label": "已完成",
"color": "4"
},
{
"id": "task1",
"type": "text",
"x": 20,
"y": 50,
"width": 260,
"height": 80,
"text": "## 任务 1
第一个任务的描述"
},
{
"id": "task2",
"type": "text",
"x": 370,
"y": 50,
"width": 260,
"height": 80,
"text": "## 任务 2
当前正在处理这个"
},
{
"id": "task3",
"type": "text",
"x": 720,
"y": 50,
"width": 260,
"height": 80,
"text": "## 任务 3
~~已完成的任务~~"
}
],
"edges": []
}
研究画布带文件和链接
{
"nodes": [
{
"id": "central",
"type": "text",
"x": 200,
"y": 200,
"width": 200,
"height": 100,
"text": "# 研究主题
主要研究问题",
"color": "6"
},
{
"id": "notes1",
"type": "file",
"x": 0,
"y": 0,
"width": 180,
"height": 150,
"file": "Research/Literature Review.md"
},
{
"id": "notes2",
"type": "file",
"x": 450,
"y": 0,
"width": 180,
"height": 150,
"file": "Research/Methodology.md"
},
{
"id": "source1",
"type": "link",
"x": 0,
"y": 350,
"width": 180,
"height": 100,
"url": "https://scholar.google.com"
},
{
"id": "source2",
"type": "link",
"x": 450,
"y": 350,
"width": 180,
"height": 100,
"url": "https://arxiv.org"
}
],
"edges": [
{
"id": "e1",
"fromNode": "central",
"toNode": "notes1",
"toEnd": "arrow",
"label": "文献"
},
{
"id": "e2",
"fromNode": "central",
"toNode": "notes2",
"toEnd": "arrow",
"label": "方法"
},
{
"id": "e3",
"fromNode": "central",
"toNode": "source1",
"toEnd": "arrow"
},
{
"id": "e4",
"fromNode": "central",
"toNode": "source2",
"toEnd": "arrow"
}
]
}
流程图
{
"nodes": [
{
"id": "start",
"type": "text",
"x": 100,
"y": 0,
"width": 150,
"height": 60,
"text": "**开始**",
"color": "4"
},
{
"id": "decision",
"type": "text",
"x": 75,
"y": 120,
"width": 200,
"height": 80,
"text": "## 决策
条件是否为真?",
"color": "3"
},
{
"id": "yes-path",
"type": "text",
"x": -100,
"y": 280,
"width": 150,
"height": 60,
"text": "**是路径**
执行操作 A"
},
{
"id": "no-path",
"type": "text",
"x": 300,
"y": 280,
"width": 150,
"height": 60,
"text": "**否路径**
执行操作 B"
},
{
"id": "end",
"type": "text",
"x": 100,
"y": 420,
"width": 150,
"height": 60,
"text": "**结束**",
"color": "1"
}
],
"edges": [
{
"id": "e1",
"fromNode": "start",
"fromSide": "bottom",
"toNode": "decision",
"toSide": "top",
"toEnd": "arrow"
},
{
"id": "e2",
"fromNode": "decision",
"fromSide": "left",
"toNode": "yes-path",
"toSide": "top",
"toEnd": "arrow",
"label": "是"
},
{
"id": "e3",
"fromNode": "decision",
"fromSide": "right",
"toNode": "no-path",
"toSide": "top",
"toEnd": "arrow",
"label": "否"
},
{
"id": "e4",
"fromNode": "yes-path",
"fromSide": "bottom",
"toNode": "end",
"toSide": "left",
"toEnd": "arrow"
},
{
"id": "e5",
"fromNode": "no-path",
"fromSide": "bottom",
"toNode": "end",
"toSide": "right",
"toEnd": "arrow"
}
]
}
ID 生成
节点和边的 ID 必须是唯一的字符串。Obsidian 生成 16 字符的十六进制 ID。
示例格式:a1b2c3d4e5f67890
布局指南
定位
- 坐标可以为负(画布无限延伸)
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"或有效的十六进制颜色