Files
BlueRoseNote/.claude/skills/obsidian-canvas-creator/references/canvas-spec.md

404 lines
8.5 KiB
Markdown
Raw Normal View History

2026-04-13 17:46:48 +08:00
# JSON Canvas Specification for Obsidian
Version 1.0 — 2024-03-11
## Overview
JSON Canvas is a format for representing infinite canvas documents. This specification defines the structure for creating canvas files compatible with Obsidian.
## Top Level Structure
The root JSON object contains two optional arrays:
```json
{
"nodes": [...],
"edges": [...]
}
```
- `nodes` (optional, array): All canvas objects (text, files, links, groups)
- `edges` (optional, array): All connections between nodes
## Node Types
### Common Attributes
All nodes share these required attributes:
- `id` (required, string): Unique identifier for the node
- `type` (required, string): Node type (`text`, `file`, `link`, `group`)
- `x` (required, integer): X position in pixels
- `y` (required, integer): Y position in pixels
- `width` (required, integer): Width in pixels
- `height` (required, integer): Height in pixels
- `color` (optional, string/number): Color (hex `"#FF0000"` or preset `"1"`)
### Text Nodes
Store plain text with Markdown formatting.
**Required Attributes:**
- `text` (string): Content in Markdown syntax
**Example:**
```json
{
"id": "abc123",
"type": "text",
"x": 0,
"y": 0,
"width": 250,
"height": 100,
"text": "# Main Topic\n\nKey point here",
"color": "4"
}
```
### File Nodes
Reference other files or attachments (images, PDFs, etc.).
**Required Attributes:**
- `file` (string): Path to file in the vault
**Optional Attributes:**
- `subpath` (string): Link to specific heading/block (starts with `#`)
**Example:**
```json
{
"id": "def456",
"type": "file",
"x": 300,
"y": 0,
"width": 400,
"height": 300,
"file": "Images/diagram.png"
}
```
**With Subpath:**
```json
{
"id": "ghi789",
"type": "file",
"x": 0,
"y": 200,
"width": 250,
"height": 100,
"file": "Notes/Meeting Notes.md",
"subpath": "#Action Items"
}
```
### Link Nodes
Reference external URLs.
**Required Attributes:**
- `url` (string): Full URL including protocol
**Example:**
```json
{
"id": "jkl012",
"type": "link",
"x": 0,
"y": -200,
"width": 250,
"height": 100,
"url": "https://obsidian.md",
"color": "5"
}
```
### Group Nodes
Visual containers for organizing related nodes.
**Optional Attributes:**
- `label` (string): Text label for the group (recommended)
- `background` (string): Path to background image
- `backgroundStyle` (string): Image rendering style
- `cover`: Fill entire node
- `ratio`: Maintain aspect ratio
- `repeat`: Tile as pattern
**Example:**
```json
{
"id": "group1",
"type": "group",
"x": -50,
"y": -50,
"width": 600,
"height": 400,
"label": "Main Concepts",
"color": "4"
}
```
**With Background:**
```json
{
"id": "group2",
"type": "group",
"x": 700,
"y": 0,
"width": 500,
"height": 600,
"label": "Reference Materials",
"background": "Images/texture.png",
"backgroundStyle": "repeat"
}
```
## Z-Index and Layering
Nodes are displayed in array order:
- **First node**: Bottom layer (rendered below others)
- **Last node**: Top layer (rendered above others)
**Best Practice Order:**
1. Group nodes (backgrounds)
2. Sub-groups
3. Regular nodes (text, file, link)
This ensures groups appear behind content.
## Edges (Connections)
Edges connect nodes with lines.
**Required Attributes:**
- `id` (required, string): Unique identifier
- `fromNode` (required, string): Starting node ID
- `toNode` (required, string): Ending node ID
**Optional Attributes:**
- `fromSide` (string): Starting edge side
- Values: `top`, `right`, `bottom`, `left`
- `fromEnd` (string): Start endpoint shape
- Values: `none` (default), `arrow`
- `toSide` (string): Ending edge side
- Values: `top`, `right`, `bottom`, `left`
- `toEnd` (string): End endpoint shape
- Values: `arrow` (default), `none`
- `color` (string/number): Edge color
- `label` (string): Text label on edge
**Example - Simple Connection:**
```json
{
"id": "edge1",
"fromNode": "abc123",
"toNode": "def456"
}
```
**Example - Fully Specified:**
```json
{
"id": "edge2",
"fromNode": "def456",
"fromSide": "bottom",
"fromEnd": "none",
"toNode": "ghi789",
"toSide": "top",
"toEnd": "arrow",
"color": "3",
"label": "leads to"
}
```
## Color System
### Preset Colors
Use string numbers `"1"` through `"6"`:
- `"1"` - Red
- `"2"` - Orange
- `"3"` - Yellow
- `"4"` - Green
- `"5"` - Cyan
- `"6"` - Purple
**Note:** Exact colors adapt to Obsidian's theme. These provide semantic meaning across light/dark modes.
### Custom Hex Colors
Use hex format: `"#RRGGBB"`
**Examples:**
- `"#4A90E2"` (blue)
- `"#50E3C2"` (teal)
- `"#F5A623"` (orange)
**Best Practice:** Use consistent format within a canvas (all hex OR all presets).
## Complete Example
```json
{
"nodes": [
{
"id": "group001",
"type": "group",
"x": -50,
"y": -50,
"width": 700,
"height": 500,
"label": "Core Concepts",
"color": "4"
},
{
"id": "center01",
"type": "text",
"x": 0,
"y": 0,
"width": 300,
"height": 120,
"text": "# Central Topic\n\nMain idea here",
"color": "4"
},
{
"id": "branch01",
"type": "text",
"x": 400,
"y": -100,
"width": 220,
"height": 100,
"text": "Subtopic A",
"color": "5"
},
{
"id": "branch02",
"type": "text",
"x": 400,
"y": 100,
"width": 220,
"height": 100,
"text": "Subtopic B",
"color": "5"
},
{
"id": "detail01",
"type": "text",
"x": 700,
"y": -100,
"width": 200,
"height": 80,
"text": "Detail 1",
"color": "6"
}
],
"edges": [
{
"id": "e1",
"fromNode": "center01",
"fromSide": "right",
"toNode": "branch01",
"toSide": "left",
"toEnd": "arrow"
},
{
"id": "e2",
"fromNode": "center01",
"fromSide": "right",
"toNode": "branch02",
"toSide": "left",
"toEnd": "arrow"
},
{
"id": "e3",
"fromNode": "branch01",
"fromSide": "right",
"toNode": "detail01",
"toSide": "left",
"toEnd": "arrow",
"color": "3"
}
]
}
```
## Validation Requirements
When creating canvas files, ensure:
1. **Unique IDs**: All `id` values must be unique across nodes and edges
2. **Valid References**: All edge `fromNode` and `toNode` must reference existing node IDs
3. **Required Fields**: All required attributes are present for each type
4. **Valid Coordinates**: All position/dimension values are integers
5. **Color Format**: Colors use either hex (`"#RRGGBB"`) or preset strings (`"1"` to `"6"`)
6. **Quote Escaping**: Special characters properly escaped in JSON strings
## Common Issues and Solutions
### Issue: Canvas won't open in Obsidian
**Solutions:**
- Validate JSON syntax (use JSON validator)
- Check all IDs are unique
- Verify all edge references exist
- Ensure required fields present
### Issue: Nodes appear overlapped
**Solutions:**
- Increase spacing between coordinates
- Account for node dimensions in positioning
- Use minimum spacing: 320px horizontal, 200px vertical
### Issue: Groups don't show properly
**Solutions:**
- Ensure groups appear before content nodes in array
- Add explicit `label` to all groups
- Check group dimensions encompass child nodes
### Issue: Colors don't match expectations
**Solutions:**
- Use consistent color format (all hex OR all presets)
- Remember presets adapt to theme
- Test in both light and dark mode if using custom colors
### Issue: Text appears truncated
**Solutions:**
- Increase node dimensions
- Break long text into multiple nodes
- Use file nodes for lengthy content
## Character Encoding for Chinese Content
When canvas contains Chinese text, apply these transformations:
- Chinese double quotes `"``『』`
- Chinese single quotes `'``「」`
- English double quotes must be escaped: `\"`
**Example:**
```json
{
"text": "『核心概念』包含:「子概念A」和「子概念B」"
}
```
This prevents JSON parsing errors with mixed-language content.
## Performance Considerations
- **Large Canvases**: Keep node count reasonable (<500 for smooth performance)
- **Image Files**: Use compressed images for backgrounds
- **Text Length**: Keep node text concise; use file nodes for long content
- **Edge Complexity**: Minimize crossing edges for clarity
## Future Extensions
This specification may be extended with:
- Additional node types
- More edge styling options
- Animation properties
- Interactive behaviors
Always check Obsidian documentation for latest Canvas features.