- name
- obsidian-canvas
- description
- Create and manage Obsidian Canvas files with automatic layout generation. Use when creating visual knowledge maps, weekly reading summaries, or project timelines.
- allowed-tools
- ["Read","Write","Edit","Glob","Grep"]
- license
- MIT
# Obsidian Canvas Skill
Create visual canvases with automatic layout, color-coding, and smart node positioning.
## When to Use This Skill
Activate when you need to:
- Create visual summaries of weekly reading
- Build knowledge maps connecting related topics
- Design project timelines or mind maps
- Organize scattered notes into visual structure
## Core Principle: Automatic Layout
> **๋ ์ด์์์ ์๋์ผ๋ก, ์ฝํ
์ธ ์ ์ง์คํ๋ผ**
Canvas์ ํต์ฌ์ ๋
ธ๋ ๋ฐฐ์น์ ์ฐ๊ฒฐ. ์๋์ผ๋ก ์ขํ ๊ณ์ฐํ๋ ๋์ , ํจํด๋ณ ์๋ ๋ ์ด์์ ์ฌ์ฉ.
## Edit Workflow: Draft & Atomic Replace (CRITICAL)
> **์บ๋ฒ์ค ํ์ผ์ ์ง์ ์ฌ๋ฌ ๋ฒ ๋ฎ์ด์ฐ์ง ๋ง๋ผ.**
Obsidian์ด ์บ๋ฒ์ค ํญ์ ์ด์ด๋ ์ํ์์ ์ธ๋ถ์์ `.canvas` ํ์ผ์ ์์ ํ๋ฉด, Obsidian์ด ์๊ธฐ ๋ฉ๋ชจ๋ฆฌ์ (์ข
์ข
minimalํ) ์ํ๋ก ๋์คํฌ๋ฅผ ๋ค์ ๋ฎ์ด์จ ์์
๊ฒฐ๊ณผ๊ฐ ์ฌ๋ผ์ง ์ ์๋ค.
### ๊ถ์ฅ ์ํฌํ๋ก์ฐ
1. **์์ ํ์ผ์์ ํธ์ง ์๋ฃ**: `<์๋ณธ>.canvas.draft`์ ๋ชจ๋ ๋
ธ๋ยท์ฃ์งยท์ปจํ
์ด๋๋ฅผ ํ ๋ฒ์ ์์ฑ
2. **๊ฒ์ฆ**: JSON ์ ํจ์ฑ, ๋
ธ๋ ์ขํ ์ค๋ฒ๋ฉ, ์ฃ์ง ID ๋งค์นญ ํ์ธ
3. **Atomic Replace**: `mv draft โ ์๋ณธ` ํ ๋ฒ์ ํ์ผ ์์คํ
์ด๋ฒคํธ๋ก ๊ต์ฒด
4. **๊ฒฐ๊ณผ ํ์ธ**: `wc -l`๋ก ํ์ผ ํฌ๊ธฐ ๊ฒ์ฆ (minimal ์ํ = ๋น ์บ๋ฒ์ค ์์ฌ)
### ํผํด์ผ ํ ํจํด
- ๊ฐ์ `.canvas` ํ์ผ์ ์ฐ์์ ์ผ๋ก Write ํธ์ถ (race condition)
- Edit์ผ๋ก ๋ถ๋ถ ์์ ํ Obsidian sync ์ ๋ค์ Edit
- ์์ฑ ์งํ ๋ฐ๋ก `obsidian://open` ํธ์ถ (์์ฑ ์ค sync ์ถฉ๋ ๊ฐ๋ฅ)
- ์ฌ์ฉ์์๊ฒ "Obsidian ์๋ก๊ณ ์นจ" ๋ฐ๋ณต ์์ฒญ
### Atomic Replace ์์
```bash
# 1. ์์ ํ์ผ์ ์์ ํ ์บ๋ฒ์ค ์์ฑ
Write file: AI/Canvas/foo.canvas.draft (์ ์ฒด ๋ด์ฉ)
# 2. ํ ๋ฒ์ ๊ต์ฒด
mv "AI/Canvas/foo.canvas.draft" "AI/Canvas/foo.canvas"
# 3. ๊ฒฐ๊ณผ ๊ฒ์ฆ
wc -l "AI/Canvas/foo.canvas" # ์ ์ = ๋
ธ๋ ์์ ๋น๋กํ ์ค ์
# ๋น์ ์ = 6-9์ค (minimal ์ํ)
```
### ์์ ์์ ๋ ์ ์ฒด ์ฌ์์ฑ
๋ถ๋ถ ์์ ์ด ํ์ํด๋ **์ ์ฒด ์บ๋ฒ์ค JSON์ ์์ ํ์ผ์ ๋ค์ ์ฐ๊ณ atomic replace**. Edit ๋๊ตฌ๋ก ํ ๋
ธ๋๋ง ์์ ํ๋ ํจํด์ sync ์ถฉ๋์ ์ผ์ผํฌ ์ ์๋ค.
## Canvas File Structure
```json
{
"nodes": [
{
"id": "unique-id",
"type": "text" | "file" | "link" | "group",
"text": "content or file path",
"x": 0, "y": 0,
"width": 250, "height": 60,
"color": "1-6"
}
],
"edges": [
{
"id": "edge-id",
"fromNode": "node-id",
"fromSide": "top|bottom|left|right",
"toNode": "node-id",
"toSide": "top|bottom|left|right",
"color": "1-6"
}
]
}
```
## Layout Patterns
### 1. Radial Layout (๋ฐฉ์ฌํ)
์ค์ฌ ๋
ธ๋์์ ์นดํ
๊ณ ๋ฆฌ๋ณ๋ก ๋ฐฉ์ฌํ ๋ฐฐ์น
```
Topic1
|
Topic4 - CENTER - Topic2
|
Topic3
```
**Use case**: Weekly reading, topic overview
**Spacing**: 400-600px from center
### 2. Grid Layout (๊ทธ๋ฆฌ๋)
์นดํ
๊ณ ๋ฆฌ๋ณ ์ธ๋ก ์ด๋ก ๋ฐฐ์น
```
Category1 Category2 Category3
Item1 Item1 Item1
Item2 Item2 Item2
Item3 Item3 Item3
```
**Use case**: Comparative analysis, multi-column organization
**Spacing**: X: 400px, Y: 100px between items
### 3. Timeline Layout (ํ์๋ผ์ธ)
์๊ฐ์ ๊ฐ๋ก ํ๋ฆ
```
Event1 โ Event2 โ Event3 โ Event4
```
**Use case**: Project milestones, historical events
**Spacing**: 300px horizontal
### 4. Hierarchical Layout (๊ณ์ธตํ)
ํธ๋ฆฌ ๊ตฌ์กฐ๋ก ์โ์๋ ํ์ฅ
```
Root
/ \
Child1 Child2
/ \ / \
A B C D
```
**Use case**: Concept breakdown, org charts
**Spacing**: Y: 200px per level
### 5. Side-by-side Comparison (๊ฐ๋ก ๋น๊ต)
๊ด๋ จ ํญ๋ชฉ๋ค์ ๊ฐ๋ก๋ก ๋ฐฐ์นํ์ฌ ํ๋์ ๋น๊ต
```
โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ
โ ํญ๋ชฉ1 โ โ ํญ๋ชฉ2 โ โ ํญ๋ชฉ3 โ
โ (350px) โ โ (350px) โ โ (350px) โ
โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ
```
**Use case**: ์ต์
๋น๊ต, ์์ฝ ์นด๋, ๊ด๋ จ ๊ฐ๋
๋์ด
**Node width**: 300-350px (์ข๊ฒ)
**X spacing**: 40px between nodes
**X position calculation** (centered at x=0):
- 2 nodes: x = -195, 195
- 3 nodes: x = -390, 0, 390
- ๊ณ์ฐ์: ์ฒซ ๋
ธ๋ x = -(์ด๋๋น/2) + (๋
ธ๋๋๋น/2)
### 6. Two-Column Comparison (2์ด ๋น๊ต)
๋์กฐ๋๋ ๋ ๊ด์ /์ต์
์ ์์ชฝ์ ๋ฐฐ์น
```
LEFT COLUMN RIGHT COLUMN
โโโโโโโโโโโ โโโโโโโโโโโ
โ Header โ โ Header โ
โโโโโโโโโโโค โโโโโโโโโโโค
โ Item 1 โ โ Item 1 โ
โ Item 2 โ โ Item 2 โ
โ Item 3 โ โ Item 3 โ
โโโโโโฌโโโโโ โโโโโโฌโโโโโ
โโโโโโโโโฌโโโโโโโโโโโโ
โโโโโโโดโโโโโโ
โ Common โ
โ Ground โ
โโโโโโโโโโโโโ
```
**Use case**: A vs B ๋น๊ต, ์ฐฌ๋ฐ, Before/After, ๊ด์ ๋์กฐ
**Column width**: 500-550px each
**X spacing**: 750px between column centers (left: -375, right: 375)
**Center elements**: x = 0 (์์ชฝ ์ฐ๊ฒฐ)
## Color Scheme
| Color | ID | Use Case |
|-------|-----|----------|
| Red | 1 | AI & Tech |
| Orange | 2 | Work & Projects |
| Yellow | 3 | Current Events |
| Green | 4 | PKM & Learning |
| Purple | 5 | Personal & Meta |
| Blue | 6 | Education & Career |
## Node Types & Sizes
### Text Node
- **Default**: 250x60 (single line)
- **Quote**: 280x60 (wider for readability)
- **Multi-line**: 250x(60 + 20*lines)
### File Node
- **Link to note**: 280x90 (includes title + summary)
- **Path format**: Use wiki links in text field
### Group Node
- **Category header**: 200x50
- **Container**: Auto-size based on children
### Width Adaptation (ํญ ๋ณ๊ฒฝ ์ ์ฝํ
์ธ ์กฐ์ )
๋ ์ด์์ ๋ณ๊ฒฝ์ผ๋ก ๋
ธ๋ ํญ์ด ์ค์ด๋ค ๋:
| ํญ ๋ณ๊ฒฝ | ์ฝํ
์ธ ์กฐ์ |
|--------|------------|
| 550px โ 350px | ํ
์ด๋ธ ์ด ์ถ์, ๊ธด ๋ฌธ์ฅ ๋ถ๋ฆฌ |
| 350px โ 300px | ๋ถ๋ฆฟ 2-3๊ฐ๋ง, ์์ ์ ๊ฑฐ |
| 300px โ 250px | ์ ๋ชฉ + ํ ์ค ์์ฝ๋ง |
**์ถ์ฝ ์ฐ์ ์์** (๋จผ์ ์ ๊ฑฐํ ๊ฒ):
1. ๋ถ์ฐ ์ค๋ช
, ๊ดํธ ๋ด์ฉ
2. ์์, ์ฐธ์กฐ
3. ํ
์ด๋ธ ํ (ํต์ฌ๋ง ์ ์ง)
4. ๋ถ๋ฆฟ ํฌ์ธํธ ์
## Auto-Layout Algorithm
### Step 1: Categorize Nodes
Group nodes by topic/category using tags or manual grouping.
### Step 2: Calculate Positions
Based on layout pattern:
- **Radial**: Divide 360ยฐ by category count
- **Grid**: Calculate column width, row height
- **Timeline**: Distribute evenly on X-axis
- **Hierarchy**: BFS traversal, level-by-level
### Step 3: Avoid Overlaps
- Minimum spacing: 50px
- Check bounding boxes
- Adjust if collision detected
### Step 4: Create Edges
- Connect center to categories (radial)
- Connect sequential items (timeline)
- Connect parent-child (hierarchy)
## Example Templates
### Weekly Reading Canvas
```json
{
"nodes": [
{
"id": "center",
"type": "text",
"text": "# Weekly Reading\n## Dec 20-27, 2025",
"x": 0, "y": 0,
"width": 200, "height": 80,
"color": "5"
},
{
"id": "group-ai",
"type": "text",
"text": "## AI & Learning",
"x": -380, "y": -200,
"width": 180, "height": 50,
"color": "1"
}
],
"edges": [
{
"id": "edge-center-ai",
"fromNode": "center",
"fromSide": "left",
"toNode": "group-ai",
"toSide": "right",
"color": "1"
}
]
}
```
### Project Timeline Canvas
```json
{
"nodes": [
{
"id": "phase1",
"type": "text",
"text": "**Phase 1**\nResearch",
"x": 0, "y": 0,
"width": 200, "height": 80,
"color": "1"
},
{
"id": "phase2",
"type": "text",
"text": "**Phase 2**\nDevelopment",
"x": 300, "y": 0,
"width": 200, "height": 80,
"color": "2"
}
],
"edges": [
{
"id": "edge-1-2",
"fromNode": "phase1",
"fromSide": "right",
"toNode": "phase2",
"toSide": "left"
}
]
}
```
## Best Practices
### Content First, Layout Second
1. List all items to include
2. Group by category/theme
3. Choose layout pattern
4. Generate coordinates
5. Add edges last
### Keep It Scannable
- Max 20 nodes per canvas
- 4-6 categories ideal
- Clear visual hierarchy
- Consistent spacing
### Link to Notes
- Use wiki link format: `[[Note Title]]`
- Include section links: `[[Note#Section]]`
- Add emoji for visual cues
### Iterate Layout
- Start with template
- Adjust spacing if crowded
- Test in Obsidian preview
- Refine edge routing
### Part Headers for Long Documents
๊ธด ์บ๋ฒ์ค๋ Part ํค๋๋ก ์น์
๊ตฌ๋ถ
**์ธ์ ์ฌ์ฉ**:
- ๋
ธ๋ ์ 15๊ฐ ์ด์
- ๋
ผ๋ฆฌ์ ์ผ๋ก ๊ตฌ๋ถ๋๋ ๋จ๊ณ/์น์
์กด์ฌ
**Part ํค๋ ํ์**:
```json
{"id":"part1","type":"text","text":"# ๐ Part 1: [์น์
๋ช
]","x":-275,"y":[y],"width":550,"height":60,"color":"[์์]"}
```
**Part ๊ฐ ์์ ๊ตฌ๋ถ**:
- ๊ฐ Part์ ๋ค๋ฅธ ์์ ํ ๋น
- Part ๋ด ๋
ธ๋๋ค์ ๋์ผ ์์ ๊ณ์ด ์ฌ์ฉ
- ์๊ฐ์ ๋ค๋น๊ฒ์ด์
ํฅ์
## Overlap Prevention (์ค๋ฒ๋ฉ ๋ฐฉ์ง)
์บ๋ฒ์ค ์
๋ฐ์ดํธ ์ **ํญ์** ์ค๋ฒ๋ฉ์ ์ฒดํฌํด์ผ ํ๋ค. ์ค๋ฒ๋ฉ์ ๊ฐ๋
์ฑ์ ํด์น๊ณ ๋
ธ๋ ์ ํ์ ์ด๋ ต๊ฒ ๋ง๋ ๋ค.
### ์ค๋ฒ๋ฉ ๊ณ์ฐ ๊ณต์
๋ ๋
ธ๋๊ฐ ๊ฒน์น๋์ง ํ์ธ:
```
Node A: (x1, y1, width1, height1)
Node B: (x2, y2, width2, height2)
์ค๋ฒ๋ฉ ์กฐ๊ฑด (๋ ๋ค ๋ง์กฑ ์ ์ค๋ฒ๋ฉ):
- X์ถ: x1 < x2 + width2 AND x1 + width1 > x2
- Y์ถ: y1 < y2 + height2 AND y1 + height1 > y2
```
### ์ ์ ๊ฐ๊ฒฉ ๊ณ์ฐ
๋
ธ๋ ๊ฐ ๊ฐ๊ฒฉ์ ์ ์งํ๊ธฐ ์ํ ๊ณต์:
```
๋ค์ ๋
ธ๋ Y = ํ์ฌ ๋
ธ๋ Y + ํ์ฌ ๋
ธ๋ Height + Gap(30-50px)
์์:
- Node A: y=500, height=180 โ Node A ํ๋จ = 680
- Node B ์์: y = 680 + 40(gap) = 720
```
### ๋
ธ๋ ๋์ด ๊ถ์ฅ ๊ธฐ์ค
| ์ฝํ
์ธ ์ ํ | ๊ถ์ฅ ๋์ด |
|------------|----------|
| ํ ์ค ์ ๋ชฉ | 60-80px |
| 2-3์ค ํ
์คํธ | 100-120px |
| ์ค๊ฐ ์ค๋ช
(4-6์ค) | 140-180px |
| ๊ธด ์ค๋ช
(7-10์ค) | 200-260px |
| ํ
์ด๋ธ ํฌํจ | 250-350px |
### ์บ๋ฒ์ค ์์ ์ ์ฒดํฌ๋ฆฌ์คํธ
1. **์์ ์ **: ํ์ฌ ๋
ธ๋๋ค์ Y ์ขํ + Height ํ์
2. **๋
ธ๋ ์ถ๊ฐ ์**: ์ฝ์
์์น ๊ธฐ์ค ํ๋จ ๋ชจ๋ ๋
ธ๋ Y๊ฐ ์กฐ์
3. **Height ๋ณ๊ฒฝ ์**: ํด๋น ๋
ธ๋ ์ดํ ๋ชจ๋ ๋
ธ๋ Y๊ฐ ์ฌ๊ณ์ฐ
4. **์์ ํ**: ๋ชจ๋ ์ธ์ ๋
ธ๋ ์์ ๋ํด ์ค๋ฒ๋ฉ ๊ฒ์ฌ
### ๋ ์ด์์ ํจํด๋ณ ๊ฐ๊ฒฉ
| ๋ ์ด์์ | X ๊ฐ๊ฒฉ | Y ๊ฐ๊ฒฉ |
|---------|--------|--------|
| Radial | 400-600px | N/A |
| Grid | 350-450px | 40-60px |
| Timeline | 280-350px | N/A |
| Hierarchical | N/A | 150-250px |
| Two-Column | 500-700px | 40-60px |
### ์๋ ์ค๋ฒ๋ฉ ์์ ์ ์ฐจ
```
1. ๋ชจ๋ ๋
ธ๋๋ฅผ Y ์ขํ ๊ธฐ์ค ์ ๋ ฌ
2. ๊ฐ ๋
ธ๋์ ๋ํด:
a. ์ด์ ๋
ธ๋์ ํ๋จ(y + height)๊ณผ ํ์ฌ ๋
ธ๋์ ์๋จ(y) ๋น๊ต
b. ๊ฒน์น๋ฉด: ํ์ฌ ๋
ธ๋ y = ์ด์ ๋
ธ๋ ํ๋จ + 40px
c. ์ดํ ๋ชจ๋ ๋
ธ๋ y ๊ฐ์ ๋์ผ delta๋งํผ ์ด๋
3. ์ผํฐ ์ ๋ ฌ์ด ํ์ํ ๋
ธ๋๋ x ๊ฐ๋ ์กฐ์
```
## Quality Checklist
Before finalizing canvas:
- [ ] All nodes have unique IDs
- [ ] **No overlapping nodes** (run overlap check formula above)
- [ ] Minimum 30-50px spacing between adjacent nodes
- [ ] Colors follow scheme (AI=1, PKM=4, etc.)
- [ ] Center node clearly visible
- [ ] Edges don't cross unnecessarily
- [ ] Wiki links are valid
- [ ] Canvas renders in Obsidian without errors
## Common Use Cases
### 1. Weekly Reading Summary
- **Layout**: Radial
- **Categories**: AI, PKM, Current Events, Education
- **Nodes**: Article links with quotes
- **Output**: `AI/Canvas/YYYY-MM-DD Weekly Reading.canvas`
### 2. Project Planning
- **Layout**: Timeline or Hierarchical
- **Nodes**: Milestones, tasks, deliverables
Ver en GitHub