/canvas
AI-orchestrated visual production for Obsidian Canvas. Create presentations, flowcharts, mood boards, knowledge graphs, galleries, storyboards, timelines, dashboards, and more with intelligent layout and AI-generated content. Claude acts as Creative Director — dispatching
$ npx -y skills add AgriciDaniel/claude-canvas --skill canvas --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/canvas
Context preview
The summary Claude sees to decide when to auto-load this skill.
AI-orchestrated visual production for Obsidian Canvas. Create presentations, flowcharts, mood boards, knowledge graphs, galleries, storyboards, timelines, dashboards, and more with intelligent layout and AI-generated content. Claude acts as Creative Director — dispatching
SKILL.md
canvas.SKILL.mdname: canvas
description: >
AI-orchestrated visual production for Obsidian Canvas. Create presentations,
flowcharts, mood boards, knowledge graphs, galleries, storyboards, timelines,
dashboards, and more with intelligent layout and AI-generated content. Claude
acts as Creative Director — dispatching sub-agents for image generation, SVG
diagrams, GIF creation, and spatial layout. Supports 12 template archetypes,
6 layout algorithms, and Advanced Canvas presentation mode.
Triggers on: /canvas, create canvas, build canvas, make a presentation,
visual board, mood board, flowchart canvas, storyboard, canvas from template,
lay out canvas, export canvas, canvas layout, canvas generate, add to canvas,
put this on the canvas, open canvas, canvas present, canvas template.
canvas: AI-Orchestrated Visual Production
Claude acts as Creative Director for Obsidian Canvas. Describe what you want and get a fully populated, professionally laid-out `.canvas` file.
---
Context Detection
Before any operation, determine the canvas directory:
1. If `wiki/canvases/` exists in the current directory or a parent: use it (claude-obsidian vault mode).
- Media goes to `_attachments/images/canvas/`
2. Otherwise: use `.canvases/` in the current working directory (standalone mode).
- Media goes to `.canvases/assets/`
3. Create the directory if it doesn't exist.
**Default canvas**: `[canvas_dir]/main.canvas`
---
Command Routing
| Command | Sub-skill | Description | |---------|-----------|-------------| | `/canvas` (no args) | (inline) | Status: list canvases, node counts, zones | | `/canvas create [name]` | canvas-create | Create blank or templated canvas | | `/canvas create [name] from [template]` | canvas-create | Create from archetype | | `/canvas add [type] [content]` | canvas-populate | Add node (image/text/pdf/note/link/mermaid/svg/gif/banana) | | `/canvas zone [name] [color]` | canvas-populate | Add group node | | `/canvas connect [from] [to] [label]` | canvas-populate | Add edge between nodes | | `/canvas from banana` | canvas-populate | Import recent AI-generated images | | `/canvas layout [algorithm]` | canvas-layout | Re-layout (auto/grid/dagre/radial/force/linear) | | `/canvas present [topic]` | canvas-present | Build presentation canvas (1200x675 slides) | | `/canvas present from [notes]` | canvas-present | Presentation from existing content | | `/canvas generate [description]` | canvas-generate | AI-orchestrated full canvas generation | | `/canvas template list` | canvas-template | Browse 12 archetypes | | `/canvas template use [name]` | canvas-template | Instantiate a template | | `/canvas export [format] [path]` | canvas-export | Export to PNG/SVG/PDF | | `/canvas list` | (inline) | List all canvases with stats |
---
Status / List (Inline Operations)
`/canvas` (no args)
1. Detect canvas directory (vault or standalone). 2. Find default canvas (`main.canvas`). 3. If exists: read JSON, count nodes by type, list zone labels. Report: "Canvas has N nodes: X images, Y text, Z files. Zones: [list]" 4. If not exists: report "No canvas found. Run `/canvas create [name]` to start."
`/canvas list`
1. Glob `[canvas_dir]/*.canvas`. 2. For each: read JSON, count nodes by type. 3. Report table:
main.canvas 14 nodes (8 images, 3 text, 2 file, 1 group)
design-ideas.canvas 42 nodes (30 images, 4 text, 8 groups)
---
Key References
Read these references before performing canvas operations:
- `references/canvas-spec.md` — JSON Canvas 1.0 format, coordinate system, node types, edges, colors, sizing
- `references/performance-guide.md` — Node limits, GIF lag, SVG gotchas, 20px grid snapping
Additional references:
- `references/layout-algorithms.md` — 6 layout algorithms (canvas-layout)
- `references/template-catalog.md` — 12 archetypes (canvas-template)
- `references/presentation-spec.md` — Advanced Canvas slides (canvas-present)
- `references/mermaid-patterns.md` — Mermaid in text nodes (canvas-populate, canvas-generate)
- `references/media-guide.md` — Image/GIF/SVG integration (canvas-generate, canvas-populate)
---
Auto-Positioning Algorithm
Used by canvas-populate to place new nodes. Read `references/canvas-spec.md` for the full coordinate system.
def next_position(canvas_nodes, target_zone_label, new_w, new_h):
# Find zone group node
zone = next((n for n in canvas_nodes
if n.get('type') == 'group'
and n.get('label') == target_zone_label), None)
if zone is None:
# No zone: place below all content
max_y = max((n['y'] + n.get('height', 0) for n in canvas_nodes), default=-140)
return snap_grid(-400, max_y + 60)
zx, zy = zone['x'], zone['y']
zw, zh = zone['width'], zone['height']
# Nodes inside this zone (exclude groups)
inside = [n for n in canvas_nodes
if n.get('type') != 'group'
and zx <= n['x'] < zx + zw
and zy <= n['y'] < zy + zh]
if not inside:
return snap_grid(zx + 20, zy + 20)
# Find the bottom-most row: nodes whose bottom edge is closest to the zone bottom
max_bottom = max(n['y'] + n.get('height', 0) for n in inside)
# Nodes on the last row: those whose top y is within one row-height of the bottom
last_row = [n for n in inside if n['y'] + n.get('height', 0) >= max_bottom - 20]
if not last_row:
last_row = inside # fallback
rightmost_x = max(n['x'] + n.get('width', 0) for n in last_row)
next_x = rightmost_x + 40
if next_x + new_w > zx + zw:
# Overflow: new row below the current last row
return snap_grid(zx + 20, max_bottom + 20)
# Same row: align to top of the LAST row (not all nodes)
current_row_y = min(n['y'] for n in last_row)
return snap_grid(next_x, current_row_y)
def snap_grid(x, y, grid=20):
return (round(x / grid) * grid, round(y / grid) * grid)---
ID Generation
Re
Read more
name: canvas description: > AI-orchestrated visual production for Obsidian Canvas. Create presentations, flowcharts, mood boards, knowledge graphs, galleries, storyboards, timelines, dashboards, and more with intelligent layout and AI-generated content. Claude acts as Creative Director — dispatching sub-agents for image generation, SVG diagrams, GIF creation, and spatial layout. Supports 12 template archetypes, 6 layout algorithms, and Advanced Canvas presentation mode. Triggers on: /canvas, create canvas, build canvas, make a presentation, visual board, mood board, flowchart canvas, storyboard, canvas from template, lay out canvas, export canvas, canvas layout, canvas generate, add to canvas, put this on the canvas, open canvas, canvas present, canvas template.
canvas: AI-Orchestrated Visual Production
Claude acts as Creative Director for Obsidian Canvas. Describe what you want and get a fully populated, professionally laid-out `.canvas` file.
---
Context Detection
Before any operation, determine the canvas directory:
1. If `wiki/canvases/` exists in the current directory or a parent: use it (claude-obsidian vault mode).
- Media goes to `_attachments/images/canvas/`
2. Otherwise: use `.canvases/` in the current working directory (standalone mode).
- Media goes to `.canvases/assets/`
3. Create the directory if it doesn't exist.
**Default canvas**: `[canvas_dir]/main.canvas`
---
Command Routing
| Command | Sub-skill | Description | |---------|-----------|-------------| | `/canvas` (no args) | (inline) | Status: list canvases, node counts, zones | | `/canvas create [name]` | canvas-create | Create blank or templated canvas | | `/canvas create [name] from [template]` | canvas-create | Create from archetype | | `/canvas add [type] [content]` | canvas-populate | Add node (image/text/pdf/note/link/mermaid/svg/gif/banana) | | `/canvas zone [name] [color]` | canvas-populate | Add group node | | `/canvas connect [from] [to] [label]` | canvas-populate | Add edge between nodes | | `/canvas from banana` | canvas-populate | Import recent AI-generated images | | `/canvas layout [algorithm]` | canvas-layout | Re-layout (auto/grid/dagre/radial/force/linear) | | `/canvas present [topic]` | canvas-present | Build presentation canvas (1200x675 slides) | | `/canvas present from [notes]` | canvas-present | Presentation from existing content | | `/canvas generate [description]` | canvas-generate | AI-orchestrated full canvas generation | | `/canvas template list` | canvas-template | Browse 12 archetypes | | `/canvas template use [name]` | canvas-template | Instantiate a template | | `/canvas export [format] [path]` | canvas-export | Export to PNG/SVG/PDF | | `/canvas list` | (inline) | List all canvases with stats |
---
Status / List (Inline Operations)
`/canvas` (no args)
1. Detect canvas directory (vault or standalone). 2. Find default canvas (`main.canvas`). 3. If exists: read JSON, count nodes by type, list zone labels. Report: "Canvas has N nodes: X images, Y text, Z files. Zones: [list]" 4. If not exists: report "No canvas found. Run `/canvas create [name]` to start."
`/canvas list`
1. Glob `[canvas_dir]/*.canvas`. 2. For each: read JSON, count nodes by type. 3. Report table:
main.canvas 14 nodes (8 images, 3 text, 2 file, 1 group) design-ideas.canvas 42 nodes (30 images, 4 text, 8 groups)
---
Key References
Read these references before performing canvas operations:
- `references/canvas-spec.md` — JSON Canvas 1.0 format, coordinate system, node types, edges, colors, sizing
- `references/performance-guide.md` — Node limits, GIF lag, SVG gotchas, 20px grid snapping
Additional references:
- `references/layout-algorithms.md` — 6 layout algorithms (canvas-layout)
- `references/template-catalog.md` — 12 archetypes (canvas-template)
- `references/presentation-spec.md` — Advanced Canvas slides (canvas-present)
- `references/mermaid-patterns.md` — Mermaid in text nodes (canvas-populate, canvas-generate)
- `references/media-guide.md` — Image/GIF/SVG integration (canvas-generate, canvas-populate)
---
Auto-Positioning Algorithm
Used by canvas-populate to place new nodes. Read `references/canvas-spec.md` for the full coordinate system.
def next_position(canvas_nodes, target_zone_label, new_w, new_h):
# Find zone group node
zone = next((n for n in canvas_nodes
if n.get('type') == 'group'
and n.get('label') == target_zone_label), None)
if zone is None:
# No zone: place below all content
max_y = max((n['y'] + n.get('height', 0) for n in canvas_nodes), default=-140)
return snap_grid(-400, max_y + 60)
zx, zy = zone['x'], zone['y']
zw, zh = zone['width'], zone['height']
# Nodes inside this zone (exclude groups)
inside = [n for n in canvas_nodes
if n.get('type') != 'group'
and zx <= n['x'] < zx + zw
and zy <= n['y'] < zy + zh]
if not inside:
return snap_grid(zx + 20, zy + 20)
# Find the bottom-most row: nodes whose bottom edge is closest to the zone bottom
max_bottom = max(n['y'] + n.get('height', 0) for n in inside)
# Nodes on the last row: those whose top y is within one row-height of the bottom
last_row = [n for n in inside if n['y'] + n.get('height', 0) >= max_bottom - 20]
if not last_row:
last_row = inside # fallback
rightmost_x = max(n['x'] + n.get('width', 0) for n in last_row)
next_x = rightmost_x + 40
if next_x + new_w > zx + zw:
# Overflow: new row below the current last row
return snap_grid(zx + 20, max_bottom + 20)
# Same row: align to top of the LAST row (not all nodes)
current_row_y = min(n['y'] for n in last_row)
return snap_grid(next_x, current_row_y)
def snap_grid(x, y, grid=20):
return (round(x / grid) * grid, round(y / grid) * grid)---
ID Generation
Re
AI-orchestrated visual production for Obsidian Canvas. Create presentations, flowcharts, mood boards, knowledge graphs, and galleries with intelligent layout and AI-generated content.
Other skills on claude-canvas.
- /canvas-create
Create new Obsidian Canvas files — blank with a starter structure, or from one of 12 template archetypes (presentation, flowchart, mind-map, gallery, dashboard, storyboard, knowledge-graph, mood-board, timeline, comparison, kanban, project-brief). Handles directory creation,
Open skill - /canvas-export
Export Obsidian Canvas files to PNG, SVG, or PDF formats. Uses the Advanced Canvas plugin's built-in export when Obsidian is running, or falls back to Playwright browser-based screenshot capture. Supports single canvas export, presentation slide-per-page PDF export, and batch
Open skill - /canvas-generate
AI-orchestrated full canvas generation. Given a description, detects the best archetype, generates content and visuals, instantiates a template, applies layout, and produces a complete canvas. The flagship command. Dispatches canvas-media and canvas-composer agents for parallel
Open skill - /canvas-layout
Re-layout existing Obsidian Canvas nodes using 6 spatial algorithms: grid (galleries, mood boards), dagre (flowcharts, org charts), radial (mind maps), force-directed (knowledge graphs), linear (timelines), and auto-detect. Preserves group membership, snaps to 20px grid, refits
Open skill - /canvas-populate
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
Open skill - /canvas-present
Build presentation-mode canvases for the Advanced Canvas plugin. Creates slide-deck canvases with 1200x675 group nodes connected by edges for arrow-key navigation. Supports title slides, content slides with images, full-text slides, and optional script annotation columns for
Open skill

