canvas-populate
Obsidian Canvasファイルに、画像、テキスト、PDF、Webリンクなど様々なコンテンツを追加し、ノード間の接続やグループ化も行い、AI生成画像も取り込めるように拡張するSkill。
📜 元の英語説明(参考)
Add content to existing Obsidian Canvas files. Supports all node types: images (with auto aspect ratio detection), text cards, PDFs, wiki notes, web links, Mermaid diagrams, SVGs, GIFs, AI-generated images via banana. Also adds zones (groups), edges between nodes, and imports recent banana images. Triggers on: canvas add, add to canvas, put on canvas, canvas zone, canvas connect, canvas from banana, add image to canvas, add text to canvas.
🇯🇵 日本人クリエイター向け解説
Obsidian Canvasファイルに、画像、テキスト、PDF、Webリンクなど様々なコンテンツを追加し、ノード間の接続やグループ化も行い、AI生成画像も取り込めるように拡張するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o canvas-populate.zip https://jpskill.com/download/10542.zip && unzip -o canvas-populate.zip && rm canvas-populate.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/10542.zip -OutFile "$d\canvas-populate.zip"; Expand-Archive "$d\canvas-populate.zip" -DestinationPath $d -Force; ri "$d\canvas-populate.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
canvas-populate.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
canvas-populateフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
canvas-populate: キャンバスへのコンテンツの追加
編集を行う前に、完全な JSON 形式については ../canvas/references/canvas-spec.md を参照してください。
ノードの制限と制約については、../canvas/references/performance-guide.md を参照してください。
一般的なワークフロー
追加操作ごとに:
- 読み込み: 対象のキャンバス JSON を読み込みます。
nodesとedges配列を解析します。 - 既存の ID を収集: 衝突を防ぐために、既存の ID を収集します。
- 新しい ID を生成:
[type]-[slug]-[unix-timestamp]の形式で新しい ID を生成します。 - 位置を計算: 自動配置アルゴリズムを使用して位置を計算します (キャンバスオーケストレーターを参照)。
- 間隔チェック: 計算された位置が、既存のすべてのコンテンツノードから少なくとも水平方向に 80px、垂直方向に 60px の間隔があることを確認します。間隔が確保されていない場合は、間隔が空くまで位置をずらします。
- 追加: 新しいノードを
nodes配列に追加します (グループの後に追加します — z-index の順序)。 - 検証:
python3 scripts/canvas_validate.py <path>を実行します — 重なりやノード数を確認します。 - 書き込み: 更新されたキャンバス JSON を書き込みます。
- 報告: "[説明] を ([x], [y]) の位置にある [ゾーン] ゾーンに追加しました。"
ノード操作
画像の追加 (/canvas add image [path or url])
画像の解決:
- URL の場合 (
httpで始まる):curl -sL [url] -o [media_dir]/[filename]でダウンロードします。 URL パスからファイル名を導出するか、不明確な場合はimg-[timestamp].jpgを使用します。 - キャンバスディレクトリ外のローカルパスの場合:
cp [path] [media_dir]/ - すでにキャンバス相対パスの場合: そのまま使用します。
アスペクト比の検出:
python3 -c "from PIL import Image; img=Image.open('[path]'); print(img.width, img.height)"
# またはフォールバック
identify -format '%w %h' [path]
../canvas/references/canvas-spec.md のサイズテーブルにマッピングします (7 つの比率 + PDF + フォールバック)。
ファイルノードを作成: 計算された寸法でファイルノードを作成します。自動レイアウトを使用して配置します。
テキストの追加 (/canvas add text [content])
{
"id": "text-[slug]-[timestamp]",
"type": "text",
"text": "[content]",
"x": 0, "y": 0,
"width": 300, "height": 120
}
複数行のコンテンツの場合、高さを推定します: 改行数を数え、24 を掛け、40px のパディングを追加します。最小 120px。
PDF の追加 (/canvas add pdf [path])
キャンバスディレクトリ外にある場合は [media_dir]/ にコピーします。固定サイズ: width=400, height=520。
ノートの追加 (/canvas add note [wiki-page])
- ページ名に一致するファイルを探します (大文字と小文字を区別しない、部分一致)。
"type": "file"と vault 相対パスを使用します。"type": "link"ではありません — それは URL 専用です。- デフォルトサイズ: width=300, height=100。
リンクの追加 (/canvas add link [url])
{
"id": "link-[slug]-[timestamp]",
"type": "link",
"url": "[url]",
"x": 0, "y": 0,
"width": 400, "height": 120
}
Obsidian は Open Graph プレビューを自動的に取得します。
Mermaid の追加 (/canvas add mermaid [code])
Mermaid は Obsidian テキストノードでネイティブにレンダリングされます。フェンス付きコードブロックでラップします:
{
"id": "text-mermaid-[timestamp]",
"type": "text",
"text": "```mermaid\n[code]\n```",
"x": 0, "y": 0,
"width": 500, "height": 400,
"color": "5"
}
Mermaid には、より広いテキストノードが適しています (幅 400px 以上、高さ 300px 以上)。
SVG の追加 (/canvas add svg [description or path])
- パスの場合: SVG をメディアディレクトリにコピーし、ファイルノードとして追加します。Width=400、height は viewBox アスペクト比に基づきます。
- 説明の場合:
/svgスキルに委譲して生成し、出力ファイルを追加します。 - SVG は
<img>としてレンダリングされます — インタラクティブ性はありません。viewBox属性が必要です。
GIF の追加 (/canvas add gif [description or path])
- パスの場合: GIF をメディアディレクトリにコピーし、ファイルノードとして追加します。
- 説明の場合:
/claude-gif-generateスキルに委譲して生成し、出力を追加します。 - パフォーマンス制限: キャンバスあたり最大 3 つの GIF、最大幅 480px。超過した場合は警告します。
banana の追加 (/canvas add banana [prompt])
- banana スキルが利用可能かどうかを確認します。利用できない場合: "AI 画像生成のために banana スキルをインストールしてください。"
- プロンプトとともに banana スキルに委譲します。
- 画像生成を待ちます。
- 生成された画像をファイルノードとして追加します (アスペクト比を検出し、自動サイズ調整)。
- キャンバスディレクトリの
.recent-images.txtにパスを記録します。
ゾーン操作
ゾーン (/canvas zone [name] [color])
- キャンバス JSON を読み込みます。
- 既存のすべてのノードの max_y を見つけます。キャンバスが空の場合は
-80を使用します (タイトルが y=-300 にあり、デフォルトゾーンが y=-140 にあるスターターキャンバスレイアウトと一致します):if not canvas_nodes: max_y = -80 else: max_y = max(n["y"] + n.get("height", 0) for n in canvas_nodes) + 60 - グループノードを作成します:
{
"id": "zone-[slug]-[timestamp]",
"type": "group",
"label": "[name]",
"x": -400,
"y": "[max_y]",
"width": 1000,
"height": 400,
"color": "[color or '4']"
}
有効な色: "1"=赤 "2"=オレンジ "3"=黄 "4"=緑 "5"=シアン "6"=紫
- グループノードを、配列内のコンテンツノードの前に挿入します (z-index: グループは背面にレンダリングされます)。
- 書き込みと報告を行います。
エッジ操作
接続 (/canvas connect [from] [to] [label])
- キャンバス JSON を読み込みます。
- ID、ラベルテキスト、または部分一致で
fromおよびtoノードを見つけます。 - 曖昧な場合は、一致するものをリストし、ユーザーに明確にするように求めます。
- エッジを作成します:
{
"id": "e-[from-slug]-[to-slug]-[timestamp]",
"fromNode": "[from-id]",
"toNode": "[to-id]",
"toEnd": "arrow"
}
- 自動ルーティングのために
fromSide/toSideを省略します (より良い結果が得られます)。 - 提供されている場合は、オプションの
labelを追加します。 - 書き込みと報告を行います。
Banana インポート
from banana (/canvas from banana)
- 最近記録された画像パスについて
[canvas_dir]/.recent-images.txtを確認します。 - 見つからない場合、または空の場合: 過去 10 分間に変更された画像を検索します:
find [media_dir] -name "*.png" -o -name "*.jpg" -newer /tmp/ten-min-ago - それでもない場合: 最近変更された 5 つの画像を表示します。
- リストを提示します: "N 個の最近の画像が見つかりました。キャンバスに追加しますか?どのゾーンに追加しますか?"
- 確認時: 画像追加ロジックを使用してそれぞれを追加します。
メディアディレクトリ
- Vault モード:
_attachments/images/canvas/ - スタンドアロンモード:
.canvases/assets/ - 存在しない場合は作成します。
- すべてのファイルノードパスは、vault/プロジェクトルートからの相対パスである必要があります。
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
canvas-populate: Add Content to Canvases
Read ../canvas/references/canvas-spec.md for the full JSON format before any edit.
Read ../canvas/references/performance-guide.md for node limits and constraints.
General Workflow
For every add operation:
- Read the target canvas JSON. Parse
nodesandedgesarrays. - Collect existing IDs to prevent collisions.
- Generate a new ID:
[type]-[slug]-[unix-timestamp]. - Calculate position using the auto-positioning algorithm (see canvas orchestrator).
- Spacing check: Verify the calculated position has at least 80px horizontal and 60px vertical gap from ALL existing content nodes. If not, shift the position until spacing is clear.
- Append the new node to the
nodesarray (after any groups — z-index ordering). - Validate: Run
python3 scripts/canvas_validate.py <path>— check for overlaps and node count. - Write the updated canvas JSON.
- Report: "Added [description] to [zone] zone at position ([x], [y])."
Node Operations
add image (/canvas add image [path or url])
Resolve the image:
- If URL (starts with
http): download withcurl -sL [url] -o [media_dir]/[filename]. Derive filename from URL path, or useimg-[timestamp].jpgif unclear. - If local path outside canvas dir:
cp [path] [media_dir]/ - If already canvas-relative: use as-is.
Detect aspect ratio:
python3 -c "from PIL import Image; img=Image.open('[path]'); print(img.width, img.height)"
# or fallback
identify -format '%w %h' [path]
Map to the sizing table in ../canvas/references/canvas-spec.md (7 ratios + PDF + fallback).
Create file node with calculated dimensions. Position using auto-layout.
add text (/canvas add text [content])
{
"id": "text-[slug]-[timestamp]",
"type": "text",
"text": "[content]",
"x": 0, "y": 0,
"width": 300, "height": 120
}
For multi-line content, estimate height: count newlines, multiply by 24, add 40px padding. Minimum 120px.
add pdf (/canvas add pdf [path])
Copy to [media_dir]/ if outside canvas dir. Fixed size: width=400, height=520.
add note (/canvas add note [wiki-page])
- Search for a file matching the page name (case-insensitive, partial match).
- Use
"type": "file"with vault-relative path. Not"type": "link"— that's for URLs only. - Default size: width=300, height=100.
add link (/canvas add link [url])
{
"id": "link-[slug]-[timestamp]",
"type": "link",
"url": "[url]",
"x": 0, "y": 0,
"width": 400, "height": 120
}
Obsidian fetches Open Graph preview automatically.
add mermaid (/canvas add mermaid [code])
Mermaid renders natively in Obsidian text nodes. Wrap in a fenced code block:
{
"id": "text-mermaid-[timestamp]",
"type": "text",
"text": "```mermaid\n[code]\n```",
"x": 0, "y": 0,
"width": 500, "height": 400,
"color": "5"
}
Wider text nodes work better for Mermaid (min 400px wide, 300px tall).
add svg (/canvas add svg [description or path])
- If path: copy SVG to media dir, add as file node. Width=400, height based on viewBox aspect ratio.
- If description: delegate to
/svgskill to generate, then add the output file. - SVGs render as
<img>— no interactivity. Must haveviewBoxattribute.
add gif (/canvas add gif [description or path])
- If path: copy GIF to media dir, add as file node.
- If description: delegate to
/claude-gif-generateskill, then add the output. - Performance limit: max 3 GIFs per canvas, max 480px width. Warn if exceeded.
add banana (/canvas add banana [prompt])
- Check if banana skill is available. If not: "Install the banana skill for AI image generation."
- Delegate to banana skill with the prompt.
- Wait for image generation.
- Add the generated image as a file node (detect aspect ratio, auto-size).
- Log the path to
.recent-images.txtin the canvas directory.
Zone Operations
zone (/canvas zone [name] [color])
- Read canvas JSON.
- Find max_y of all existing nodes. Use
-80if canvas is empty (consistent with starter canvas layout where title is at y=-300 and default zone at y=-140):if not canvas_nodes: max_y = -80 else: max_y = max(n["y"] + n.get("height", 0) for n in canvas_nodes) + 60 - Create group node:
{
"id": "zone-[slug]-[timestamp]",
"type": "group",
"label": "[name]",
"x": -400,
"y": "[max_y]",
"width": 1000,
"height": 400,
"color": "[color or '4']"
}
Valid colors: "1"=red "2"=orange "3"=yellow "4"=green "5"=cyan "6"=purple
- Insert the group node BEFORE content nodes in the array (z-index: groups render behind).
- Write and report.
Edge Operations
connect (/canvas connect [from] [to] [label])
- Read canvas JSON.
- Find
fromandtonodes by ID, label text, or partial match. - If ambiguous, list matches and ask the user to clarify.
- Create edge:
{
"id": "e-[from-slug]-[to-slug]-[timestamp]",
"fromNode": "[from-id]",
"toNode": "[to-id]",
"toEnd": "arrow"
}
- Omit
fromSide/toSidefor auto-routing (better results). - Add optional
labelif provided. - Write and report.
Banana Import
from banana (/canvas from banana)
- Check
[canvas_dir]/.recent-images.txtfor recently logged image paths. - If not found or empty: search for images modified in the last 10 minutes:
find [media_dir] -name "*.png" -o -name "*.jpg" -newer /tmp/ten-min-ago - If still none: show the 5 most recently modified images.
- Present list: "Found N recent images. Add to canvas? Which zone?"
- On confirmation: add each using the add image logic.
Media Directory
- Vault mode:
_attachments/images/canvas/ - Standalone mode:
.canvases/assets/ - Create if it doesn't exist.
- All file node paths must be relative to the vault/project root.