mcpField
J
json-canvas

json-canvas

github.com/davepoon生産性3.7k153 回インストール1 日前に更新
リポジトリ

json-canvas について

Obsidian などで使う JSON Canvas(.canvas)ファイルを Claude Code で作成・編集するスキルです。JSON Canvas Spec 1.0 に沿ってノード、エッジ、レイアウトを構成します。

主な機能

  1. 01.canvas ファイルの作成・編集
  2. 02テキスト・ファイル・リンク・グループノード
  3. 03ラベル付きエッジによるノード接続
  4. 04色と背景スタイルの設定
  5. 05JSON Canvas Spec 1.0 への準拠

活用シーン

  1. 01ビジュアルなマインドマップの作成
  2. 02フローチャートとノード関係の図示
  3. 03プロジェクトボードや計画の整理
  4. 04ノートやリンクのキャンバス配置

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/davepoon/buildwithclaude --skill json-canvas

インストール後、Claude Code で/json-canvasを入力して読み込まれたか確認します。

詳細

JSON Canvas

このスキルを使うと、Obsidian やその他のアプリケーションで使用される、有効な JSON Canvas ファイル(.canvas)を Claude Code で作成、編集できます。

概要

JSON Canvas は、無限キャンバスデータ向けのオープンなファイル形式です。キャンバスファイルは .canvas 拡張子を使用し、JSON Canvas Spec 1.0 に準拠した有効な JSON を含みます。

このスキルを使用する場面

  • Obsidian で .canvas ファイルを作成、編集するとき
  • ビジュアルなマインドマップやフローチャートを作成するとき
  • プロジェクトボードや計画書を作成するとき
  • ノートをつながりとともに視覚的に整理するとき
  • リンクされたコンテンツを含む図を作成するとき

ファイル構造

キャンバスファイルには、トップレベルの配列が 2 つあります。

{
  "nodes": [],
  "edges": []
}
  • nodes(任意):ノードオブジェクトの配列
  • edges(任意):ノードを接続するエッジオブジェクトの配列

ノード

ノードはキャンバス上に配置されるオブジェクトです。ノードには 4 つの種類があります。

  • text - Markdown を含むテキストコンテンツ
  • file - ファイルや添付ファイルへの参照
  • link - 外部 URL
  • group - その他のノードをまとめる視覚的なコンテナ
Z インデックスの順序

最初のノード = 最背面のレイヤー(他のノードより下に表示) 最後のノード = 最前面のレイヤー(他のノードより上に表示)

共通のノード属性
属性必須型説明
idはいstringノードの一意な識別子
typeはいstringノードの種類:text、file、link、または group
xはいintegerピクセル単位の X 位置
yはいintegerピクセル単位の Y 位置
widthはいintegerピクセル単位の幅
heightはいintegerピクセル単位の高さ
colorいいえcanvasColorノードの色(「色」のセクションを参照)
テキストノード

テキストノードには Markdown コンテンツが含まれます。

{
  "id": "text1",
  "type": "text",
  "x": 0,
  "y": 0,
  "width": 300,
  "height": 150,
  "text": "# Heading\n\nThis is **markdown** content."
}
ファイルノード

ファイルノードはファイルや添付ファイル(画像、動画、PDF、ノートなど)を参照します。

属性必須型説明
fileはいstringシステム内のファイルパス
subpathいいえstring見出しまたはブロックへのリンク(# で始まります)
{
  "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いいえstringグループのテキストラベル
backgroundいいえstring背景画像のパス
backgroundStyleいいえstring背景の描画スタイル
背景スタイル
値説明
coverノードの幅と高さ全体に広げます
ratio背景画像のアスペクト比を維持します
repeat画像を両方向にパターンとして繰り返します
{
  "id": "group1",
  "type": "group",
  "x": -50,
  "y": -50,
  "width": 800,
  "height": 500,
  "label": "Project Ideas",
  "color": "4"
}

エッジ

エッジはノードを接続する線です。

属性必須型デフォルト説明
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矢印の端点
{
  "id": "edge1",
  "fromNode": "text1",
  "fromSide": "right",
  "toNode": "file1",
  "toSide": "left",
  "toEnd": "arrow",
  "label": "references"
}

色

canvasColor 型は、16 進数カラーとプリセットの両方に対応しています。

16 進数カラー
{
  "color": "#FF0000"
}
プリセットカラー
プリセット色
"1"赤
"2"オレンジ
"3"黄色
"4"緑
"5"シアン
"6"紫

プリセットの具体的な色の値は意図的に定義されていません。これにより、各アプリケーションで独自のブランドカラーを使用できます。

完全な例

テキストと接続を含むシンプルなキャンバス
{
  "nodes": [
    {
      "id": "idea1",
      "type": "text",
      "x": 0,
      "y": 0,
      "width": 250,
      "height": 100,
      "text": "# Main Idea\n\nCore concept goes here"
    },
    {
      "id": "idea2",
      "type": "text",
      "x": 350,
      "y": -50,
      "width": 200,
      "height": 80,
      "text": "## Supporting Point 1\n\nDetails..."
    },
    {
      "id": "idea3",
      "type": "text",
      "x": 350,
      "y": 100,
      "width": 200,
      "height": 80,
      "text": "## Supporting Point 2\n\nMore details..."
    }
  ],
  "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": "To Do",
      "color": "1"
    },
    {
      "id": "progress-group",
      "type": "group",
      "x": 350,
      "y": 0,
      "width": 300,
      "height": 400,
      "label": "In Progress",
      "color": "3"
    },
    {
      "id": "done-group",
      "type": "group",
      "x": 700,
      "y": 0,
      "width": 300,
      "height": 400,
      "label": "Done",
      "color": "4"
    },
    {
      "id": "task1",
      "type": "text",
      "x": 20,
      "y": 50,
      "width": 260,
      "height": 80,
      "text": "## Task 1\n\nDescription of first task"
    },
    {
      "id": "task2",
      "type": "text",
      "x": 370,
      "y": 50,
      "width": 260,
      "height": 80,
      "text": "## Task 2\n\nCurrently working on this"
    },
    {
      "id": "task3",
      "type": "text",
      "x": 720,
      "y": 50,
      "width": 260,
      "height": 80,
      "text": "## Task 3\n\n~~Completed task~~"
    }
  ],
  "edges": []
}
ファイルとリンクを含むリサーチキャンバス
{
  "nodes": [
    {
      "id": "central",
      "type": "text",
      "x": 200,
      "y": 200,
      "width": 200,
      "height": 100,
      "text": "# Research Topic\n\nMain research question",
      "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": "literature"
    },
    {
      "id": "e2",
      "fromNode": "central",
      "toNode": "notes2",
      "toEnd": "arrow",
      "label": "methods"
    },
    {
      "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": "**Start**",
      "color": "4"
    },
    {
      "id": "decision",
      "type": "text",
      "x": 75,
      "y": 120,
      "width": 200,
      "height": 80,
      "text": "## Decision\n\nIs condition true?",
      "color": "3"
    },
    {
      "id": "yes-path",
      "type": "text",
      "x": -100,
      "y": 280,
      "width": 150,
      "height": 60,
      "text": "**Yes Path**\n\nDo action A"
    },
    {
      "id": "no-path",
      "type": "text",
      "x": 300,
      "y": 280,
      "width": 150,
      "height": 60,
      "text": "**No Path**\n\nDo action B"
    },
    {
      "id": "end",
      "type": "text",
      "x": 100,
      "y": 420,
      "width": 150,
      "height": 60,
      "text": "**End**",
      "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": "Yes"
    },
    {
      "id": "e3",
      "fromNode": "decision",
      "fromSide": "right",
      "toNode": "no-path",
      "toSide": "top",
      "toEnd": "arrow",
      "label": "No"
    },
    {
      "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 文字の 16 進数 ID を生成します。

形式の例:a1b2c3d4e5f67890

レイアウトのガイドライン

配置
  • 座標には負の値を指定できます(キャンバスは無限に広がります)
  • 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" のいずれか、または有効な 16 進数カラーである必要があります

参考資料

コメント