mcpField
J
json-canvas

json-canvas

github.com/davila7生产力33.0k397 次安装1 天前更新
代码仓库

关于 json-canvas

用于 Claude Code 的 Skill,可创建和编辑供 Obsidian 等应用使用的有效 JSON Canvas 文件,涵盖节点、边、布局及格式校验规则。

主要功能

  1. 01创建和编辑 .canvas 文件
  2. 02支持文本、文件、链接和分组节点
  3. 03定义边与节点连接
  4. 04设置布局、颜色和背景选项
  5. 05检查 JSON Canvas 校验规则

适用场景

  1. 01构建 Obsidian 项目看板
  2. 02在画布上整理研究文件和链接
  3. 03制作带连接关系的图表和流程图

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/davila7/claude-code-templates --skill json-canvas

安装后在 Claude Code 中输入/json-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 - 外部 URL
  • group - 其他节点的可视化容器
Z-Index 顺序

节点在数组中按 z-index 排序:

  • 第一个节点 = 底层(显示在其他节点下方)
  • 最后一个节点 = 顶层(显示在其他节点上方)
通用节点属性

所有节点共享以下属性:

属性必需类型描述
id是string节点的唯一标识符
type是string节点类型:text、file、link 或 group
x是integerX 位置(像素)
y是integerY 位置(像素)
width是integer宽度(像素)
height是integer高度(像素)
color否canvasColor节点颜色(见颜色部分)
文本节点

文本节点包含 Markdown 内容。

{
  "id": "6f0ad84f44ce9c17",
  "type": "text",
  "x": 0,
  "y": 0,
  "width": 400,
  "height": 200,
  "text": "# Hello World\n\nThis is **Markdown** content."
}
属性必需类型描述
text是string带有 Markdown 语法的纯文本
文件节点

文件节点引用文件或附件(图片、视频、PDF、笔记等)。

{
  "id": "a1b2c3d4e5f67890",
  "type": "file",
  "x": 500,
  "y": 0,
  "width": 400,
  "height": 300,
  "file": "Attachments/diagram.png"
}
{
  "id": "b2c3d4e5f6789012",
  "type": "file",
  "x": 500,
  "y": 400,
  "width": 400,
  "height": 300,
  "file": "Notes/Project Overview.md",
  "subpath": "#Implementation"
}
属性必需类型描述
file是string系统中文件的路径
subpath否string指向标题或块的链接(以 # 开头)
链接节点

链接节点显示外部 URL。

{
  "id": "c3d4e5f678901234",
  "type": "link",
  "x": 1000,
  "y": 0,
  "width": 400,
  "height": 200,
  "url": "https://obsidian.md"
}
属性必需类型描述
url是string外部 URL
分组节点

分组节点是用于组织其他节点的可视化容器。

{
  "id": "d4e5f6789012345a",
  "type": "group",
  "x": -50,
  "y": -50,
  "width": 1000,
  "height": 600,
  "label": "Project Overview",
  "color": "4"
}
{
  "id": "e5f67890123456ab",
  "type": "group",
  "x": 0,
  "y": 700,
  "width": 800,
  "height": 500,
  "label": "Resources",
  "background": "Attachments/background.png",
  "backgroundStyle": "cover"
}
属性必需类型描述
label否string分组的文本标签
background否string背景图片的路径
backgroundStyle否string背景渲染样式
背景样式
值描述
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": "leads to"
}
属性必需类型默认值描述
id是string-边的唯一标识符
fromNode是string-连接起点的节点 ID
fromSide否string-边起始的一侧
fromEnd否stringnone边起点处的形状
toNode是string-连接终点的节点 ID
toSide否string-边结束的一侧
toEnd否stringarrow边终点处的形状
color否canvasColor-线条颜色
label否string-边的文本标签
侧值
值描述
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": "# Main Idea\n\nThis is the central concept."
    },
    {
      "id": "1a2b3c4d5e6f7a8b",
      "type": "text",
      "x": 400,
      "y": -100,
      "width": 250,
      "height": 100,
      "text": "## Supporting Point A\n\nDetails here."
    },
    {
      "id": "2b3c4d5e6f7a8b9c",
      "type": "text",
      "x": 400,
      "y": 100,
      "width": 250,
      "height": 100,
      "text": "## Supporting Point B\n\nMore details."
    }
  ],
  "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": "To Do",
      "color": "1"
    },
    {
      "id": "6f7a8b9c0d1e2f3a",
      "type": "group",
      "x": 350,
      "y": 0,
      "width": 300,
      "height": 500,
      "label": "In Progress",
      "color": "3"
    },
    {
      "id": "7a8b9c0d1e2f3a4b",
      "type": "group",
      "x": 700,
      "y": 0,
      "width": 300,
      "height": 500,
      "label": "Done",
      "color": "4"
    },
    {
      "id": "8b9c0d1e2f3a4b5c",
      "type": "text",
      "x": 20,
      "y": 50,
      "width": 260,
      "height": 80,
      "text": "## Task 1\n\nImplement feature X"
    },
    {
      "id": "9c0d1e2f3a4b5c6d",
      "type": "text",
      "x": 370,
      "y": 50,
      "width": 260,
      "height": 80,
      "text": "## Task 2\n\nReview PR #123",
      "color": "2"
    },
    {
      "id": "0d1e2f3a4b5c6d7e",
      "type": "text",
      "x": 720,
      "y": 50,
      "width": 260,
      "height": 80,
      "text": "## Task 3\n\n~~Setup CI/CD~~"
    }
  ],
  "edges": []
}
带文件和链接的研究画布
{
  "nodes": [
    {
      "id": "1e2f3a4b5c6d7e8f",
      "type": "text",
      "x": 300,
      "y": 200,
      "width": 400,
      "height": 200,
      "text": "# Research Topic\n\n## Key Questions\n\n- How does X affect Y?\n- What are the implications?",
      "color": "5"
    },
    {
      "id": "2f3a4b5c6d7e8f9a",
      "type": "file",
      "x": 0,
      "y": 0,
      "width": 250,
      "height": 150,
      "file": "Literature/Paper A.pdf"
    },
    {
      "id": "3a4b5c6d7e8f9a0b",
      "type": "file",
      "x": 0,
      "y": 200,
      "width": 250,
      "height": 150,
      "file": "Notes/Meeting Notes.md",
      "subpath": "#Key Insights"
    },
    {
      "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": "Attachments/diagram.png"
    }
  ],
  "edges": [
    {
      "id": "6d7e8f9a0b1c2d3e",
      "fromNode": "2f3a4b5c6d7e8f9a",
      "fromSide": "right",
      "toNode": "1e2f3a4b5c6d7e8f",
      "toSide": "left",
      "label": "supports"
    },
    {
      "id": "7e8f9a0b1c2d3e4f",
      "fromNode": "3a4b5c6d7e8f9a0b",
      "fromSide": "right",
      "toNode": "1e2f3a4b5c6d7e8f",
      "toSide": "left",
      "label": "informs"
    },
    {
      "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": "visualized by"
    }
  ]
}
流程图
{
  "nodes": [
    {
      "id": "a0b1c2d3e4f5a6b7",
      "type": "text",
      "x": 200,
      "y": 0,
      "width": 150,
      "height": 60,
      "text": "**Start**",
      "color": "4"
    },
    {
      "id": "b1c2d3e4f5a6b7c8",
      "type": "text",
      "x": 200,
      "y": 100,
      "width": 150,
      "height": 60,
      "text": "Step 1:\nGather data"
    },
    {
      "id": "c2d3e4f5a6b7c8d9",
      "type": "text",
      "x": 200,
      "y": 200,
      "width": 150,
      "height": 80,
      "text": "**Decision**\n\nIs data valid?",
      "color": "3"
    },
    {
      "id": "d3e4f5a6b7c8d9e0",
      "type": "text",
      "x": 400,
      "y": 200,
      "width": 150,
      "height": 60,
      "text": "Process data"
    },
    {
      "id": "e4f5a6b7c8d9e0f1",
      "type": "text",
      "x": 0,
      "y": 200,
      "width": 150,
      "height": 60,
      "text": "Request new data",
      "color": "1"
    },
    {
      "id": "f5a6b7c8d9e0f1a2",
      "type": "text",
      "x": 400,
      "y": 320,
      "width": 150,
      "height": 60,
      "text": "**End**",
      "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": "Yes",
      "color": "4"
    },
    {
      "id": "d9e0f1a2b3c4d5e6",
      "fromNode": "c2d3e4f5a6b7c8d9",
      "fromSide": "left",
      "toNode": "e4f5a6b7c8d9e0f1",
      "toSide": "right",
      "label": "No",
      "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-30080-150
中段文本300-450150-300
大段文本400-600300-500
文件预览300-500200-400
链接预览250-400100-200
分组不定不定
间距
  • 在分组内留出 20-50px 的内边距
  • 节点之间间隔 50-100px 以提升可读性
  • 将节点对齐到网格(10 或 20 的倍数)以获得更整洁的布局

校验规则

  1. 所有 id 值在节点和连线之间必须唯一
  2. fromNode 和 toNode 必须引用已存在的节点 ID
  3. 每种节点类型都必须包含必填字段
  4. type 必须是以下之一:text、file、link、group
  5. backgroundStyle 必须是以下之一:cover、ratio、repeat
  6. fromSide、toSide 必须是以下之一:top、right、bottom、left
  7. fromEnd、toEnd 必须是以下之一:none、arrow
  8. 颜色预设必须是 "1" 到 "6" 或有效的十六进制颜色

参考资料

评论

支持 Markdown