@pinepaper.studio/mcp-server 1.4.3 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -0
- package/dist/__tests__/fixtures/mock-generators.d.ts +147 -0
- package/dist/__tests__/fixtures/mock-generators.d.ts.map +1 -1
- package/dist/__tests__/fixtures/mock-generators.js +85 -0
- package/dist/__tests__/fixtures/mock-generators.js.map +1 -1
- package/dist/agent/export-manager.d.ts +77 -0
- package/dist/agent/export-manager.d.ts.map +1 -0
- package/dist/agent/export-manager.js +455 -0
- package/dist/agent/export-manager.js.map +1 -0
- package/dist/agent/index.d.ts +9 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +12 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/session-manager.d.ts +109 -0
- package/dist/agent/session-manager.d.ts.map +1 -0
- package/dist/agent/session-manager.js +311 -0
- package/dist/agent/session-manager.js.map +1 -0
- package/dist/agent/types.d.ts +385 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +141 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/puppeteer-controller.d.ts +89 -5
- package/dist/browser/puppeteer-controller.d.ts.map +1 -1
- package/dist/browser/puppeteer-controller.js +412 -11
- package/dist/browser/puppeteer-controller.js.map +1 -1
- package/dist/cli.js +3 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2717 -147
- package/dist/index.js.map +1 -1
- package/dist/prompts/index.d.ts +39 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +254 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/tools/compact-descriptions.d.ts +9 -0
- package/dist/tools/compact-descriptions.d.ts.map +1 -0
- package/dist/tools/compact-descriptions.js +260 -0
- package/dist/tools/compact-descriptions.js.map +1 -0
- package/dist/tools/definitions.d.ts +12 -0
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +4844 -1559
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/handlers.d.ts.map +1 -1
- package/dist/tools/handlers.js +915 -17
- package/dist/tools/handlers.js.map +1 -1
- package/dist/tools/index.d.ts +2 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/types/code-generator.d.ts +197 -1
- package/dist/types/code-generator.d.ts.map +1 -1
- package/dist/types/code-generator.js +2338 -26
- package/dist/types/code-generator.js.map +1 -1
- package/dist/types/schemas.d.ts +5294 -1134
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/types/schemas.js +886 -4
- package/dist/types/schemas.js.map +1 -1
- package/manifest.json +70 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11,92 +11,127 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
13
13
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
14
|
-
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
15
|
-
import { PINEPAPER_TOOLS } from './tools/definitions.js';
|
|
14
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
15
|
+
import { PINEPAPER_TOOLS, getToolsForVerbosity } from './tools/definitions.js';
|
|
16
16
|
import { handleToolCall, getExecutionMode } from './tools/handlers.js';
|
|
17
17
|
import { initI18n, DEFAULT_LOCALE, } from './i18n/index.js';
|
|
18
|
+
import { PROMPTS, getPromptMessages } from './prompts/index.js';
|
|
18
19
|
// =============================================================================
|
|
19
20
|
// SERVER INFO
|
|
20
21
|
// =============================================================================
|
|
21
22
|
const SERVER_INFO = {
|
|
22
23
|
name: 'pinepaper-mcp',
|
|
23
|
-
version: '1.
|
|
24
|
+
version: '1.5.0',
|
|
24
25
|
description: 'MCP Server for PinePaper Studio - Create animated graphics with AI',
|
|
25
26
|
};
|
|
26
27
|
// =============================================================================
|
|
27
28
|
// RESOURCES (Documentation & Examples)
|
|
28
29
|
// =============================================================================
|
|
29
30
|
const RESOURCES = [
|
|
31
|
+
// === CORE GUIDES (Start here) ===
|
|
30
32
|
{
|
|
31
33
|
uri: 'pinepaper://docs/getting-started',
|
|
32
|
-
name: 'Getting Started
|
|
33
|
-
description: '
|
|
34
|
+
name: '🚀 Getting Started',
|
|
35
|
+
description: 'START HERE: Tool categories, quick examples, and how to find the right tools',
|
|
36
|
+
mimeType: 'text/markdown',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
uri: 'pinepaper://docs/templates',
|
|
40
|
+
name: '📋 Templates Guide',
|
|
41
|
+
description: 'Pre-built templates with animations ready - just change content. Check here first!',
|
|
42
|
+
mimeType: 'text/markdown',
|
|
43
|
+
},
|
|
44
|
+
// === FEATURE GUIDES (How to use each feature) ===
|
|
45
|
+
{
|
|
46
|
+
uri: 'pinepaper://docs/map-tools',
|
|
47
|
+
name: '🗺️ Maps Guide',
|
|
48
|
+
description: 'Create USA state maps, world maps, choropleth coloring, and animated map regions',
|
|
49
|
+
mimeType: 'text/markdown',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
uri: 'pinepaper://docs/diagrams',
|
|
53
|
+
name: '📊 Diagrams Guide',
|
|
54
|
+
description: 'Create flowcharts, UML diagrams, network diagrams, and auto-layout',
|
|
55
|
+
mimeType: 'text/markdown',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
uri: 'pinepaper://docs/masks',
|
|
59
|
+
name: '🎭 Masks Guide',
|
|
60
|
+
description: 'Create reveal effects: wipes, iris, curtains, and custom animated masks',
|
|
34
61
|
mimeType: 'text/markdown',
|
|
35
62
|
},
|
|
36
63
|
{
|
|
37
64
|
uri: 'pinepaper://docs/relations',
|
|
38
|
-
name: '
|
|
39
|
-
description: '
|
|
65
|
+
name: '🔄 Animation Guide',
|
|
66
|
+
description: 'Animate with relations: orbit, follow, attached, bounce, and more',
|
|
40
67
|
mimeType: 'text/markdown',
|
|
41
68
|
},
|
|
42
69
|
{
|
|
43
70
|
uri: 'pinepaper://docs/generators',
|
|
44
|
-
name: '
|
|
45
|
-
description: '
|
|
71
|
+
name: '🎨 Backgrounds Guide',
|
|
72
|
+
description: 'Create procedural backgrounds: 14 generators including sunburst, grid, waves, bokeh, gradient mesh, wind field, noise textures',
|
|
46
73
|
mimeType: 'text/markdown',
|
|
47
74
|
},
|
|
48
75
|
{
|
|
49
|
-
uri: 'pinepaper://docs/
|
|
50
|
-
name: '
|
|
51
|
-
description: '
|
|
76
|
+
uri: 'pinepaper://docs/effects-and-filters',
|
|
77
|
+
name: '✨ Effects Guide',
|
|
78
|
+
description: 'Add visual effects: sparkle, blast, filters, and post-processing',
|
|
52
79
|
mimeType: 'text/markdown',
|
|
53
80
|
},
|
|
54
81
|
{
|
|
55
|
-
uri: 'pinepaper://docs/
|
|
56
|
-
name: '
|
|
57
|
-
description: '
|
|
82
|
+
uri: 'pinepaper://docs/customization',
|
|
83
|
+
name: '🔧 Customization Guide',
|
|
84
|
+
description: 'How to adapt templates, create custom designs, and handle any user request',
|
|
58
85
|
mimeType: 'text/markdown',
|
|
59
86
|
},
|
|
87
|
+
// === EXAMPLES (Copy-paste workflows) ===
|
|
60
88
|
{
|
|
61
|
-
uri: 'pinepaper://
|
|
62
|
-
name: '
|
|
63
|
-
description: '
|
|
89
|
+
uri: 'pinepaper://examples/us-states-animated',
|
|
90
|
+
name: '🇺🇸 US States Animated',
|
|
91
|
+
description: 'EXAMPLE: Create a US map with random colors that animate in a loop',
|
|
64
92
|
mimeType: 'text/markdown',
|
|
65
93
|
},
|
|
66
94
|
{
|
|
67
|
-
uri: 'pinepaper://
|
|
68
|
-
name: '
|
|
69
|
-
description: '
|
|
95
|
+
uri: 'pinepaper://examples/world-population-map',
|
|
96
|
+
name: '🌍 World Population Map',
|
|
97
|
+
description: 'EXAMPLE: Choropleth map with population data and color scale',
|
|
70
98
|
mimeType: 'text/markdown',
|
|
71
99
|
},
|
|
72
100
|
{
|
|
73
|
-
uri: 'pinepaper://
|
|
74
|
-
name: '
|
|
75
|
-
description: '
|
|
101
|
+
uri: 'pinepaper://examples/flowchart',
|
|
102
|
+
name: '📋 Flowchart Example',
|
|
103
|
+
description: 'EXAMPLE: Create a decision flowchart with auto-layout',
|
|
76
104
|
mimeType: 'text/markdown',
|
|
77
105
|
},
|
|
78
106
|
{
|
|
79
107
|
uri: 'pinepaper://examples/solar-system',
|
|
80
|
-
name: 'Solar System
|
|
81
|
-
description: '
|
|
108
|
+
name: '🪐 Solar System',
|
|
109
|
+
description: 'EXAMPLE: Orbiting planets with relations',
|
|
82
110
|
mimeType: 'text/markdown',
|
|
83
111
|
},
|
|
84
112
|
{
|
|
85
|
-
uri: 'pinepaper://examples/
|
|
86
|
-
name: '
|
|
87
|
-
description: '
|
|
113
|
+
uri: 'pinepaper://examples/reveal-animation',
|
|
114
|
+
name: '🎬 Reveal Animation',
|
|
115
|
+
description: 'EXAMPLE: Text reveal with mask animations',
|
|
88
116
|
mimeType: 'text/markdown',
|
|
89
117
|
},
|
|
90
118
|
{
|
|
91
|
-
uri: 'pinepaper://
|
|
92
|
-
name: '
|
|
93
|
-
description: 'Create
|
|
119
|
+
uri: 'pinepaper://docs/fonts',
|
|
120
|
+
name: 'Guide: Font Studio',
|
|
121
|
+
description: 'Create custom hand-drawn fonts with Font Studio tools',
|
|
94
122
|
mimeType: 'text/markdown',
|
|
95
123
|
},
|
|
124
|
+
// === ADVANCED (For developers) ===
|
|
96
125
|
{
|
|
97
|
-
uri: 'pinepaper://
|
|
98
|
-
name: '
|
|
99
|
-
description: '
|
|
126
|
+
uri: 'pinepaper://docs/custom-paths',
|
|
127
|
+
name: 'Advanced: Custom Paths',
|
|
128
|
+
description: 'SVG paths, Paper.js paths, and path animations',
|
|
129
|
+
mimeType: 'text/markdown',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
uri: 'pinepaper://docs/paperjs-in-pinepaper',
|
|
133
|
+
name: 'Advanced: Paper.js API',
|
|
134
|
+
description: 'Write Paper.js code directly for full control',
|
|
100
135
|
mimeType: 'text/markdown',
|
|
101
136
|
},
|
|
102
137
|
];
|
|
@@ -105,70 +140,457 @@ const RESOURCE_CONTENTS = {
|
|
|
105
140
|
|
|
106
141
|
## Overview
|
|
107
142
|
|
|
108
|
-
PinePaper is a canvas-based animation tool
|
|
143
|
+
PinePaper is a canvas-based animation tool with 121 tools for creating animated graphics, custom fonts, maps, diagrams, and more. This guide helps you find the right tools.
|
|
109
144
|
|
|
110
|
-
##
|
|
145
|
+
## FIRST: Check Templates
|
|
111
146
|
|
|
112
|
-
|
|
113
|
-
2. **Clear the canvas**: Use \`pinepaper_clear_canvas\` or \`pinepaper_refresh_page\` to start fresh
|
|
114
|
-
3. **Create items**: Use \`pinepaper_create_item\` to add text, shapes, or graphics
|
|
115
|
-
4. **Add animation**: Use \`pinepaper_add_relation\` for behavior-based animation
|
|
116
|
-
5. **Verify**: Use \`pinepaper_browser_screenshot\` to see your work
|
|
117
|
-
6. **Export**: Use \`pinepaper_export_svg\` to save your work
|
|
147
|
+
PinePaper Studio includes pre-built templates for common use cases. **Templates already have animations configured** - you just change the content!
|
|
118
148
|
|
|
119
|
-
|
|
149
|
+
**Before building from scratch, consider:**
|
|
150
|
+
- Is there a template that matches this use case?
|
|
151
|
+
- Can I modify an existing template instead of building new?
|
|
152
|
+
- Templates save time: just update text, colors, or data
|
|
153
|
+
|
|
154
|
+
**Use \`pinepaper_create_scene\` for complex animated scenes** - it's 4-8x faster than individual tool calls:
|
|
155
|
+
|
|
156
|
+
\`\`\`
|
|
157
|
+
pinepaper_create_scene
|
|
158
|
+
backgroundColor: "#0a0a0a"
|
|
159
|
+
items:
|
|
160
|
+
- name: "sun", itemType: "circle", position: {x: 400, y: 300}, properties: {radius: 50, color: "#fbbf24"}
|
|
161
|
+
- name: "earth", itemType: "circle", position: {x: 550, y: 300}, properties: {radius: 20, color: "#3b82f6"}
|
|
162
|
+
relations:
|
|
163
|
+
- source: "earth", target: "sun", type: "orbits", params: {radius: 150, speed: 0.5}
|
|
164
|
+
animations:
|
|
165
|
+
- target: "sun", type: "pulse", speed: 0.3
|
|
166
|
+
\`\`\`
|
|
167
|
+
|
|
168
|
+
## Tool Categories at a Glance
|
|
169
|
+
|
|
170
|
+
| Category | Use When | Key Tools |
|
|
171
|
+
|----------|----------|-----------|
|
|
172
|
+
| **Scenes** | Multi-item animated scenes | \`pinepaper_create_scene\` (FASTEST) |
|
|
173
|
+
| **Maps** | US states, world maps, choropleth | \`pinepaper_load_map\`, \`pinepaper_apply_data_colors\`, \`pinepaper_animate_map_regions\` |
|
|
174
|
+
| **Shapes** | Circles, stars, text, rectangles | \`pinepaper_create_item\` |
|
|
175
|
+
| **Animation** | Orbiting, following, pulsing | \`pinepaper_add_relation\`, \`pinepaper_animate\` |
|
|
176
|
+
| **Masks** | Reveal effects, wipes, transitions | \`pinepaper_apply_animated_mask\` |
|
|
177
|
+
| **Diagrams** | Flowcharts, UML, connections | \`pinepaper_create_diagram_shape\`, \`pinepaper_connect\` |
|
|
178
|
+
| **Backgrounds** | Patterns, gradients, generators | \`pinepaper_execute_generator\` |
|
|
179
|
+
|
|
180
|
+
## Quick Examples
|
|
181
|
+
|
|
182
|
+
### Create a US Map with Animated Colors
|
|
183
|
+
\`\`\`
|
|
184
|
+
1. pinepaper_load_map mapId: "usa", options: { projection: "albers" }
|
|
185
|
+
2. pinepaper_apply_data_colors data: { "CA": 100, "TX": 80, "NY": 70 }, options: { colorScale: "blues" }
|
|
186
|
+
3. pinepaper_animate_map_wave duration: 10, loop: true, colors: ["#ef4444", "#22c55e", "#3b82f6"]
|
|
187
|
+
\`\`\`
|
|
188
|
+
|
|
189
|
+
### Create Orbiting Animation (Using create_scene - Recommended)
|
|
190
|
+
\`\`\`
|
|
191
|
+
pinepaper_create_scene
|
|
192
|
+
items:
|
|
193
|
+
- name: "sun", itemType: "circle", position: {x: 400, y: 300}, properties: {radius: 50, color: "#fbbf24"}
|
|
194
|
+
- name: "planet", itemType: "circle", position: {x: 550, y: 300}, properties: {radius: 15, color: "#3b82f6"}
|
|
195
|
+
relations:
|
|
196
|
+
- source: "planet", target: "sun", type: "orbits"
|
|
197
|
+
\`\`\`
|
|
198
|
+
|
|
199
|
+
### Create Reveal Animation
|
|
200
|
+
\`\`\`
|
|
201
|
+
1. pinepaper_create_item type: "text", params: { x: 400, y: 300, content: "Hello", fontSize: 48 }
|
|
202
|
+
2. pinepaper_apply_animated_mask itemId: "item_1", preset: "wipeLeft", options: { duration: 0.5 }
|
|
203
|
+
\`\`\`
|
|
204
|
+
|
|
205
|
+
## Quick Start
|
|
206
|
+
|
|
207
|
+
Agent mode connects automatically on first tool call. Just start creating!
|
|
120
208
|
|
|
121
|
-
|
|
209
|
+
1. **Check templates first** - existing designs just need content changes
|
|
210
|
+
2. **Use \`pinepaper_create_scene\`** for multi-item animated scenes (fastest)
|
|
211
|
+
3. **Or create items individually**: \`pinepaper_create_item\` for shapes/text
|
|
212
|
+
4. **Add animation**: \`pinepaper_add_relation\` for behavior-based animation
|
|
213
|
+
5. **Verify**: \`pinepaper_browser_screenshot\` to see your work
|
|
214
|
+
6. **Export**: \`pinepaper_export_svg\` to save
|
|
122
215
|
|
|
123
|
-
|
|
124
|
-
- **Option 1**: Use \`pinepaper_clear_canvas\` to remove all items
|
|
125
|
-
- **Option 2**: Use \`pinepaper_refresh_page\` to reload the page (most reliable)
|
|
126
|
-
- After clearing, verify with \`pinepaper_get_items\` that the canvas is empty
|
|
216
|
+
## IMPORTANT: Welcome Template
|
|
127
217
|
|
|
128
|
-
|
|
218
|
+
First-time visitors see a welcome template. Clear it with:
|
|
219
|
+
- \`pinepaper_clear_canvas\` - removes all items
|
|
220
|
+
- \`pinepaper_agent_reset\` - quick reset
|
|
129
221
|
|
|
130
222
|
## Key Concepts
|
|
131
223
|
|
|
132
224
|
### Items
|
|
133
|
-
Everything on
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
- \`
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
225
|
+
Everything on canvas has a registry ID (e.g., "item_1"). Use this ID for animations and modifications.
|
|
226
|
+
|
|
227
|
+
### Relations (Animation)
|
|
228
|
+
Describe behavior between items:
|
|
229
|
+
- \`orbits\`: Circular motion around target
|
|
230
|
+
- \`follows\`: Move toward target with smoothing
|
|
231
|
+
- \`attached_to\`: Fixed offset from parent
|
|
232
|
+
- \`points_at\`: Rotate to face target
|
|
233
|
+
|
|
234
|
+
### Maps
|
|
235
|
+
Built-in maps: \`world\`, \`worldHighRes\`, \`usa\` (US states)
|
|
236
|
+
Load with \`pinepaper_load_map\`, animate with \`pinepaper_animate_map_regions\` or \`pinepaper_animate_map_wave\`
|
|
237
|
+
|
|
238
|
+
### Masks
|
|
239
|
+
Reveal effects: wipeLeft, wipeRight, wipeUp, wipeDown, iris, irisOut, star, heart, curtainHorizontal, curtainVertical, cinematic, diagonalWipe, revealUp, revealDown
|
|
240
|
+
Apply with \`pinepaper_apply_animated_mask\`
|
|
241
|
+
|
|
242
|
+
## Agent Workflow (Recommended)
|
|
243
|
+
|
|
244
|
+
For AI agents, use the batch pipeline for maximum efficiency:
|
|
245
|
+
|
|
246
|
+
1. \`pinepaper_agent_start_job\` — clear canvas, set preset → returns canvasSize {width, height} for positioning
|
|
247
|
+
2. \`pinepaper_agent_batch_execute\` — ONE call with ALL operations (12 types: canvas, background, generators, items, animations, keyframes, relations, masks, effects, playback)
|
|
248
|
+
3. \`pinepaper_agent_end_job\` — returns screenshot for user validation
|
|
249
|
+
4. User reviews → modify specific items or start new job
|
|
250
|
+
|
|
251
|
+
See the \`pinepaper_agent_batch_execute\` tool description for full operation reference.
|
|
252
|
+
|
|
253
|
+
**Note:** Diagrams (flowcharts, UML) use their own tools — \`pinepaper_create_diagram_shape\` + \`pinepaper_connect\` — not batch_execute. See \`pinepaper://docs/diagrams\`.
|
|
254
|
+
|
|
255
|
+
## Detailed Guides
|
|
256
|
+
|
|
257
|
+
- Maps: Read \`pinepaper://docs/map-tools\`
|
|
258
|
+
- Diagrams: Read \`pinepaper://docs/diagrams\`
|
|
259
|
+
- Masks: Read \`pinepaper://docs/masks\`
|
|
260
|
+
- Relations: Read \`pinepaper://docs/relations\`
|
|
261
|
+
- Generators: Read \`pinepaper://docs/generators\`
|
|
262
|
+
- Fonts: Read \`pinepaper://docs/fonts\`
|
|
263
|
+
- Customization: Read \`pinepaper://docs/customization\`
|
|
264
|
+
`,
|
|
265
|
+
'pinepaper://docs/customization': `# Customization Guide
|
|
266
|
+
|
|
267
|
+
**Intent:** Learn how to handle any user design request by combining tools, adapting templates, and creating custom solutions.
|
|
268
|
+
|
|
269
|
+
## Understanding User Requests
|
|
270
|
+
|
|
271
|
+
Users will ask for varied graphics. Here's how to approach any request:
|
|
272
|
+
|
|
273
|
+
### Step 1: Identify the Category
|
|
274
|
+
|
|
275
|
+
| Request Type | Primary Tools | Example |
|
|
276
|
+
|-------------|---------------|---------|
|
|
277
|
+
| Map visualization | \`load_map\`, \`apply_data_colors\` | "Show sales by state" |
|
|
278
|
+
| Animated logo | \`create_item\`, \`add_relation\` | "Make my logo pulse" |
|
|
279
|
+
| Infographic | \`create_diagram_shape\`, \`connect\` | "Create a flowchart" |
|
|
280
|
+
| Social media | \`set_canvas_size\`, \`create_item\` | "Instagram post" |
|
|
281
|
+
| Data chart | \`create_item\` (rectangles for bars) | "Bar chart of values" |
|
|
282
|
+
| Reveal/intro | \`apply_animated_mask\` | "Text wipe animation" |
|
|
283
|
+
|
|
284
|
+
### Step 2: Choose Your Approach
|
|
285
|
+
|
|
286
|
+
| Complexity | Approach | When |
|
|
287
|
+
|------------|----------|------|
|
|
288
|
+
| Simple | Single tools | One shape, one animation |
|
|
289
|
+
| Medium | \`create_scene\` | Multiple items with relations |
|
|
290
|
+
| Complex | Step-by-step tools | Custom logic, conditional design |
|
|
291
|
+
|
|
292
|
+
## Customization Patterns
|
|
293
|
+
|
|
294
|
+
### Pattern 1: Color Scheme Changes
|
|
295
|
+
|
|
296
|
+
User: "Make it blue instead of red"
|
|
297
|
+
|
|
298
|
+
\`\`\`
|
|
299
|
+
// Original
|
|
300
|
+
pinepaper_create_item itemType: "circle" properties: {color: "#ef4444"}
|
|
301
|
+
|
|
302
|
+
// Customized - change color property
|
|
303
|
+
pinepaper_create_item itemType: "circle" properties: {color: "#3b82f6"}
|
|
304
|
+
\`\`\`
|
|
305
|
+
|
|
306
|
+
**Common color palettes:**
|
|
307
|
+
| Theme | Colors |
|
|
308
|
+
|-------|--------|
|
|
309
|
+
| Professional | #1e293b, #3b82f6, #f8fafc |
|
|
310
|
+
| Vibrant | #ef4444, #fbbf24, #22c55e, #3b82f6 |
|
|
311
|
+
| Pastel | #fecaca, #fef08a, #bbf7d0, #bfdbfe |
|
|
312
|
+
| Dark mode | #0f172a, #1e293b, #334155, #f8fafc |
|
|
313
|
+
|
|
314
|
+
### Pattern 2: Size and Position Adjustments
|
|
315
|
+
|
|
316
|
+
User: "Make it bigger" or "Center it"
|
|
317
|
+
|
|
318
|
+
\`\`\`
|
|
319
|
+
// Get canvas size first
|
|
320
|
+
pinepaper_get_canvas_size → {width: 800, height: 600}
|
|
321
|
+
|
|
322
|
+
// Center position = (width/2, height/2)
|
|
323
|
+
pinepaper_create_item itemType: "text" position: {x: 400, y: 300}
|
|
324
|
+
properties: {content: "Centered", fontSize: 48}
|
|
325
|
+
|
|
326
|
+
// Make bigger - increase radius, fontSize, width/height
|
|
327
|
+
pinepaper_modify_item itemId: "item_1" properties: {scale: 1.5}
|
|
328
|
+
\`\`\`
|
|
329
|
+
|
|
330
|
+
### Pattern 3: Animation Speed/Style Changes
|
|
331
|
+
|
|
332
|
+
User: "Make it faster" or "Smoother animation"
|
|
333
|
+
|
|
334
|
+
\`\`\`
|
|
335
|
+
// Faster orbit
|
|
336
|
+
pinepaper_add_relation sourceId: "item_1" targetId: "item_2" relationType: "orbits"
|
|
337
|
+
params: {speed: 2.0} // Higher = faster
|
|
338
|
+
|
|
339
|
+
// Smoother following
|
|
340
|
+
pinepaper_add_relation sourceId: "item_1" targetId: "item_2" relationType: "follows"
|
|
341
|
+
params: {smoothing: 0.95} // Higher = smoother (0-1)
|
|
342
|
+
|
|
343
|
+
// Different easing for masks
|
|
344
|
+
pinepaper_apply_animated_mask itemId: "item_1" preset: "wipeLeft"
|
|
345
|
+
options: {easing: "easeInOut"} // linear, easeIn, easeOut, easeInOut, bounce
|
|
346
|
+
\`\`\`
|
|
347
|
+
|
|
348
|
+
### Pattern 4: Adding Text to Any Design
|
|
349
|
+
|
|
350
|
+
User: "Add a title" or "Label the items"
|
|
351
|
+
|
|
352
|
+
\`\`\`
|
|
353
|
+
// Title at top
|
|
354
|
+
pinepaper_create_item itemType: "text" position: {x: 400, y: 50}
|
|
355
|
+
properties: {content: "My Title", fontSize: 36, fontWeight: "bold", color: "#ffffff"}
|
|
356
|
+
|
|
357
|
+
// Label attached to item (moves with it)
|
|
358
|
+
pinepaper_create_item itemType: "text" position: {x: 400, y: 280}
|
|
359
|
+
properties: {content: "Earth", fontSize: 14, color: "#94a3b8"}
|
|
360
|
+
→ label_1
|
|
361
|
+
|
|
362
|
+
pinepaper_add_relation sourceId: "label_1" targetId: "earth" relationType: "attached_to"
|
|
363
|
+
params: {offset: [0, -30]} // Above the item
|
|
364
|
+
\`\`\`
|
|
365
|
+
|
|
366
|
+
### Pattern 5: Creating Data-Driven Graphics
|
|
367
|
+
|
|
368
|
+
User: "Show these numbers as a chart"
|
|
369
|
+
|
|
370
|
+
\`\`\`
|
|
371
|
+
// Bar chart from data
|
|
372
|
+
// Data: [10, 25, 15, 30, 20]
|
|
373
|
+
|
|
374
|
+
// Bar 1 (height proportional to value)
|
|
375
|
+
pinepaper_create_item itemType: "rectangle" position: {x: 150, y: 350}
|
|
376
|
+
properties: {width: 40, height: 100, color: "#3b82f6"} // height = value * scale
|
|
377
|
+
|
|
378
|
+
// Bar 2
|
|
379
|
+
pinepaper_create_item itemType: "rectangle" position: {x: 210, y: 275}
|
|
380
|
+
properties: {width: 40, height: 250, color: "#3b82f6"}
|
|
381
|
+
|
|
382
|
+
// Continue for each data point...
|
|
383
|
+
// Position x increases by spacing, height = value * multiplier
|
|
384
|
+
\`\`\`
|
|
385
|
+
|
|
386
|
+
### Pattern 6: Responsive Canvas Sizes
|
|
387
|
+
|
|
388
|
+
User: "Make it for Instagram" or "YouTube thumbnail"
|
|
389
|
+
|
|
390
|
+
\`\`\`
|
|
391
|
+
// Set canvas FIRST, then position items relative to it
|
|
392
|
+
pinepaper_set_canvas_size preset: "instagram-post" // 1080x1080
|
|
393
|
+
|
|
394
|
+
// Now center = (540, 540)
|
|
395
|
+
pinepaper_create_item itemType: "text" position: {x: 540, y: 540}
|
|
396
|
+
properties: {content: "Centered!", fontSize: 64}
|
|
397
|
+
\`\`\`
|
|
398
|
+
|
|
399
|
+
**Common presets:**
|
|
400
|
+
| Preset | Size | Use |
|
|
401
|
+
|--------|------|-----|
|
|
402
|
+
| instagram-post | 1080x1080 | Square posts |
|
|
403
|
+
| instagram-story | 1080x1920 | Stories, Reels |
|
|
404
|
+
| youtube-thumbnail | 1280x720 | Video thumbnails |
|
|
405
|
+
| twitter-post | 1200x675 | Twitter/X images |
|
|
406
|
+
|
|
407
|
+
### Pattern 7: Complex Animations with Multiple Relations
|
|
408
|
+
|
|
409
|
+
User: "Make planets orbit the sun with moons"
|
|
410
|
+
|
|
411
|
+
\`\`\`
|
|
412
|
+
pinepaper_create_scene
|
|
413
|
+
backgroundColor: "#0a0a0a"
|
|
414
|
+
items:
|
|
415
|
+
- name: "sun", itemType: "circle", position: {x: 400, y: 300}
|
|
416
|
+
properties: {radius: 50, color: "#fbbf24"}
|
|
417
|
+
- name: "earth", itemType: "circle", position: {x: 550, y: 300}
|
|
418
|
+
properties: {radius: 20, color: "#3b82f6"}
|
|
419
|
+
- name: "moon", itemType: "circle", position: {x: 580, y: 300}
|
|
420
|
+
properties: {radius: 6, color: "#9ca3af"}
|
|
421
|
+
- name: "mars", itemType: "circle", position: {x: 650, y: 300}
|
|
422
|
+
properties: {radius: 15, color: "#ef4444"}
|
|
423
|
+
relations:
|
|
424
|
+
- source: "earth", target: "sun", type: "orbits", params: {radius: 150, speed: 0.5}
|
|
425
|
+
- source: "moon", target: "earth", type: "orbits", params: {radius: 30, speed: 2}
|
|
426
|
+
- source: "mars", target: "sun", type: "orbits", params: {radius: 250, speed: 0.3}
|
|
427
|
+
animations:
|
|
428
|
+
- target: "sun", type: "pulse", speed: 0.3
|
|
429
|
+
\`\`\`
|
|
430
|
+
|
|
431
|
+
## Handling Edge Cases
|
|
432
|
+
|
|
433
|
+
### User Provides Specific Colors
|
|
434
|
+
Always use their exact hex codes:
|
|
435
|
+
\`\`\`
|
|
436
|
+
User: "Use #FF5733 for the background"
|
|
437
|
+
→ properties: {color: "#FF5733"}
|
|
438
|
+
\`\`\`
|
|
439
|
+
|
|
440
|
+
### User Wants Something Not Directly Supported
|
|
441
|
+
Combine tools creatively:
|
|
442
|
+
\`\`\`
|
|
443
|
+
User: "3D cube effect"
|
|
444
|
+
→ Create 3 parallelograms with offset positions and colors
|
|
445
|
+
Use paths with segments to draw isometric shapes
|
|
446
|
+
\`\`\`
|
|
447
|
+
|
|
448
|
+
### User Changes Mind Mid-Design
|
|
449
|
+
Use modify and delete:
|
|
450
|
+
\`\`\`
|
|
451
|
+
pinepaper_modify_item itemId: "item_1" properties: {color: "#new_color"}
|
|
452
|
+
pinepaper_delete_item itemId: "item_2"
|
|
453
|
+
\`\`\`
|
|
454
|
+
|
|
455
|
+
### Performance with Many Items
|
|
456
|
+
Use batch operations:
|
|
457
|
+
\`\`\`
|
|
458
|
+
pinepaper_batch_create items: [{...}, {...}, {...}] // Instead of multiple create_item calls
|
|
459
|
+
\`\`\`
|
|
460
|
+
|
|
461
|
+
## Decision Tree for Any Request
|
|
462
|
+
|
|
463
|
+
\`\`\`
|
|
464
|
+
Is it a MAP? → pinepaper_load_map
|
|
465
|
+
Is it a DIAGRAM/FLOWCHART? → pinepaper_create_diagram_shape + pinepaper_connect
|
|
466
|
+
Is it ANIMATED? → pinepaper_add_relation or pinepaper_animate
|
|
467
|
+
Is it a REVEAL/INTRO? → pinepaper_apply_animated_mask
|
|
468
|
+
Is it DATA VISUALIZATION? → Create shapes proportional to data values
|
|
469
|
+
Is it a BACKGROUND? → pinepaper_execute_generator
|
|
470
|
+
Otherwise → pinepaper_create_item for shapes/text
|
|
471
|
+
\`\`\`
|
|
472
|
+
|
|
473
|
+
## Example: Complete Custom Request
|
|
474
|
+
|
|
475
|
+
User: "Create an animated infographic showing 3 steps with arrows"
|
|
476
|
+
|
|
477
|
+
\`\`\`
|
|
478
|
+
// 1. Set canvas
|
|
479
|
+
pinepaper_set_canvas_size preset: "presentation-16x9"
|
|
480
|
+
|
|
481
|
+
// 2. Create step boxes
|
|
482
|
+
pinepaper_create_diagram_shape shapeType: "process" position: {x: 300, y: 400}
|
|
483
|
+
label: "Step 1: Research" style: {fillColor: "#3b82f6"} → item_1
|
|
484
|
+
|
|
485
|
+
pinepaper_create_diagram_shape shapeType: "process" position: {x: 600, y: 400}
|
|
486
|
+
label: "Step 2: Design" style: {fillColor: "#8b5cf6"} → item_2
|
|
487
|
+
|
|
488
|
+
pinepaper_create_diagram_shape shapeType: "process" position: {x: 900, y: 400}
|
|
489
|
+
label: "Step 3: Build" style: {fillColor: "#22c55e"} → item_3
|
|
490
|
+
|
|
491
|
+
// 3. Connect with arrows
|
|
492
|
+
pinepaper_connect sourceItemId: "item_1" targetItemId: "item_2"
|
|
493
|
+
routing: "direct" animated: true
|
|
494
|
+
|
|
495
|
+
pinepaper_connect sourceItemId: "item_2" targetItemId: "item_3"
|
|
496
|
+
routing: "direct" animated: true
|
|
497
|
+
|
|
498
|
+
// 4. Add title
|
|
499
|
+
pinepaper_create_item itemType: "text" position: {x: 600, y: 150}
|
|
500
|
+
properties: {content: "Our Process", fontSize: 48, fontWeight: "bold"}
|
|
501
|
+
|
|
502
|
+
// 5. Apply reveal animations
|
|
503
|
+
pinepaper_apply_animated_mask itemId: "item_1" preset: "wipeLeft"
|
|
504
|
+
options: {startTime: 0, duration: 0.4}
|
|
505
|
+
|
|
506
|
+
pinepaper_apply_animated_mask itemId: "item_2" preset: "wipeLeft"
|
|
507
|
+
options: {startTime: 0.3, duration: 0.4}
|
|
508
|
+
|
|
509
|
+
pinepaper_apply_animated_mask itemId: "item_3" preset: "wipeLeft"
|
|
510
|
+
options: {startTime: 0.6, duration: 0.4}
|
|
511
|
+
\`\`\`
|
|
512
|
+
|
|
513
|
+
## Key Principles
|
|
514
|
+
|
|
515
|
+
1. **Understand first** - What is the user trying to achieve?
|
|
516
|
+
2. **Start simple** - Use the most direct tool for the job
|
|
517
|
+
3. **Build incrementally** - Add complexity one step at a time
|
|
518
|
+
4. **Verify with screenshots** - \`pinepaper_browser_screenshot\` after each major step
|
|
519
|
+
5. **Offer alternatives** - If something can't be done exactly, suggest similar approaches
|
|
520
|
+
`,
|
|
521
|
+
'pinepaper://docs/templates': `# Templates & Timed Animation Guide
|
|
522
|
+
|
|
523
|
+
## Apply a Template
|
|
524
|
+
|
|
525
|
+
\`pinepaper_list_templates\` — browse available pre-built templates.
|
|
526
|
+
\`pinepaper_apply_template\` — load a template by name. Animations are pre-configured.
|
|
527
|
+
After applying: modify text/colors with \`pinepaper_modify_item\`, then export.
|
|
528
|
+
|
|
529
|
+
## Template Categories
|
|
530
|
+
|
|
531
|
+
| Category | Examples |
|
|
532
|
+
|----------|----------|
|
|
533
|
+
| Map | US Election, World Data, Travel Route |
|
|
534
|
+
| Animation | Solar System, Logo Reveal, Text Intro, Particle Burst |
|
|
535
|
+
| Diagram | Flowchart, Org Chart, Network |
|
|
536
|
+
| Social Media | YouTube Thumbnail (1280x720), Instagram Story (1080x1920), TikTok |
|
|
537
|
+
|
|
538
|
+
## Modifying Templates
|
|
539
|
+
|
|
540
|
+
Change safely: \`properties.content\`, \`properties.color\`, \`backgroundColor\`, positions, sizes.
|
|
541
|
+
Preserve: \`relations\` array, \`animations\` array, item \`name\` values (relations reference these).
|
|
542
|
+
|
|
543
|
+
## Building Timed Animations (4 steps)
|
|
544
|
+
|
|
545
|
+
For invitations, intros, promos, reveals — any timed animation:
|
|
546
|
+
|
|
547
|
+
**1. Create items** — \`pinepaper_create_scene\` with all items. Timed reveals: set \`opacity: 0\`.
|
|
548
|
+
Items get sequential IDs: first = \`item_1\`, second = \`item_2\`, etc.
|
|
549
|
+
|
|
550
|
+
**2. Animate items** — ONE \`pinepaper_execute_custom_code\` call with all animations:
|
|
551
|
+
\`\`\`
|
|
552
|
+
app.addAnimation(registryId, keyframes, options)
|
|
553
|
+
registryId: 'item_1'
|
|
554
|
+
keyframes: [{time: 0, properties: {opacity: 0}, easing: 'easeInOut'},
|
|
555
|
+
{time: 1, properties: {opacity: 1}}]
|
|
556
|
+
options: {duration: number, loop?: boolean, pingPong?: boolean}
|
|
557
|
+
\`\`\`
|
|
558
|
+
Animatable properties: \`opacity\`, \`scale\`, \`scaleX\`, \`scaleY\`, \`x\`, \`y\`, \`rotation\`, \`fillColor\`, \`strokeColor\`, \`fontSize\`.
|
|
559
|
+
Stagger items by offsetting \`time\` values across items.
|
|
560
|
+
|
|
561
|
+
**3. Play** — \`pinepaper_play_timeline\`
|
|
562
|
+
|
|
563
|
+
**4. Export** — \`pinepaper_agent_export\` (SVG/PNG/GIF/MP4/WebM/PDF)
|
|
564
|
+
|
|
565
|
+
## Text Reveal Pattern
|
|
566
|
+
|
|
567
|
+
Create text items, then apply mask reveals with staggered start times:
|
|
568
|
+
\`\`\`
|
|
569
|
+
pinepaper_apply_animated_mask itemId: "item_1" preset: "wipeLeft" options: {duration: 0.5}
|
|
570
|
+
pinepaper_apply_animated_mask itemId: "item_2" preset: "wipeLeft" options: {startTime: 0.3, duration: 0.5}
|
|
571
|
+
\`\`\`
|
|
572
|
+
Mask presets: wipeLeft, wipeRight, wipeUp, wipeDown, iris, irisOut, star, heart, curtainHorizontal, curtainVertical, cinematic, diagonalWipe, revealUp, revealDown.
|
|
573
|
+
|
|
574
|
+
## Advanced Capabilities (via execute_custom_code)
|
|
575
|
+
|
|
576
|
+
**Time-scoped relations** — relation active only during a time window:
|
|
577
|
+
\`\`\`
|
|
578
|
+
app.addRelation(sourceId, targetId, type, {startTime: 2, endTime: 5, autoRemove: true, ...params})
|
|
579
|
+
\`\`\`
|
|
580
|
+
|
|
581
|
+
**Keyframe priority** — when keyframes and relations target the same property:
|
|
582
|
+
\`\`\`
|
|
583
|
+
app.addRelation(sourceId, targetId, type, {relationBehavior: 'keyframeFirst', ...params})
|
|
584
|
+
\`\`\`
|
|
585
|
+
|
|
586
|
+
**Per-item timing** — offset an item into the global timeline:
|
|
587
|
+
\`\`\`
|
|
588
|
+
app.setTimeOffset(registryId, offsetSeconds)
|
|
589
|
+
\`\`\`
|
|
590
|
+
|
|
591
|
+
**Atomic relation replace** — swap relation params without remove+add:
|
|
592
|
+
\`\`\`
|
|
593
|
+
app.replaceRelation(sourceId, targetId, type, newParams)
|
|
172
594
|
\`\`\`
|
|
173
595
|
`,
|
|
174
596
|
'pinepaper://docs/relations': `# Relations Guide
|
|
@@ -226,6 +648,101 @@ Stay within target's bounds.
|
|
|
226
648
|
- \`padding\`: Inner padding
|
|
227
649
|
- \`bounce\`: Bounce off edges
|
|
228
650
|
|
|
651
|
+
### morphs_to
|
|
652
|
+
Smoothly transform source shape into target shape over time.
|
|
653
|
+
- \`duration\`: Morph duration in seconds (default: 1)
|
|
654
|
+
- \`hideTarget\`: Hide target item since it's just a shape reference (default: true)
|
|
655
|
+
- \`removeTargetOnComplete\`: Delete target after morph completes (default: false)
|
|
656
|
+
- \`easing\`: Timing function ('linear', 'easeIn', 'easeOut', 'easeInOut')
|
|
657
|
+
|
|
658
|
+
**Usage patterns:**
|
|
659
|
+
\`\`\`
|
|
660
|
+
// Default: Circle morphs to star's shape, star stays hidden
|
|
661
|
+
pinepaper_add_relation sourceId: "circle" targetId: "star" relationType: "morphs_to"
|
|
662
|
+
params: {duration: 1}
|
|
663
|
+
|
|
664
|
+
// Clean up: Delete star after morph completes
|
|
665
|
+
pinepaper_add_relation sourceId: "circle" targetId: "star" relationType: "morphs_to"
|
|
666
|
+
params: {duration: 1, removeTargetOnComplete: true}
|
|
667
|
+
|
|
668
|
+
// Both visible: Keep star visible (you'll see two stars at end)
|
|
669
|
+
pinepaper_add_relation sourceId: "circle" targetId: "star" relationType: "morphs_to"
|
|
670
|
+
params: {duration: 1, hideTarget: false}
|
|
671
|
+
\`\`\`
|
|
672
|
+
|
|
673
|
+
**Great for:** Logo animations, shape transitions, loading indicators, morphing icons
|
|
674
|
+
|
|
675
|
+
### camera_follows
|
|
676
|
+
Camera pans to follow a target item (like Manim MovingCameraScene).
|
|
677
|
+
- \`smoothing\`: 0-1 (higher = smoother following)
|
|
678
|
+
- \`offset\`: [x, y] offset from target
|
|
679
|
+
- \`zoom\`: Zoom level to maintain
|
|
680
|
+
- \`deadzone\`: Pixels before camera starts moving
|
|
681
|
+
- \`bounds\`: {minX, maxX, minY, maxY} camera movement limits
|
|
682
|
+
|
|
683
|
+
\`\`\`
|
|
684
|
+
// Camera follows the player character
|
|
685
|
+
pinepaper_add_relation sourceId: "camera" targetId: "player" relationType: "camera_follows"
|
|
686
|
+
params: {smoothing: 0.9, zoom: 1.5, deadzone: 50}
|
|
687
|
+
\`\`\`
|
|
688
|
+
|
|
689
|
+
**Great for:** Game-like scenes, following animations, focus tracking
|
|
690
|
+
|
|
691
|
+
### camera_animates
|
|
692
|
+
Keyframe-based camera zoom and pan animations. Use the special "camera" virtual item.
|
|
693
|
+
- \`keyframes\`: Array of keyframe objects with time, zoom, center, easing
|
|
694
|
+
- \`duration\`: Total animation duration in seconds
|
|
695
|
+
- \`loop\`: Whether to loop the animation
|
|
696
|
+
- \`delay\`: Delay before starting
|
|
697
|
+
|
|
698
|
+
**Keyframe properties:**
|
|
699
|
+
- \`time\`: Normalized time 0-1
|
|
700
|
+
- \`zoom\`: Zoom level (1 = normal, 2 = 2x zoom in)
|
|
701
|
+
- \`center\`: [x, y] pan center position
|
|
702
|
+
- \`easing\`: Easing function for this keyframe
|
|
703
|
+
|
|
704
|
+
\`\`\`
|
|
705
|
+
// Cinematic zoom and pan sequence
|
|
706
|
+
pinepaper_add_relation sourceId: "camera" targetId: "camera" relationType: "camera_animates"
|
|
707
|
+
params:
|
|
708
|
+
duration: 5
|
|
709
|
+
loop: false
|
|
710
|
+
keyframes:
|
|
711
|
+
- time: 0, zoom: 1, center: [400, 300], easing: "easeOut"
|
|
712
|
+
- time: 0.3, zoom: 1.5, center: [200, 200], easing: "easeInOut"
|
|
713
|
+
- time: 0.7, zoom: 2, center: [600, 400], easing: "easeInOut"
|
|
714
|
+
- time: 1, zoom: 1, center: [400, 300], easing: "easeIn"
|
|
715
|
+
\`\`\`
|
|
716
|
+
|
|
717
|
+
**Great for:** Cinematic intros, presentations, dramatic reveals, tour animations
|
|
718
|
+
|
|
719
|
+
## Camera API (Direct Code)
|
|
720
|
+
|
|
721
|
+
For simpler camera control, use the \`app.camera\` helper API:
|
|
722
|
+
|
|
723
|
+
\`\`\`javascript
|
|
724
|
+
// Zoom
|
|
725
|
+
app.camera.zoomIn(1.5, 0.5); // Zoom to 1.5x over 0.5 seconds
|
|
726
|
+
app.camera.zoomOut(0.5, 0.5); // Zoom out to 0.5x
|
|
727
|
+
|
|
728
|
+
// Pan
|
|
729
|
+
app.camera.panTo(200, 300, 1); // Pan to coordinates
|
|
730
|
+
app.camera.panBy(100, 0, 0.5); // Pan right by 100px
|
|
731
|
+
app.camera.panLeft(50, 0.3); // Pan left
|
|
732
|
+
app.camera.panRight(50, 0.3); // Pan right
|
|
733
|
+
app.camera.panUp(50, 0.3); // Pan up
|
|
734
|
+
app.camera.panDown(50, 0.3); // Pan down
|
|
735
|
+
|
|
736
|
+
// Combined
|
|
737
|
+
app.camera.moveTo(200, 300, 2, 1); // Pan to (200,300) and zoom to 2x
|
|
738
|
+
|
|
739
|
+
// Control
|
|
740
|
+
app.camera.reset(0.5); // Reset to default
|
|
741
|
+
app.camera.stop(); // Stop current animation
|
|
742
|
+
app.camera.getState(); // Returns { zoom, center: [x, y] }
|
|
743
|
+
app.camera.isAnimating(); // Check if animating
|
|
744
|
+
\`\`\`
|
|
745
|
+
|
|
229
746
|
## Verifying Animations Are Working
|
|
230
747
|
|
|
231
748
|
After adding a relation, **always verify** that the animation is actually running:
|
|
@@ -268,44 +785,136 @@ addRelation(label, planet, 'attached_to', { offset: [0, -30] })
|
|
|
268
785
|
|
|
269
786
|
The label will follow the planet as it orbits the star!
|
|
270
787
|
`,
|
|
271
|
-
'pinepaper://docs/generators': `# Background Generators
|
|
788
|
+
'pinepaper://docs/generators': `# Background Generators Guide
|
|
789
|
+
|
|
790
|
+
**Intent:** Create procedural backgrounds with 14 generators covering patterns, effects, organic flows, particles, and textures.
|
|
272
791
|
|
|
273
|
-
|
|
792
|
+
## Key Tool
|
|
274
793
|
|
|
275
|
-
|
|
794
|
+
\`\`\`
|
|
795
|
+
pinepaper_execute_generator
|
|
796
|
+
generatorName: "drawSunburst"
|
|
797
|
+
params: { rayCount: 16, colors: ["#fbbf24", "#f59e0b"], animated: true }
|
|
798
|
+
\`\`\`
|
|
799
|
+
|
|
800
|
+
## Classic Generators (7)
|
|
276
801
|
|
|
277
802
|
### drawSunburst
|
|
278
|
-
Radial rays from center.
|
|
279
|
-
-
|
|
280
|
-
-
|
|
281
|
-
- \`bgColor\`: Background color
|
|
282
|
-
- \`animated\`: Enable rotation
|
|
803
|
+
Radial rays from center — energy, attention-grabbing backgrounds.
|
|
804
|
+
- **Core:** rayCount (16), colors, bgColor, animated
|
|
805
|
+
- **Enhanced:** opacity, rayGap (degrees between rays), gradientRays (radial gradient per ray)
|
|
283
806
|
|
|
284
807
|
### drawSunsetScene
|
|
285
|
-
Animated sunset with clouds.
|
|
286
|
-
-
|
|
287
|
-
-
|
|
288
|
-
- \`cloudCount\`: Number of clouds
|
|
808
|
+
Animated sunset with clouds — calm, atmospheric.
|
|
809
|
+
- **Core:** sunColor, skyColors, cloudCount
|
|
810
|
+
- **Enhanced:** skyOpacity, starCount, starColor, reflectionEnabled, reflectionOpacity
|
|
289
811
|
|
|
290
812
|
### drawGrid
|
|
291
|
-
|
|
292
|
-
-
|
|
293
|
-
-
|
|
294
|
-
- \`lineColor\`: Grid color
|
|
813
|
+
Lines, dots, or squares — clean, technical, modern.
|
|
814
|
+
- **Core:** gridType (lines|dots|squares), spacing (40), lineColor, bgColor, lineWidth
|
|
815
|
+
- **Enhanced:** opacity, gap (pixel gap), randomRotation, colorMode (checkerboard|gradient|random|rows|columns), strokeColor, strokeWidth
|
|
295
816
|
|
|
296
817
|
### drawWaves
|
|
297
|
-
Layered wave pattern.
|
|
298
|
-
-
|
|
299
|
-
-
|
|
300
|
-
- \`amplitude\`: Wave height
|
|
301
|
-
- \`animated\`: Animate waves
|
|
818
|
+
Layered wave pattern — organic, flowing.
|
|
819
|
+
- **Core:** waveCount (5), colors, amplitude (50), frequency (2), bgColor, animated
|
|
820
|
+
- **Enhanced:** opacity, fill (fill between waves), fillOpacity, amplitudeVariation, blendMode
|
|
302
821
|
|
|
303
822
|
### drawCircuit
|
|
304
|
-
|
|
305
|
-
-
|
|
306
|
-
-
|
|
307
|
-
|
|
308
|
-
|
|
823
|
+
Circuit board pattern — futuristic, digital.
|
|
824
|
+
- **Core:** lineColor, nodeColor, bgColor, density (0-1), animated, boltColor
|
|
825
|
+
- **Enhanced:** traceOpacity, nodeOpacity, diagonalPaths (45-degree traces), chipDensity (auto|none|low|medium|high)
|
|
826
|
+
|
|
827
|
+
### drawStackedCircles
|
|
828
|
+
Overlapping circles with distribution algorithms.
|
|
829
|
+
- **Core:** count (8), colors, distribution (random|poisson|golden)
|
|
830
|
+
- **Enhanced:** opacityMin/opacityMax, blendMode, strokeWidth, strokeColor, sizeGradient, animationType (pulse|float|none)
|
|
831
|
+
|
|
832
|
+
### drawPattern
|
|
833
|
+
Geometric shapes in orbit rings.
|
|
834
|
+
- **Core:** patternType, size, color, bgColor
|
|
835
|
+
- **Enhanced:** opacity, blendMode, layers (1-5 concentric rings), layerScaleDecay
|
|
836
|
+
|
|
837
|
+
## New Generators (7)
|
|
838
|
+
|
|
839
|
+
### drawBokeh (effects)
|
|
840
|
+
Soft-focus circles — dreamy, photographic depth-of-field.
|
|
841
|
+
\`\`\`
|
|
842
|
+
params: { count: 30, colors: ["#f472b6", "#818cf8", "#34d399"], bgColor: "#0f172a",
|
|
843
|
+
shadowBlur: 20, distribution: "poisson", driftAnimation: true }
|
|
844
|
+
\`\`\`
|
|
845
|
+
|
|
846
|
+
### drawGradientMesh (organic)
|
|
847
|
+
Radial gradient blobs with screen blending — modern, vibrant.
|
|
848
|
+
\`\`\`
|
|
849
|
+
params: { colors: ["#ec4899", "#8b5cf6", "#06b6d4"], blobCount: 5,
|
|
850
|
+
blendMode: "screen", drift: true }
|
|
851
|
+
\`\`\`
|
|
852
|
+
|
|
853
|
+
### drawGeometricAbstract (geometric)
|
|
854
|
+
Mixed translucent shapes with blend modes — artistic, contemporary.
|
|
855
|
+
\`\`\`
|
|
856
|
+
params: { colors: ["#f43f5e", "#3b82f6", "#10b981"], shapeCount: 12,
|
|
857
|
+
blendMode: "multiply", rotation: true }
|
|
858
|
+
\`\`\`
|
|
859
|
+
|
|
860
|
+
### drawWindField (particles)
|
|
861
|
+
Directional wind particles with noise turbulence — weather, motion.
|
|
862
|
+
\`\`\`
|
|
863
|
+
params: { particleCount: 200, colors: ["#e0f2fe", "#bae6fd"], direction: 45,
|
|
864
|
+
turbulence: 0.5, trailLength: 30, speed: 1.5 }
|
|
865
|
+
\`\`\`
|
|
866
|
+
|
|
867
|
+
### drawFluidFlow (organic)
|
|
868
|
+
Sinusoidal stream paths with depth layering — liquid, flowing.
|
|
869
|
+
\`\`\`
|
|
870
|
+
params: { streamCount: 8, colors: ["#67e8f9", "#a78bfa", "#f9a8d4"],
|
|
871
|
+
depthLayers: 3, speed: 0.8 }
|
|
872
|
+
\`\`\`
|
|
873
|
+
|
|
874
|
+
### drawOrganicFlow (organic)
|
|
875
|
+
Aurora/silk layers — natural, ethereal glow.
|
|
876
|
+
\`\`\`
|
|
877
|
+
params: { layerCount: 4, colors: ["#34d399", "#6ee7b7", "#a7f3d0"],
|
|
878
|
+
blendMode: "screen", fillToBottom: true, animated: true }
|
|
879
|
+
\`\`\`
|
|
880
|
+
|
|
881
|
+
### drawNoiseTexture (textures)
|
|
882
|
+
Perlin/grain/stipple noise — subtle, textured.
|
|
883
|
+
\`\`\`
|
|
884
|
+
params: { noiseType: "perlin", colors: ["#94a3b8", "#64748b"],
|
|
885
|
+
scale: 0.01, density: 0.7, animated: true }
|
|
886
|
+
\`\`\`
|
|
887
|
+
noiseType options: perlin, grain, stipple
|
|
888
|
+
|
|
889
|
+
## Quick Mood Guide
|
|
890
|
+
|
|
891
|
+
| Mood | Generators |
|
|
892
|
+
|------|-----------|
|
|
893
|
+
| Dreamy/soft | drawBokeh, drawGradientMesh, drawOrganicFlow |
|
|
894
|
+
| Techy/modern | drawCircuit, drawGrid, drawWindField |
|
|
895
|
+
| Nature/warm | drawSunsetScene, drawSunburst, drawWaves |
|
|
896
|
+
| Abstract | drawGeometricAbstract, drawFluidFlow, drawNoiseTexture |
|
|
897
|
+
| Decorative | drawPattern, drawStackedCircles |
|
|
898
|
+
|
|
899
|
+
## Combining Generators with Items
|
|
900
|
+
|
|
901
|
+
\`\`\`
|
|
902
|
+
// Background + content on top
|
|
903
|
+
pinepaper_execute_generator
|
|
904
|
+
generatorName: "drawBokeh"
|
|
905
|
+
params: {count: 20, colors: ["#f472b6", "#818cf8"], shadowBlur: 25}
|
|
906
|
+
|
|
907
|
+
pinepaper_create_item itemType: "text" position: {x: 400, y: 300}
|
|
908
|
+
properties: {content: "Welcome", fontSize: 72, color: "#ffffff"}
|
|
909
|
+
\`\`\`
|
|
910
|
+
|
|
911
|
+
## Best Practices
|
|
912
|
+
|
|
913
|
+
1. **Call generator first** — before creating items
|
|
914
|
+
2. **Use complementary colors** — items should contrast with background
|
|
915
|
+
3. **Consider animation performance** — animated generators + many animated items can slow down
|
|
916
|
+
4. **Match themes** — sunburst for energy, waves for calm, circuit for tech, bokeh for elegance, noise for texture
|
|
917
|
+
5. **Use blendMode** — "screen" brightens, "multiply" darkens, great for layered effects
|
|
309
918
|
`,
|
|
310
919
|
'pinepaper://docs/custom-paths': `# Custom Paths Guide
|
|
311
920
|
|
|
@@ -593,8 +1202,7 @@ Create an animated solar system featuring custom paths, orbital rings, and plane
|
|
|
593
1202
|
## Step 1: Canvas Setup
|
|
594
1203
|
|
|
595
1204
|
\`\`\`
|
|
596
|
-
|
|
597
|
-
pinepaper_clear_canvas
|
|
1205
|
+
pinepaper_clear_canvas # Browser auto-connects in agent mode
|
|
598
1206
|
pinepaper_set_background_color color: "#0a0a1a"
|
|
599
1207
|
\`\`\`
|
|
600
1208
|
|
|
@@ -2341,8 +2949,7 @@ An animated company logo featuring:
|
|
|
2341
2949
|
## Step 1: Canvas Setup
|
|
2342
2950
|
|
|
2343
2951
|
\`\`\`
|
|
2344
|
-
|
|
2345
|
-
pinepaper_clear_canvas
|
|
2952
|
+
pinepaper_clear_canvas # Browser auto-connects in agent mode
|
|
2346
2953
|
pinepaper_set_background_color color: "#0f172a"
|
|
2347
2954
|
pinepaper_set_canvas_size width: 800 height: 600
|
|
2348
2955
|
\`\`\`
|
|
@@ -2581,8 +3188,7 @@ Create animated charts and infographics that bring data to life.
|
|
|
2581
3188
|
|
|
2582
3189
|
### Step 1: Setup
|
|
2583
3190
|
\`\`\`
|
|
2584
|
-
|
|
2585
|
-
pinepaper_clear_canvas
|
|
3191
|
+
pinepaper_clear_canvas # Browser auto-connects in agent mode
|
|
2586
3192
|
pinepaper_set_background_color color: "#1f2937"
|
|
2587
3193
|
\`\`\`
|
|
2588
3194
|
|
|
@@ -2903,8 +3509,7 @@ Build dynamic particle effects like fireworks, starfields, snow, and fire.
|
|
|
2903
3509
|
|
|
2904
3510
|
### Step 1: Create Background
|
|
2905
3511
|
\`\`\`
|
|
2906
|
-
|
|
2907
|
-
pinepaper_clear_canvas
|
|
3512
|
+
pinepaper_clear_canvas # Browser auto-connects in agent mode
|
|
2908
3513
|
pinepaper_set_background_color color: "#000011"
|
|
2909
3514
|
\`\`\`
|
|
2910
3515
|
|
|
@@ -3183,29 +3788,1969 @@ pinepaper_animate_item itemId: "bubble4" animationType: "wobble" speed: 0.7
|
|
|
3183
3788
|
| Dust | Tiny circles, slow fade, random positions |
|
|
3184
3789
|
| Confetti | Small rectangles, rotate + bounce, rainbow colors |
|
|
3185
3790
|
`,
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3791
|
+
'pinepaper://docs/map-tools': `# Map Tools Guide
|
|
3792
|
+
|
|
3793
|
+
Create geographic visualizations with world maps, choropleth coloring, markers, and labels.
|
|
3794
|
+
|
|
3795
|
+
## Available Maps
|
|
3796
|
+
|
|
3797
|
+
| Map | Description | Region ID Format |
|
|
3798
|
+
|-----|-------------|------------------|
|
|
3799
|
+
| \`world\` | World countries (110m) | Full names: "United States of America", "France" |
|
|
3800
|
+
| \`worldHighRes\` | World countries (50m, detailed) | Full names |
|
|
3801
|
+
| \`usa\` | US states | State codes: "CA", "TX", "NY" |
|
|
3802
|
+
|
|
3803
|
+
## Projections
|
|
3804
|
+
|
|
3805
|
+
| Projection | Best For |
|
|
3806
|
+
|------------|----------|
|
|
3807
|
+
| \`naturalEarth\` | World maps (recommended) |
|
|
3808
|
+
| \`mercator\` | Web-style maps |
|
|
3809
|
+
| \`equalEarth\` | Equal-area comparisons |
|
|
3810
|
+
| \`orthographic\` | Globe/3D sphere view |
|
|
3811
|
+
| \`albers\` | USA maps (recommended) |
|
|
3812
|
+
| \`stereographic\` | Polar regions |
|
|
3813
|
+
|
|
3814
|
+
## Loading Maps
|
|
3815
|
+
|
|
3816
|
+
\`\`\`
|
|
3817
|
+
// Load world map with Natural Earth projection
|
|
3818
|
+
pinepaper_load_map mapId: "world"
|
|
3819
|
+
options:
|
|
3820
|
+
projection: "naturalEarth"
|
|
3821
|
+
quality: "balanced"
|
|
3822
|
+
fillColor: "#e5e7eb"
|
|
3823
|
+
strokeColor: "#9ca3af"
|
|
3824
|
+
enableHover: true
|
|
3825
|
+
|
|
3826
|
+
// Load USA with Albers projection
|
|
3827
|
+
pinepaper_load_map mapId: "usa"
|
|
3828
|
+
options:
|
|
3829
|
+
projection: "albers"
|
|
3830
|
+
quality: "professional"
|
|
3831
|
+
\`\`\`
|
|
3832
|
+
|
|
3833
|
+
## Highlighting Regions
|
|
3834
|
+
|
|
3835
|
+
\`\`\`
|
|
3836
|
+
// Highlight countries (use full names for world map)
|
|
3837
|
+
pinepaper_highlight_regions
|
|
3838
|
+
regionIds: ["United States of America", "Canada", "Mexico"]
|
|
3839
|
+
options:
|
|
3840
|
+
fillColor: "#3b82f6"
|
|
3841
|
+
strokeColor: "#1d4ed8"
|
|
3842
|
+
animate: true
|
|
3843
|
+
|
|
3844
|
+
// Highlight US states (use state codes)
|
|
3845
|
+
pinepaper_highlight_regions
|
|
3846
|
+
regionIds: ["CA", "TX", "NY", "FL"]
|
|
3847
|
+
options:
|
|
3848
|
+
fillColor: "#22c55e"
|
|
3849
|
+
|
|
3850
|
+
// Remove highlights
|
|
3851
|
+
pinepaper_unhighlight_regions regionIds: "all"
|
|
3852
|
+
\`\`\`
|
|
3853
|
+
|
|
3854
|
+
## Choropleth (Data-Driven Colors)
|
|
3855
|
+
|
|
3856
|
+
\`\`\`
|
|
3857
|
+
// Population data visualization
|
|
3858
|
+
pinepaper_apply_data_colors
|
|
3859
|
+
data:
|
|
3860
|
+
"California": 39538223
|
|
3861
|
+
"Texas": 29145505
|
|
3862
|
+
"Florida": 21538187
|
|
3863
|
+
"New York": 20201249
|
|
3864
|
+
options:
|
|
3865
|
+
colorScale: "blues"
|
|
3866
|
+
showLegend: true
|
|
3867
|
+
legendPosition: "bottom-right"
|
|
3868
|
+
legendTitle: "Population"
|
|
3869
|
+
\`\`\`
|
|
3870
|
+
|
|
3871
|
+
### Color Scales
|
|
3872
|
+
- \`blues\` - Light to dark blue
|
|
3873
|
+
- \`greens\` - Light to dark green
|
|
3874
|
+
- \`reds\` - Light to dark red
|
|
3875
|
+
- \`oranges\` - Light to dark orange
|
|
3876
|
+
- \`purples\` - Light to dark purple
|
|
3877
|
+
- \`heat\` - Yellow to red heat map
|
|
3878
|
+
|
|
3879
|
+
## Map Markers
|
|
3880
|
+
|
|
3881
|
+
\`\`\`
|
|
3882
|
+
// Add marker at coordinates
|
|
3883
|
+
pinepaper_add_marker
|
|
3884
|
+
lat: 37.7749
|
|
3885
|
+
lon: -122.4194
|
|
3886
|
+
label: "San Francisco"
|
|
3887
|
+
color: "#ef4444"
|
|
3888
|
+
size: 8
|
|
3889
|
+
pulse: true
|
|
3890
|
+
|
|
3891
|
+
// Add marker with different shape
|
|
3892
|
+
pinepaper_add_marker
|
|
3893
|
+
lat: 40.7128
|
|
3894
|
+
lon: -74.0060
|
|
3895
|
+
label: "New York"
|
|
3896
|
+
shape: "pin"
|
|
3897
|
+
\`\`\`
|
|
3898
|
+
|
|
3899
|
+
### Marker Shapes
|
|
3900
|
+
- \`circle\` - Simple circle (default)
|
|
3901
|
+
- \`pin\` - Map pin icon
|
|
3902
|
+
- \`star\` - Star shape
|
|
3903
|
+
|
|
3904
|
+
## Map Labels
|
|
3905
|
+
|
|
3906
|
+
\`\`\`
|
|
3907
|
+
// Add labels to all visible regions
|
|
3908
|
+
pinepaper_add_map_labels
|
|
3909
|
+
options:
|
|
3910
|
+
fontSize: 10
|
|
3911
|
+
fontColor: "#374151"
|
|
3912
|
+
labelType: "name"
|
|
3913
|
+
|
|
3914
|
+
// Add labels to specific regions
|
|
3915
|
+
pinepaper_add_map_labels
|
|
3916
|
+
regions: ["California", "Texas"]
|
|
3917
|
+
options:
|
|
3918
|
+
labelType: "code"
|
|
3919
|
+
\`\`\`
|
|
3920
|
+
|
|
3921
|
+
### Label Types
|
|
3922
|
+
- \`name\` - Full region name
|
|
3923
|
+
- \`code\` - Region code (e.g., "CA")
|
|
3924
|
+
- \`value\` - Data value (after applyDataColors)
|
|
3925
|
+
|
|
3926
|
+
## Map Navigation
|
|
3927
|
+
|
|
3928
|
+
\`\`\`
|
|
3929
|
+
// Pan to coordinates
|
|
3930
|
+
pinepaper_pan_map lat: 50 lon: 10 animate: true duration: 1
|
|
3931
|
+
|
|
3932
|
+
// Zoom in
|
|
3933
|
+
pinepaper_zoom_map level: 2 animate: true
|
|
3934
|
+
\`\`\`
|
|
3935
|
+
|
|
3936
|
+
## Importing Custom Maps
|
|
3937
|
+
|
|
3938
|
+
\`\`\`
|
|
3939
|
+
// Import from URL
|
|
3940
|
+
pinepaper_import_custom_map
|
|
3941
|
+
url: "https://example.com/custom-boundaries.geojson"
|
|
3942
|
+
options:
|
|
3943
|
+
projection: "mercator"
|
|
3944
|
+
|
|
3945
|
+
// Import GeoJSON directly
|
|
3946
|
+
pinepaper_import_custom_map
|
|
3947
|
+
geoJson: { "type": "FeatureCollection", "features": [...] }
|
|
3948
|
+
options:
|
|
3949
|
+
projection: "naturalEarth"
|
|
3950
|
+
\`\`\`
|
|
3951
|
+
|
|
3952
|
+
## Example: US Population Map
|
|
3953
|
+
|
|
3954
|
+
\`\`\`
|
|
3955
|
+
// 1. Load USA map
|
|
3956
|
+
pinepaper_load_map mapId: "usa"
|
|
3957
|
+
options:
|
|
3958
|
+
projection: "albers"
|
|
3959
|
+
quality: "professional"
|
|
3960
|
+
fillColor: "#e5e7eb"
|
|
3961
|
+
strokeColor: "#9ca3af"
|
|
3962
|
+
strokeWidth: 0.5
|
|
3963
|
+
enableHover: true
|
|
3964
|
+
|
|
3965
|
+
// 2. Apply population data
|
|
3966
|
+
pinepaper_apply_data_colors
|
|
3967
|
+
data:
|
|
3968
|
+
"CA": 39538223
|
|
3969
|
+
"TX": 29145505
|
|
3970
|
+
"FL": 21538187
|
|
3971
|
+
"NY": 20201249
|
|
3972
|
+
"PA": 13002700
|
|
3973
|
+
"IL": 12812508
|
|
3974
|
+
"OH": 11799448
|
|
3975
|
+
"GA": 10711908
|
|
3976
|
+
options:
|
|
3977
|
+
colorScale: "blues"
|
|
3978
|
+
showLegend: true
|
|
3979
|
+
legendTitle: "Population"
|
|
3980
|
+
|
|
3981
|
+
// 3. Add major city markers
|
|
3982
|
+
pinepaper_add_marker lat: 34.0522 lon: -118.2437 label: "Los Angeles" pulse: true
|
|
3983
|
+
pinepaper_add_marker lat: 40.7128 lon: -74.0060 label: "New York" pulse: true
|
|
3984
|
+
pinepaper_add_marker lat: 41.8781 lon: -87.6298 label: "Chicago" pulse: true
|
|
3985
|
+
|
|
3986
|
+
// 4. Export final map
|
|
3987
|
+
pinepaper_export_map
|
|
3988
|
+
\`\`\`
|
|
3989
|
+
|
|
3990
|
+
## Example: World Comparison
|
|
3991
|
+
|
|
3992
|
+
\`\`\`
|
|
3993
|
+
// 1. Load world map
|
|
3994
|
+
pinepaper_load_map mapId: "worldHighRes"
|
|
3995
|
+
options:
|
|
3996
|
+
projection: "naturalEarth"
|
|
3997
|
+
quality: "balanced"
|
|
3998
|
+
fillColor: "#f3f4f6"
|
|
3999
|
+
strokeColor: "#d1d5db"
|
|
4000
|
+
|
|
4001
|
+
// 2. Highlight regions of interest
|
|
4002
|
+
pinepaper_highlight_regions
|
|
4003
|
+
regionIds: ["United States of America", "China", "Japan", "Germany", "United Kingdom"]
|
|
4004
|
+
options:
|
|
4005
|
+
fillColor: "#3b82f6"
|
|
4006
|
+
animate: true
|
|
4007
|
+
|
|
4008
|
+
// 3. Add capital markers
|
|
4009
|
+
pinepaper_add_marker lat: 38.9072 lon: -77.0369 label: "Washington DC"
|
|
4010
|
+
pinepaper_add_marker lat: 39.9042 lon: 116.4074 label: "Beijing"
|
|
4011
|
+
pinepaper_add_marker lat: 35.6762 lon: 139.6503 label: "Tokyo"
|
|
4012
|
+
pinepaper_add_marker lat: 52.5200 lon: 13.4050 label: "Berlin"
|
|
4013
|
+
pinepaper_add_marker lat: 51.5074 lon: -0.1278 label: "London"
|
|
4014
|
+
\`\`\`
|
|
4015
|
+
|
|
4016
|
+
## Hit Testing
|
|
4017
|
+
|
|
4018
|
+
\`\`\`
|
|
4019
|
+
// Find region at canvas coordinates
|
|
4020
|
+
pinepaper_get_region_at_point x: 400 y: 300
|
|
4021
|
+
// Returns: { regionId, regionName, properties }
|
|
4022
|
+
\`\`\`
|
|
4023
|
+
|
|
4024
|
+
## Region Animations
|
|
4025
|
+
|
|
4026
|
+
Animate map regions with keyframe-based color transitions:
|
|
4027
|
+
|
|
4028
|
+
\`\`\`
|
|
4029
|
+
// Animate specific regions with keyframes
|
|
4030
|
+
pinepaper_animate_map_regions
|
|
4031
|
+
duration: 8
|
|
4032
|
+
loop: true
|
|
4033
|
+
regions:
|
|
4034
|
+
"USA":
|
|
4035
|
+
- time: 0, fillColor: "#ef4444"
|
|
4036
|
+
- time: 4, fillColor: "#22c55e"
|
|
4037
|
+
- time: 8, fillColor: "#ef4444"
|
|
4038
|
+
"France":
|
|
4039
|
+
- time: 0, fillColor: "#3b82f6"
|
|
4040
|
+
- time: 8, fillColor: "#fbbf24"
|
|
4041
|
+
|
|
4042
|
+
// Wave animation across all regions
|
|
4043
|
+
pinepaper_animate_map_wave
|
|
4044
|
+
duration: 10
|
|
4045
|
+
loop: true
|
|
4046
|
+
colors: ["#ef4444", "#fbbf24", "#22c55e", "#3b82f6"]
|
|
4047
|
+
waveDirection: "horizontal"
|
|
4048
|
+
|
|
4049
|
+
// Stop animations
|
|
4050
|
+
pinepaper_stop_map_animations
|
|
4051
|
+
pinepaper_stop_map_animations regions: ["USA", "France"] resetColors: true
|
|
4052
|
+
|
|
4053
|
+
// Query animated regions
|
|
4054
|
+
pinepaper_get_animated_map_regions
|
|
4055
|
+
\`\`\`
|
|
4056
|
+
|
|
4057
|
+
## CSV Export & Import
|
|
4058
|
+
|
|
4059
|
+
Export and import map state via CSV for data-driven workflows:
|
|
4060
|
+
|
|
4061
|
+
\`\`\`
|
|
4062
|
+
// Export region data as CSV
|
|
4063
|
+
pinepaper_export_map_region_csv
|
|
4064
|
+
includeHighlighted: true
|
|
4065
|
+
includeColors: true
|
|
4066
|
+
download: true
|
|
4067
|
+
filename: "map-export.csv"
|
|
4068
|
+
|
|
4069
|
+
// Import CSV to update regions
|
|
4070
|
+
pinepaper_import_map_region_csv
|
|
4071
|
+
csvText: "regionId,fillColor,highlighted\\nUSA,#22c55e,1\\nFrance,#3b82f6,0"
|
|
4072
|
+
applyColors: true
|
|
4073
|
+
applyHighlight: true
|
|
4074
|
+
\`\`\`
|
|
4075
|
+
|
|
4076
|
+
## Programmatic Selection
|
|
4077
|
+
|
|
4078
|
+
Control region selection programmatically:
|
|
4079
|
+
|
|
4080
|
+
\`\`\`
|
|
4081
|
+
// Select regions
|
|
4082
|
+
pinepaper_select_map_regions regionIds: ["USA", "Canada", "Mexico"]
|
|
4083
|
+
|
|
4084
|
+
// Deselect specific regions
|
|
4085
|
+
pinepaper_deselect_map_regions regionIds: ["USA"]
|
|
4086
|
+
|
|
4087
|
+
// Deselect all
|
|
4088
|
+
pinepaper_deselect_map_regions
|
|
4089
|
+
|
|
4090
|
+
// Query highlighted regions
|
|
4091
|
+
pinepaper_get_highlighted_map_regions
|
|
4092
|
+
\`\`\`
|
|
4093
|
+
`,
|
|
4094
|
+
'pinepaper://examples/world-population-map': `# World Population Map Example
|
|
4095
|
+
|
|
4096
|
+
Create an animated choropleth map showing world population data with country highlights and major city markers.
|
|
4097
|
+
|
|
4098
|
+
## Final Result
|
|
4099
|
+
|
|
4100
|
+
A beautiful world map showing population density by color intensity, with pulsing markers on major capitals.
|
|
4101
|
+
|
|
4102
|
+
---
|
|
4103
|
+
|
|
4104
|
+
## Step 1: Set Up Canvas and Background
|
|
4105
|
+
|
|
4106
|
+
\`\`\`
|
|
4107
|
+
// Set dark background for contrast
|
|
4108
|
+
pinepaper_set_background_color color: "#1a1a2e"
|
|
4109
|
+
|
|
4110
|
+
// Set canvas size for presentation
|
|
4111
|
+
pinepaper_set_canvas_size preset: "presentation-16x9"
|
|
4112
|
+
\`\`\`
|
|
4113
|
+
|
|
4114
|
+
---
|
|
4115
|
+
|
|
4116
|
+
## Step 2: Load World Map
|
|
4117
|
+
|
|
4118
|
+
\`\`\`
|
|
4119
|
+
pinepaper_load_map mapId: "worldHighRes"
|
|
4120
|
+
options:
|
|
4121
|
+
projection: "naturalEarth"
|
|
4122
|
+
quality: "professional"
|
|
4123
|
+
fillColor: "#374151"
|
|
4124
|
+
strokeColor: "#4b5563"
|
|
4125
|
+
strokeWidth: 0.3
|
|
4126
|
+
enableHover: true
|
|
4127
|
+
hoverFill: "#6b7280"
|
|
4128
|
+
\`\`\`
|
|
4129
|
+
|
|
4130
|
+
---
|
|
4131
|
+
|
|
4132
|
+
## Step 3: Apply Population Data (Choropleth)
|
|
4133
|
+
|
|
4134
|
+
\`\`\`
|
|
4135
|
+
pinepaper_apply_data_colors
|
|
4136
|
+
data:
|
|
4137
|
+
"China": 1412
|
|
4138
|
+
"India": 1408
|
|
4139
|
+
"United States of America": 332
|
|
4140
|
+
"Indonesia": 276
|
|
4141
|
+
"Pakistan": 229
|
|
4142
|
+
"Brazil": 215
|
|
4143
|
+
"Nigeria": 218
|
|
4144
|
+
"Bangladesh": 169
|
|
4145
|
+
"Russia": 144
|
|
4146
|
+
"Mexico": 130
|
|
4147
|
+
"Japan": 125
|
|
4148
|
+
"Ethiopia": 120
|
|
4149
|
+
"Philippines": 113
|
|
4150
|
+
"Egypt": 104
|
|
4151
|
+
"Vietnam": 99
|
|
4152
|
+
"Germany": 84
|
|
4153
|
+
"Turkey": 85
|
|
4154
|
+
"Iran": 87
|
|
4155
|
+
"Thailand": 70
|
|
4156
|
+
"United Kingdom": 67
|
|
4157
|
+
"France": 68
|
|
4158
|
+
"Italy": 59
|
|
4159
|
+
"South Africa": 60
|
|
4160
|
+
"Tanzania": 63
|
|
4161
|
+
"Kenya": 54
|
|
4162
|
+
"South Korea": 52
|
|
4163
|
+
"Colombia": 51
|
|
4164
|
+
"Spain": 47
|
|
4165
|
+
"Argentina": 46
|
|
4166
|
+
"Algeria": 45
|
|
4167
|
+
"Sudan": 45
|
|
4168
|
+
"Ukraine": 41
|
|
4169
|
+
"Iraq": 42
|
|
4170
|
+
"Poland": 38
|
|
4171
|
+
"Canada": 38
|
|
4172
|
+
"Morocco": 37
|
|
4173
|
+
"Saudi Arabia": 35
|
|
4174
|
+
"Peru": 33
|
|
4175
|
+
"Malaysia": 33
|
|
4176
|
+
"Australia": 26
|
|
4177
|
+
options:
|
|
4178
|
+
colorScale: "blues"
|
|
4179
|
+
showLegend: true
|
|
4180
|
+
legendPosition: "bottom-right"
|
|
4181
|
+
legendTitle: "Population (millions)"
|
|
4182
|
+
\`\`\`
|
|
4183
|
+
|
|
4184
|
+
---
|
|
4185
|
+
|
|
4186
|
+
## Step 4: Highlight Top 5 Countries
|
|
4187
|
+
|
|
4188
|
+
\`\`\`
|
|
4189
|
+
pinepaper_highlight_regions
|
|
4190
|
+
regionIds: ["China", "India", "United States of America", "Indonesia", "Pakistan"]
|
|
4191
|
+
options:
|
|
4192
|
+
strokeColor: "#fbbf24"
|
|
4193
|
+
strokeWidth: 2
|
|
4194
|
+
animate: true
|
|
4195
|
+
\`\`\`
|
|
4196
|
+
|
|
4197
|
+
---
|
|
4198
|
+
|
|
4199
|
+
## Step 5: Add Capital City Markers
|
|
4200
|
+
|
|
4201
|
+
\`\`\`
|
|
4202
|
+
// Beijing - China
|
|
4203
|
+
pinepaper_add_marker lat: 39.9042 lon: 116.4074
|
|
4204
|
+
label: "Beijing"
|
|
4205
|
+
color: "#ef4444"
|
|
4206
|
+
size: 10
|
|
4207
|
+
pulse: true
|
|
4208
|
+
|
|
4209
|
+
// New Delhi - India
|
|
4210
|
+
pinepaper_add_marker lat: 28.6139 lon: 77.2090
|
|
4211
|
+
label: "New Delhi"
|
|
4212
|
+
color: "#ef4444"
|
|
4213
|
+
size: 10
|
|
4214
|
+
pulse: true
|
|
4215
|
+
|
|
4216
|
+
// Washington DC - USA
|
|
4217
|
+
pinepaper_add_marker lat: 38.9072 lon: -77.0369
|
|
4218
|
+
label: "Washington DC"
|
|
4219
|
+
color: "#ef4444"
|
|
4220
|
+
size: 8
|
|
4221
|
+
pulse: true
|
|
4222
|
+
|
|
4223
|
+
// Jakarta - Indonesia
|
|
4224
|
+
pinepaper_add_marker lat: -6.2088 lon: 106.8456
|
|
4225
|
+
label: "Jakarta"
|
|
4226
|
+
color: "#f59e0b"
|
|
4227
|
+
size: 8
|
|
4228
|
+
pulse: true
|
|
4229
|
+
|
|
4230
|
+
// Islamabad - Pakistan
|
|
4231
|
+
pinepaper_add_marker lat: 33.6844 lon: 73.0479
|
|
4232
|
+
label: "Islamabad"
|
|
4233
|
+
color: "#f59e0b"
|
|
4234
|
+
size: 8
|
|
4235
|
+
pulse: true
|
|
4236
|
+
\`\`\`
|
|
4237
|
+
|
|
4238
|
+
---
|
|
4239
|
+
|
|
4240
|
+
## Step 6: Add Title
|
|
4241
|
+
|
|
4242
|
+
\`\`\`
|
|
4243
|
+
pinepaper_create_item itemType: "text"
|
|
4244
|
+
position: {x: 640, y: 50}
|
|
4245
|
+
properties:
|
|
4246
|
+
content: "World Population 2024"
|
|
4247
|
+
fontSize: 36
|
|
4248
|
+
fontFamily: "Inter, sans-serif"
|
|
4249
|
+
fontWeight: "bold"
|
|
4250
|
+
color: "#ffffff"
|
|
4251
|
+
\`\`\`
|
|
4252
|
+
|
|
4253
|
+
---
|
|
4254
|
+
|
|
4255
|
+
## Step 7: Export
|
|
4256
|
+
|
|
4257
|
+
\`\`\`
|
|
4258
|
+
pinepaper_export_svg
|
|
4259
|
+
pinepaper_export_map
|
|
4260
|
+
\`\`\`
|
|
4261
|
+
|
|
4262
|
+
---
|
|
4263
|
+
|
|
4264
|
+
## Variations
|
|
4265
|
+
|
|
4266
|
+
### Heat Map Version
|
|
4267
|
+
\`\`\`
|
|
4268
|
+
pinepaper_apply_data_colors
|
|
4269
|
+
data: { ... }
|
|
4270
|
+
options:
|
|
4271
|
+
colorScale: "heat"
|
|
4272
|
+
showLegend: true
|
|
4273
|
+
\`\`\`
|
|
4274
|
+
|
|
4275
|
+
### Regional Focus (Asia)
|
|
4276
|
+
\`\`\`
|
|
4277
|
+
pinepaper_pan_map lat: 35 lon: 100 animate: true duration: 2
|
|
4278
|
+
pinepaper_zoom_map level: 2.5 animate: true
|
|
4279
|
+
\`\`\`
|
|
4280
|
+
`,
|
|
4281
|
+
'pinepaper://examples/us-election-map': `# US Election Map Example
|
|
4282
|
+
|
|
4283
|
+
Build an interactive US election results visualization with state-by-state coloring and key battleground state highlights.
|
|
4284
|
+
|
|
4285
|
+
## Final Result
|
|
4286
|
+
|
|
4287
|
+
A classic red/blue election map with swing states highlighted and electoral vote counts.
|
|
4288
|
+
|
|
4289
|
+
---
|
|
4290
|
+
|
|
4291
|
+
## Step 1: Set Up Canvas
|
|
4292
|
+
|
|
4293
|
+
\`\`\`
|
|
4294
|
+
pinepaper_set_background_color color: "#f8fafc"
|
|
4295
|
+
pinepaper_set_canvas_size preset: "presentation-16x9"
|
|
4296
|
+
\`\`\`
|
|
4297
|
+
|
|
4298
|
+
---
|
|
4299
|
+
|
|
4300
|
+
## Step 2: Load USA Map
|
|
4301
|
+
|
|
4302
|
+
\`\`\`
|
|
4303
|
+
pinepaper_load_map mapId: "usa"
|
|
4304
|
+
options:
|
|
4305
|
+
projection: "albers"
|
|
4306
|
+
quality: "professional"
|
|
4307
|
+
fillColor: "#e2e8f0"
|
|
4308
|
+
strokeColor: "#94a3b8"
|
|
4309
|
+
strokeWidth: 1
|
|
4310
|
+
enableHover: true
|
|
4311
|
+
enableClick: true
|
|
4312
|
+
\`\`\`
|
|
4313
|
+
|
|
4314
|
+
---
|
|
4315
|
+
|
|
4316
|
+
## Step 3: Color Democratic States (Blue)
|
|
4317
|
+
|
|
4318
|
+
\`\`\`
|
|
4319
|
+
pinepaper_highlight_regions
|
|
4320
|
+
regionIds: ["CA", "WA", "OR", "NV", "CO", "NM", "MN", "IL", "VA", "MD", "DE", "NJ", "CT", "RI", "MA", "VT", "NH", "ME", "NY", "HI"]
|
|
4321
|
+
options:
|
|
4322
|
+
fillColor: "#2563eb"
|
|
4323
|
+
strokeColor: "#1d4ed8"
|
|
4324
|
+
\`\`\`
|
|
4325
|
+
|
|
4326
|
+
---
|
|
4327
|
+
|
|
4328
|
+
## Step 4: Color Republican States (Red)
|
|
4329
|
+
|
|
4330
|
+
\`\`\`
|
|
4331
|
+
pinepaper_highlight_regions
|
|
4332
|
+
regionIds: ["TX", "OK", "KS", "NE", "SD", "ND", "MT", "WY", "ID", "UT", "AZ", "AK", "MO", "AR", "LA", "MS", "AL", "TN", "KY", "WV", "IN", "OH", "SC", "FL"]
|
|
4333
|
+
options:
|
|
4334
|
+
fillColor: "#dc2626"
|
|
4335
|
+
strokeColor: "#b91c1c"
|
|
4336
|
+
\`\`\`
|
|
4337
|
+
|
|
4338
|
+
---
|
|
4339
|
+
|
|
4340
|
+
## Step 5: Highlight Swing States
|
|
4341
|
+
|
|
4342
|
+
\`\`\`
|
|
4343
|
+
// Key battleground states with gold border
|
|
4344
|
+
pinepaper_highlight_regions
|
|
4345
|
+
regionIds: ["PA", "MI", "WI", "GA", "NC", "AZ"]
|
|
4346
|
+
options:
|
|
4347
|
+
strokeColor: "#fbbf24"
|
|
4348
|
+
strokeWidth: 3
|
|
4349
|
+
animate: true
|
|
4350
|
+
\`\`\`
|
|
4351
|
+
|
|
4352
|
+
---
|
|
4353
|
+
|
|
4354
|
+
## Step 6: Add Electoral Vote Labels
|
|
4355
|
+
|
|
4356
|
+
\`\`\`
|
|
4357
|
+
// California - 54 votes
|
|
4358
|
+
pinepaper_add_marker lat: 36.7783 lon: -119.4179
|
|
4359
|
+
label: "54"
|
|
4360
|
+
color: "#2563eb"
|
|
4361
|
+
size: 12
|
|
4362
|
+
|
|
4363
|
+
// Texas - 40 votes
|
|
4364
|
+
pinepaper_add_marker lat: 31.9686 lon: -99.9018
|
|
4365
|
+
label: "40"
|
|
4366
|
+
color: "#dc2626"
|
|
4367
|
+
size: 12
|
|
4368
|
+
|
|
4369
|
+
// Florida - 30 votes
|
|
4370
|
+
pinepaper_add_marker lat: 27.6648 lon: -81.5158
|
|
4371
|
+
label: "30"
|
|
4372
|
+
color: "#dc2626"
|
|
4373
|
+
size: 10
|
|
4374
|
+
|
|
4375
|
+
// New York - 28 votes
|
|
4376
|
+
pinepaper_add_marker lat: 42.1657 lon: -74.9481
|
|
4377
|
+
label: "28"
|
|
4378
|
+
color: "#2563eb"
|
|
4379
|
+
size: 10
|
|
4380
|
+
|
|
4381
|
+
// Pennsylvania - 19 votes (swing)
|
|
4382
|
+
pinepaper_add_marker lat: 41.2033 lon: -77.1945
|
|
4383
|
+
label: "19"
|
|
4384
|
+
color: "#fbbf24"
|
|
4385
|
+
size: 10
|
|
4386
|
+
pulse: true
|
|
4387
|
+
|
|
4388
|
+
// Michigan - 15 votes (swing)
|
|
4389
|
+
pinepaper_add_marker lat: 44.3148 lon: -85.6024
|
|
4390
|
+
label: "15"
|
|
4391
|
+
color: "#fbbf24"
|
|
4392
|
+
size: 9
|
|
4393
|
+
pulse: true
|
|
4394
|
+
|
|
4395
|
+
// Georgia - 16 votes (swing)
|
|
4396
|
+
pinepaper_add_marker lat: 32.1656 lon: -82.9001
|
|
4397
|
+
label: "16"
|
|
4398
|
+
color: "#fbbf24"
|
|
4399
|
+
size: 9
|
|
4400
|
+
pulse: true
|
|
4401
|
+
\`\`\`
|
|
4402
|
+
|
|
4403
|
+
---
|
|
4404
|
+
|
|
4405
|
+
## Step 7: Add Title and Legend
|
|
4406
|
+
|
|
4407
|
+
\`\`\`
|
|
4408
|
+
// Title
|
|
4409
|
+
pinepaper_create_item itemType: "text"
|
|
4410
|
+
position: {x: 640, y: 40}
|
|
4411
|
+
properties:
|
|
4412
|
+
content: "US Presidential Election Results"
|
|
4413
|
+
fontSize: 32
|
|
4414
|
+
fontWeight: "bold"
|
|
4415
|
+
color: "#1e293b"
|
|
4416
|
+
|
|
4417
|
+
// Legend - Democratic
|
|
4418
|
+
pinepaper_create_item itemType: "rectangle"
|
|
4419
|
+
position: {x: 100, y: 550}
|
|
4420
|
+
properties:
|
|
4421
|
+
width: 20
|
|
4422
|
+
height: 20
|
|
4423
|
+
color: "#2563eb"
|
|
4424
|
+
|
|
4425
|
+
pinepaper_create_item itemType: "text"
|
|
4426
|
+
position: {x: 130, y: 550}
|
|
4427
|
+
properties:
|
|
4428
|
+
content: "Democratic"
|
|
4429
|
+
fontSize: 14
|
|
4430
|
+
color: "#1e293b"
|
|
4431
|
+
|
|
4432
|
+
// Legend - Republican
|
|
4433
|
+
pinepaper_create_item itemType: "rectangle"
|
|
4434
|
+
position: {x: 250, y: 550}
|
|
4435
|
+
properties:
|
|
4436
|
+
width: 20
|
|
4437
|
+
height: 20
|
|
4438
|
+
color: "#dc2626"
|
|
4439
|
+
|
|
4440
|
+
pinepaper_create_item itemType: "text"
|
|
4441
|
+
position: {x: 280, y: 550}
|
|
4442
|
+
properties:
|
|
4443
|
+
content: "Republican"
|
|
4444
|
+
fontSize: 14
|
|
4445
|
+
color: "#1e293b"
|
|
4446
|
+
|
|
4447
|
+
// Legend - Swing State
|
|
4448
|
+
pinepaper_create_item itemType: "rectangle"
|
|
4449
|
+
position: {x: 400, y: 550}
|
|
4450
|
+
properties:
|
|
4451
|
+
width: 20
|
|
4452
|
+
height: 20
|
|
4453
|
+
color: "#fbbf24"
|
|
4454
|
+
|
|
4455
|
+
pinepaper_create_item itemType: "text"
|
|
4456
|
+
position: {x: 430, y: 550}
|
|
4457
|
+
properties:
|
|
4458
|
+
content: "Swing State"
|
|
4459
|
+
fontSize: 14
|
|
4460
|
+
color: "#1e293b"
|
|
4461
|
+
\`\`\`
|
|
4462
|
+
|
|
4463
|
+
---
|
|
4464
|
+
|
|
4465
|
+
## Step 8: Add Vote Totals
|
|
4466
|
+
|
|
4467
|
+
\`\`\`
|
|
4468
|
+
// Electoral vote boxes
|
|
4469
|
+
pinepaper_create_item itemType: "rectangle"
|
|
4470
|
+
position: {x: 200, y: 100}
|
|
4471
|
+
properties:
|
|
4472
|
+
width: 150
|
|
4473
|
+
height: 80
|
|
4474
|
+
color: "#2563eb"
|
|
4475
|
+
cornerRadius: 8
|
|
4476
|
+
|
|
4477
|
+
pinepaper_create_item itemType: "text"
|
|
4478
|
+
position: {x: 200, y: 90}
|
|
4479
|
+
properties:
|
|
4480
|
+
content: "270"
|
|
4481
|
+
fontSize: 36
|
|
4482
|
+
fontWeight: "bold"
|
|
4483
|
+
color: "#ffffff"
|
|
4484
|
+
|
|
4485
|
+
pinepaper_create_item itemType: "text"
|
|
4486
|
+
position: {x: 200, y: 120}
|
|
4487
|
+
properties:
|
|
4488
|
+
content: "Electoral Votes"
|
|
4489
|
+
fontSize: 12
|
|
4490
|
+
color: "#bfdbfe"
|
|
4491
|
+
|
|
4492
|
+
// Republican votes
|
|
4493
|
+
pinepaper_create_item itemType: "rectangle"
|
|
4494
|
+
position: {x: 1080, y: 100}
|
|
4495
|
+
properties:
|
|
4496
|
+
width: 150
|
|
4497
|
+
height: 80
|
|
4498
|
+
color: "#dc2626"
|
|
4499
|
+
cornerRadius: 8
|
|
4500
|
+
|
|
4501
|
+
pinepaper_create_item itemType: "text"
|
|
4502
|
+
position: {x: 1080, y: 90}
|
|
4503
|
+
properties:
|
|
4504
|
+
content: "268"
|
|
4505
|
+
fontSize: 36
|
|
4506
|
+
fontWeight: "bold"
|
|
4507
|
+
color: "#ffffff"
|
|
4508
|
+
|
|
4509
|
+
pinepaper_create_item itemType: "text"
|
|
4510
|
+
position: {x: 1080, y: 120}
|
|
4511
|
+
properties:
|
|
4512
|
+
content: "Electoral Votes"
|
|
4513
|
+
fontSize: 12
|
|
4514
|
+
color: "#fecaca"
|
|
4515
|
+
\`\`\`
|
|
4516
|
+
|
|
4517
|
+
---
|
|
4518
|
+
|
|
4519
|
+
## Step 9: Export
|
|
4520
|
+
|
|
4521
|
+
\`\`\`
|
|
4522
|
+
pinepaper_export_svg
|
|
4523
|
+
\`\`\`
|
|
4524
|
+
`,
|
|
4525
|
+
'pinepaper://examples/travel-route-map': `# Travel Route Map Example
|
|
4526
|
+
|
|
4527
|
+
Visualize a travel itinerary across Europe with city markers, connecting routes, and animated journey highlights.
|
|
4528
|
+
|
|
4529
|
+
## Final Result
|
|
4530
|
+
|
|
4531
|
+
An elegant travel map showing a European tour with cities connected by animated paths.
|
|
4532
|
+
|
|
4533
|
+
---
|
|
4534
|
+
|
|
4535
|
+
## Step 1: Set Up Canvas
|
|
4536
|
+
|
|
4537
|
+
\`\`\`
|
|
4538
|
+
pinepaper_set_background_color color: "#0f172a"
|
|
4539
|
+
pinepaper_set_canvas_size preset: "presentation-16x9"
|
|
4540
|
+
\`\`\`
|
|
4541
|
+
|
|
4542
|
+
---
|
|
4543
|
+
|
|
4544
|
+
## Step 2: Load World Map (Focused on Europe)
|
|
4545
|
+
|
|
4546
|
+
\`\`\`
|
|
4547
|
+
pinepaper_load_map mapId: "worldHighRes"
|
|
4548
|
+
options:
|
|
4549
|
+
projection: "mercator"
|
|
4550
|
+
quality: "professional"
|
|
4551
|
+
fillColor: "#1e293b"
|
|
4552
|
+
strokeColor: "#334155"
|
|
4553
|
+
strokeWidth: 0.5
|
|
4554
|
+
center: [10, 50]
|
|
4555
|
+
enableHover: true
|
|
4556
|
+
\`\`\`
|
|
4557
|
+
|
|
4558
|
+
---
|
|
4559
|
+
|
|
4560
|
+
## Step 3: Zoom to Europe
|
|
4561
|
+
|
|
4562
|
+
\`\`\`
|
|
4563
|
+
pinepaper_pan_map lat: 48 lon: 10 animate: true duration: 1
|
|
4564
|
+
pinepaper_zoom_map level: 4 animate: true duration: 1
|
|
4565
|
+
\`\`\`
|
|
4566
|
+
|
|
4567
|
+
---
|
|
4568
|
+
|
|
4569
|
+
## Step 4: Highlight Countries on Itinerary
|
|
4570
|
+
|
|
4571
|
+
\`\`\`
|
|
4572
|
+
pinepaper_highlight_regions
|
|
4573
|
+
regionIds: ["United Kingdom", "France", "Germany", "Italy", "Spain"]
|
|
4574
|
+
options:
|
|
4575
|
+
fillColor: "#334155"
|
|
4576
|
+
strokeColor: "#60a5fa"
|
|
4577
|
+
strokeWidth: 1
|
|
4578
|
+
animate: true
|
|
4579
|
+
\`\`\`
|
|
4580
|
+
|
|
4581
|
+
---
|
|
4582
|
+
|
|
4583
|
+
## Step 5: Add City Markers (The Journey)
|
|
4584
|
+
|
|
4585
|
+
\`\`\`
|
|
4586
|
+
// Day 1-3: London
|
|
4587
|
+
pinepaper_add_marker lat: 51.5074 lon: -0.1278
|
|
4588
|
+
label: "London"
|
|
4589
|
+
color: "#f59e0b"
|
|
4590
|
+
size: 12
|
|
4591
|
+
shape: "pin"
|
|
4592
|
+
pulse: true
|
|
4593
|
+
|
|
4594
|
+
// Day 4-5: Paris
|
|
4595
|
+
pinepaper_add_marker lat: 48.8566 lon: 2.3522
|
|
4596
|
+
label: "Paris"
|
|
4597
|
+
color: "#f59e0b"
|
|
4598
|
+
size: 12
|
|
4599
|
+
shape: "pin"
|
|
4600
|
+
pulse: true
|
|
4601
|
+
|
|
4602
|
+
// Day 6-7: Berlin
|
|
4603
|
+
pinepaper_add_marker lat: 52.5200 lon: 13.4050
|
|
4604
|
+
label: "Berlin"
|
|
4605
|
+
color: "#f59e0b"
|
|
4606
|
+
size: 12
|
|
4607
|
+
shape: "pin"
|
|
4608
|
+
pulse: true
|
|
4609
|
+
|
|
4610
|
+
// Day 8-10: Rome
|
|
4611
|
+
pinepaper_add_marker lat: 41.9028 lon: 12.4964
|
|
4612
|
+
label: "Rome"
|
|
4613
|
+
color: "#f59e0b"
|
|
4614
|
+
size: 12
|
|
4615
|
+
shape: "pin"
|
|
4616
|
+
pulse: true
|
|
4617
|
+
|
|
4618
|
+
// Day 11-12: Barcelona
|
|
4619
|
+
pinepaper_add_marker lat: 41.3851 lon: 2.1734
|
|
4620
|
+
label: "Barcelona"
|
|
4621
|
+
color: "#f59e0b"
|
|
4622
|
+
size: 12
|
|
4623
|
+
shape: "pin"
|
|
4624
|
+
pulse: true
|
|
4625
|
+
\`\`\`
|
|
4626
|
+
|
|
4627
|
+
---
|
|
4628
|
+
|
|
4629
|
+
## Step 6: Draw Route Lines
|
|
4630
|
+
|
|
4631
|
+
\`\`\`
|
|
4632
|
+
// London to Paris
|
|
4633
|
+
pinepaper_create_item itemType: "line"
|
|
4634
|
+
properties:
|
|
4635
|
+
from: {x: 380, y: 180}
|
|
4636
|
+
to: {x: 420, y: 220}
|
|
4637
|
+
strokeColor: "#60a5fa"
|
|
4638
|
+
strokeWidth: 2
|
|
4639
|
+
dashArray: [5, 5]
|
|
4640
|
+
→ route1
|
|
4641
|
+
|
|
4642
|
+
// Paris to Berlin
|
|
4643
|
+
pinepaper_create_item itemType: "line"
|
|
4644
|
+
properties:
|
|
4645
|
+
from: {x: 420, y: 220}
|
|
4646
|
+
to: {x: 520, y: 180}
|
|
4647
|
+
strokeColor: "#60a5fa"
|
|
4648
|
+
strokeWidth: 2
|
|
4649
|
+
dashArray: [5, 5]
|
|
4650
|
+
→ route2
|
|
4651
|
+
|
|
4652
|
+
// Berlin to Rome
|
|
4653
|
+
pinepaper_create_item itemType: "line"
|
|
4654
|
+
properties:
|
|
4655
|
+
from: {x: 520, y: 180}
|
|
4656
|
+
to: {x: 500, y: 340}
|
|
4657
|
+
strokeColor: "#60a5fa"
|
|
4658
|
+
strokeWidth: 2
|
|
4659
|
+
dashArray: [5, 5]
|
|
4660
|
+
→ route3
|
|
4661
|
+
|
|
4662
|
+
// Rome to Barcelona
|
|
4663
|
+
pinepaper_create_item itemType: "line"
|
|
4664
|
+
properties:
|
|
4665
|
+
from: {x: 500, y: 340}
|
|
4666
|
+
to: {x: 380, y: 330}
|
|
4667
|
+
strokeColor: "#60a5fa"
|
|
4668
|
+
strokeWidth: 2
|
|
4669
|
+
dashArray: [5, 5]
|
|
4670
|
+
→ route4
|
|
4671
|
+
\`\`\`
|
|
4672
|
+
|
|
4673
|
+
---
|
|
4674
|
+
|
|
4675
|
+
## Step 7: Animate Routes
|
|
4676
|
+
|
|
4677
|
+
\`\`\`
|
|
4678
|
+
pinepaper_animate_item itemId: "route1" animationType: "pulse" speed: 2
|
|
4679
|
+
pinepaper_animate_item itemId: "route2" animationType: "pulse" speed: 2
|
|
4680
|
+
pinepaper_animate_item itemId: "route3" animationType: "pulse" speed: 2
|
|
4681
|
+
pinepaper_animate_item itemId: "route4" animationType: "pulse" speed: 2
|
|
4682
|
+
\`\`\`
|
|
4683
|
+
|
|
4684
|
+
---
|
|
4685
|
+
|
|
4686
|
+
## Step 8: Add Day Numbers
|
|
4687
|
+
|
|
4688
|
+
\`\`\`
|
|
4689
|
+
// London days
|
|
4690
|
+
pinepaper_create_item itemType: "text"
|
|
4691
|
+
position: {x: 360, y: 160}
|
|
4692
|
+
properties:
|
|
4693
|
+
content: "Days 1-3"
|
|
4694
|
+
fontSize: 10
|
|
4695
|
+
color: "#94a3b8"
|
|
4696
|
+
|
|
4697
|
+
// Paris days
|
|
4698
|
+
pinepaper_create_item itemType: "text"
|
|
4699
|
+
position: {x: 440, y: 235}
|
|
4700
|
+
properties:
|
|
4701
|
+
content: "Days 4-5"
|
|
4702
|
+
fontSize: 10
|
|
4703
|
+
color: "#94a3b8"
|
|
4704
|
+
|
|
4705
|
+
// Berlin days
|
|
4706
|
+
pinepaper_create_item itemType: "text"
|
|
4707
|
+
position: {x: 540, y: 165}
|
|
4708
|
+
properties:
|
|
4709
|
+
content: "Days 6-7"
|
|
4710
|
+
fontSize: 10
|
|
4711
|
+
color: "#94a3b8"
|
|
4712
|
+
|
|
4713
|
+
// Rome days
|
|
4714
|
+
pinepaper_create_item itemType: "text"
|
|
4715
|
+
position: {x: 520, y: 355}
|
|
4716
|
+
properties:
|
|
4717
|
+
content: "Days 8-10"
|
|
4718
|
+
fontSize: 10
|
|
4719
|
+
color: "#94a3b8"
|
|
4720
|
+
|
|
4721
|
+
// Barcelona days
|
|
4722
|
+
pinepaper_create_item itemType: "text"
|
|
4723
|
+
position: {x: 360, y: 345}
|
|
4724
|
+
properties:
|
|
4725
|
+
content: "Days 11-12"
|
|
4726
|
+
fontSize: 10
|
|
4727
|
+
color: "#94a3b8"
|
|
4728
|
+
\`\`\`
|
|
4729
|
+
|
|
4730
|
+
---
|
|
4731
|
+
|
|
4732
|
+
## Step 9: Add Title and Decorations
|
|
4733
|
+
|
|
4734
|
+
\`\`\`
|
|
4735
|
+
// Title
|
|
4736
|
+
pinepaper_create_item itemType: "text"
|
|
4737
|
+
position: {x: 640, y: 40}
|
|
4738
|
+
properties:
|
|
4739
|
+
content: "European Adventure 2024"
|
|
4740
|
+
fontSize: 28
|
|
4741
|
+
fontWeight: "bold"
|
|
4742
|
+
color: "#f8fafc"
|
|
4743
|
+
|
|
4744
|
+
// Subtitle
|
|
4745
|
+
pinepaper_create_item itemType: "text"
|
|
4746
|
+
position: {x: 640, y: 70}
|
|
4747
|
+
properties:
|
|
4748
|
+
content: "12 Days • 5 Cities • 1 Amazing Journey"
|
|
4749
|
+
fontSize: 14
|
|
4750
|
+
color: "#94a3b8"
|
|
4751
|
+
|
|
4752
|
+
// Airplane icon at start
|
|
4753
|
+
pinepaper_create_item itemType: "text"
|
|
4754
|
+
position: {x: 340, y: 180}
|
|
4755
|
+
properties:
|
|
4756
|
+
content: "✈️"
|
|
4757
|
+
fontSize: 20
|
|
4758
|
+
\`\`\`
|
|
4759
|
+
|
|
4760
|
+
---
|
|
4761
|
+
|
|
4762
|
+
## Step 10: Add Summary Box
|
|
4763
|
+
|
|
4764
|
+
\`\`\`
|
|
4765
|
+
// Summary background
|
|
4766
|
+
pinepaper_create_item itemType: "rectangle"
|
|
4767
|
+
position: {x: 1100, y: 300}
|
|
4768
|
+
properties:
|
|
4769
|
+
width: 180
|
|
4770
|
+
height: 200
|
|
4771
|
+
color: "#1e293b"
|
|
4772
|
+
cornerRadius: 12
|
|
4773
|
+
strokeColor: "#334155"
|
|
4774
|
+
strokeWidth: 1
|
|
4775
|
+
|
|
4776
|
+
// Summary title
|
|
4777
|
+
pinepaper_create_item itemType: "text"
|
|
4778
|
+
position: {x: 1100, y: 230}
|
|
4779
|
+
properties:
|
|
4780
|
+
content: "Trip Summary"
|
|
4781
|
+
fontSize: 14
|
|
4782
|
+
fontWeight: "bold"
|
|
4783
|
+
color: "#f8fafc"
|
|
4784
|
+
|
|
4785
|
+
// Stats
|
|
4786
|
+
pinepaper_create_item itemType: "text"
|
|
4787
|
+
position: {x: 1100, y: 260}
|
|
4788
|
+
properties:
|
|
4789
|
+
content: "📍 5 Cities"
|
|
4790
|
+
fontSize: 12
|
|
4791
|
+
color: "#94a3b8"
|
|
4792
|
+
|
|
4793
|
+
pinepaper_create_item itemType: "text"
|
|
4794
|
+
position: {x: 1100, y: 285}
|
|
4795
|
+
properties:
|
|
4796
|
+
content: "📅 12 Days"
|
|
4797
|
+
fontSize: 12
|
|
4798
|
+
color: "#94a3b8"
|
|
4799
|
+
|
|
4800
|
+
pinepaper_create_item itemType: "text"
|
|
4801
|
+
position: {x: 1100, y: 310}
|
|
4802
|
+
properties:
|
|
4803
|
+
content: "🛫 4 Flights"
|
|
4804
|
+
fontSize: 12
|
|
4805
|
+
color: "#94a3b8"
|
|
4806
|
+
|
|
4807
|
+
pinepaper_create_item itemType: "text"
|
|
4808
|
+
position: {x: 1100, y: 335}
|
|
4809
|
+
properties:
|
|
4810
|
+
content: "🏨 11 Nights"
|
|
4811
|
+
fontSize: 12
|
|
4812
|
+
color: "#94a3b8"
|
|
4813
|
+
\`\`\`
|
|
4814
|
+
|
|
4815
|
+
---
|
|
4816
|
+
|
|
4817
|
+
## Step 11: Export
|
|
4818
|
+
|
|
4819
|
+
\`\`\`
|
|
4820
|
+
pinepaper_export_svg
|
|
4821
|
+
\`\`\`
|
|
4822
|
+
|
|
4823
|
+
---
|
|
4824
|
+
|
|
4825
|
+
## Variations
|
|
4826
|
+
|
|
4827
|
+
### Animated Route Reveal
|
|
4828
|
+
Use keyframe animations to reveal the route step by step:
|
|
4829
|
+
\`\`\`
|
|
4830
|
+
pinepaper_keyframe_animate itemId: "route1"
|
|
4831
|
+
keyframes:
|
|
4832
|
+
- time: 0, properties: {opacity: 0}
|
|
4833
|
+
- time: 1, properties: {opacity: 1}
|
|
4834
|
+
|
|
4835
|
+
pinepaper_keyframe_animate itemId: "route2"
|
|
4836
|
+
keyframes:
|
|
4837
|
+
- time: 1, properties: {opacity: 0}
|
|
4838
|
+
- time: 2, properties: {opacity: 1}
|
|
4839
|
+
\`\`\`
|
|
4840
|
+
|
|
4841
|
+
### Distance Labels
|
|
4842
|
+
Add distance between cities:
|
|
4843
|
+
\`\`\`
|
|
4844
|
+
pinepaper_create_item itemType: "text"
|
|
4845
|
+
position: {x: 400, y: 200}
|
|
4846
|
+
properties:
|
|
4847
|
+
content: "344 km"
|
|
4848
|
+
fontSize: 8
|
|
4849
|
+
color: "#60a5fa"
|
|
4850
|
+
\`\`\`
|
|
4851
|
+
`,
|
|
4852
|
+
'pinepaper://docs/diagrams': `# Diagrams Guide
|
|
4853
|
+
|
|
4854
|
+
**Intent:** Create flowcharts, UML diagrams, network architectures, and connect any visual elements with smart arrows.
|
|
4855
|
+
|
|
4856
|
+
## When to Use Diagrams
|
|
4857
|
+
|
|
4858
|
+
Use diagram tools when you need to:
|
|
4859
|
+
- Build flowcharts with decision logic
|
|
4860
|
+
- Create UML diagrams (class, use case)
|
|
4861
|
+
- Design network/architecture diagrams
|
|
4862
|
+
- Connect any items (images, shapes, text) with arrows
|
|
4863
|
+
- Show process flows with animated connectors
|
|
4864
|
+
|
|
4865
|
+
## Key Tools
|
|
4866
|
+
|
|
4867
|
+
| Tool | Purpose |
|
|
4868
|
+
|------|---------|
|
|
4869
|
+
| \`pinepaper_create_diagram_shape\` | Create flowchart/UML/network shapes |
|
|
4870
|
+
| \`pinepaper_connect\` | Connect items with smart arrows |
|
|
4871
|
+
| \`pinepaper_auto_layout\` | Automatically arrange connected shapes |
|
|
4872
|
+
| \`pinepaper_get_diagram_shapes\` | List available shape types |
|
|
4873
|
+
| \`pinepaper_diagram_mode\` | Enable/disable diagram editing mode |
|
|
4874
|
+
|
|
4875
|
+
## Shape Types
|
|
4876
|
+
|
|
4877
|
+
### Flowchart Shapes
|
|
4878
|
+
| Shape | Use For |
|
|
4879
|
+
|-------|---------|
|
|
4880
|
+
| \`process\` | Actions, steps (rectangle) |
|
|
4881
|
+
| \`decision\` | Yes/No branching (diamond) |
|
|
4882
|
+
| \`terminal\` | Start/End points (rounded) |
|
|
4883
|
+
| \`data\` | Input/Output (parallelogram) |
|
|
4884
|
+
| \`document\` | Documents (wavy bottom) |
|
|
4885
|
+
| \`database\` | Data storage (cylinder) |
|
|
4886
|
+
| \`preparation\` | Setup steps (hexagon) |
|
|
4887
|
+
|
|
4888
|
+
### UML Shapes
|
|
4889
|
+
| Shape | Use For |
|
|
4890
|
+
|-------|---------|
|
|
4891
|
+
| \`uml-class\` | Class definitions |
|
|
4892
|
+
| \`uml-usecase\` | Use case ellipse |
|
|
4893
|
+
| \`uml-actor\` | Stick figure actor |
|
|
4894
|
+
|
|
4895
|
+
### Network Shapes
|
|
4896
|
+
| Shape | Use For |
|
|
4897
|
+
|-------|---------|
|
|
4898
|
+
| \`cloud\` | Cloud services |
|
|
4899
|
+
| \`server\` | Server/computer |
|
|
4900
|
+
|
|
4901
|
+
## Creating a Flowchart
|
|
4902
|
+
|
|
4903
|
+
\`\`\`
|
|
4904
|
+
// Step 1: Create shapes
|
|
4905
|
+
pinepaper_create_diagram_shape
|
|
4906
|
+
shapeType: "terminal"
|
|
4907
|
+
position: {x: 400, y: 100}
|
|
4908
|
+
label: "Start"
|
|
4909
|
+
style: {fillColor: "#22c55e"}
|
|
4910
|
+
→ item_1
|
|
4911
|
+
|
|
4912
|
+
pinepaper_create_diagram_shape
|
|
4913
|
+
shapeType: "process"
|
|
4914
|
+
position: {x: 400, y: 200}
|
|
4915
|
+
label: "Process Data"
|
|
4916
|
+
→ item_2
|
|
4917
|
+
|
|
4918
|
+
pinepaper_create_diagram_shape
|
|
4919
|
+
shapeType: "decision"
|
|
4920
|
+
position: {x: 400, y: 320}
|
|
4921
|
+
label: "Valid?"
|
|
4922
|
+
style: {fillColor: "#fbbf24"}
|
|
4923
|
+
→ item_3
|
|
4924
|
+
|
|
4925
|
+
pinepaper_create_diagram_shape
|
|
4926
|
+
shapeType: "terminal"
|
|
4927
|
+
position: {x: 400, y: 440}
|
|
4928
|
+
label: "End"
|
|
4929
|
+
style: {fillColor: "#ef4444"}
|
|
4930
|
+
→ item_4
|
|
4931
|
+
|
|
4932
|
+
// Step 2: Connect shapes
|
|
4933
|
+
pinepaper_connect
|
|
4934
|
+
sourceItemId: "item_1"
|
|
4935
|
+
targetItemId: "item_2"
|
|
4936
|
+
routing: "orthogonal"
|
|
4937
|
+
|
|
4938
|
+
pinepaper_connect
|
|
4939
|
+
sourceItemId: "item_2"
|
|
4940
|
+
targetItemId: "item_3"
|
|
4941
|
+
|
|
4942
|
+
pinepaper_connect
|
|
4943
|
+
sourceItemId: "item_3"
|
|
4944
|
+
targetItemId: "item_4"
|
|
4945
|
+
label: "Yes"
|
|
4946
|
+
\`\`\`
|
|
4947
|
+
|
|
4948
|
+
## Connector Options
|
|
4949
|
+
|
|
4950
|
+
### Routing Styles
|
|
4951
|
+
| Style | Description |
|
|
4952
|
+
|-------|-------------|
|
|
4953
|
+
| \`orthogonal\` | Right-angle paths (default, best for flowcharts) |
|
|
4954
|
+
| \`curved\` | Smooth curved paths |
|
|
4955
|
+
| \`direct\` | Straight line |
|
|
4956
|
+
|
|
4957
|
+
### Arrow Styles
|
|
4958
|
+
| Style | Description |
|
|
4959
|
+
|-------|-------------|
|
|
4960
|
+
| \`classic\` | Standard arrow (default) |
|
|
4961
|
+
| \`stealth\` | Sleek pointed arrow |
|
|
4962
|
+
| \`sharp\` | Sharp angular arrow |
|
|
4963
|
+
| \`open\` | Outlined arrow |
|
|
4964
|
+
| \`diamond\` | Diamond shape |
|
|
4965
|
+
| \`circle\` | Circle endpoint |
|
|
4966
|
+
| \`none\` | No arrowhead |
|
|
4967
|
+
|
|
4968
|
+
### Line Styles
|
|
4969
|
+
| Style | Description |
|
|
4970
|
+
|-------|-------------|
|
|
4971
|
+
| \`solid\` | Continuous line |
|
|
4972
|
+
| \`dashed\` | Dashed line |
|
|
4973
|
+
| \`dotted\` | Dotted line |
|
|
4974
|
+
|
|
4975
|
+
## Connector Example
|
|
4976
|
+
|
|
4977
|
+
\`\`\`
|
|
4978
|
+
pinepaper_connect
|
|
4979
|
+
sourceItemId: "item_1"
|
|
4980
|
+
targetItemId: "item_2"
|
|
4981
|
+
routing: "curved"
|
|
4982
|
+
lineColor: "#3b82f6"
|
|
4983
|
+
lineWidth: 2
|
|
4984
|
+
lineStyle: "dashed"
|
|
4985
|
+
headStyle: "stealth"
|
|
4986
|
+
label: "Yes"
|
|
4987
|
+
animated: true // Bolt effect shows direction
|
|
4988
|
+
\`\`\`
|
|
4989
|
+
|
|
4990
|
+
## Connecting Any Items
|
|
4991
|
+
|
|
4992
|
+
Diagram connectors work with ANY canvas items, not just diagram shapes:
|
|
4993
|
+
|
|
4994
|
+
\`\`\`
|
|
4995
|
+
// Connect images
|
|
4996
|
+
pinepaper_import_svg url: "https://example.com/icon1.svg" → item_1
|
|
4997
|
+
pinepaper_import_svg url: "https://example.com/icon2.svg" → item_2
|
|
4998
|
+
pinepaper_connect sourceItemId: "item_1" targetItemId: "item_2"
|
|
4999
|
+
|
|
5000
|
+
// Connect text labels
|
|
5001
|
+
pinepaper_create_item itemType: "text" properties: {content: "A"} → item_3
|
|
5002
|
+
pinepaper_create_item itemType: "text" properties: {content: "B"} → item_4
|
|
5003
|
+
pinepaper_connect sourceItemId: "item_3" targetItemId: "item_4"
|
|
5004
|
+
\`\`\`
|
|
5005
|
+
|
|
5006
|
+
## Auto Layout
|
|
5007
|
+
|
|
5008
|
+
Automatically arrange connected shapes:
|
|
5009
|
+
|
|
5010
|
+
\`\`\`
|
|
5011
|
+
pinepaper_auto_layout
|
|
5012
|
+
direction: "TB" // TB, BT, LR, RL
|
|
5013
|
+
spacing: {horizontal: 80, vertical: 60}
|
|
5014
|
+
\`\`\`
|
|
5015
|
+
|
|
5016
|
+
| Direction | Description |
|
|
5017
|
+
|-----------|-------------|
|
|
5018
|
+
| \`TB\` | Top to Bottom |
|
|
5019
|
+
| \`BT\` | Bottom to Top |
|
|
5020
|
+
| \`LR\` | Left to Right |
|
|
5021
|
+
| \`RL\` | Right to Left |
|
|
5022
|
+
`,
|
|
5023
|
+
'pinepaper://docs/masks': `# Masks Guide
|
|
5024
|
+
|
|
5025
|
+
**Intent:** Create reveal animations and transitions using animated clipping masks (wipes, iris, curtains, custom shapes).
|
|
5026
|
+
|
|
5027
|
+
## When to Use Masks
|
|
5028
|
+
|
|
5029
|
+
Use mask tools when you need to:
|
|
5030
|
+
- Reveal text or images with wipe effects
|
|
5031
|
+
- Create iris/zoom reveal animations
|
|
5032
|
+
- Build curtain-style transitions
|
|
5033
|
+
- Design custom reveal sequences
|
|
5034
|
+
- Add cinematic letterbox effects
|
|
5035
|
+
|
|
5036
|
+
## Key Tools
|
|
5037
|
+
|
|
5038
|
+
| Tool | Purpose |
|
|
5039
|
+
|------|---------|
|
|
5040
|
+
| \`pinepaper_apply_animated_mask\` | Apply reveal animation (preset or custom) |
|
|
5041
|
+
| \`pinepaper_apply_custom_mask\` | Full keyframe control |
|
|
5042
|
+
| \`pinepaper_remove_mask\` | Remove mask from item |
|
|
5043
|
+
| \`pinepaper_get_mask_animations\` | List available presets |
|
|
5044
|
+
| \`pinepaper_get_mask_types\` | List mask shapes |
|
|
5045
|
+
| \`pinepaper_get_animatable_properties\` | Get keyframeable properties |
|
|
5046
|
+
| \`pinepaper_get_available_easings\` | List easing functions |
|
|
5047
|
+
|
|
5048
|
+
## Animation Presets
|
|
5049
|
+
|
|
5050
|
+
### Wipe Effects
|
|
5051
|
+
| Preset | Effect |
|
|
5052
|
+
|--------|--------|
|
|
5053
|
+
| \`wipeLeft\` | Reveal from left to right |
|
|
5054
|
+
| \`wipeRight\` | Reveal from right to left |
|
|
5055
|
+
| \`wipeUp\` | Reveal from bottom to top |
|
|
5056
|
+
| \`wipeDown\` | Reveal from top to bottom |
|
|
5057
|
+
| \`diagonalWipe\` | Angled reveal from corner |
|
|
5058
|
+
|
|
5059
|
+
### Iris Effects
|
|
5060
|
+
| Preset | Effect |
|
|
5061
|
+
|--------|--------|
|
|
5062
|
+
| \`iris\` | Circle expands from center |
|
|
5063
|
+
| \`irisOut\` | Circle shrinks to center (hide) |
|
|
5064
|
+
|
|
5065
|
+
### Shape Reveals
|
|
5066
|
+
| Preset | Effect |
|
|
5067
|
+
|--------|--------|
|
|
5068
|
+
| \`star\` | Star shape scales up |
|
|
5069
|
+
| \`heart\` | Heart shape scales up |
|
|
5070
|
+
|
|
5071
|
+
### Curtain Effects
|
|
5072
|
+
| Preset | Effect |
|
|
5073
|
+
|--------|--------|
|
|
5074
|
+
| \`curtainHorizontal\` | Opens from center horizontally |
|
|
5075
|
+
| \`curtainVertical\` | Opens from center vertically |
|
|
5076
|
+
| \`cinematic\` | Letterbox bars animate away |
|
|
5077
|
+
|
|
5078
|
+
### Text Reveals
|
|
5079
|
+
| Preset | Effect |
|
|
5080
|
+
|--------|--------|
|
|
5081
|
+
| \`revealUp\` | Text slides up within mask |
|
|
5082
|
+
| \`revealDown\` | Text slides down within mask |
|
|
5083
|
+
|
|
5084
|
+
## Quick Start: Preset Mode
|
|
5085
|
+
|
|
5086
|
+
\`\`\`
|
|
5087
|
+
// Create an item
|
|
5088
|
+
pinepaper_create_item
|
|
5089
|
+
itemType: "text"
|
|
5090
|
+
position: {x: 400, y: 300}
|
|
5091
|
+
properties: {content: "Hello World", fontSize: 48, color: "#ffffff"}
|
|
5092
|
+
→ item_1
|
|
5093
|
+
|
|
5094
|
+
// Apply wipe reveal
|
|
5095
|
+
pinepaper_apply_animated_mask
|
|
5096
|
+
itemId: "item_1"
|
|
5097
|
+
preset: "wipeLeft"
|
|
5098
|
+
options:
|
|
5099
|
+
duration: 0.5
|
|
5100
|
+
easing: "easeOut"
|
|
5101
|
+
\`\`\`
|
|
5102
|
+
|
|
5103
|
+
## Preset Options
|
|
5104
|
+
|
|
5105
|
+
| Option | Type | Default | Description |
|
|
5106
|
+
|--------|------|---------|-------------|
|
|
5107
|
+
| \`startTime\` | number | 0 | Delay before animation starts (seconds) |
|
|
5108
|
+
| \`duration\` | number | 0.8 | Animation duration (seconds) |
|
|
5109
|
+
| \`easing\` | string | "easeOut" | Timing function |
|
|
5110
|
+
| \`reversed\` | boolean | false | Play in reverse (hide instead of reveal) |
|
|
5111
|
+
| \`loop\` | boolean | false | Loop the animation |
|
|
5112
|
+
|
|
5113
|
+
## Easing Functions
|
|
5114
|
+
|
|
5115
|
+
| Easing | Description |
|
|
5116
|
+
|--------|-------------|
|
|
5117
|
+
| \`linear\` | Constant speed |
|
|
5118
|
+
| \`easeIn\` | Slow start, fast end |
|
|
5119
|
+
| \`easeOut\` | Fast start, slow end |
|
|
5120
|
+
| \`easeInOut\` | Slow start and end |
|
|
5121
|
+
| \`bounce\` | Bouncing effect at end |
|
|
5122
|
+
| \`elastic\` | Spring-like overshoot |
|
|
5123
|
+
|
|
5124
|
+
## Custom Keyframe Animation
|
|
5125
|
+
|
|
5126
|
+
For full control, define keyframes manually:
|
|
5127
|
+
|
|
5128
|
+
\`\`\`
|
|
5129
|
+
pinepaper_apply_animated_mask
|
|
5130
|
+
itemId: "item_1"
|
|
5131
|
+
maskType: "rectangle"
|
|
5132
|
+
keyframes:
|
|
5133
|
+
- time: 0
|
|
5134
|
+
properties: {x: 200, y: 250, width: 0, height: 100}
|
|
5135
|
+
easing: "linear"
|
|
5136
|
+
- time: 0.5
|
|
5137
|
+
properties: {x: 200, y: 250, width: 100, height: 100}
|
|
5138
|
+
easing: "easeIn"
|
|
5139
|
+
- time: 1
|
|
5140
|
+
properties: {x: 200, y: 250, width: 200, height: 100}
|
|
5141
|
+
easing: "easeOut"
|
|
5142
|
+
\`\`\`
|
|
5143
|
+
|
|
5144
|
+
## Mask Types
|
|
5145
|
+
|
|
5146
|
+
| Type | Animatable Properties |
|
|
5147
|
+
|------|----------------------|
|
|
5148
|
+
| \`rectangle\` | x, y, width, height, rotation, opacity |
|
|
5149
|
+
| \`circle\` | x, y, radius, scale, opacity |
|
|
5150
|
+
| \`ellipse\` | x, y, radiusX, radiusY, rotation, scale, opacity |
|
|
5151
|
+
| \`star\` | x, y, radius, scale, rotation, opacity |
|
|
5152
|
+
| \`triangle\` | x, y, scale, rotation, opacity |
|
|
5153
|
+
| \`hexagon\` | x, y, scale, rotation, opacity |
|
|
5154
|
+
| \`heart\` | x, y, scale, rotation, opacity |
|
|
5155
|
+
| \`rounded\` | x, y, width, height, cornerRadius, opacity |
|
|
5156
|
+
|
|
5157
|
+
## Hybrid Mode: Preset + Custom Keyframes
|
|
5158
|
+
|
|
5159
|
+
Combine preset behavior with custom timing:
|
|
5160
|
+
|
|
5161
|
+
\`\`\`
|
|
5162
|
+
pinepaper_apply_animated_mask
|
|
5163
|
+
itemId: "item_1"
|
|
5164
|
+
preset: "iris"
|
|
5165
|
+
keyframes:
|
|
5166
|
+
- time: 0
|
|
5167
|
+
properties: {scale: 0.01}
|
|
5168
|
+
easing: "linear"
|
|
5169
|
+
- time: 0.3
|
|
5170
|
+
properties: {scale: 0.3}
|
|
5171
|
+
easing: "easeIn"
|
|
5172
|
+
- time: 0.7
|
|
5173
|
+
properties: {scale: 0.8}
|
|
5174
|
+
easing: "easeOut"
|
|
5175
|
+
- time: 1
|
|
5176
|
+
properties: {scale: 1}
|
|
5177
|
+
easing: "bounce"
|
|
5178
|
+
\`\`\`
|
|
5179
|
+
|
|
5180
|
+
## Staggered Text Reveal
|
|
5181
|
+
|
|
5182
|
+
Reveal multiple words with delays:
|
|
5183
|
+
|
|
5184
|
+
\`\`\`
|
|
5185
|
+
// Create words
|
|
5186
|
+
pinepaper_create_item itemType: "text" position: {x: 200, y: 300}
|
|
5187
|
+
properties: {content: "Hello", fontSize: 36} → item_1
|
|
5188
|
+
|
|
5189
|
+
pinepaper_create_item itemType: "text" position: {x: 350, y: 300}
|
|
5190
|
+
properties: {content: "Beautiful", fontSize: 36} → item_2
|
|
5191
|
+
|
|
5192
|
+
pinepaper_create_item itemType: "text" position: {x: 550, y: 300}
|
|
5193
|
+
properties: {content: "World", fontSize: 36} → item_3
|
|
5194
|
+
|
|
5195
|
+
// Apply staggered reveals
|
|
5196
|
+
pinepaper_apply_animated_mask itemId: "item_1" preset: "wipeUp"
|
|
5197
|
+
options: {startTime: 0, duration: 0.3}
|
|
5198
|
+
|
|
5199
|
+
pinepaper_apply_animated_mask itemId: "item_2" preset: "wipeUp"
|
|
5200
|
+
options: {startTime: 0.2, duration: 0.3}
|
|
5201
|
+
|
|
5202
|
+
pinepaper_apply_animated_mask itemId: "item_3" preset: "wipeUp"
|
|
5203
|
+
options: {startTime: 0.4, duration: 0.3}
|
|
5204
|
+
\`\`\`
|
|
5205
|
+
|
|
5206
|
+
## Removing Masks
|
|
5207
|
+
|
|
5208
|
+
\`\`\`
|
|
5209
|
+
pinepaper_remove_mask itemId: "item_1"
|
|
5210
|
+
\`\`\`
|
|
5211
|
+
`,
|
|
5212
|
+
'pinepaper://docs/fonts': `# Font Studio Guide
|
|
5213
|
+
|
|
5214
|
+
**Intent:** Create custom hand-drawn fonts by drawing glyphs on a dedicated canvas, then export as OTF files or use directly in PinePaper documents.
|
|
5215
|
+
|
|
5216
|
+
## Overview
|
|
5217
|
+
|
|
5218
|
+
Font Studio provides 16 tools for creating custom fonts programmatically. You draw each character as a Paper.js path, clean it up, and convert it to a font glyph.
|
|
5219
|
+
|
|
5220
|
+
## Key Tools
|
|
5221
|
+
|
|
5222
|
+
| Tool | Purpose |
|
|
5223
|
+
|------|---------|
|
|
5224
|
+
| \`pinepaper_font_show_studio\` | Open the Font Studio UI with guide lines |
|
|
5225
|
+
| \`pinepaper_font_set_name\` | Set font family name |
|
|
5226
|
+
| \`pinepaper_font_get_required_chars\` | Get list of characters needed |
|
|
5227
|
+
| \`pinepaper_font_get_status\` | Check completion progress |
|
|
5228
|
+
| \`pinepaper_font_create_glyph\` | Convert a drawn path to a glyph |
|
|
5229
|
+
| \`pinepaper_font_create_space\` | Create the space character |
|
|
5230
|
+
| \`pinepaper_font_remove_glyph\` | Remove a glyph for redrawing |
|
|
5231
|
+
| \`pinepaper_font_set_metrics\` | Configure font metrics (advanced) |
|
|
5232
|
+
| \`pinepaper_font_export\` | Export as OTF file |
|
|
5233
|
+
| \`pinepaper_font_load_into_document\` | Use font in current document |
|
|
5234
|
+
| \`pinepaper_font_export_data\` | Save progress as JSON |
|
|
5235
|
+
| \`pinepaper_font_import_data\` | Resume from saved data |
|
|
5236
|
+
| \`pinepaper_font_clear\` | Reset all glyphs |
|
|
5237
|
+
| \`pinepaper_font_remove_overlap\` | Merge overlapping path strokes |
|
|
5238
|
+
| \`pinepaper_font_correct_direction\` | Fix path winding for fills |
|
|
5239
|
+
| \`pinepaper_font_cleanup_path\` | All-in-one path preparation |
|
|
5240
|
+
|
|
5241
|
+
## Workflow
|
|
5242
|
+
|
|
5243
|
+
### Step 1: Open Font Studio
|
|
5244
|
+
\`\`\`
|
|
5245
|
+
pinepaper_font_show_studio
|
|
5246
|
+
\`\`\`
|
|
5247
|
+
|
|
5248
|
+
Opens the interactive Font Studio UI with typography guide lines:
|
|
5249
|
+
- **Cap Height** (Red): Top of capital letters (H, T, A)
|
|
5250
|
+
- **x-Height** (Cyan): Top of lowercase letters (a, e, x)
|
|
5251
|
+
- **Baseline** (Green): Where letters sit
|
|
5252
|
+
- **Descender** (Purple): Below baseline for g, p, y, j
|
|
5253
|
+
|
|
5254
|
+
### Step 2: Set Font Name
|
|
5255
|
+
\`\`\`
|
|
5256
|
+
pinepaper_font_set_name name: "MyHandwriting"
|
|
5257
|
+
\`\`\`
|
|
5258
|
+
|
|
5259
|
+
### Step 3: Check Required Characters
|
|
5260
|
+
\`\`\`
|
|
5261
|
+
pinepaper_font_get_required_chars set: "minimum"
|
|
5262
|
+
\`\`\`
|
|
5263
|
+
|
|
5264
|
+
Two character sets available:
|
|
5265
|
+
- **minimum**: A-Z, a-z, 0-9, space (63 chars) - enough for basic text
|
|
5266
|
+
- **standard**: adds punctuation and symbols (90+ chars)
|
|
5267
|
+
|
|
5268
|
+
### Step 4: Draw and Create Glyphs
|
|
5269
|
+
|
|
5270
|
+
For each character:
|
|
5271
|
+
|
|
5272
|
+
1. **Draw the character** as a Paper.js path on the canvas
|
|
5273
|
+
2. **Clean up the path** (recommended):
|
|
5274
|
+
\`\`\`
|
|
5275
|
+
pinepaper_font_cleanup_path pathId: "item_42"
|
|
5276
|
+
\`\`\`
|
|
5277
|
+
3. **Create the glyph**:
|
|
5278
|
+
\`\`\`
|
|
5279
|
+
pinepaper_font_create_glyph character: "A" pathId: "item_42"
|
|
5280
|
+
\`\`\`
|
|
5281
|
+
|
|
5282
|
+
For the space character (no visible path needed):
|
|
5283
|
+
\`\`\`
|
|
5284
|
+
pinepaper_font_create_space width: 250
|
|
5285
|
+
\`\`\`
|
|
5286
|
+
|
|
5287
|
+
### Step 5: Check Progress
|
|
5288
|
+
\`\`\`
|
|
5289
|
+
pinepaper_font_get_status
|
|
5290
|
+
\`\`\`
|
|
5291
|
+
|
|
5292
|
+
Returns: font name, total/completed/pending counts, percentage, and character lists.
|
|
5293
|
+
|
|
5294
|
+
### Step 6: Export
|
|
5295
|
+
|
|
5296
|
+
Export as OTF file:
|
|
5297
|
+
\`\`\`
|
|
5298
|
+
pinepaper_font_export
|
|
5299
|
+
\`\`\`
|
|
5300
|
+
|
|
5301
|
+
Or load directly into the document:
|
|
5302
|
+
\`\`\`
|
|
5303
|
+
pinepaper_font_load_into_document
|
|
5304
|
+
\`\`\`
|
|
5305
|
+
|
|
5306
|
+
## Path Cleanup Tools
|
|
5307
|
+
|
|
5308
|
+
Before converting a drawn path to a glyph, clean it up for best results:
|
|
5309
|
+
|
|
5310
|
+
| Tool | What It Does |
|
|
5311
|
+
|------|-------------|
|
|
5312
|
+
| \`pinepaper_font_remove_overlap\` | Merges overlapping strokes into one outline |
|
|
5313
|
+
| \`pinepaper_font_correct_direction\` | Fixes winding so fills render correctly |
|
|
5314
|
+
| \`pinepaper_font_cleanup_path\` | Does all cleanup in one call (overlap + direction + smooth) |
|
|
5315
|
+
|
|
5316
|
+
The \`cleanup_path\` tool accepts options:
|
|
5317
|
+
\`\`\`
|
|
5318
|
+
pinepaper_font_cleanup_path
|
|
5319
|
+
pathId: "item_42"
|
|
5320
|
+
removeOverlap: true
|
|
5321
|
+
correctDirection: true
|
|
5322
|
+
smooth: true
|
|
5323
|
+
smoothTolerance: 2.5
|
|
5324
|
+
\`\`\`
|
|
5325
|
+
|
|
5326
|
+
## Font Metrics (Advanced)
|
|
5327
|
+
|
|
5328
|
+
Configure the font's coordinate system:
|
|
5329
|
+
\`\`\`
|
|
5330
|
+
pinepaper_font_set_metrics
|
|
5331
|
+
unitsPerEm: 1000
|
|
5332
|
+
ascender: 800
|
|
5333
|
+
descender: -200
|
|
5334
|
+
xHeight: 500
|
|
5335
|
+
capHeight: 700
|
|
5336
|
+
\`\`\`
|
|
5337
|
+
|
|
5338
|
+
## Save and Resume Progress
|
|
5339
|
+
|
|
5340
|
+
Save work-in-progress:
|
|
5341
|
+
\`\`\`
|
|
5342
|
+
pinepaper_font_export_data
|
|
5343
|
+
\`\`\`
|
|
5344
|
+
|
|
5345
|
+
Resume later:
|
|
5346
|
+
\`\`\`
|
|
5347
|
+
pinepaper_font_import_data data: { ... }
|
|
5348
|
+
\`\`\`
|
|
5349
|
+
|
|
5350
|
+
## Best Practices
|
|
5351
|
+
|
|
5352
|
+
- Keep stroke width consistent across all characters
|
|
5353
|
+
- Uppercase letters should touch the cap height line
|
|
5354
|
+
- Lowercase (except b, d, f, h, k, l, t) stay within x-height
|
|
5355
|
+
- Letters g, j, p, q, y extend below baseline to descender
|
|
5356
|
+
- Always run \`cleanup_path\` before \`create_glyph\` for cleanest results
|
|
5357
|
+
- Use \`get_status\` frequently to track progress
|
|
5358
|
+
- Save progress with \`export_data\` periodically
|
|
5359
|
+
`,
|
|
5360
|
+
'pinepaper://examples/us-states-animated': `# US States Animated Map Example
|
|
5361
|
+
|
|
5362
|
+
**Intent:** Create a US map with animated color transitions that loop continuously.
|
|
5363
|
+
|
|
5364
|
+
## What You'll Build
|
|
5365
|
+
|
|
5366
|
+
A USA map where states randomly change colors in a flowing wave animation.
|
|
5367
|
+
|
|
5368
|
+
## Step 1: Load the Map
|
|
5369
|
+
|
|
5370
|
+
\`\`\`
|
|
5371
|
+
pinepaper_load_map
|
|
5372
|
+
mapId: "usa"
|
|
5373
|
+
options:
|
|
5374
|
+
projection: "albers"
|
|
5375
|
+
quality: "balanced"
|
|
5376
|
+
fillColor: "#e5e7eb"
|
|
5377
|
+
strokeColor: "#9ca3af"
|
|
5378
|
+
\`\`\`
|
|
5379
|
+
|
|
5380
|
+
## Step 2: Apply Wave Animation
|
|
5381
|
+
|
|
5382
|
+
\`\`\`
|
|
5383
|
+
pinepaper_animate_map_wave
|
|
5384
|
+
duration: 10
|
|
5385
|
+
loop: true
|
|
5386
|
+
colors: ["#ef4444", "#f97316", "#fbbf24", "#22c55e", "#3b82f6", "#8b5cf6"]
|
|
5387
|
+
options:
|
|
5388
|
+
delayBetween: 0.1
|
|
5389
|
+
easing: "easeInOut"
|
|
5390
|
+
\`\`\`
|
|
5391
|
+
|
|
5392
|
+
## Result
|
|
5393
|
+
|
|
5394
|
+
States will animate through the color palette in a wave pattern, creating a mesmerizing continuous animation.
|
|
5395
|
+
|
|
5396
|
+
## Alternative: Data-Driven Colors
|
|
5397
|
+
|
|
5398
|
+
Apply colors based on data values:
|
|
5399
|
+
|
|
5400
|
+
\`\`\`
|
|
5401
|
+
pinepaper_apply_data_colors
|
|
5402
|
+
data:
|
|
5403
|
+
"CA": 100
|
|
5404
|
+
"TX": 85
|
|
5405
|
+
"FL": 70
|
|
5406
|
+
"NY": 65
|
|
5407
|
+
"PA": 50
|
|
5408
|
+
"IL": 45
|
|
5409
|
+
"OH": 40
|
|
5410
|
+
options:
|
|
5411
|
+
colorScale: "blues"
|
|
5412
|
+
legend: true
|
|
5413
|
+
legendPosition: "bottom-right"
|
|
5414
|
+
\`\`\`
|
|
5415
|
+
|
|
5416
|
+
## Alternative: Highlight Specific States
|
|
5417
|
+
|
|
5418
|
+
\`\`\`
|
|
5419
|
+
pinepaper_highlight_regions
|
|
5420
|
+
regionIds: ["CA", "OR", "WA"]
|
|
5421
|
+
options:
|
|
5422
|
+
fillColor: "#22c55e"
|
|
5423
|
+
strokeColor: "#16a34a"
|
|
5424
|
+
animated: true
|
|
5425
|
+
\`\`\`
|
|
5426
|
+
|
|
5427
|
+
## Key Tools Used
|
|
5428
|
+
|
|
5429
|
+
| Tool | Purpose |
|
|
5430
|
+
|------|---------|
|
|
5431
|
+
| \`pinepaper_load_map\` | Load USA map with Albers projection |
|
|
5432
|
+
| \`pinepaper_animate_map_wave\` | Create looping color animation |
|
|
5433
|
+
| \`pinepaper_apply_data_colors\` | Color by numeric values |
|
|
5434
|
+
| \`pinepaper_highlight_regions\` | Highlight specific states |
|
|
5435
|
+
|
|
5436
|
+
## Region ID Format
|
|
5437
|
+
|
|
5438
|
+
For USA maps, use 2-letter state codes:
|
|
5439
|
+
- CA, TX, NY, FL, WA, OR, etc.
|
|
5440
|
+
|
|
5441
|
+
## Export
|
|
5442
|
+
|
|
5443
|
+
\`\`\`
|
|
5444
|
+
pinepaper_export_svg animated: true
|
|
5445
|
+
\`\`\`
|
|
5446
|
+
`,
|
|
5447
|
+
'pinepaper://examples/flowchart': `# Flowchart Example
|
|
5448
|
+
|
|
5449
|
+
**Intent:** Create a decision flowchart with auto-layout and animated connectors.
|
|
5450
|
+
|
|
5451
|
+
## What You'll Build
|
|
5452
|
+
|
|
5453
|
+
A simple decision flowchart: Start → Process → Decision → End
|
|
5454
|
+
|
|
5455
|
+
## Step 1: Create Shapes
|
|
5456
|
+
|
|
5457
|
+
\`\`\`
|
|
5458
|
+
// Start terminal
|
|
5459
|
+
pinepaper_create_diagram_shape
|
|
5460
|
+
shapeType: "terminal"
|
|
5461
|
+
position: {x: 400, y: 80}
|
|
5462
|
+
label: "Start"
|
|
5463
|
+
style: {fillColor: "#22c55e", strokeColor: "#16a34a"}
|
|
5464
|
+
→ item_1
|
|
5465
|
+
|
|
5466
|
+
// Process step
|
|
5467
|
+
pinepaper_create_diagram_shape
|
|
5468
|
+
shapeType: "process"
|
|
5469
|
+
position: {x: 400, y: 180}
|
|
5470
|
+
label: "Check Input"
|
|
5471
|
+
style: {fillColor: "#3b82f6", strokeColor: "#2563eb"}
|
|
5472
|
+
→ item_2
|
|
5473
|
+
|
|
5474
|
+
// Decision diamond
|
|
5475
|
+
pinepaper_create_diagram_shape
|
|
5476
|
+
shapeType: "decision"
|
|
5477
|
+
position: {x: 400, y: 300}
|
|
5478
|
+
label: "Valid?"
|
|
5479
|
+
style: {fillColor: "#fbbf24", strokeColor: "#f59e0b"}
|
|
5480
|
+
→ item_3
|
|
5481
|
+
|
|
5482
|
+
// Success path
|
|
5483
|
+
pinepaper_create_diagram_shape
|
|
5484
|
+
shapeType: "process"
|
|
5485
|
+
position: {x: 250, y: 420}
|
|
5486
|
+
label: "Process Data"
|
|
5487
|
+
style: {fillColor: "#3b82f6", strokeColor: "#2563eb"}
|
|
5488
|
+
→ item_4
|
|
5489
|
+
|
|
5490
|
+
// Error path
|
|
5491
|
+
pinepaper_create_diagram_shape
|
|
5492
|
+
shapeType: "process"
|
|
5493
|
+
position: {x: 550, y: 420}
|
|
5494
|
+
label: "Show Error"
|
|
5495
|
+
style: {fillColor: "#ef4444", strokeColor: "#dc2626"}
|
|
5496
|
+
→ item_5
|
|
5497
|
+
|
|
5498
|
+
// End terminal
|
|
5499
|
+
pinepaper_create_diagram_shape
|
|
5500
|
+
shapeType: "terminal"
|
|
5501
|
+
position: {x: 400, y: 540}
|
|
5502
|
+
label: "End"
|
|
5503
|
+
style: {fillColor: "#6b7280", strokeColor: "#4b5563"}
|
|
5504
|
+
→ item_6
|
|
5505
|
+
\`\`\`
|
|
5506
|
+
|
|
5507
|
+
## Step 2: Connect Shapes
|
|
5508
|
+
|
|
5509
|
+
\`\`\`
|
|
5510
|
+
// Start to Check
|
|
5511
|
+
pinepaper_connect
|
|
5512
|
+
sourceItemId: "item_1"
|
|
5513
|
+
targetItemId: "item_2"
|
|
5514
|
+
routing: "orthogonal"
|
|
5515
|
+
lineColor: "#374151"
|
|
5516
|
+
|
|
5517
|
+
// Check to Decision
|
|
5518
|
+
pinepaper_connect
|
|
5519
|
+
sourceItemId: "item_2"
|
|
5520
|
+
targetItemId: "item_3"
|
|
5521
|
+
routing: "orthogonal"
|
|
5522
|
+
lineColor: "#374151"
|
|
5523
|
+
|
|
5524
|
+
// Decision Yes path
|
|
5525
|
+
pinepaper_connect
|
|
5526
|
+
sourceItemId: "item_3"
|
|
5527
|
+
targetItemId: "item_4"
|
|
5528
|
+
routing: "orthogonal"
|
|
5529
|
+
lineColor: "#22c55e"
|
|
5530
|
+
label: "Yes"
|
|
5531
|
+
|
|
5532
|
+
// Decision No path
|
|
5533
|
+
pinepaper_connect
|
|
5534
|
+
sourceItemId: "item_3"
|
|
5535
|
+
targetItemId: "item_5"
|
|
5536
|
+
routing: "orthogonal"
|
|
5537
|
+
lineColor: "#ef4444"
|
|
5538
|
+
label: "No"
|
|
5539
|
+
|
|
5540
|
+
// Process to End
|
|
5541
|
+
pinepaper_connect
|
|
5542
|
+
sourceItemId: "item_4"
|
|
5543
|
+
targetItemId: "item_6"
|
|
5544
|
+
routing: "orthogonal"
|
|
5545
|
+
lineColor: "#374151"
|
|
5546
|
+
|
|
5547
|
+
// Error to End
|
|
5548
|
+
pinepaper_connect
|
|
5549
|
+
sourceItemId: "item_5"
|
|
5550
|
+
targetItemId: "item_6"
|
|
5551
|
+
routing: "orthogonal"
|
|
5552
|
+
lineColor: "#374151"
|
|
5553
|
+
\`\`\`
|
|
5554
|
+
|
|
5555
|
+
## Step 3: Apply Auto-Layout (Optional)
|
|
5556
|
+
|
|
5557
|
+
\`\`\`
|
|
5558
|
+
pinepaper_auto_layout
|
|
5559
|
+
direction: "TB"
|
|
5560
|
+
spacing: {horizontal: 100, vertical: 80}
|
|
5561
|
+
\`\`\`
|
|
5562
|
+
|
|
5563
|
+
## Adding Animation
|
|
5564
|
+
|
|
5565
|
+
Make connectors animated to show flow direction:
|
|
5566
|
+
|
|
5567
|
+
\`\`\`
|
|
5568
|
+
pinepaper_connect
|
|
5569
|
+
sourceItemId: "item_1"
|
|
5570
|
+
targetItemId: "item_2"
|
|
5571
|
+
animated: true // Bolt effect shows direction
|
|
5572
|
+
lineColor: "#3b82f6"
|
|
5573
|
+
\`\`\`
|
|
5574
|
+
|
|
5575
|
+
## Key Tools Used
|
|
5576
|
+
|
|
5577
|
+
| Tool | Purpose |
|
|
5578
|
+
|------|---------|
|
|
5579
|
+
| \`pinepaper_create_diagram_shape\` | Create flowchart symbols |
|
|
5580
|
+
| \`pinepaper_connect\` | Draw smart connectors |
|
|
5581
|
+
| \`pinepaper_auto_layout\` | Automatic arrangement |
|
|
5582
|
+
|
|
5583
|
+
## Shape Reference
|
|
5584
|
+
|
|
5585
|
+
| Shape | Symbol | Use For |
|
|
5586
|
+
|-------|--------|---------|
|
|
5587
|
+
| \`terminal\` | Rounded rectangle | Start/End |
|
|
5588
|
+
| \`process\` | Rectangle | Actions |
|
|
5589
|
+
| \`decision\` | Diamond | Yes/No branching |
|
|
5590
|
+
| \`data\` | Parallelogram | Input/Output |
|
|
5591
|
+
| \`document\` | Wavy rectangle | Documents |
|
|
5592
|
+
`,
|
|
5593
|
+
'pinepaper://examples/reveal-animation': `# Reveal Animation Example
|
|
5594
|
+
|
|
5595
|
+
**Intent:** Create a text reveal animation using mask effects.
|
|
5596
|
+
|
|
5597
|
+
## What You'll Build
|
|
5598
|
+
|
|
5599
|
+
Text that reveals with a smooth wipe animation, perfect for intros and titles.
|
|
5600
|
+
|
|
5601
|
+
## Method 1: Simple Preset
|
|
5602
|
+
|
|
5603
|
+
\`\`\`
|
|
5604
|
+
// Create text
|
|
5605
|
+
pinepaper_create_item
|
|
5606
|
+
itemType: "text"
|
|
5607
|
+
position: {x: 400, y: 300}
|
|
5608
|
+
properties:
|
|
5609
|
+
content: "Welcome"
|
|
5610
|
+
fontSize: 64
|
|
5611
|
+
fontWeight: "bold"
|
|
5612
|
+
color: "#ffffff"
|
|
5613
|
+
→ item_1
|
|
5614
|
+
|
|
5615
|
+
// Apply wipe reveal
|
|
5616
|
+
pinepaper_apply_animated_mask
|
|
5617
|
+
itemId: "item_1"
|
|
5618
|
+
preset: "wipeLeft"
|
|
5619
|
+
options:
|
|
5620
|
+
duration: 0.6
|
|
5621
|
+
easing: "easeOut"
|
|
5622
|
+
\`\`\`
|
|
5623
|
+
|
|
5624
|
+
## Method 2: Staggered Word Reveal
|
|
5625
|
+
|
|
5626
|
+
\`\`\`
|
|
5627
|
+
// Word 1
|
|
5628
|
+
pinepaper_create_item itemType: "text" position: {x: 200, y: 300}
|
|
5629
|
+
properties: {content: "Create", fontSize: 48, color: "#3b82f6"}
|
|
5630
|
+
→ item_1
|
|
5631
|
+
|
|
5632
|
+
// Word 2
|
|
5633
|
+
pinepaper_create_item itemType: "text" position: {x: 370, y: 300}
|
|
5634
|
+
properties: {content: "Beautiful", fontSize: 48, color: "#8b5cf6"}
|
|
5635
|
+
→ item_2
|
|
5636
|
+
|
|
5637
|
+
// Word 3
|
|
5638
|
+
pinepaper_create_item itemType: "text" position: {x: 580, y: 300}
|
|
5639
|
+
properties: {content: "Graphics", fontSize: 48, color: "#ec4899"}
|
|
5640
|
+
→ item_3
|
|
5641
|
+
|
|
5642
|
+
// Staggered reveals
|
|
5643
|
+
pinepaper_apply_animated_mask itemId: "item_1" preset: "wipeUp"
|
|
5644
|
+
options: {startTime: 0, duration: 0.4, easing: "easeOut"}
|
|
5645
|
+
|
|
5646
|
+
pinepaper_apply_animated_mask itemId: "item_2" preset: "wipeUp"
|
|
5647
|
+
options: {startTime: 0.15, duration: 0.4, easing: "easeOut"}
|
|
5648
|
+
|
|
5649
|
+
pinepaper_apply_animated_mask itemId: "item_3" preset: "wipeUp"
|
|
5650
|
+
options: {startTime: 0.3, duration: 0.4, easing: "easeOut"}
|
|
5651
|
+
\`\`\`
|
|
5652
|
+
|
|
5653
|
+
## Method 3: Iris Reveal for Images
|
|
5654
|
+
|
|
5655
|
+
\`\`\`
|
|
5656
|
+
// Create a shape or import image
|
|
5657
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300}
|
|
5658
|
+
properties: {radius: 100, color: "#3b82f6"}
|
|
5659
|
+
→ item_1
|
|
5660
|
+
|
|
5661
|
+
// Iris reveal from center
|
|
5662
|
+
pinepaper_apply_animated_mask
|
|
5663
|
+
itemId: "item_1"
|
|
5664
|
+
preset: "iris"
|
|
5665
|
+
options:
|
|
5666
|
+
duration: 0.8
|
|
5667
|
+
easing: "easeOut"
|
|
5668
|
+
\`\`\`
|
|
5669
|
+
|
|
5670
|
+
## Method 4: Cinematic Letterbox
|
|
5671
|
+
|
|
5672
|
+
\`\`\`
|
|
5673
|
+
// Create main content
|
|
5674
|
+
pinepaper_create_item itemType: "rectangle" position: {x: 400, y: 300}
|
|
5675
|
+
properties: {width: 600, height: 300, color: "#1e40af"}
|
|
5676
|
+
→ item_1
|
|
5677
|
+
|
|
5678
|
+
// Cinematic reveal (letterbox bars animate away)
|
|
5679
|
+
pinepaper_apply_animated_mask
|
|
5680
|
+
itemId: "item_1"
|
|
5681
|
+
preset: "cinematic"
|
|
5682
|
+
options:
|
|
5683
|
+
duration: 1.2
|
|
5684
|
+
easing: "easeInOut"
|
|
5685
|
+
\`\`\`
|
|
5686
|
+
|
|
5687
|
+
## Available Presets
|
|
5688
|
+
|
|
5689
|
+
| Preset | Effect | Best For |
|
|
5690
|
+
|--------|--------|----------|
|
|
5691
|
+
| \`wipeLeft\` | Left to right | Text, titles |
|
|
5692
|
+
| \`wipeRight\` | Right to left | Text |
|
|
5693
|
+
| \`wipeUp\` | Bottom to top | Credits, lists |
|
|
5694
|
+
| \`wipeDown\` | Top to bottom | Headers |
|
|
5695
|
+
| \`iris\` | Circle from center | Images, focus |
|
|
5696
|
+
| \`irisOut\` | Circle shrinks | Transitions out |
|
|
5697
|
+
| \`star\` | Star shape reveal | Fun, playful |
|
|
5698
|
+
| \`heart\` | Heart shape reveal | Love themes |
|
|
5699
|
+
| \`curtainHorizontal\` | Opens from center | Stage, dramatic |
|
|
5700
|
+
| \`curtainVertical\` | Opens vertically | Reveals |
|
|
5701
|
+
| \`cinematic\` | Letterbox effect | Film style |
|
|
5702
|
+
| \`diagonalWipe\` | Angled wipe | Dynamic |
|
|
5703
|
+
|
|
5704
|
+
## Combining with Other Animations
|
|
5705
|
+
|
|
5706
|
+
\`\`\`
|
|
5707
|
+
// Create text
|
|
5708
|
+
pinepaper_create_item itemType: "text" position: {x: 400, y: 300}
|
|
5709
|
+
properties: {content: "Animated!", fontSize: 48}
|
|
5710
|
+
→ item_1
|
|
5711
|
+
|
|
5712
|
+
// Apply mask reveal
|
|
5713
|
+
pinepaper_apply_animated_mask itemId: "item_1" preset: "wipeLeft"
|
|
5714
|
+
options: {duration: 0.5}
|
|
5715
|
+
|
|
5716
|
+
// Add pulse animation after reveal
|
|
5717
|
+
pinepaper_animate_item itemId: "item_1" animationType: "pulse" speed: 0.5
|
|
5718
|
+
\`\`\`
|
|
5719
|
+
|
|
5720
|
+
## Key Tools
|
|
5721
|
+
|
|
5722
|
+
| Tool | Purpose |
|
|
5723
|
+
|------|---------|
|
|
5724
|
+
| \`pinepaper_apply_animated_mask\` | Apply reveal preset |
|
|
5725
|
+
| \`pinepaper_get_mask_animations\` | List all presets |
|
|
5726
|
+
| \`pinepaper_remove_mask\` | Remove mask effect |
|
|
5727
|
+
`,
|
|
5728
|
+
};
|
|
5729
|
+
// =============================================================================
|
|
5730
|
+
// SERVER CREATION
|
|
5731
|
+
// =============================================================================
|
|
5732
|
+
export async function createServer(options = {}) {
|
|
5733
|
+
// Initialize i18n with specified locale
|
|
5734
|
+
const locale = options.locale || detectLocaleFromEnvironment();
|
|
5735
|
+
const verbosity = options.verbosity || detectVerbosityFromEnvironment();
|
|
5736
|
+
const i18n = await initI18n(locale);
|
|
5737
|
+
const tools = getToolsForVerbosity(verbosity);
|
|
5738
|
+
const server = new Server(SERVER_INFO, {
|
|
5739
|
+
capabilities: {
|
|
5740
|
+
tools: {},
|
|
5741
|
+
resources: {},
|
|
5742
|
+
prompts: {},
|
|
5743
|
+
},
|
|
5744
|
+
});
|
|
5745
|
+
// ---------------------------------------------------------------------------
|
|
3201
5746
|
// TOOL HANDLERS
|
|
3202
5747
|
// ---------------------------------------------------------------------------
|
|
3203
|
-
// List available tools (with optional localization)
|
|
5748
|
+
// List available tools (with optional localization and verbosity)
|
|
3204
5749
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
3205
5750
|
// Tool descriptions are kept in English for AI understanding
|
|
3206
|
-
//
|
|
5751
|
+
// Compact mode trims the 13 largest descriptions to save ~5K tokens
|
|
3207
5752
|
return {
|
|
3208
|
-
tools
|
|
5753
|
+
tools,
|
|
3209
5754
|
};
|
|
3210
5755
|
});
|
|
3211
5756
|
// Handle tool calls with i18n support for errors and success messages
|
|
@@ -3247,6 +5792,16 @@ export async function createServer(options = {}) {
|
|
|
3247
5792
|
],
|
|
3248
5793
|
};
|
|
3249
5794
|
});
|
|
5795
|
+
// ---------------------------------------------------------------------------
|
|
5796
|
+
// PROMPT HANDLERS
|
|
5797
|
+
// ---------------------------------------------------------------------------
|
|
5798
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
5799
|
+
return { prompts: PROMPTS };
|
|
5800
|
+
});
|
|
5801
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
5802
|
+
const { name, arguments: args } = request.params;
|
|
5803
|
+
return getPromptMessages(name, args);
|
|
5804
|
+
});
|
|
3250
5805
|
return server;
|
|
3251
5806
|
}
|
|
3252
5807
|
// =============================================================================
|
|
@@ -3277,6 +5832,13 @@ function detectLocaleFromEnvironment() {
|
|
|
3277
5832
|
}
|
|
3278
5833
|
return DEFAULT_LOCALE;
|
|
3279
5834
|
}
|
|
5835
|
+
/**
|
|
5836
|
+
* Detect tool description verbosity from environment.
|
|
5837
|
+
* Set PINEPAPER_TOOL_VERBOSITY=compact to use trimmed descriptions (~5K tokens saved).
|
|
5838
|
+
*/
|
|
5839
|
+
function detectVerbosityFromEnvironment() {
|
|
5840
|
+
return process.env.PINEPAPER_TOOL_VERBOSITY === 'compact' ? 'compact' : 'verbose';
|
|
5841
|
+
}
|
|
3280
5842
|
/**
|
|
3281
5843
|
* Check if a string is a valid supported locale
|
|
3282
5844
|
*/
|
|
@@ -3331,19 +5893,27 @@ function isValidLocale(locale) {
|
|
|
3331
5893
|
// =============================================================================
|
|
3332
5894
|
async function main() {
|
|
3333
5895
|
const locale = detectLocaleFromEnvironment();
|
|
3334
|
-
const
|
|
5896
|
+
const verbosity = detectVerbosityFromEnvironment();
|
|
5897
|
+
const server = await createServer({ locale, verbosity });
|
|
3335
5898
|
const transport = new StdioServerTransport();
|
|
3336
5899
|
console.error('PinePaper MCP Server starting...');
|
|
3337
5900
|
console.error(`Version: ${SERVER_INFO.version}`);
|
|
3338
5901
|
console.error(`Locale: ${locale}`);
|
|
5902
|
+
console.error(`Verbosity: ${verbosity}`);
|
|
3339
5903
|
console.error(`Tools: ${PINEPAPER_TOOLS.length}`);
|
|
3340
5904
|
console.error(`Resources: ${RESOURCES.length}`);
|
|
3341
5905
|
await server.connect(transport);
|
|
3342
5906
|
console.error('PinePaper MCP Server running on stdio');
|
|
3343
5907
|
}
|
|
3344
|
-
// Run if executed directly
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
5908
|
+
// Run if executed directly (not when imported by cli.ts or other modules)
|
|
5909
|
+
// Check: Node uses process.argv[1], Bun supports import.meta.main
|
|
5910
|
+
const isDirectExecution = typeof import.meta.main === 'boolean'
|
|
5911
|
+
? import.meta.main
|
|
5912
|
+
: process.argv[1]?.replace(/\\/g, '/').endsWith('index.js');
|
|
5913
|
+
if (isDirectExecution) {
|
|
5914
|
+
main().catch((error) => {
|
|
5915
|
+
console.error('Fatal error:', error);
|
|
5916
|
+
process.exit(1);
|
|
5917
|
+
});
|
|
5918
|
+
}
|
|
3349
5919
|
//# sourceMappingURL=index.js.map
|