
Canvas Populate
- 13 installs
- 246 repo stars
- Updated April 10, 2026
- agricidaniel/claude-canvas
canvas-populate is a Claude Code skill that adds images, text, diagrams, zones, and edges to an existing Obsidian Canvas.
About
canvas-populate adds content to an existing Obsidian Canvas: images with aspect-ratio detection, text cards, PDFs, wiki notes, web links, Mermaid diagrams, SVGs, and GIFs. It also adds zones and edges, auto-positions nodes with spacing checks, and validates the result. A developer uses it to fill or extend a canvas board node by node.
- Adds nodes to existing Obsidian Canvas files
- Supports images, text, PDFs, notes, links, Mermaid, SVGs, GIFs
- Adds zones, edges, and auto-positions with spacing checks
Canvas Populate by the numbers
- 13 all-time installs (skills.sh)
- Ranked #1,418 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
canvas-populate capabilities & compatibility
- Capabilities
- canvas populate · add node · add edge · mermaid diagram
- Works with
- obsidian
- Use cases
- documentation · ui design · image generation
- Pricing
- Free
What canvas-populate says it does
Add content to existing Obsidian Canvas files.
Also adds zones (groups), edges between nodes, and imports recent banana images.
npx skills add https://github.com/agricidaniel/claude-canvas --skill canvas-populateAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 13 |
|---|---|
| repo stars | ★ 246 |
| Last updated | April 10, 2026 |
| Repository | agricidaniel/claude-canvas ↗ |
What it does
Add images, text, diagrams, zones, and edges to an existing Obsidian Canvas with auto-positioning.
Who is it for?
Adding nodes, zones, and connections to a canvas that already exists.
When should I use this skill?
You say canvas add, add to canvas, canvas zone, or canvas connect.
What you get
New nodes, zones, or edges are added with correct sizing, spacing, and a validated canvas.
- Updated canvas with new nodes, zones, or edges
By the numbers
- 80px horizontal / 60px vertical spacing check
- max 3 GIFs per canvas
Files
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:
1. Read the target canvas JSON. Parse nodes and edges arrays. 2. Collect existing IDs to prevent collisions. 3. Generate a new ID: [type]-[slug]-[unix-timestamp]. 4. Calculate position using the auto-positioning algorithm (see canvas orchestrator). 5. 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. 6. Append the new node to the nodes array (after any groups — z-index ordering). 7. Validate: Run python3 scripts/canvas_validate.py <path> — check for overlaps and node count. 8. Write the updated canvas JSON. 9. 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 use img-[timestamp].jpg if 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])
1. Search for a file matching the page name (case-insensitive, partial match). 2. Use "type": "file" with vault-relative path. Not "type": "link" — that's for URLs only. 3. 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])
1. Check if banana skill is available. If not: "Install the banana skill for AI image generation." 2. Delegate to banana skill with the prompt. 3. Wait for image generation. 4. Add the generated image as a file node (detect aspect ratio, auto-size). 5. Log the path to .recent-images.txt in the canvas directory.
---
Zone Operations
zone (/canvas zone [name] [color])
1. Read canvas JSON. 2. Find max_y of all existing nodes. Use -80 if 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) + 603. 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
4. Insert the group node BEFORE content nodes in the array (z-index: groups render behind). 5. Write and report.
---
Edge Operations
connect (/canvas connect [from] [to] [label])
1. Read canvas JSON. 2. Find from and to nodes by ID, label text, or partial match. 3. If ambiguous, list matches and ask the user to clarify. 4. Create edge:
{
"id": "e-[from-slug]-[to-slug]-[timestamp]",
"fromNode": "[from-id]",
"toNode": "[to-id]",
"toEnd": "arrow"
}5. Omit fromSide/toSide for auto-routing (better results). 6. Add optional label if provided. 7. Write and report.
---
Banana Import
from banana (/canvas from banana)
1. Check [canvas_dir]/.recent-images.txt for recently logged image paths. 2. 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-ago3. If still none: show the 5 most recently modified images. 4. Present list: "Found N recent images. Add to canvas? Which zone?" 5. 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.
Related skills
FAQ
What node types can it add?
Images, text cards, PDFs, wiki notes, web links, Mermaid diagrams, SVGs, GIFs, and AI-generated images, plus zones and edges.
How does it avoid overlaps?
It runs a spacing check requiring at least 80px horizontal and 60px vertical gap from existing content nodes, then validates for overlaps.