| 名称 | json-canvas category: document-processing |
| 描述 | 创建和编辑 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"或有效的十六进制颜色