mcpField
J
json-canvas

json-canvas

github.com/mavcui生产力19361 次安装33 周前更新
代码仓库

关于 json-canvas

json-canvas 是供兼容 skills 的 Agent 使用的技能,用于创建和编辑 Obsidian 等应用采用的 JSON Canvas 文件。它涵盖节点、连线、颜色、布局与校验规则。

主要功能

  1. 01创建和编辑 .canvas 文件
  2. 02支持文本、文件、链接和分组节点
  3. 03配置节点间连线与端点
  4. 04设置颜色和背景样式
  5. 05遵循 JSON Canvas Spec 1.0

适用场景

  1. 01制作包含文本与连线的画布
  2. 02整理项目看板和分组内容
  3. 03构建研究资料或流程图画布

安装

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

$npx skills add https://github.com/mavcui/agent-skills-hunter --skill json-canvas

安装后在 Claude Code 中输入/json-canvas确认已加载。

详细介绍

JSON Canvas 技能

此技能支持兼容技能的 Agent 创建和编辑有效的 JSON Canvas 文件(.canvas),供 Obsidian 和其他应用程序使用。

概述

JSON Canvas 是一种用于无限画布数据的开放文件格式。画布文件使用 .canvas 扩展名,并包含符合 JSON Canvas Spec 1.0 的有效 JSON。

文件结构

画布文件包含两个顶层数组:

{
  "nodes": [],
  "edges": []
}
  • nodes(可选):节点对象数组
  • edges(可选):连接节点的边对象数组

节点

节点是放置在画布上的对象。共有四种节点类型:

  • text - Markdown 文本内容
  • file - 文件或附件引用
  • link - 外部 URL
  • group - 其他节点的可视化容器
Z 轴顺序

数组中的节点按 Z 轴顺序排列:

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

所有节点共享以下属性:

属性必填类型说明
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