@pinepaper.studio/mcp-server 1.1.0 → 1.2.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/dist/index.d.ts.map +1 -1
- package/dist/index.js +2899 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -45,10 +45,58 @@ const RESOURCES = [
|
|
|
45
45
|
description: 'Available procedural background generators',
|
|
46
46
|
mimeType: 'text/markdown',
|
|
47
47
|
},
|
|
48
|
+
{
|
|
49
|
+
uri: 'pinepaper://docs/custom-paths',
|
|
50
|
+
name: 'Custom Paths Guide',
|
|
51
|
+
description: 'Advanced path creation with SVG, Paper.js paths, and animations',
|
|
52
|
+
mimeType: 'text/markdown',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
uri: 'pinepaper://docs/mathematical-patterns',
|
|
56
|
+
name: 'Mathematical Patterns',
|
|
57
|
+
description: 'Create spirals, waves, fractals, geometric patterns, and physics simulations',
|
|
58
|
+
mimeType: 'text/markdown',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
uri: 'pinepaper://docs/effects-and-filters',
|
|
62
|
+
name: 'Effects & Filters Guide',
|
|
63
|
+
description: 'Complete reference for visual effects, filters, and post-processing',
|
|
64
|
+
mimeType: 'text/markdown',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
uri: 'pinepaper://docs/interactive-animations',
|
|
68
|
+
name: 'Interactive Animations',
|
|
69
|
+
description: 'Create game-like behaviors with follows, bounds, and dynamic interactions',
|
|
70
|
+
mimeType: 'text/markdown',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
uri: 'pinepaper://docs/paperjs-in-pinepaper',
|
|
74
|
+
name: 'Paper.js in PinePaper',
|
|
75
|
+
description: 'Write Paper.js code directly in PinePaper - API reference and examples',
|
|
76
|
+
mimeType: 'text/markdown',
|
|
77
|
+
},
|
|
48
78
|
{
|
|
49
79
|
uri: 'pinepaper://examples/solar-system',
|
|
50
80
|
name: 'Solar System Example',
|
|
51
|
-
description: 'Create an animated solar system with
|
|
81
|
+
description: 'Create an animated solar system with custom paths, orbital rings, and planetary details',
|
|
82
|
+
mimeType: 'text/markdown',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
uri: 'pinepaper://examples/logo-animation',
|
|
86
|
+
name: 'Logo Animation Example',
|
|
87
|
+
description: 'Animate a company logo with entrance effects and continuous motion',
|
|
88
|
+
mimeType: 'text/markdown',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
uri: 'pinepaper://examples/data-visualization',
|
|
92
|
+
name: 'Data Visualization Example',
|
|
93
|
+
description: 'Create animated charts, graphs, and infographics',
|
|
94
|
+
mimeType: 'text/markdown',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
uri: 'pinepaper://examples/particle-systems',
|
|
98
|
+
name: 'Particle Systems Example',
|
|
99
|
+
description: 'Build particle effects like fireworks, snow, and starfields',
|
|
52
100
|
mimeType: 'text/markdown',
|
|
53
101
|
},
|
|
54
102
|
];
|
|
@@ -259,55 +307,2881 @@ Tech circuit board.
|
|
|
259
307
|
- \`density\`: 0-1 complexity
|
|
260
308
|
- \`animated\`: Enable bolt effect
|
|
261
309
|
`,
|
|
262
|
-
'pinepaper://
|
|
310
|
+
'pinepaper://docs/custom-paths': `# Custom Paths Guide
|
|
311
|
+
|
|
312
|
+
Every item in PinePaper is ultimately a Paper.js path. This guide covers advanced path creation techniques including SVG import, custom segments, and path animation.
|
|
313
|
+
|
|
314
|
+
## Understanding Paths in PinePaper
|
|
315
|
+
|
|
316
|
+
PinePaper uses Paper.js under the hood. All shapes (circles, stars, rectangles) are paths with specific segment configurations. You can create any shape by defining custom paths.
|
|
317
|
+
|
|
318
|
+
## Path Creation Methods
|
|
319
|
+
|
|
320
|
+
### Method 1: Segment-Based Paths (Polygons)
|
|
321
|
+
|
|
322
|
+
Use the \`path\` item type with \`segments\` to create polygons from coordinate points:
|
|
323
|
+
|
|
324
|
+
\`\`\`
|
|
325
|
+
pinepaper_create_item
|
|
326
|
+
itemType: "path"
|
|
327
|
+
position: {x: 400, y: 300}
|
|
328
|
+
properties:
|
|
329
|
+
segments: [[0, -50], [50, 50], [-50, 50]] // Triangle
|
|
330
|
+
closed: true
|
|
331
|
+
fillColor: "#3b82f6"
|
|
332
|
+
strokeColor: "#1e40af"
|
|
333
|
+
strokeWidth: 2
|
|
334
|
+
\`\`\`
|
|
335
|
+
|
|
336
|
+
Each segment is an [x, y] coordinate relative to the item's position.
|
|
337
|
+
|
|
338
|
+
**Examples:**
|
|
339
|
+
- Triangle: \`[[0, -50], [50, 50], [-50, 50]]\`
|
|
340
|
+
- Diamond: \`[[0, -60], [40, 0], [0, 60], [-40, 0]]\`
|
|
341
|
+
- Arrow: \`[[0, -40], [30, 20], [10, 20], [10, 60], [-10, 60], [-10, 20], [-30, 20]]\`
|
|
342
|
+
- Hexagon: \`[[30, -52], [60, 0], [30, 52], [-30, 52], [-60, 0], [-30, -52]]\`
|
|
343
|
+
|
|
344
|
+
### Method 2: SVG Path Data (Bezier Curves)
|
|
345
|
+
|
|
346
|
+
Use \`pathData\` for complex curves using SVG path syntax:
|
|
347
|
+
|
|
348
|
+
\`\`\`
|
|
349
|
+
pinepaper_create_item
|
|
350
|
+
itemType: "path"
|
|
351
|
+
position: {x: 400, y: 300}
|
|
352
|
+
properties:
|
|
353
|
+
pathData: "M 0 -50 C 50 -50 50 50 0 50 C -50 50 -50 -50 0 -50"
|
|
354
|
+
fillColor: "#ec4899"
|
|
355
|
+
strokeWidth: 0
|
|
356
|
+
\`\`\`
|
|
357
|
+
|
|
358
|
+
**SVG Path Commands:**
|
|
359
|
+
- \`M x y\` - Move to (start point)
|
|
360
|
+
- \`L x y\` - Line to
|
|
361
|
+
- \`C x1 y1 x2 y2 x y\` - Cubic Bezier curve
|
|
362
|
+
- \`Q x1 y1 x y\` - Quadratic Bezier curve
|
|
363
|
+
- \`A rx ry rotation large-arc sweep x y\` - Arc
|
|
364
|
+
- \`Z\` - Close path
|
|
365
|
+
|
|
366
|
+
**Example Shapes with pathData:**
|
|
367
|
+
\`\`\`
|
|
368
|
+
// Heart shape
|
|
369
|
+
pathData: "M 0 -30 C -30 -60 -60 -30 -60 0 C -60 30 -30 60 0 80 C 30 60 60 30 60 0 C 60 -30 30 -60 0 -30"
|
|
370
|
+
|
|
371
|
+
// Smooth wave
|
|
372
|
+
pathData: "M -100 0 Q -50 -40 0 0 Q 50 40 100 0"
|
|
373
|
+
|
|
374
|
+
// Crescent moon
|
|
375
|
+
pathData: "M 0 -50 A 50 50 0 1 1 0 50 A 35 35 0 1 0 0 -50"
|
|
376
|
+
\`\`\`
|
|
377
|
+
|
|
378
|
+
### Method 3: Smooth Paths
|
|
379
|
+
|
|
380
|
+
Add \`smooth: true\` to automatically smooth segment connections:
|
|
381
|
+
|
|
382
|
+
\`\`\`
|
|
383
|
+
pinepaper_create_item
|
|
384
|
+
itemType: "path"
|
|
385
|
+
properties:
|
|
386
|
+
segments: [[0, 0], [50, -30], [100, 0], [150, 30], [200, 0]]
|
|
387
|
+
smooth: true
|
|
388
|
+
closed: false
|
|
389
|
+
strokeColor: "#10b981"
|
|
390
|
+
strokeWidth: 3
|
|
391
|
+
fillColor: null
|
|
392
|
+
\`\`\`
|
|
393
|
+
|
|
394
|
+
### Method 4: Lines and Arcs
|
|
395
|
+
|
|
396
|
+
**Simple Line:**
|
|
397
|
+
\`\`\`
|
|
398
|
+
pinepaper_create_item
|
|
399
|
+
itemType: "line"
|
|
400
|
+
properties:
|
|
401
|
+
from: [100, 100]
|
|
402
|
+
to: [300, 200]
|
|
403
|
+
strokeColor: "#f59e0b"
|
|
404
|
+
strokeWidth: 2
|
|
405
|
+
\`\`\`
|
|
406
|
+
|
|
407
|
+
**Arc (through 3 points):**
|
|
408
|
+
\`\`\`
|
|
409
|
+
pinepaper_create_item
|
|
410
|
+
itemType: "arc"
|
|
411
|
+
properties:
|
|
412
|
+
from: [100, 300]
|
|
413
|
+
through: [200, 200]
|
|
414
|
+
to: [300, 300]
|
|
415
|
+
strokeColor: "#8b5cf6"
|
|
416
|
+
strokeWidth: 3
|
|
417
|
+
\`\`\`
|
|
418
|
+
|
|
419
|
+
## Importing SVGs
|
|
420
|
+
|
|
421
|
+
### Import SVG from String
|
|
422
|
+
|
|
423
|
+
\`\`\`
|
|
424
|
+
pinepaper_import_svg
|
|
425
|
+
svgString: "<svg viewBox='0 0 100 100'><circle cx='50' cy='50' r='40' fill='#ff6b6b'/></svg>"
|
|
426
|
+
position: {x: 400, y: 300}
|
|
427
|
+
scale: 2.0
|
|
428
|
+
\`\`\`
|
|
429
|
+
|
|
430
|
+
### Import SVG from URL
|
|
431
|
+
|
|
432
|
+
\`\`\`
|
|
433
|
+
pinepaper_import_svg
|
|
434
|
+
url: "https://example.com/icon.svg"
|
|
435
|
+
position: {x: 400, y: 300}
|
|
436
|
+
scale: 1.5
|
|
437
|
+
\`\`\`
|
|
438
|
+
|
|
439
|
+
**Tips for SVG Import:**
|
|
440
|
+
- Imported SVGs become Paper.js Group items
|
|
441
|
+
- Use \`scale\` to resize (1.0 = original size)
|
|
442
|
+
- Position is the center point of the imported SVG
|
|
443
|
+
- Complex SVGs with many paths work best when simplified first
|
|
444
|
+
|
|
445
|
+
## Animating Paths
|
|
446
|
+
|
|
447
|
+
### Relation-Based Animation (Recommended)
|
|
448
|
+
|
|
449
|
+
Paths can use all standard relations:
|
|
450
|
+
|
|
451
|
+
\`\`\`
|
|
452
|
+
// Make a custom arrow orbit around a center point
|
|
453
|
+
pinepaper_create_item itemType: "path" properties: {segments: [...], closed: true}
|
|
454
|
+
→ Returns item_1 (arrow)
|
|
455
|
+
|
|
456
|
+
pinepaper_create_item itemType: "circle" properties: {radius: 10}
|
|
457
|
+
→ Returns item_2 (center)
|
|
458
|
+
|
|
459
|
+
pinepaper_add_relation
|
|
460
|
+
sourceId: "item_1"
|
|
461
|
+
targetId: "item_2"
|
|
462
|
+
relationType: "orbits"
|
|
463
|
+
params: {radius: 100, speed: 0.5}
|
|
464
|
+
\`\`\`
|
|
465
|
+
|
|
466
|
+
### Keyframe Animation for Paths
|
|
467
|
+
|
|
468
|
+
Animate path properties over time:
|
|
469
|
+
|
|
470
|
+
\`\`\`
|
|
471
|
+
pinepaper_keyframe_animate
|
|
472
|
+
itemId: "item_1"
|
|
473
|
+
keyframes:
|
|
474
|
+
- time: 0
|
|
475
|
+
properties: {opacity: 1, scaling: 1}
|
|
476
|
+
- time: 1
|
|
477
|
+
properties: {opacity: 0.5, scaling: 1.2}
|
|
478
|
+
- time: 2
|
|
479
|
+
properties: {opacity: 1, scaling: 1}
|
|
480
|
+
duration: 2
|
|
481
|
+
loop: true
|
|
482
|
+
\`\`\`
|
|
483
|
+
|
|
484
|
+
**Animatable Path Properties:**
|
|
485
|
+
- \`opacity\` - Transparency (0-1)
|
|
486
|
+
- \`scaling\` - Size multiplier
|
|
487
|
+
- \`rotation\` - Rotation in degrees
|
|
488
|
+
- \`position.x\`, \`position.y\` - Position
|
|
489
|
+
- \`strokeWidth\` - Line thickness
|
|
490
|
+
- \`strokeColor\`, \`fillColor\` - Colors (as hex strings)
|
|
491
|
+
|
|
492
|
+
### Simple Loop Animations
|
|
493
|
+
|
|
494
|
+
\`\`\`
|
|
495
|
+
pinepaper_animate_item
|
|
496
|
+
itemId: "item_1"
|
|
497
|
+
animationType: "pulse" // or: rotate, bounce, fade, wobble
|
|
498
|
+
speed: 1.5
|
|
499
|
+
\`\`\`
|
|
500
|
+
|
|
501
|
+
## Drawing Orbital Rings
|
|
502
|
+
|
|
503
|
+
Create visible orbital path rings (not just invisible orbit relations):
|
|
504
|
+
|
|
505
|
+
\`\`\`
|
|
506
|
+
// Draw a dashed orbital ring
|
|
507
|
+
pinepaper_create_item
|
|
508
|
+
itemType: "circle"
|
|
509
|
+
position: {x: 400, y: 300}
|
|
510
|
+
properties:
|
|
511
|
+
radius: 150
|
|
512
|
+
fillColor: null // No fill - ring only
|
|
513
|
+
strokeColor: "#374151"
|
|
514
|
+
strokeWidth: 1
|
|
515
|
+
\`\`\`
|
|
516
|
+
|
|
517
|
+
For elliptical orbits, use an ellipse or path:
|
|
518
|
+
|
|
519
|
+
\`\`\`
|
|
520
|
+
pinepaper_create_item
|
|
521
|
+
itemType: "ellipse"
|
|
522
|
+
position: {x: 400, y: 300}
|
|
523
|
+
properties:
|
|
524
|
+
width: 300
|
|
525
|
+
height: 150
|
|
526
|
+
fillColor: null
|
|
527
|
+
strokeColor: "#4b5563"
|
|
528
|
+
strokeWidth: 1
|
|
529
|
+
\`\`\`
|
|
530
|
+
|
|
531
|
+
## Creating Complex Shapes
|
|
532
|
+
|
|
533
|
+
### Compound Paths (Multiple Subpaths)
|
|
534
|
+
|
|
535
|
+
For shapes with holes, use SVG path data with multiple subpaths:
|
|
536
|
+
|
|
537
|
+
\`\`\`
|
|
538
|
+
// Ring/donut shape (outer circle + inner circle cutout)
|
|
539
|
+
pathData: "M 0 -50 A 50 50 0 1 1 0 50 A 50 50 0 1 1 0 -50 M 0 -25 A 25 25 0 1 0 0 25 A 25 25 0 1 0 0 -25"
|
|
540
|
+
\`\`\`
|
|
541
|
+
|
|
542
|
+
### Planetary Surface Details
|
|
543
|
+
|
|
544
|
+
Create texture details with multiple paths:
|
|
545
|
+
|
|
546
|
+
\`\`\`
|
|
547
|
+
// Planet with crater
|
|
548
|
+
1. Main planet: circle with fillColor
|
|
549
|
+
2. Crater: smaller ellipse with darker fillColor, attached_to planet
|
|
550
|
+
3. Highlight: arc with light strokeColor, attached_to planet
|
|
551
|
+
\`\`\`
|
|
552
|
+
|
|
553
|
+
## Exporting Paths
|
|
554
|
+
|
|
555
|
+
### Export as Animated SVG
|
|
556
|
+
|
|
557
|
+
\`\`\`
|
|
558
|
+
pinepaper_export_svg
|
|
559
|
+
animated: true
|
|
560
|
+
\`\`\`
|
|
561
|
+
|
|
562
|
+
Returns SVG with embedded \`<animate>\` elements for CSS/SMIL animation.
|
|
563
|
+
|
|
564
|
+
### Export Training Data
|
|
565
|
+
|
|
566
|
+
\`\`\`
|
|
567
|
+
pinepaper_export_training_data
|
|
568
|
+
format: "jsonl"
|
|
569
|
+
includeMetadata: true
|
|
570
|
+
\`\`\`
|
|
571
|
+
|
|
572
|
+
## Best Practices
|
|
573
|
+
|
|
574
|
+
1. **Use relative coordinates** in segments - they're relative to item position
|
|
575
|
+
2. **Start simple** - Begin with segments, graduate to pathData for curves
|
|
576
|
+
3. **Test with screenshots** - Use \`pinepaper_browser_screenshot\` after each path
|
|
577
|
+
4. **Combine with relations** - Custom paths animate beautifully with orbits/follows
|
|
578
|
+
5. **Layer paths** - Build complex visuals from multiple simple paths
|
|
579
|
+
6. **Use smooth: true** - For organic, flowing curves from point data
|
|
580
|
+
`,
|
|
581
|
+
'pinepaper://examples/solar-system': `# Solar System Example (Advanced)
|
|
582
|
+
|
|
583
|
+
Create an animated solar system featuring custom paths, orbital rings, and planetary details.
|
|
584
|
+
|
|
585
|
+
## What You'll Learn
|
|
586
|
+
|
|
587
|
+
- Drawing orbital ring paths
|
|
588
|
+
- Creating planets with surface details using paths
|
|
589
|
+
- Using SVG path data for complex shapes
|
|
590
|
+
- Combining paths with relation-based animation
|
|
591
|
+
- Building layered visual compositions
|
|
592
|
+
|
|
593
|
+
## Step 1: Canvas Setup
|
|
594
|
+
|
|
595
|
+
\`\`\`
|
|
596
|
+
pinepaper_browser_connect
|
|
597
|
+
pinepaper_clear_canvas
|
|
598
|
+
pinepaper_set_background_color color: "#0a0a1a"
|
|
599
|
+
\`\`\`
|
|
600
|
+
|
|
601
|
+
## Step 2: Create the Sun with Corona Effect
|
|
602
|
+
|
|
603
|
+
First, create a glowing corona using a custom path:
|
|
263
604
|
|
|
264
|
-
|
|
605
|
+
\`\`\`
|
|
606
|
+
pinepaper_create_item
|
|
607
|
+
itemType: "path"
|
|
608
|
+
position: {x: 400, y: 300}
|
|
609
|
+
properties:
|
|
610
|
+
pathData: "M 0 -80 Q 20 -60 0 -40 Q -20 -60 0 -80 M 57 -57 Q 50 -35 28 -28 Q 35 -50 57 -57 M 80 0 Q 60 20 40 0 Q 60 -20 80 0 M 57 57 Q 35 50 28 28 Q 50 35 57 57 M 0 80 Q -20 60 0 40 Q 20 60 0 80 M -57 57 Q -50 35 -28 28 Q -35 50 -57 57 M -80 0 Q -60 -20 -40 0 Q -60 20 -80 0 M -57 -57 Q -35 -50 -28 -28 Q -50 -35 -57 -57"
|
|
611
|
+
strokeColor: "#fbbf24"
|
|
612
|
+
strokeWidth: 3
|
|
613
|
+
fillColor: null
|
|
614
|
+
→ Returns item_1 (corona rays)
|
|
615
|
+
\`\`\`
|
|
616
|
+
|
|
617
|
+
Now create the sun body:
|
|
618
|
+
|
|
619
|
+
\`\`\`
|
|
620
|
+
pinepaper_create_item
|
|
621
|
+
itemType: "circle"
|
|
622
|
+
position: {x: 400, y: 300}
|
|
623
|
+
properties:
|
|
624
|
+
radius: 50
|
|
625
|
+
color: "#f59e0b"
|
|
626
|
+
→ Returns item_2 (sun body)
|
|
627
|
+
\`\`\`
|
|
628
|
+
|
|
629
|
+
Animate the corona:
|
|
630
|
+
|
|
631
|
+
\`\`\`
|
|
632
|
+
pinepaper_animate_item
|
|
633
|
+
itemId: "item_1"
|
|
634
|
+
animationType: "rotate"
|
|
635
|
+
speed: 0.2
|
|
636
|
+
\`\`\`
|
|
637
|
+
|
|
638
|
+
## Step 3: Draw Visible Orbital Rings
|
|
639
|
+
|
|
640
|
+
Create orbital path rings so users can see the orbits:
|
|
641
|
+
|
|
642
|
+
\`\`\`
|
|
643
|
+
// Mercury's orbit ring
|
|
644
|
+
pinepaper_create_item
|
|
645
|
+
itemType: "circle"
|
|
646
|
+
position: {x: 400, y: 300}
|
|
647
|
+
properties:
|
|
648
|
+
radius: 90
|
|
649
|
+
fillColor: null
|
|
650
|
+
strokeColor: "#374151"
|
|
651
|
+
strokeWidth: 1
|
|
652
|
+
→ Returns item_3 (Mercury orbit ring)
|
|
653
|
+
|
|
654
|
+
// Earth's orbit ring
|
|
655
|
+
pinepaper_create_item
|
|
656
|
+
itemType: "circle"
|
|
657
|
+
position: {x: 400, y: 300}
|
|
658
|
+
properties:
|
|
659
|
+
radius: 150
|
|
660
|
+
fillColor: null
|
|
661
|
+
strokeColor: "#374151"
|
|
662
|
+
strokeWidth: 1
|
|
663
|
+
→ Returns item_4 (Earth orbit ring)
|
|
664
|
+
|
|
665
|
+
// Mars's orbit ring
|
|
666
|
+
pinepaper_create_item
|
|
667
|
+
itemType: "circle"
|
|
668
|
+
position: {x: 400, y: 300}
|
|
669
|
+
properties:
|
|
670
|
+
radius: 210
|
|
671
|
+
fillColor: null
|
|
672
|
+
strokeColor: "#374151"
|
|
673
|
+
strokeWidth: 1
|
|
674
|
+
→ Returns item_5 (Mars orbit ring)
|
|
675
|
+
\`\`\`
|
|
676
|
+
|
|
677
|
+
## Step 4: Create Mercury with Surface Detail
|
|
678
|
+
|
|
679
|
+
\`\`\`
|
|
680
|
+
// Mercury body
|
|
681
|
+
pinepaper_create_item
|
|
682
|
+
itemType: "circle"
|
|
683
|
+
position: {x: 490, y: 300}
|
|
684
|
+
properties:
|
|
685
|
+
radius: 8
|
|
686
|
+
color: "#9ca3af"
|
|
687
|
+
→ Returns item_6 (Mercury)
|
|
688
|
+
|
|
689
|
+
// Mercury crater detail (small dark circle)
|
|
690
|
+
pinepaper_create_item
|
|
691
|
+
itemType: "circle"
|
|
692
|
+
position: {x: 492, y: 298}
|
|
693
|
+
properties:
|
|
694
|
+
radius: 2
|
|
695
|
+
color: "#6b7280"
|
|
696
|
+
→ Returns item_7 (Mercury crater)
|
|
697
|
+
|
|
698
|
+
// Attach crater to Mercury
|
|
699
|
+
pinepaper_add_relation
|
|
700
|
+
sourceId: "item_7"
|
|
701
|
+
targetId: "item_6"
|
|
702
|
+
relationType: "attached_to"
|
|
703
|
+
params: {offset: [2, -2]}
|
|
704
|
+
|
|
705
|
+
// Mercury orbits the Sun
|
|
706
|
+
pinepaper_add_relation
|
|
707
|
+
sourceId: "item_6"
|
|
708
|
+
targetId: "item_2"
|
|
709
|
+
relationType: "orbits"
|
|
710
|
+
params: {radius: 90, speed: 1.5, direction: "counterclockwise"}
|
|
711
|
+
\`\`\`
|
|
265
712
|
|
|
266
|
-
## Step
|
|
713
|
+
## Step 5: Create Earth with Continent Path
|
|
267
714
|
|
|
268
|
-
### 1. Set up the canvas
|
|
269
715
|
\`\`\`
|
|
270
|
-
|
|
716
|
+
// Earth body
|
|
717
|
+
pinepaper_create_item
|
|
718
|
+
itemType: "circle"
|
|
719
|
+
position: {x: 550, y: 300}
|
|
720
|
+
properties:
|
|
721
|
+
radius: 15
|
|
722
|
+
color: "#3b82f6"
|
|
723
|
+
→ Returns item_8 (Earth)
|
|
724
|
+
|
|
725
|
+
// Continent shape using custom path
|
|
726
|
+
pinepaper_create_item
|
|
727
|
+
itemType: "path"
|
|
728
|
+
position: {x: 550, y: 300}
|
|
729
|
+
properties:
|
|
730
|
+
segments: [[-5, -8], [3, -10], [8, -5], [6, 2], [0, 5], [-7, 3], [-8, -3]]
|
|
731
|
+
closed: true
|
|
732
|
+
smooth: true
|
|
733
|
+
fillColor: "#22c55e"
|
|
734
|
+
strokeWidth: 0
|
|
735
|
+
→ Returns item_9 (continent)
|
|
736
|
+
|
|
737
|
+
// Attach continent to Earth
|
|
738
|
+
pinepaper_add_relation
|
|
739
|
+
sourceId: "item_9"
|
|
740
|
+
targetId: "item_8"
|
|
741
|
+
relationType: "attached_to"
|
|
742
|
+
params: {offset: [0, 0], inherit_rotation: true}
|
|
743
|
+
|
|
744
|
+
// Earth orbits the Sun
|
|
745
|
+
pinepaper_add_relation
|
|
746
|
+
sourceId: "item_8"
|
|
747
|
+
targetId: "item_2"
|
|
748
|
+
relationType: "orbits"
|
|
749
|
+
params: {radius: 150, speed: 0.5, direction: "counterclockwise"}
|
|
271
750
|
\`\`\`
|
|
272
751
|
|
|
273
|
-
|
|
752
|
+
## Step 6: Create Moon Orbiting Earth
|
|
753
|
+
|
|
274
754
|
\`\`\`
|
|
275
|
-
|
|
276
|
-
|
|
755
|
+
pinepaper_create_item
|
|
756
|
+
itemType: "circle"
|
|
757
|
+
position: {x: 575, y: 300}
|
|
758
|
+
properties:
|
|
759
|
+
radius: 5
|
|
760
|
+
color: "#d1d5db"
|
|
761
|
+
→ Returns item_10 (Moon)
|
|
762
|
+
|
|
763
|
+
// Moon orbits Earth (not the Sun!)
|
|
764
|
+
pinepaper_add_relation
|
|
765
|
+
sourceId: "item_10"
|
|
766
|
+
targetId: "item_8"
|
|
767
|
+
relationType: "orbits"
|
|
768
|
+
params: {radius: 25, speed: 2.0, direction: "counterclockwise"}
|
|
277
769
|
\`\`\`
|
|
278
770
|
|
|
279
|
-
|
|
771
|
+
## Step 7: Create Mars with Polar Ice Cap
|
|
772
|
+
|
|
280
773
|
\`\`\`
|
|
281
|
-
|
|
282
|
-
|
|
774
|
+
// Mars body
|
|
775
|
+
pinepaper_create_item
|
|
776
|
+
itemType: "circle"
|
|
777
|
+
position: {x: 610, y: 300}
|
|
778
|
+
properties:
|
|
779
|
+
radius: 12
|
|
780
|
+
color: "#dc2626"
|
|
781
|
+
→ Returns item_11 (Mars)
|
|
782
|
+
|
|
783
|
+
// Polar ice cap using arc path
|
|
784
|
+
pinepaper_create_item
|
|
785
|
+
itemType: "path"
|
|
786
|
+
position: {x: 610, y: 300}
|
|
787
|
+
properties:
|
|
788
|
+
pathData: "M -8 -8 A 12 12 0 0 1 8 -8 L 4 -5 A 8 8 0 0 0 -4 -5 Z"
|
|
789
|
+
fillColor: "#fef2f2"
|
|
790
|
+
strokeWidth: 0
|
|
791
|
+
→ Returns item_12 (ice cap)
|
|
792
|
+
|
|
793
|
+
// Attach ice cap to Mars
|
|
794
|
+
pinepaper_add_relation
|
|
795
|
+
sourceId: "item_12"
|
|
796
|
+
targetId: "item_11"
|
|
797
|
+
relationType: "attached_to"
|
|
798
|
+
params: {offset: [0, 0]}
|
|
799
|
+
|
|
800
|
+
// Mars orbits the Sun
|
|
801
|
+
pinepaper_add_relation
|
|
802
|
+
sourceId: "item_11"
|
|
803
|
+
targetId: "item_2"
|
|
804
|
+
relationType: "orbits"
|
|
805
|
+
params: {radius: 210, speed: 0.3, direction: "counterclockwise", phase: 45}
|
|
283
806
|
\`\`\`
|
|
284
807
|
|
|
285
|
-
|
|
808
|
+
## Step 8: Add Asteroid Belt with Custom Paths
|
|
809
|
+
|
|
810
|
+
Create a few asteroid shapes:
|
|
811
|
+
|
|
286
812
|
\`\`\`
|
|
287
|
-
|
|
288
|
-
|
|
813
|
+
// Asteroid 1 - irregular polygon
|
|
814
|
+
pinepaper_create_item
|
|
815
|
+
itemType: "path"
|
|
816
|
+
position: {x: 280, y: 300}
|
|
817
|
+
properties:
|
|
818
|
+
segments: [[0, -4], [3, -2], [4, 2], [1, 4], [-3, 3], [-4, -1]]
|
|
819
|
+
closed: true
|
|
820
|
+
fillColor: "#78716c"
|
|
821
|
+
strokeWidth: 0
|
|
822
|
+
→ Returns item_13
|
|
823
|
+
|
|
824
|
+
// Asteroid 2
|
|
825
|
+
pinepaper_create_item
|
|
826
|
+
itemType: "path"
|
|
827
|
+
position: {x: 520, y: 300}
|
|
828
|
+
properties:
|
|
829
|
+
segments: [[0, -3], [4, 0], [2, 4], [-2, 3], [-4, 0]]
|
|
830
|
+
closed: true
|
|
831
|
+
fillColor: "#a8a29e"
|
|
832
|
+
strokeWidth: 0
|
|
833
|
+
→ Returns item_14
|
|
834
|
+
|
|
835
|
+
// Asteroids orbit at different speeds
|
|
836
|
+
pinepaper_add_relation sourceId: "item_13" targetId: "item_2" relationType: "orbits"
|
|
837
|
+
params: {radius: 270, speed: 0.15, phase: 0}
|
|
838
|
+
|
|
839
|
+
pinepaper_add_relation sourceId: "item_14" targetId: "item_2" relationType: "orbits"
|
|
840
|
+
params: {radius: 275, speed: 0.12, phase: 180}
|
|
289
841
|
\`\`\`
|
|
290
842
|
|
|
291
|
-
|
|
843
|
+
## Step 9: Add Comet with Tail Path
|
|
844
|
+
|
|
292
845
|
\`\`\`
|
|
293
|
-
|
|
294
|
-
|
|
846
|
+
// Comet head
|
|
847
|
+
pinepaper_create_item
|
|
848
|
+
itemType: "circle"
|
|
849
|
+
position: {x: 200, y: 200}
|
|
850
|
+
properties:
|
|
851
|
+
radius: 6
|
|
852
|
+
color: "#67e8f9"
|
|
853
|
+
→ Returns item_15 (comet head)
|
|
854
|
+
|
|
855
|
+
// Comet tail using curved path
|
|
856
|
+
pinepaper_create_item
|
|
857
|
+
itemType: "path"
|
|
858
|
+
position: {x: 200, y: 200}
|
|
859
|
+
properties:
|
|
860
|
+
pathData: "M 6 0 Q 40 -10 80 -5 Q 120 0 150 10 Q 100 5 50 2 Q 20 0 6 0"
|
|
861
|
+
fillColor: "#22d3ee"
|
|
862
|
+
opacity: 0.6
|
|
863
|
+
strokeWidth: 0
|
|
864
|
+
→ Returns item_16 (comet tail)
|
|
865
|
+
|
|
866
|
+
// Tail follows comet head
|
|
867
|
+
pinepaper_add_relation
|
|
868
|
+
sourceId: "item_16"
|
|
869
|
+
targetId: "item_15"
|
|
870
|
+
relationType: "attached_to"
|
|
871
|
+
params: {offset: [0, 0]}
|
|
872
|
+
|
|
873
|
+
// Comet on elliptical-like orbit (using orbits with high speed variation)
|
|
874
|
+
pinepaper_add_relation
|
|
875
|
+
sourceId: "item_15"
|
|
876
|
+
targetId: "item_2"
|
|
877
|
+
relationType: "orbits"
|
|
878
|
+
params: {radius: 320, speed: 0.8, direction: "clockwise"}
|
|
879
|
+
|
|
880
|
+
// Comet tail points away from sun
|
|
881
|
+
pinepaper_add_relation
|
|
882
|
+
sourceId: "item_16"
|
|
883
|
+
targetId: "item_2"
|
|
884
|
+
relationType: "points_at"
|
|
885
|
+
params: {offset_angle: 180}
|
|
295
886
|
\`\`\`
|
|
296
887
|
|
|
297
|
-
|
|
888
|
+
## Step 10: Verify and Screenshot
|
|
889
|
+
|
|
298
890
|
\`\`\`
|
|
299
|
-
|
|
300
|
-
Add relation: text attached_to item_1 with offset [0, -70]
|
|
891
|
+
pinepaper_browser_screenshot
|
|
301
892
|
\`\`\`
|
|
302
893
|
|
|
894
|
+
Take multiple screenshots to verify:
|
|
895
|
+
1. All orbital relations are animating
|
|
896
|
+
2. Attached items (craters, continents, ice caps) move with their planets
|
|
897
|
+
3. The comet tail points away from the sun
|
|
898
|
+
|
|
303
899
|
## Result
|
|
304
900
|
|
|
305
|
-
|
|
901
|
+
You now have a dynamic solar system featuring:
|
|
902
|
+
- **Custom corona rays** around the sun (rotating SVG path)
|
|
903
|
+
- **Visible orbital rings** showing each planet's path
|
|
904
|
+
- **Surface details** on planets using paths (craters, continents, ice caps)
|
|
905
|
+
- **Irregular asteroids** using polygon paths
|
|
906
|
+
- **A comet** with a curved tail path that points away from the sun
|
|
907
|
+
|
|
908
|
+
## Key Techniques Used
|
|
909
|
+
|
|
910
|
+
| Technique | Example |
|
|
911
|
+
|-----------|---------|
|
|
912
|
+
| SVG pathData | Corona rays, polar ice cap, comet tail |
|
|
913
|
+
| Segment arrays | Continents, asteroids |
|
|
914
|
+
| smooth: true | Organic continent shapes |
|
|
915
|
+
| attached_to | Details that move with planets |
|
|
916
|
+
| orbits | All celestial body motion |
|
|
917
|
+
| points_at | Comet tail direction |
|
|
918
|
+
| Layered composition | Planet + details as separate items |
|
|
919
|
+
|
|
920
|
+
## Training Data Generated
|
|
921
|
+
|
|
922
|
+
This scene produces rich training pairs:
|
|
923
|
+
- "Create a continent shape on Earth" → path with segments + attached_to relation
|
|
924
|
+
- "Draw the Sun's corona with ray shapes" → SVG pathData with rotate animation
|
|
925
|
+
- "Add visible orbit rings" → unfilled circles with stroke only
|
|
926
|
+
- "Make comet tail point away from sun" → points_at with offset_angle: 180
|
|
927
|
+
`,
|
|
928
|
+
'pinepaper://docs/mathematical-patterns': `# Mathematical Patterns Guide
|
|
929
|
+
|
|
930
|
+
Create stunning visualizations using mathematical formulas. PinePaper excels at bringing math to life through animation.
|
|
931
|
+
|
|
932
|
+
## Coordinate Systems
|
|
933
|
+
|
|
934
|
+
PinePaper uses a standard canvas coordinate system:
|
|
935
|
+
- **Origin (0, 0)**: Top-left corner
|
|
936
|
+
- **X-axis**: Increases rightward
|
|
937
|
+
- **Y-axis**: Increases downward
|
|
938
|
+
- **Center of 800x600 canvas**: (400, 300)
|
|
939
|
+
|
|
940
|
+
## Spirals
|
|
941
|
+
|
|
942
|
+
### Archimedean Spiral
|
|
943
|
+
Points move outward at constant rate. Formula: r = a + b*θ
|
|
944
|
+
|
|
945
|
+
\`\`\`
|
|
946
|
+
// Create spiral with 8 points
|
|
947
|
+
// Each point: x = cx + r*cos(θ), y = cy + r*sin(θ)
|
|
948
|
+
|
|
949
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300} properties: {radius: 4, color: "#3b82f6"}
|
|
950
|
+
pinepaper_create_item itemType: "circle" position: {x: 410, y: 295} properties: {radius: 4, color: "#3b82f6"}
|
|
951
|
+
pinepaper_create_item itemType: "circle" position: {x: 405, y: 280} properties: {radius: 4, color: "#3b82f6"}
|
|
952
|
+
pinepaper_create_item itemType: "circle" position: {x: 385, y: 275} properties: {radius: 4, color: "#3b82f6"}
|
|
953
|
+
pinepaper_create_item itemType: "circle" position: {x: 365, y: 290} properties: {radius: 4, color: "#3b82f6"}
|
|
954
|
+
pinepaper_create_item itemType: "circle" position: {x: 360, y: 320} properties: {radius: 4, color: "#3b82f6"}
|
|
955
|
+
pinepaper_create_item itemType: "circle" position: {x: 380, y: 345} properties: {radius: 4, color: "#3b82f6"}
|
|
956
|
+
pinepaper_create_item itemType: "circle" position: {x: 415, y: 355} properties: {radius: 4, color: "#3b82f6"}
|
|
957
|
+
\`\`\`
|
|
958
|
+
|
|
959
|
+
### Logarithmic Spiral (Golden Spiral)
|
|
960
|
+
Formula: r = a * e^(b*θ) - Found in nature (shells, galaxies)
|
|
961
|
+
|
|
962
|
+
\`\`\`
|
|
963
|
+
// Connect points with a smooth path
|
|
964
|
+
pinepaper_create_item
|
|
965
|
+
itemType: "path"
|
|
966
|
+
position: {x: 400, y: 300}
|
|
967
|
+
properties:
|
|
968
|
+
segments: [[0, 0], [10, -5], [8, -20], [-10, -28], [-35, -15], [-40, 20], [-20, 50], [25, 60]]
|
|
969
|
+
smooth: true
|
|
970
|
+
closed: false
|
|
971
|
+
strokeColor: "#f59e0b"
|
|
972
|
+
strokeWidth: 2
|
|
973
|
+
fillColor: null
|
|
974
|
+
\`\`\`
|
|
975
|
+
|
|
976
|
+
## Waves and Oscillations
|
|
977
|
+
|
|
978
|
+
### Sine Wave
|
|
979
|
+
Formula: y = A * sin(ωx + φ)
|
|
980
|
+
- A = amplitude (wave height)
|
|
981
|
+
- ω = angular frequency (wave density)
|
|
982
|
+
- φ = phase shift
|
|
983
|
+
|
|
984
|
+
\`\`\`
|
|
985
|
+
// Create a sine wave using smooth path
|
|
986
|
+
pinepaper_create_item
|
|
987
|
+
itemType: "path"
|
|
988
|
+
position: {x: 400, y: 300}
|
|
989
|
+
properties:
|
|
990
|
+
segments: [
|
|
991
|
+
[-200, 0], [-150, -40], [-100, 0], [-50, 40], [0, 0],
|
|
992
|
+
[50, -40], [100, 0], [150, 40], [200, 0]
|
|
993
|
+
]
|
|
994
|
+
smooth: true
|
|
995
|
+
closed: false
|
|
996
|
+
strokeColor: "#10b981"
|
|
997
|
+
strokeWidth: 3
|
|
998
|
+
fillColor: null
|
|
999
|
+
\`\`\`
|
|
1000
|
+
|
|
1001
|
+
### Standing Wave Animation
|
|
1002
|
+
Two waves traveling in opposite directions:
|
|
1003
|
+
|
|
1004
|
+
\`\`\`
|
|
1005
|
+
// Create two wave paths, animate in opposite directions
|
|
1006
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 280}
|
|
1007
|
+
properties: {segments: [[-200, 0], [-100, -30], [0, 0], [100, 30], [200, 0]], smooth: true, strokeColor: "#3b82f6", strokeWidth: 2}
|
|
1008
|
+
→ item_1
|
|
1009
|
+
|
|
1010
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 320}
|
|
1011
|
+
properties: {segments: [[-200, 0], [-100, 30], [0, 0], [100, -30], [200, 0]], smooth: true, strokeColor: "#ef4444", strokeWidth: 2}
|
|
1012
|
+
→ item_2
|
|
1013
|
+
|
|
1014
|
+
pinepaper_animate_item itemId: "item_1" animationType: "slide" speed: 0.5
|
|
1015
|
+
pinepaper_animate_item itemId: "item_2" animationType: "slide" speed: -0.5
|
|
1016
|
+
\`\`\`
|
|
1017
|
+
|
|
1018
|
+
## Geometric Patterns
|
|
1019
|
+
|
|
1020
|
+
### Regular Polygons
|
|
1021
|
+
Formula for vertices: x = r*cos(2πk/n), y = r*sin(2πk/n)
|
|
1022
|
+
|
|
1023
|
+
**Pentagon (5 sides):**
|
|
1024
|
+
\`\`\`
|
|
1025
|
+
pinepaper_create_item itemType: "polygon" position: {x: 400, y: 300}
|
|
1026
|
+
properties: {sides: 5, radius: 80, color: "#8b5cf6"}
|
|
1027
|
+
\`\`\`
|
|
1028
|
+
|
|
1029
|
+
**Hexagon (6 sides):**
|
|
1030
|
+
\`\`\`
|
|
1031
|
+
pinepaper_create_item itemType: "polygon" position: {x: 400, y: 300}
|
|
1032
|
+
properties: {sides: 6, radius: 80, color: "#06b6d4"}
|
|
1033
|
+
\`\`\`
|
|
1034
|
+
|
|
1035
|
+
**Octagon (8 sides):**
|
|
1036
|
+
\`\`\`
|
|
1037
|
+
pinepaper_create_item itemType: "polygon" position: {x: 400, y: 300}
|
|
1038
|
+
properties: {sides: 8, radius: 80, color: "#f43f5e"}
|
|
1039
|
+
\`\`\`
|
|
1040
|
+
|
|
1041
|
+
### Nested Polygons (Mandala Pattern)
|
|
1042
|
+
\`\`\`
|
|
1043
|
+
// Create concentric rotating polygons
|
|
1044
|
+
pinepaper_create_item itemType: "polygon" position: {x: 400, y: 300}
|
|
1045
|
+
properties: {sides: 6, radius: 120, color: null, strokeColor: "#3b82f6", strokeWidth: 2}
|
|
1046
|
+
→ item_1
|
|
1047
|
+
|
|
1048
|
+
pinepaper_create_item itemType: "polygon" position: {x: 400, y: 300}
|
|
1049
|
+
properties: {sides: 6, radius: 90, color: null, strokeColor: "#8b5cf6", strokeWidth: 2}
|
|
1050
|
+
→ item_2
|
|
1051
|
+
|
|
1052
|
+
pinepaper_create_item itemType: "polygon" position: {x: 400, y: 300}
|
|
1053
|
+
properties: {sides: 6, radius: 60, color: null, strokeColor: "#ec4899", strokeWidth: 2}
|
|
1054
|
+
→ item_3
|
|
1055
|
+
|
|
1056
|
+
// Rotate at different speeds
|
|
1057
|
+
pinepaper_animate_item itemId: "item_1" animationType: "rotate" speed: 0.2
|
|
1058
|
+
pinepaper_animate_item itemId: "item_2" animationType: "rotate" speed: -0.3
|
|
1059
|
+
pinepaper_animate_item itemId: "item_3" animationType: "rotate" speed: 0.5
|
|
1060
|
+
\`\`\`
|
|
1061
|
+
|
|
1062
|
+
## Stars and Stellations
|
|
1063
|
+
|
|
1064
|
+
### Star Geometry
|
|
1065
|
+
Stars are defined by two radii: outer (points) and inner (valleys)
|
|
1066
|
+
- **Sharp stars**: inner radius << outer radius
|
|
1067
|
+
- **Thick stars**: inner radius close to outer radius
|
|
1068
|
+
|
|
1069
|
+
\`\`\`
|
|
1070
|
+
// Sharp 5-pointed star
|
|
1071
|
+
pinepaper_create_item itemType: "star" position: {x: 300, y: 300}
|
|
1072
|
+
properties: {points: 5, radius1: 80, radius2: 30, color: "#fbbf24"}
|
|
1073
|
+
|
|
1074
|
+
// Thick 5-pointed star
|
|
1075
|
+
pinepaper_create_item itemType: "star" position: {x: 500, y: 300}
|
|
1076
|
+
properties: {points: 5, radius1: 80, radius2: 55, color: "#f59e0b"}
|
|
1077
|
+
\`\`\`
|
|
1078
|
+
|
|
1079
|
+
### Star Variations
|
|
1080
|
+
\`\`\`
|
|
1081
|
+
// 4-pointed star (diamond burst)
|
|
1082
|
+
pinepaper_create_item itemType: "star" properties: {points: 4, radius1: 60, radius2: 15, color: "#ef4444"}
|
|
1083
|
+
|
|
1084
|
+
// 8-pointed star (compass rose)
|
|
1085
|
+
pinepaper_create_item itemType: "star" properties: {points: 8, radius1: 70, radius2: 35, color: "#3b82f6"}
|
|
1086
|
+
|
|
1087
|
+
// 12-pointed star (sun burst)
|
|
1088
|
+
pinepaper_create_item itemType: "star" properties: {points: 12, radius1: 80, radius2: 60, color: "#fbbf24"}
|
|
1089
|
+
\`\`\`
|
|
1090
|
+
|
|
1091
|
+
## Lissajous Figures
|
|
1092
|
+
|
|
1093
|
+
Curves from parametric equations: x = A*sin(at + δ), y = B*sin(bt)
|
|
1094
|
+
|
|
1095
|
+
These create beautiful interlocking patterns based on frequency ratios:
|
|
1096
|
+
|
|
1097
|
+
\`\`\`
|
|
1098
|
+
// 1:2 Lissajous (figure-8 pattern)
|
|
1099
|
+
pinepaper_create_item
|
|
1100
|
+
itemType: "path"
|
|
1101
|
+
position: {x: 400, y: 300}
|
|
1102
|
+
properties:
|
|
1103
|
+
pathData: "M 0 -60 C 60 -60 60 0 0 0 C -60 0 -60 60 0 60 C 60 60 60 0 0 0 C -60 0 -60 -60 0 -60"
|
|
1104
|
+
strokeColor: "#10b981"
|
|
1105
|
+
strokeWidth: 2
|
|
1106
|
+
fillColor: null
|
|
1107
|
+
\`\`\`
|
|
1108
|
+
|
|
1109
|
+
## Circular Arrangements
|
|
1110
|
+
|
|
1111
|
+
### Items Around a Circle
|
|
1112
|
+
Place n items evenly around a circle of radius r:
|
|
1113
|
+
- angle = 2π * i / n
|
|
1114
|
+
- x = center_x + r * cos(angle)
|
|
1115
|
+
- y = center_y + r * sin(angle)
|
|
1116
|
+
|
|
1117
|
+
\`\`\`
|
|
1118
|
+
// 8 circles arranged in a ring
|
|
1119
|
+
pinepaper_create_item itemType: "circle" position: {x: 480, y: 300} properties: {radius: 15, color: "#ef4444"}
|
|
1120
|
+
pinepaper_create_item itemType: "circle" position: {x: 457, y: 357} properties: {radius: 15, color: "#f59e0b"}
|
|
1121
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 380} properties: {radius: 15, color: "#eab308"}
|
|
1122
|
+
pinepaper_create_item itemType: "circle" position: {x: 343, y: 357} properties: {radius: 15, color: "#22c55e"}
|
|
1123
|
+
pinepaper_create_item itemType: "circle" position: {x: 320, y: 300} properties: {radius: 15, color: "#06b6d4"}
|
|
1124
|
+
pinepaper_create_item itemType: "circle" position: {x: 343, y: 243} properties: {radius: 15, color: "#3b82f6"}
|
|
1125
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 220} properties: {radius: 15, color: "#8b5cf6"}
|
|
1126
|
+
pinepaper_create_item itemType: "circle" position: {x: 457, y: 243} properties: {radius: 15, color: "#ec4899"}
|
|
1127
|
+
\`\`\`
|
|
1128
|
+
|
|
1129
|
+
### Animated Circular Arrangement
|
|
1130
|
+
\`\`\`
|
|
1131
|
+
// Create center anchor
|
|
1132
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300} properties: {radius: 5, color: "#ffffff"}
|
|
1133
|
+
→ item_center
|
|
1134
|
+
|
|
1135
|
+
// Create orbiting items with different phases
|
|
1136
|
+
pinepaper_create_item itemType: "circle" position: {x: 480, y: 300} properties: {radius: 12, color: "#ef4444"}
|
|
1137
|
+
→ item_1
|
|
1138
|
+
pinepaper_add_relation sourceId: "item_1" targetId: "item_center" relationType: "orbits"
|
|
1139
|
+
params: {radius: 80, speed: 0.5, phase: 0}
|
|
1140
|
+
|
|
1141
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 380} properties: {radius: 12, color: "#22c55e"}
|
|
1142
|
+
→ item_2
|
|
1143
|
+
pinepaper_add_relation sourceId: "item_2" targetId: "item_center" relationType: "orbits"
|
|
1144
|
+
params: {radius: 80, speed: 0.5, phase: 90}
|
|
1145
|
+
|
|
1146
|
+
pinepaper_create_item itemType: "circle" position: {x: 320, y: 300} properties: {radius: 12, color: "#3b82f6"}
|
|
1147
|
+
→ item_3
|
|
1148
|
+
pinepaper_add_relation sourceId: "item_3" targetId: "item_center" relationType: "orbits"
|
|
1149
|
+
params: {radius: 80, speed: 0.5, phase: 180}
|
|
1150
|
+
|
|
1151
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 220} properties: {radius: 12, color: "#f59e0b"}
|
|
1152
|
+
→ item_4
|
|
1153
|
+
pinepaper_add_relation sourceId: "item_4" targetId: "item_center" relationType: "orbits"
|
|
1154
|
+
params: {radius: 80, speed: 0.5, phase: 270}
|
|
1155
|
+
\`\`\`
|
|
1156
|
+
|
|
1157
|
+
## Fractals and Self-Similarity
|
|
1158
|
+
|
|
1159
|
+
### Simple Fractal Tree (3 levels)
|
|
1160
|
+
\`\`\`
|
|
1161
|
+
// Trunk
|
|
1162
|
+
pinepaper_create_item itemType: "line" properties: {from: [400, 400], to: [400, 300], strokeColor: "#78350f", strokeWidth: 8}
|
|
1163
|
+
|
|
1164
|
+
// Level 1 branches
|
|
1165
|
+
pinepaper_create_item itemType: "line" properties: {from: [400, 300], to: [350, 230], strokeColor: "#78350f", strokeWidth: 5}
|
|
1166
|
+
pinepaper_create_item itemType: "line" properties: {from: [400, 300], to: [450, 230], strokeColor: "#78350f", strokeWidth: 5}
|
|
1167
|
+
|
|
1168
|
+
// Level 2 branches (left)
|
|
1169
|
+
pinepaper_create_item itemType: "line" properties: {from: [350, 230], to: [320, 180], strokeColor: "#166534", strokeWidth: 3}
|
|
1170
|
+
pinepaper_create_item itemType: "line" properties: {from: [350, 230], to: [370, 175], strokeColor: "#166534", strokeWidth: 3}
|
|
1171
|
+
|
|
1172
|
+
// Level 2 branches (right)
|
|
1173
|
+
pinepaper_create_item itemType: "line" properties: {from: [450, 230], to: [430, 175], strokeColor: "#166534", strokeWidth: 3}
|
|
1174
|
+
pinepaper_create_item itemType: "line" properties: {from: [450, 230], to: [480, 180], strokeColor: "#166534", strokeWidth: 3}
|
|
1175
|
+
\`\`\`
|
|
1176
|
+
|
|
1177
|
+
### Sierpinski Triangle Pattern
|
|
1178
|
+
\`\`\`
|
|
1179
|
+
// Main triangle
|
|
1180
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 320}
|
|
1181
|
+
properties: {segments: [[0, -100], [87, 50], [-87, 50]], closed: true, strokeColor: "#8b5cf6", strokeWidth: 2, fillColor: null}
|
|
1182
|
+
|
|
1183
|
+
// Inner inverted triangle (creates the hole)
|
|
1184
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 320}
|
|
1185
|
+
properties: {segments: [[0, 0], [43, -50], [-43, -50]], closed: true, fillColor: "#1a1a2e", strokeWidth: 0}
|
|
1186
|
+
\`\`\`
|
|
1187
|
+
|
|
1188
|
+
## Physics Simulations
|
|
1189
|
+
|
|
1190
|
+
### Pendulum Motion
|
|
1191
|
+
\`\`\`
|
|
1192
|
+
// Fixed pivot point
|
|
1193
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 150} properties: {radius: 8, color: "#6b7280"}
|
|
1194
|
+
→ pivot
|
|
1195
|
+
|
|
1196
|
+
// Pendulum bob
|
|
1197
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 350} properties: {radius: 25, color: "#3b82f6"}
|
|
1198
|
+
→ bob
|
|
1199
|
+
|
|
1200
|
+
// Use wobble animation to simulate pendulum swing
|
|
1201
|
+
pinepaper_animate_item itemId: "bob" animationType: "wobble" speed: 0.8
|
|
1202
|
+
\`\`\`
|
|
1203
|
+
|
|
1204
|
+
### Orbital Mechanics (Kepler's Laws)
|
|
1205
|
+
\`\`\`
|
|
1206
|
+
// Central body (star)
|
|
1207
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300} properties: {radius: 40, color: "#fbbf24"}
|
|
1208
|
+
→ star
|
|
1209
|
+
|
|
1210
|
+
// Inner planet (faster orbit - Kepler's 3rd law)
|
|
1211
|
+
pinepaper_create_item itemType: "circle" position: {x: 480, y: 300} properties: {radius: 10, color: "#ef4444"}
|
|
1212
|
+
→ inner
|
|
1213
|
+
pinepaper_add_relation sourceId: "inner" targetId: "star" relationType: "orbits"
|
|
1214
|
+
params: {radius: 80, speed: 2.0}
|
|
1215
|
+
|
|
1216
|
+
// Outer planet (slower orbit)
|
|
1217
|
+
pinepaper_create_item itemType: "circle" position: {x: 560, y: 300} properties: {radius: 15, color: "#3b82f6"}
|
|
1218
|
+
→ outer
|
|
1219
|
+
pinepaper_add_relation sourceId: "outer" targetId: "star" relationType: "orbits"
|
|
1220
|
+
params: {radius: 160, speed: 0.7}
|
|
1221
|
+
\`\`\`
|
|
1222
|
+
|
|
1223
|
+
## Trigonometric Visualizations
|
|
1224
|
+
|
|
1225
|
+
### Unit Circle
|
|
1226
|
+
\`\`\`
|
|
1227
|
+
// Circle
|
|
1228
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300}
|
|
1229
|
+
properties: {radius: 100, fillColor: null, strokeColor: "#4b5563", strokeWidth: 2}
|
|
1230
|
+
|
|
1231
|
+
// X-axis
|
|
1232
|
+
pinepaper_create_item itemType: "line" properties: {from: [280, 300], to: [520, 300], strokeColor: "#6b7280", strokeWidth: 1}
|
|
1233
|
+
|
|
1234
|
+
// Y-axis
|
|
1235
|
+
pinepaper_create_item itemType: "line" properties: {from: [400, 180], to: [400, 420], strokeColor: "#6b7280", strokeWidth: 1}
|
|
1236
|
+
|
|
1237
|
+
// Rotating radius line
|
|
1238
|
+
pinepaper_create_item itemType: "line" properties: {from: [400, 300], to: [500, 300], strokeColor: "#ef4444", strokeWidth: 2}
|
|
1239
|
+
→ radius
|
|
1240
|
+
pinepaper_animate_item itemId: "radius" animationType: "rotate" speed: 0.3
|
|
1241
|
+
|
|
1242
|
+
// Point on circle
|
|
1243
|
+
pinepaper_create_item itemType: "circle" position: {x: 500, y: 300} properties: {radius: 6, color: "#ef4444"}
|
|
1244
|
+
→ point
|
|
1245
|
+
pinepaper_add_relation sourceId: "point" targetId: "radius" relationType: "attached_to"
|
|
1246
|
+
params: {offset: [100, 0], inherit_rotation: true}
|
|
1247
|
+
\`\`\`
|
|
1248
|
+
|
|
1249
|
+
## Color Mathematics
|
|
1250
|
+
|
|
1251
|
+
### Color Wheel
|
|
1252
|
+
\`\`\`
|
|
1253
|
+
// 12 hues arranged in a circle (30° apart)
|
|
1254
|
+
// Hue values: 0°=red, 60°=yellow, 120°=green, 180°=cyan, 240°=blue, 300°=magenta
|
|
1255
|
+
|
|
1256
|
+
pinepaper_create_item itemType: "circle" position: {x: 480, y: 300} properties: {radius: 20, color: "#ef4444"} // 0° Red
|
|
1257
|
+
pinepaper_create_item itemType: "circle" position: {x: 457, y: 357} properties: {radius: 20, color: "#f97316"} // 30° Orange
|
|
1258
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 380} properties: {radius: 20, color: "#eab308"} // 60° Yellow
|
|
1259
|
+
pinepaper_create_item itemType: "circle" position: {x: 343, y: 357} properties: {radius: 20, color: "#84cc16"} // 90° Yellow-Green
|
|
1260
|
+
pinepaper_create_item itemType: "circle" position: {x: 320, y: 300} properties: {radius: 20, color: "#22c55e"} // 120° Green
|
|
1261
|
+
pinepaper_create_item itemType: "circle" position: {x: 343, y: 243} properties: {radius: 20, color: "#14b8a6"} // 150° Teal
|
|
1262
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 220} properties: {radius: 20, color: "#06b6d4"} // 180° Cyan
|
|
1263
|
+
pinepaper_create_item itemType: "circle" position: {x: 457, y: 243} properties: {radius: 20, color: "#3b82f6"} // 210° Blue
|
|
1264
|
+
\`\`\`
|
|
1265
|
+
|
|
1266
|
+
## Formulas Quick Reference
|
|
1267
|
+
|
|
1268
|
+
| Pattern | Formula | PinePaper Approach |
|
|
1269
|
+
|---------|---------|-------------------|
|
|
1270
|
+
| Circle point | (r*cos θ, r*sin θ) | Use orbits relation |
|
|
1271
|
+
| Spiral | r = a + bθ | Create points, connect with smooth path |
|
|
1272
|
+
| Sine wave | y = A*sin(ωx) | Path with smooth segments |
|
|
1273
|
+
| Regular polygon | 2π/n angle between vertices | Use polygon itemType with sides param |
|
|
1274
|
+
| Golden ratio | φ = 1.618... | radius2 = radius1 / 1.618 for stars |
|
|
1275
|
+
| Fibonacci | 1, 1, 2, 3, 5, 8... | Size sequence for nested shapes |
|
|
1276
|
+
`,
|
|
1277
|
+
'pinepaper://docs/effects-and-filters': `# Effects & Filters Guide
|
|
1278
|
+
|
|
1279
|
+
Complete reference for visual effects, particle effects, and post-processing filters in PinePaper.
|
|
1280
|
+
|
|
1281
|
+
## Particle Effects
|
|
1282
|
+
|
|
1283
|
+
### Sparkle Effect
|
|
1284
|
+
Adds glittering particles around an item.
|
|
1285
|
+
|
|
1286
|
+
\`\`\`
|
|
1287
|
+
pinepaper_apply_effect
|
|
1288
|
+
itemId: "item_1"
|
|
1289
|
+
effectType: "sparkle"
|
|
1290
|
+
params:
|
|
1291
|
+
color: "#fbbf24" // Sparkle color (default: gold)
|
|
1292
|
+
speed: 1.5 // Animation speed multiplier
|
|
1293
|
+
size: 4 // Particle size in pixels
|
|
1294
|
+
\`\`\`
|
|
1295
|
+
|
|
1296
|
+
**Use cases:**
|
|
1297
|
+
- Magic wand effects
|
|
1298
|
+
- Highlight important items
|
|
1299
|
+
- Create fairy dust trails
|
|
1300
|
+
- Award/achievement animations
|
|
1301
|
+
|
|
1302
|
+
### Blast Effect
|
|
1303
|
+
Creates an explosion/burst of particles from an item.
|
|
1304
|
+
|
|
1305
|
+
\`\`\`
|
|
1306
|
+
pinepaper_apply_effect
|
|
1307
|
+
itemId: "item_1"
|
|
1308
|
+
effectType: "blast"
|
|
1309
|
+
params:
|
|
1310
|
+
color: "#ef4444" // Particle color (default: red)
|
|
1311
|
+
radius: 150 // How far particles travel
|
|
1312
|
+
count: 30 // Number of particles
|
|
1313
|
+
\`\`\`
|
|
1314
|
+
|
|
1315
|
+
**Use cases:**
|
|
1316
|
+
- Explosions
|
|
1317
|
+
- Confetti celebrations
|
|
1318
|
+
- Impact effects
|
|
1319
|
+
- Dramatic reveals
|
|
1320
|
+
|
|
1321
|
+
## Canvas Filters
|
|
1322
|
+
|
|
1323
|
+
Filters apply to the entire canvas and can be stacked for combined effects.
|
|
1324
|
+
|
|
1325
|
+
### Color Adjustments
|
|
1326
|
+
|
|
1327
|
+
**Grayscale** - Remove color saturation
|
|
1328
|
+
\`\`\`
|
|
1329
|
+
pinepaper_add_filter filterType: "grayscale" params: {intensity: 1.0}
|
|
1330
|
+
// intensity: 0 (no effect) to 1 (full grayscale)
|
|
1331
|
+
\`\`\`
|
|
1332
|
+
|
|
1333
|
+
**Sepia** - Warm vintage brown tones
|
|
1334
|
+
\`\`\`
|
|
1335
|
+
pinepaper_add_filter filterType: "sepia" params: {intensity: 0.8}
|
|
1336
|
+
\`\`\`
|
|
1337
|
+
|
|
1338
|
+
**Saturation** - Boost or reduce color intensity
|
|
1339
|
+
\`\`\`
|
|
1340
|
+
pinepaper_add_filter filterType: "saturate" params: {value: 50}
|
|
1341
|
+
// value: -100 (desaturated) to 100 (oversaturated)
|
|
1342
|
+
\`\`\`
|
|
1343
|
+
|
|
1344
|
+
**Brightness** - Lighten or darken
|
|
1345
|
+
\`\`\`
|
|
1346
|
+
pinepaper_add_filter filterType: "brightness" params: {value: 20}
|
|
1347
|
+
// value: -100 (black) to 100 (white)
|
|
1348
|
+
\`\`\`
|
|
1349
|
+
|
|
1350
|
+
**Contrast** - Increase or decrease contrast
|
|
1351
|
+
\`\`\`
|
|
1352
|
+
pinepaper_add_filter filterType: "contrast" params: {value: 30}
|
|
1353
|
+
// value: -100 (flat gray) to 100 (high contrast)
|
|
1354
|
+
\`\`\`
|
|
1355
|
+
|
|
1356
|
+
**Invert** - Invert all colors
|
|
1357
|
+
\`\`\`
|
|
1358
|
+
pinepaper_add_filter filterType: "invert" params: {intensity: 1.0}
|
|
1359
|
+
\`\`\`
|
|
1360
|
+
|
|
1361
|
+
**Color Overlay** - Tint with a color
|
|
1362
|
+
\`\`\`
|
|
1363
|
+
pinepaper_add_filter filterType: "colorOverlay" params: {
|
|
1364
|
+
color: "#3b82f6",
|
|
1365
|
+
intensity: 0.3
|
|
1366
|
+
}
|
|
1367
|
+
\`\`\`
|
|
1368
|
+
|
|
1369
|
+
### Blur & Sharpness
|
|
1370
|
+
|
|
1371
|
+
**Blur** - Gaussian blur effect
|
|
1372
|
+
\`\`\`
|
|
1373
|
+
pinepaper_add_filter filterType: "blur" params: {radius: 5}
|
|
1374
|
+
// radius: 0 (sharp) to 20 (very blurry)
|
|
1375
|
+
\`\`\`
|
|
1376
|
+
|
|
1377
|
+
**Sharpen** - Increase edge definition
|
|
1378
|
+
\`\`\`
|
|
1379
|
+
pinepaper_add_filter filterType: "sharpen" params: {intensity: 50}
|
|
1380
|
+
// intensity: 0 to 100
|
|
1381
|
+
\`\`\`
|
|
1382
|
+
|
|
1383
|
+
### Artistic Effects
|
|
1384
|
+
|
|
1385
|
+
**Noise/Grain** - Film grain texture
|
|
1386
|
+
\`\`\`
|
|
1387
|
+
pinepaper_add_filter filterType: "noise" params: {
|
|
1388
|
+
intensity: 30, // Grain amount (0-100)
|
|
1389
|
+
monochrome: true // Black and white grain
|
|
1390
|
+
}
|
|
1391
|
+
\`\`\`
|
|
1392
|
+
|
|
1393
|
+
**Vignette** - Darken edges
|
|
1394
|
+
\`\`\`
|
|
1395
|
+
pinepaper_add_filter filterType: "vignette" params: {
|
|
1396
|
+
intensity: 0.5, // Darkness (0-1)
|
|
1397
|
+
radius: 0.7 // How far from edge (0-1)
|
|
1398
|
+
}
|
|
1399
|
+
\`\`\`
|
|
1400
|
+
|
|
1401
|
+
**Emboss** - 3D relief effect
|
|
1402
|
+
\`\`\`
|
|
1403
|
+
pinepaper_add_filter filterType: "emboss" params: {}
|
|
1404
|
+
\`\`\`
|
|
1405
|
+
|
|
1406
|
+
**Posterize** - Reduce color levels
|
|
1407
|
+
\`\`\`
|
|
1408
|
+
pinepaper_add_filter filterType: "posterize" params: {levels: 4}
|
|
1409
|
+
// levels: 2 (extreme) to 32 (subtle)
|
|
1410
|
+
\`\`\`
|
|
1411
|
+
|
|
1412
|
+
### Preset Combinations
|
|
1413
|
+
|
|
1414
|
+
**Vintage** - Classic old photo look
|
|
1415
|
+
\`\`\`
|
|
1416
|
+
pinepaper_add_filter filterType: "vintage" params: {intensity: 0.7}
|
|
1417
|
+
// Combines sepia, vignette, and noise
|
|
1418
|
+
\`\`\`
|
|
1419
|
+
|
|
1420
|
+
## Filter Stacking Examples
|
|
1421
|
+
|
|
1422
|
+
### Cinematic Look
|
|
1423
|
+
\`\`\`
|
|
1424
|
+
pinepaper_add_filter filterType: "contrast" params: {value: 15}
|
|
1425
|
+
pinepaper_add_filter filterType: "vignette" params: {intensity: 0.4, radius: 0.8}
|
|
1426
|
+
pinepaper_add_filter filterType: "colorOverlay" params: {color: "#1e3a5f", intensity: 0.15}
|
|
1427
|
+
\`\`\`
|
|
1428
|
+
|
|
1429
|
+
### Dreamy/Soft
|
|
1430
|
+
\`\`\`
|
|
1431
|
+
pinepaper_add_filter filterType: "blur" params: {radius: 2}
|
|
1432
|
+
pinepaper_add_filter filterType: "brightness" params: {value: 10}
|
|
1433
|
+
pinepaper_add_filter filterType: "saturate" params: {value: -20}
|
|
1434
|
+
\`\`\`
|
|
1435
|
+
|
|
1436
|
+
### Retro/80s
|
|
1437
|
+
\`\`\`
|
|
1438
|
+
pinepaper_add_filter filterType: "contrast" params: {value: 20}
|
|
1439
|
+
pinepaper_add_filter filterType: "saturate" params: {value: 40}
|
|
1440
|
+
pinepaper_add_filter filterType: "noise" params: {intensity: 15, monochrome: false}
|
|
1441
|
+
\`\`\`
|
|
1442
|
+
|
|
1443
|
+
### Horror/Dark
|
|
1444
|
+
\`\`\`
|
|
1445
|
+
pinepaper_add_filter filterType: "contrast" params: {value: 40}
|
|
1446
|
+
pinepaper_add_filter filterType: "saturate" params: {value: -50}
|
|
1447
|
+
pinepaper_add_filter filterType: "vignette" params: {intensity: 0.8, radius: 0.5}
|
|
1448
|
+
\`\`\`
|
|
1449
|
+
|
|
1450
|
+
### Old Film
|
|
1451
|
+
\`\`\`
|
|
1452
|
+
pinepaper_add_filter filterType: "sepia" params: {intensity: 0.6}
|
|
1453
|
+
pinepaper_add_filter filterType: "noise" params: {intensity: 40, monochrome: true}
|
|
1454
|
+
pinepaper_add_filter filterType: "vignette" params: {intensity: 0.5}
|
|
1455
|
+
pinepaper_add_filter filterType: "contrast" params: {value: 10}
|
|
1456
|
+
\`\`\`
|
|
1457
|
+
|
|
1458
|
+
## Combining Effects with Animation
|
|
1459
|
+
|
|
1460
|
+
### Glowing Orb
|
|
1461
|
+
\`\`\`
|
|
1462
|
+
// Create orb
|
|
1463
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300}
|
|
1464
|
+
properties: {radius: 40, color: "#8b5cf6"}
|
|
1465
|
+
→ item_1
|
|
1466
|
+
|
|
1467
|
+
// Add pulse animation
|
|
1468
|
+
pinepaper_animate_item itemId: "item_1" animationType: "pulse" speed: 0.8
|
|
1469
|
+
|
|
1470
|
+
// Add sparkle effect
|
|
1471
|
+
pinepaper_apply_effect itemId: "item_1" effectType: "sparkle"
|
|
1472
|
+
params: {color: "#c4b5fd", speed: 1.2, size: 3}
|
|
1473
|
+
\`\`\`
|
|
1474
|
+
|
|
1475
|
+
### Explosion Sequence
|
|
1476
|
+
\`\`\`
|
|
1477
|
+
// Create target
|
|
1478
|
+
pinepaper_create_item itemType: "star" position: {x: 400, y: 300}
|
|
1479
|
+
properties: {points: 5, radius1: 50, radius2: 20, color: "#ef4444"}
|
|
1480
|
+
→ item_1
|
|
1481
|
+
|
|
1482
|
+
// Add blast effect
|
|
1483
|
+
pinepaper_apply_effect itemId: "item_1" effectType: "blast"
|
|
1484
|
+
params: {color: "#fbbf24", radius: 200, count: 40}
|
|
1485
|
+
\`\`\`
|
|
1486
|
+
|
|
1487
|
+
## Effect Parameters Reference
|
|
1488
|
+
|
|
1489
|
+
| Effect | Parameter | Range | Default | Description |
|
|
1490
|
+
|--------|-----------|-------|---------|-------------|
|
|
1491
|
+
| sparkle | color | hex/rgb | #fbbf24 | Particle color |
|
|
1492
|
+
| sparkle | speed | 0.1-5 | 1 | Animation speed |
|
|
1493
|
+
| sparkle | size | 1-20 | 3 | Particle size |
|
|
1494
|
+
| blast | color | hex/rgb | #ef4444 | Particle color |
|
|
1495
|
+
| blast | radius | 10-500 | 100 | Explosion radius |
|
|
1496
|
+
| blast | count | 5-100 | 20 | Particle count |
|
|
1497
|
+
|
|
1498
|
+
## Filter Parameters Reference
|
|
1499
|
+
|
|
1500
|
+
| Filter | Parameter | Range | Default | Description |
|
|
1501
|
+
|--------|-----------|-------|---------|-------------|
|
|
1502
|
+
| grayscale | intensity | 0-1 | 1 | Effect strength |
|
|
1503
|
+
| sepia | intensity | 0-1 | 1 | Effect strength |
|
|
1504
|
+
| blur | radius | 0-20 | 5 | Blur amount |
|
|
1505
|
+
| brightness | value | -100 to 100 | 0 | Brightness change |
|
|
1506
|
+
| contrast | value | -100 to 100 | 0 | Contrast change |
|
|
1507
|
+
| saturate | value | -100 to 100 | 0 | Saturation change |
|
|
1508
|
+
| invert | intensity | 0-1 | 1 | Inversion amount |
|
|
1509
|
+
| noise | intensity | 0-100 | 30 | Grain amount |
|
|
1510
|
+
| noise | monochrome | boolean | false | B&W grain |
|
|
1511
|
+
| vignette | intensity | 0-1 | 0.5 | Edge darkness |
|
|
1512
|
+
| vignette | radius | 0-1 | 0.5 | Vignette size |
|
|
1513
|
+
| posterize | levels | 2-32 | 4 | Color levels |
|
|
1514
|
+
| colorOverlay | color | hex/rgb | - | Overlay color |
|
|
1515
|
+
| colorOverlay | intensity | 0-1 | 0.5 | Overlay strength |
|
|
1516
|
+
| sharpen | intensity | 0-100 | 50 | Sharpness |
|
|
1517
|
+
| vintage | intensity | 0-1 | 0.5 | Overall effect |
|
|
1518
|
+
`,
|
|
1519
|
+
'pinepaper://docs/interactive-animations': `# Interactive Animations Guide
|
|
1520
|
+
|
|
1521
|
+
Create dynamic, game-like behaviors using PinePaper's relation system. These patterns enable responsive animations that feel alive.
|
|
1522
|
+
|
|
1523
|
+
## The Follows Relation
|
|
1524
|
+
|
|
1525
|
+
The \`follows\` relation makes an item move toward a target with configurable smoothing and delay.
|
|
1526
|
+
|
|
1527
|
+
### Basic Following
|
|
1528
|
+
\`\`\`
|
|
1529
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300} properties: {radius: 30, color: "#3b82f6"}
|
|
1530
|
+
→ leader
|
|
1531
|
+
|
|
1532
|
+
pinepaper_create_item itemType: "circle" position: {x: 300, y: 300} properties: {radius: 20, color: "#ef4444"}
|
|
1533
|
+
→ follower
|
|
1534
|
+
|
|
1535
|
+
pinepaper_add_relation
|
|
1536
|
+
sourceId: "follower"
|
|
1537
|
+
targetId: "leader"
|
|
1538
|
+
relationType: "follows"
|
|
1539
|
+
params: {
|
|
1540
|
+
smoothing: 0.1, // Lower = snappier, higher = smoother
|
|
1541
|
+
delay: 0 // Seconds of lag
|
|
1542
|
+
}
|
|
1543
|
+
\`\`\`
|
|
1544
|
+
|
|
1545
|
+
### Snake/Trail Effect
|
|
1546
|
+
Create a chain of followers with increasing delay:
|
|
1547
|
+
|
|
1548
|
+
\`\`\`
|
|
1549
|
+
// Leader
|
|
1550
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300} properties: {radius: 20, color: "#22c55e"}
|
|
1551
|
+
→ head
|
|
1552
|
+
|
|
1553
|
+
// Segment 1
|
|
1554
|
+
pinepaper_create_item itemType: "circle" position: {x: 380, y: 300} properties: {radius: 18, color: "#16a34a"}
|
|
1555
|
+
→ seg1
|
|
1556
|
+
pinepaper_add_relation sourceId: "seg1" targetId: "head" relationType: "follows"
|
|
1557
|
+
params: {smoothing: 0.15, delay: 0.1}
|
|
1558
|
+
|
|
1559
|
+
// Segment 2
|
|
1560
|
+
pinepaper_create_item itemType: "circle" position: {x: 360, y: 300} properties: {radius: 16, color: "#15803d"}
|
|
1561
|
+
→ seg2
|
|
1562
|
+
pinepaper_add_relation sourceId: "seg2" targetId: "seg1" relationType: "follows"
|
|
1563
|
+
params: {smoothing: 0.15, delay: 0.1}
|
|
1564
|
+
|
|
1565
|
+
// Segment 3
|
|
1566
|
+
pinepaper_create_item itemType: "circle" position: {x: 340, y: 300} properties: {radius: 14, color: "#166534"}
|
|
1567
|
+
→ seg3
|
|
1568
|
+
pinepaper_add_relation sourceId: "seg3" targetId: "seg2" relationType: "follows"
|
|
1569
|
+
params: {smoothing: 0.15, delay: 0.1}
|
|
1570
|
+
|
|
1571
|
+
// Animate the head
|
|
1572
|
+
pinepaper_add_relation sourceId: "head" targetId: "head" relationType: "orbits"
|
|
1573
|
+
params: {radius: 100, speed: 0.5}
|
|
1574
|
+
\`\`\`
|
|
1575
|
+
|
|
1576
|
+
### Elastic Following
|
|
1577
|
+
Use low smoothing for a bouncy, elastic feel:
|
|
1578
|
+
|
|
1579
|
+
\`\`\`
|
|
1580
|
+
pinepaper_add_relation
|
|
1581
|
+
sourceId: "follower"
|
|
1582
|
+
targetId: "leader"
|
|
1583
|
+
relationType: "follows"
|
|
1584
|
+
params: {smoothing: 0.02, delay: 0} // Very low smoothing = elastic
|
|
1585
|
+
\`\`\`
|
|
1586
|
+
|
|
1587
|
+
## Maintaining Distance
|
|
1588
|
+
|
|
1589
|
+
The \`maintains_distance\` relation keeps an item at a fixed distance from a target.
|
|
1590
|
+
|
|
1591
|
+
### Orbiting Guard
|
|
1592
|
+
\`\`\`
|
|
1593
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300} properties: {radius: 30, color: "#fbbf24"}
|
|
1594
|
+
→ core
|
|
1595
|
+
|
|
1596
|
+
pinepaper_create_item itemType: "circle" position: {x: 500, y: 300} properties: {radius: 15, color: "#ef4444"}
|
|
1597
|
+
→ guard
|
|
1598
|
+
|
|
1599
|
+
pinepaper_add_relation
|
|
1600
|
+
sourceId: "guard"
|
|
1601
|
+
targetId: "core"
|
|
1602
|
+
relationType: "maintains_distance"
|
|
1603
|
+
params: {
|
|
1604
|
+
distance: 100, // Stay 100 pixels away
|
|
1605
|
+
strength: 0.8 // How strongly to enforce (0-1)
|
|
1606
|
+
}
|
|
1607
|
+
\`\`\`
|
|
1608
|
+
|
|
1609
|
+
### Magnetic Repulsion Effect
|
|
1610
|
+
Multiple items maintaining distance creates a repulsion field:
|
|
1611
|
+
|
|
1612
|
+
\`\`\`
|
|
1613
|
+
// Central attractor
|
|
1614
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300} properties: {radius: 25, color: "#8b5cf6"}
|
|
1615
|
+
→ center
|
|
1616
|
+
|
|
1617
|
+
// Floating particles that stay away
|
|
1618
|
+
pinepaper_create_item itemType: "circle" position: {x: 300, y: 250} properties: {radius: 10, color: "#c4b5fd"}
|
|
1619
|
+
→ p1
|
|
1620
|
+
pinepaper_add_relation sourceId: "p1" targetId: "center" relationType: "maintains_distance"
|
|
1621
|
+
params: {distance: 80, strength: 1}
|
|
1622
|
+
|
|
1623
|
+
pinepaper_create_item itemType: "circle" position: {x: 500, y: 350} properties: {radius: 10, color: "#c4b5fd"}
|
|
1624
|
+
→ p2
|
|
1625
|
+
pinepaper_add_relation sourceId: "p2" targetId: "center" relationType: "maintains_distance"
|
|
1626
|
+
params: {distance: 80, strength: 1}
|
|
1627
|
+
\`\`\`
|
|
1628
|
+
|
|
1629
|
+
## Bounded Movement
|
|
1630
|
+
|
|
1631
|
+
The \`bounds_to\` relation constrains an item within a boundary.
|
|
1632
|
+
|
|
1633
|
+
### Bouncing Ball
|
|
1634
|
+
\`\`\`
|
|
1635
|
+
// Create boundary rectangle (invisible or visible)
|
|
1636
|
+
pinepaper_create_item itemType: "rectangle" position: {x: 400, y: 300}
|
|
1637
|
+
properties: {width: 300, height: 200, fillColor: null, strokeColor: "#374151", strokeWidth: 2}
|
|
1638
|
+
→ bounds
|
|
1639
|
+
|
|
1640
|
+
// Create bouncing ball
|
|
1641
|
+
pinepaper_create_item itemType: "circle" position: {x: 350, y: 280} properties: {radius: 15, color: "#ef4444"}
|
|
1642
|
+
→ ball
|
|
1643
|
+
|
|
1644
|
+
pinepaper_add_relation
|
|
1645
|
+
sourceId: "ball"
|
|
1646
|
+
targetId: "bounds"
|
|
1647
|
+
relationType: "bounds_to"
|
|
1648
|
+
params: {
|
|
1649
|
+
padding: 15, // Stay this far from edges
|
|
1650
|
+
bounce: true // Bounce off walls
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
// Give the ball some motion
|
|
1654
|
+
pinepaper_animate_item itemId: "ball" animationType: "slide" speed: 2
|
|
1655
|
+
\`\`\`
|
|
1656
|
+
|
|
1657
|
+
### Contained Particles
|
|
1658
|
+
\`\`\`
|
|
1659
|
+
// Container
|
|
1660
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300}
|
|
1661
|
+
properties: {radius: 120, fillColor: null, strokeColor: "#3b82f6", strokeWidth: 2}
|
|
1662
|
+
→ container
|
|
1663
|
+
|
|
1664
|
+
// Particles inside
|
|
1665
|
+
pinepaper_create_item itemType: "circle" position: {x: 380, y: 290} properties: {radius: 8, color: "#60a5fa"}
|
|
1666
|
+
→ p1
|
|
1667
|
+
pinepaper_add_relation sourceId: "p1" targetId: "container" relationType: "bounds_to"
|
|
1668
|
+
params: {padding: 10, bounce: true}
|
|
1669
|
+
pinepaper_animate_item itemId: "p1" animationType: "bounce" speed: 1.5
|
|
1670
|
+
|
|
1671
|
+
pinepaper_create_item itemType: "circle" position: {x: 420, y: 310} properties: {radius: 8, color: "#60a5fa"}
|
|
1672
|
+
→ p2
|
|
1673
|
+
pinepaper_add_relation sourceId: "p2" targetId: "container" relationType: "bounds_to"
|
|
1674
|
+
params: {padding: 10, bounce: true}
|
|
1675
|
+
pinepaper_animate_item itemId: "p2" animationType: "wobble" speed: 1.2
|
|
1676
|
+
\`\`\`
|
|
1677
|
+
|
|
1678
|
+
## Points At (Rotation Tracking)
|
|
1679
|
+
|
|
1680
|
+
The \`points_at\` relation makes an item rotate to face a target.
|
|
1681
|
+
|
|
1682
|
+
### Compass Needle
|
|
1683
|
+
\`\`\`
|
|
1684
|
+
// North marker
|
|
1685
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 200} properties: {radius: 10, color: "#ef4444"}
|
|
1686
|
+
→ north
|
|
1687
|
+
|
|
1688
|
+
// Compass arrow
|
|
1689
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 300}
|
|
1690
|
+
properties: {
|
|
1691
|
+
segments: [[0, -40], [10, 20], [0, 10], [-10, 20]],
|
|
1692
|
+
closed: true,
|
|
1693
|
+
fillColor: "#1e40af"
|
|
1694
|
+
}
|
|
1695
|
+
→ needle
|
|
1696
|
+
|
|
1697
|
+
pinepaper_add_relation
|
|
1698
|
+
sourceId: "needle"
|
|
1699
|
+
targetId: "north"
|
|
1700
|
+
relationType: "points_at"
|
|
1701
|
+
params: {
|
|
1702
|
+
offset_angle: 0, // Additional rotation offset
|
|
1703
|
+
smoothing: 0.1 // Rotation smoothing
|
|
1704
|
+
}
|
|
1705
|
+
\`\`\`
|
|
1706
|
+
|
|
1707
|
+
### Tracking Eyes
|
|
1708
|
+
\`\`\`
|
|
1709
|
+
// Create eye
|
|
1710
|
+
pinepaper_create_item itemType: "circle" position: {x: 380, y: 300} properties: {radius: 30, color: "#ffffff"}
|
|
1711
|
+
→ eye_white
|
|
1712
|
+
|
|
1713
|
+
pinepaper_create_item itemType: "circle" position: {x: 380, y: 300} properties: {radius: 12, color: "#1f2937"}
|
|
1714
|
+
→ pupil
|
|
1715
|
+
|
|
1716
|
+
// Target to look at (could be animated)
|
|
1717
|
+
pinepaper_create_item itemType: "circle" position: {x: 500, y: 250} properties: {radius: 8, color: "#ef4444"}
|
|
1718
|
+
→ target
|
|
1719
|
+
|
|
1720
|
+
// Pupil points at target
|
|
1721
|
+
pinepaper_add_relation sourceId: "pupil" targetId: "target" relationType: "points_at"
|
|
1722
|
+
params: {smoothing: 0.2}
|
|
1723
|
+
|
|
1724
|
+
// Animate target in circle
|
|
1725
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300} properties: {radius: 3, color: null}
|
|
1726
|
+
→ orbit_center
|
|
1727
|
+
pinepaper_add_relation sourceId: "target" targetId: "orbit_center" relationType: "orbits"
|
|
1728
|
+
params: {radius: 150, speed: 0.3}
|
|
1729
|
+
\`\`\`
|
|
1730
|
+
|
|
1731
|
+
## Mirroring
|
|
1732
|
+
|
|
1733
|
+
The \`mirrors\` relation creates symmetrical movement.
|
|
1734
|
+
|
|
1735
|
+
### Horizontal Mirror
|
|
1736
|
+
\`\`\`
|
|
1737
|
+
// Original
|
|
1738
|
+
pinepaper_create_item itemType: "star" position: {x: 300, y: 300}
|
|
1739
|
+
properties: {points: 5, radius1: 30, radius2: 15, color: "#fbbf24"}
|
|
1740
|
+
→ original
|
|
1741
|
+
|
|
1742
|
+
// Mirror
|
|
1743
|
+
pinepaper_create_item itemType: "star" position: {x: 500, y: 300}
|
|
1744
|
+
properties: {points: 5, radius1: 30, radius2: 15, color: "#f59e0b"}
|
|
1745
|
+
→ mirror
|
|
1746
|
+
|
|
1747
|
+
pinepaper_add_relation
|
|
1748
|
+
sourceId: "mirror"
|
|
1749
|
+
targetId: "original"
|
|
1750
|
+
relationType: "mirrors"
|
|
1751
|
+
params: {
|
|
1752
|
+
axis: "vertical", // Mirror across vertical axis
|
|
1753
|
+
center: [400, 300] // Mirror center point
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
// Animate original - mirror follows
|
|
1757
|
+
pinepaper_animate_item itemId: "original" animationType: "bounce" speed: 1
|
|
1758
|
+
\`\`\`
|
|
1759
|
+
|
|
1760
|
+
### Kaleidoscope Effect (4-way mirror)
|
|
1761
|
+
\`\`\`
|
|
1762
|
+
// Original in top-left quadrant
|
|
1763
|
+
pinepaper_create_item itemType: "circle" position: {x: 350, y: 250} properties: {radius: 15, color: "#3b82f6"}
|
|
1764
|
+
→ orig
|
|
1765
|
+
|
|
1766
|
+
// Horizontal mirror
|
|
1767
|
+
pinepaper_create_item itemType: "circle" position: {x: 450, y: 250} properties: {radius: 15, color: "#8b5cf6"}
|
|
1768
|
+
→ h_mirror
|
|
1769
|
+
pinepaper_add_relation sourceId: "h_mirror" targetId: "orig" relationType: "mirrors"
|
|
1770
|
+
params: {axis: "vertical", center: [400, 300]}
|
|
1771
|
+
|
|
1772
|
+
// Vertical mirror
|
|
1773
|
+
pinepaper_create_item itemType: "circle" position: {x: 350, y: 350} properties: {radius: 15, color: "#ec4899"}
|
|
1774
|
+
→ v_mirror
|
|
1775
|
+
pinepaper_add_relation sourceId: "v_mirror" targetId: "orig" relationType: "mirrors"
|
|
1776
|
+
params: {axis: "horizontal", center: [400, 300]}
|
|
1777
|
+
|
|
1778
|
+
// Both axes mirror
|
|
1779
|
+
pinepaper_create_item itemType: "circle" position: {x: 450, y: 350} properties: {radius: 15, color: "#f43f5e"}
|
|
1780
|
+
→ both_mirror
|
|
1781
|
+
pinepaper_add_relation sourceId: "both_mirror" targetId: "orig" relationType: "mirrors"
|
|
1782
|
+
params: {axis: "both", center: [400, 300]}
|
|
1783
|
+
\`\`\`
|
|
1784
|
+
|
|
1785
|
+
## Parallax Depth
|
|
1786
|
+
|
|
1787
|
+
The \`parallax\` relation creates depth illusion through differential movement.
|
|
1788
|
+
|
|
1789
|
+
### Layered Background
|
|
1790
|
+
\`\`\`
|
|
1791
|
+
// Far background (moves least)
|
|
1792
|
+
pinepaper_create_item itemType: "circle" position: {x: 200, y: 400} properties: {radius: 80, color: "#1e3a5f"}
|
|
1793
|
+
→ far
|
|
1794
|
+
pinepaper_add_relation sourceId: "far" targetId: "player" relationType: "parallax"
|
|
1795
|
+
params: {depth: 0.2, origin: [400, 300]}
|
|
1796
|
+
|
|
1797
|
+
// Mid layer
|
|
1798
|
+
pinepaper_create_item itemType: "circle" position: {x: 300, y: 350} properties: {radius: 50, color: "#3b82f6"}
|
|
1799
|
+
→ mid
|
|
1800
|
+
pinepaper_add_relation sourceId: "mid" targetId: "player" relationType: "parallax"
|
|
1801
|
+
params: {depth: 0.5, origin: [400, 300]}
|
|
1802
|
+
|
|
1803
|
+
// Near foreground (moves most)
|
|
1804
|
+
pinepaper_create_item itemType: "circle" position: {x: 450, y: 300} properties: {radius: 30, color: "#60a5fa"}
|
|
1805
|
+
→ near
|
|
1806
|
+
pinepaper_add_relation sourceId: "near" targetId: "player" relationType: "parallax"
|
|
1807
|
+
params: {depth: 0.8, origin: [400, 300]}
|
|
1808
|
+
|
|
1809
|
+
// Player/camera reference
|
|
1810
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300} properties: {radius: 10, color: "#ffffff"}
|
|
1811
|
+
→ player
|
|
1812
|
+
\`\`\`
|
|
1813
|
+
|
|
1814
|
+
## Combining Relations
|
|
1815
|
+
|
|
1816
|
+
### Orbiting Follower Chain
|
|
1817
|
+
\`\`\`
|
|
1818
|
+
// Center
|
|
1819
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300} properties: {radius: 20, color: "#fbbf24"}
|
|
1820
|
+
→ sun
|
|
1821
|
+
|
|
1822
|
+
// Orbiting planet
|
|
1823
|
+
pinepaper_create_item itemType: "circle" position: {x: 500, y: 300} properties: {radius: 15, color: "#3b82f6"}
|
|
1824
|
+
→ planet
|
|
1825
|
+
pinepaper_add_relation sourceId: "planet" targetId: "sun" relationType: "orbits"
|
|
1826
|
+
params: {radius: 100, speed: 0.5}
|
|
1827
|
+
|
|
1828
|
+
// Moon follows planet with delay
|
|
1829
|
+
pinepaper_create_item itemType: "circle" position: {x: 520, y: 300} properties: {radius: 8, color: "#9ca3af"}
|
|
1830
|
+
→ moon
|
|
1831
|
+
pinepaper_add_relation sourceId: "moon" targetId: "planet" relationType: "follows"
|
|
1832
|
+
params: {offset: [30, 0], smoothing: 0.1, delay: 0.2}
|
|
1833
|
+
|
|
1834
|
+
// Comet maintains distance but also follows
|
|
1835
|
+
pinepaper_create_item itemType: "circle" position: {x: 300, y: 200} properties: {radius: 6, color: "#67e8f9"}
|
|
1836
|
+
→ comet
|
|
1837
|
+
pinepaper_add_relation sourceId: "comet" targetId: "planet" relationType: "maintains_distance"
|
|
1838
|
+
params: {distance: 60, strength: 0.5}
|
|
1839
|
+
\`\`\`
|
|
1840
|
+
|
|
1841
|
+
### Game Character
|
|
1842
|
+
\`\`\`
|
|
1843
|
+
// Character body
|
|
1844
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300} properties: {radius: 25, color: "#3b82f6"}
|
|
1845
|
+
→ body
|
|
1846
|
+
|
|
1847
|
+
// Eyes that point at mouse/target
|
|
1848
|
+
pinepaper_create_item itemType: "circle" position: {x: 395, y: 290} properties: {radius: 5, color: "#ffffff"}
|
|
1849
|
+
→ eye1
|
|
1850
|
+
pinepaper_add_relation sourceId: "eye1" targetId: "body" relationType: "attached_to"
|
|
1851
|
+
params: {offset: [-5, -10]}
|
|
1852
|
+
|
|
1853
|
+
pinepaper_create_item itemType: "circle" position: {x: 405, y: 290} properties: {radius: 5, color: "#ffffff"}
|
|
1854
|
+
→ eye2
|
|
1855
|
+
pinepaper_add_relation sourceId: "eye2" targetId: "body" relationType: "attached_to"
|
|
1856
|
+
params: {offset: [5, -10]}
|
|
1857
|
+
|
|
1858
|
+
// Shadow follows with offset
|
|
1859
|
+
pinepaper_create_item itemType: "ellipse" position: {x: 400, y: 330}
|
|
1860
|
+
properties: {width: 40, height: 15, color: "#00000044"}
|
|
1861
|
+
→ shadow
|
|
1862
|
+
pinepaper_add_relation sourceId: "shadow" targetId: "body" relationType: "follows"
|
|
1863
|
+
params: {offset: [0, 30], smoothing: 0.05}
|
|
1864
|
+
\`\`\`
|
|
1865
|
+
|
|
1866
|
+
## Relation Parameters Quick Reference
|
|
1867
|
+
|
|
1868
|
+
| Relation | Key Params | Effect |
|
|
1869
|
+
|----------|-----------|--------|
|
|
1870
|
+
| follows | smoothing: 0.01-1 | Lower = snappier movement |
|
|
1871
|
+
| follows | delay: 0-2 | Seconds of lag |
|
|
1872
|
+
| maintains_distance | strength: 0-1 | Enforcement rigidity |
|
|
1873
|
+
| bounds_to | bounce: true | Bounce off edges |
|
|
1874
|
+
| bounds_to | padding: 0+ | Inner margin |
|
|
1875
|
+
| points_at | smoothing: 0-1 | Rotation smoothness |
|
|
1876
|
+
| points_at | offset_angle: -180 to 180 | Rotation offset |
|
|
1877
|
+
| mirrors | axis: vertical/horizontal/both | Mirror axis |
|
|
1878
|
+
| parallax | depth: 0-1 | Movement factor |
|
|
1879
|
+
`,
|
|
1880
|
+
'pinepaper://docs/paperjs-in-pinepaper': `# Paper.js in PinePaper
|
|
1881
|
+
|
|
1882
|
+
PinePaper is built on Paper.js - a powerful vector graphics library. You can write Paper.js code directly in PinePaper for maximum control and flexibility.
|
|
1883
|
+
|
|
1884
|
+
## Two Ways to Create Graphics
|
|
1885
|
+
|
|
1886
|
+
### 1. MCP Tools (Recommended for AI)
|
|
1887
|
+
Natural language-friendly, declarative approach:
|
|
1888
|
+
\`\`\`
|
|
1889
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300}
|
|
1890
|
+
properties: {radius: 50, color: "#3b82f6"}
|
|
1891
|
+
\`\`\`
|
|
1892
|
+
|
|
1893
|
+
### 2. Direct Paper.js Code (Full Control)
|
|
1894
|
+
Write JavaScript using the Paper.js API:
|
|
1895
|
+
\`\`\`javascript
|
|
1896
|
+
var circle = new Path.Circle({
|
|
1897
|
+
center: new Point(400, 300),
|
|
1898
|
+
radius: 50,
|
|
1899
|
+
fillColor: '#3b82f6'
|
|
1900
|
+
});
|
|
1901
|
+
\`\`\`
|
|
1902
|
+
|
|
1903
|
+
Both approaches work in PinePaper - use whichever fits your needs!
|
|
1904
|
+
|
|
1905
|
+
## Paper.js Quick Reference
|
|
1906
|
+
|
|
1907
|
+
### The Global Objects
|
|
1908
|
+
|
|
1909
|
+
PinePaper provides these Paper.js globals:
|
|
1910
|
+
- \`paper\` - The paper scope
|
|
1911
|
+
- \`Path\` - Path constructors
|
|
1912
|
+
- \`Point\` - Point constructor
|
|
1913
|
+
- \`Size\` - Size constructor
|
|
1914
|
+
- \`Color\` - Color constructor
|
|
1915
|
+
- \`Group\` - Group constructor
|
|
1916
|
+
- \`view\` - The canvas view
|
|
1917
|
+
- \`project\` - The active project
|
|
1918
|
+
|
|
1919
|
+
### Creating Shapes
|
|
1920
|
+
|
|
1921
|
+
**Circle:**
|
|
1922
|
+
\`\`\`javascript
|
|
1923
|
+
var circle = new Path.Circle({
|
|
1924
|
+
center: new Point(400, 300),
|
|
1925
|
+
radius: 50,
|
|
1926
|
+
fillColor: '#3b82f6',
|
|
1927
|
+
strokeColor: '#1e40af',
|
|
1928
|
+
strokeWidth: 2
|
|
1929
|
+
});
|
|
1930
|
+
\`\`\`
|
|
1931
|
+
|
|
1932
|
+
**Rectangle:**
|
|
1933
|
+
\`\`\`javascript
|
|
1934
|
+
var rect = new Path.Rectangle({
|
|
1935
|
+
point: new Point(350, 250),
|
|
1936
|
+
size: new Size(100, 100),
|
|
1937
|
+
fillColor: '#22c55e',
|
|
1938
|
+
radius: 10 // Rounded corners
|
|
1939
|
+
});
|
|
1940
|
+
\`\`\`
|
|
1941
|
+
|
|
1942
|
+
**Star:**
|
|
1943
|
+
\`\`\`javascript
|
|
1944
|
+
var star = new Path.Star({
|
|
1945
|
+
center: new Point(400, 300),
|
|
1946
|
+
points: 5,
|
|
1947
|
+
radius1: 50, // Outer radius
|
|
1948
|
+
radius2: 25, // Inner radius
|
|
1949
|
+
fillColor: '#fbbf24'
|
|
1950
|
+
});
|
|
1951
|
+
\`\`\`
|
|
1952
|
+
|
|
1953
|
+
**Regular Polygon:**
|
|
1954
|
+
\`\`\`javascript
|
|
1955
|
+
var hexagon = new Path.RegularPolygon({
|
|
1956
|
+
center: new Point(400, 300),
|
|
1957
|
+
sides: 6,
|
|
1958
|
+
radius: 50,
|
|
1959
|
+
fillColor: '#8b5cf6'
|
|
1960
|
+
});
|
|
1961
|
+
\`\`\`
|
|
1962
|
+
|
|
1963
|
+
**Line:**
|
|
1964
|
+
\`\`\`javascript
|
|
1965
|
+
var line = new Path.Line({
|
|
1966
|
+
from: new Point(100, 100),
|
|
1967
|
+
to: new Point(300, 200),
|
|
1968
|
+
strokeColor: '#ef4444',
|
|
1969
|
+
strokeWidth: 3
|
|
1970
|
+
});
|
|
1971
|
+
\`\`\`
|
|
1972
|
+
|
|
1973
|
+
**Arc:**
|
|
1974
|
+
\`\`\`javascript
|
|
1975
|
+
var arc = new Path.Arc({
|
|
1976
|
+
from: new Point(100, 100),
|
|
1977
|
+
through: new Point(150, 50),
|
|
1978
|
+
to: new Point(200, 100),
|
|
1979
|
+
strokeColor: '#06b6d4',
|
|
1980
|
+
strokeWidth: 2
|
|
1981
|
+
});
|
|
1982
|
+
\`\`\`
|
|
1983
|
+
|
|
1984
|
+
### Creating Paths
|
|
1985
|
+
|
|
1986
|
+
**From Points:**
|
|
1987
|
+
\`\`\`javascript
|
|
1988
|
+
var path = new Path({
|
|
1989
|
+
segments: [
|
|
1990
|
+
new Point(100, 100),
|
|
1991
|
+
new Point(200, 50),
|
|
1992
|
+
new Point(300, 100),
|
|
1993
|
+
new Point(250, 200)
|
|
1994
|
+
],
|
|
1995
|
+
strokeColor: '#10b981',
|
|
1996
|
+
strokeWidth: 2,
|
|
1997
|
+
closed: true
|
|
1998
|
+
});
|
|
1999
|
+
path.smooth(); // Smooth the curves
|
|
2000
|
+
\`\`\`
|
|
2001
|
+
|
|
2002
|
+
**Using SVG Path Data:**
|
|
2003
|
+
\`\`\`javascript
|
|
2004
|
+
var path = new Path(
|
|
2005
|
+
'M 0 -50 C 50 -50 50 50 0 50 C -50 50 -50 -50 0 -50'
|
|
2006
|
+
);
|
|
2007
|
+
path.position = new Point(400, 300);
|
|
2008
|
+
path.fillColor = '#ec4899';
|
|
2009
|
+
\`\`\`
|
|
2010
|
+
|
|
2011
|
+
**Building Paths Segment by Segment:**
|
|
2012
|
+
\`\`\`javascript
|
|
2013
|
+
var path = new Path();
|
|
2014
|
+
path.strokeColor = '#f59e0b';
|
|
2015
|
+
path.strokeWidth = 3;
|
|
2016
|
+
|
|
2017
|
+
path.moveTo(new Point(100, 100));
|
|
2018
|
+
path.lineTo(new Point(200, 100));
|
|
2019
|
+
path.curveTo(new Point(250, 50), new Point(300, 100));
|
|
2020
|
+
path.closePath();
|
|
2021
|
+
\`\`\`
|
|
2022
|
+
|
|
2023
|
+
### Styling Properties
|
|
2024
|
+
|
|
2025
|
+
\`\`\`javascript
|
|
2026
|
+
item.fillColor = '#3b82f6'; // Fill color
|
|
2027
|
+
item.strokeColor = '#1e40af'; // Stroke color
|
|
2028
|
+
item.strokeWidth = 2; // Stroke width
|
|
2029
|
+
item.strokeCap = 'round'; // 'butt', 'round', 'square'
|
|
2030
|
+
item.strokeJoin = 'round'; // 'miter', 'round', 'bevel'
|
|
2031
|
+
item.dashArray = [10, 5]; // Dashed line
|
|
2032
|
+
item.opacity = 0.8; // Transparency (0-1)
|
|
2033
|
+
item.shadowColor = '#000000'; // Shadow color
|
|
2034
|
+
item.shadowBlur = 10; // Shadow blur
|
|
2035
|
+
item.shadowOffset = new Point(5, 5); // Shadow offset
|
|
2036
|
+
\`\`\`
|
|
2037
|
+
|
|
2038
|
+
### Transformations
|
|
2039
|
+
|
|
2040
|
+
\`\`\`javascript
|
|
2041
|
+
// Position
|
|
2042
|
+
item.position = new Point(400, 300);
|
|
2043
|
+
item.position.x += 50;
|
|
2044
|
+
|
|
2045
|
+
// Rotation
|
|
2046
|
+
item.rotation = 45; // Degrees
|
|
2047
|
+
item.rotate(15); // Rotate by amount
|
|
2048
|
+
|
|
2049
|
+
// Scale
|
|
2050
|
+
item.scaling = 1.5; // Uniform scale
|
|
2051
|
+
item.scaling = new Point(2, 1); // Non-uniform
|
|
2052
|
+
item.scale(1.2); // Scale by amount
|
|
2053
|
+
|
|
2054
|
+
// Flip
|
|
2055
|
+
item.scale(-1, 1); // Flip horizontal
|
|
2056
|
+
item.scale(1, -1); // Flip vertical
|
|
2057
|
+
\`\`\`
|
|
2058
|
+
|
|
2059
|
+
### Groups
|
|
2060
|
+
|
|
2061
|
+
\`\`\`javascript
|
|
2062
|
+
var circle = new Path.Circle({
|
|
2063
|
+
center: new Point(0, 0),
|
|
2064
|
+
radius: 30,
|
|
2065
|
+
fillColor: '#3b82f6'
|
|
2066
|
+
});
|
|
2067
|
+
|
|
2068
|
+
var square = new Path.Rectangle({
|
|
2069
|
+
point: new Point(-20, -20),
|
|
2070
|
+
size: new Size(40, 40),
|
|
2071
|
+
fillColor: '#ef4444'
|
|
2072
|
+
});
|
|
2073
|
+
|
|
2074
|
+
var group = new Group([circle, square]);
|
|
2075
|
+
group.position = new Point(400, 300);
|
|
2076
|
+
group.rotate(45); // Rotates entire group
|
|
2077
|
+
\`\`\`
|
|
2078
|
+
|
|
2079
|
+
### Animation with onFrame
|
|
2080
|
+
|
|
2081
|
+
Paper.js provides frame-by-frame animation:
|
|
2082
|
+
|
|
2083
|
+
\`\`\`javascript
|
|
2084
|
+
var circle = new Path.Circle({
|
|
2085
|
+
center: view.center,
|
|
2086
|
+
radius: 50,
|
|
2087
|
+
fillColor: '#3b82f6'
|
|
2088
|
+
});
|
|
2089
|
+
|
|
2090
|
+
var angle = 0;
|
|
2091
|
+
|
|
2092
|
+
function onFrame(event) {
|
|
2093
|
+
// event.count - frame count
|
|
2094
|
+
// event.time - total time
|
|
2095
|
+
// event.delta - time since last frame
|
|
2096
|
+
|
|
2097
|
+
angle += 2;
|
|
2098
|
+
circle.position.x = view.center.x + Math.cos(angle * Math.PI / 180) * 100;
|
|
2099
|
+
circle.position.y = view.center.y + Math.sin(angle * Math.PI / 180) * 100;
|
|
2100
|
+
}
|
|
2101
|
+
\`\`\`
|
|
2102
|
+
|
|
2103
|
+
### Event Handling
|
|
2104
|
+
|
|
2105
|
+
\`\`\`javascript
|
|
2106
|
+
// Mouse events on items
|
|
2107
|
+
circle.onMouseEnter = function(event) {
|
|
2108
|
+
this.fillColor = '#ef4444';
|
|
2109
|
+
};
|
|
2110
|
+
|
|
2111
|
+
circle.onMouseLeave = function(event) {
|
|
2112
|
+
this.fillColor = '#3b82f6';
|
|
2113
|
+
};
|
|
2114
|
+
|
|
2115
|
+
circle.onClick = function(event) {
|
|
2116
|
+
this.scale(1.2);
|
|
2117
|
+
};
|
|
2118
|
+
|
|
2119
|
+
// Global tool events
|
|
2120
|
+
function onMouseMove(event) {
|
|
2121
|
+
// event.point - mouse position
|
|
2122
|
+
circle.position = event.point;
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
function onMouseDown(event) {
|
|
2126
|
+
var path = new Path.Circle({
|
|
2127
|
+
center: event.point,
|
|
2128
|
+
radius: 20,
|
|
2129
|
+
fillColor: '#22c55e'
|
|
2130
|
+
});
|
|
2131
|
+
}
|
|
2132
|
+
\`\`\`
|
|
2133
|
+
|
|
2134
|
+
### Hit Testing
|
|
2135
|
+
|
|
2136
|
+
\`\`\`javascript
|
|
2137
|
+
function onMouseDown(event) {
|
|
2138
|
+
var hitResult = project.hitTest(event.point, {
|
|
2139
|
+
segments: true,
|
|
2140
|
+
stroke: true,
|
|
2141
|
+
fill: true,
|
|
2142
|
+
tolerance: 5
|
|
2143
|
+
});
|
|
2144
|
+
|
|
2145
|
+
if (hitResult) {
|
|
2146
|
+
hitResult.item.selected = true;
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
\`\`\`
|
|
2150
|
+
|
|
2151
|
+
### Working with Text
|
|
2152
|
+
|
|
2153
|
+
\`\`\`javascript
|
|
2154
|
+
var text = new PointText({
|
|
2155
|
+
point: new Point(400, 300),
|
|
2156
|
+
content: 'Hello PinePaper!',
|
|
2157
|
+
fillColor: '#ffffff',
|
|
2158
|
+
fontFamily: 'Arial',
|
|
2159
|
+
fontWeight: 'bold',
|
|
2160
|
+
fontSize: 48,
|
|
2161
|
+
justification: 'center'
|
|
2162
|
+
});
|
|
2163
|
+
\`\`\`
|
|
2164
|
+
|
|
2165
|
+
### Importing SVG
|
|
2166
|
+
|
|
2167
|
+
\`\`\`javascript
|
|
2168
|
+
// From string
|
|
2169
|
+
var svgString = '<svg>...</svg>';
|
|
2170
|
+
project.importSVG(svgString, function(item) {
|
|
2171
|
+
item.position = view.center;
|
|
2172
|
+
item.scale(2);
|
|
2173
|
+
});
|
|
2174
|
+
|
|
2175
|
+
// Imported items become Paper.js Groups
|
|
2176
|
+
\`\`\`
|
|
2177
|
+
|
|
2178
|
+
### Exporting SVG
|
|
2179
|
+
|
|
2180
|
+
\`\`\`javascript
|
|
2181
|
+
var svg = project.exportSVG({ asString: true });
|
|
2182
|
+
// Returns SVG string
|
|
2183
|
+
\`\`\`
|
|
2184
|
+
|
|
2185
|
+
## Combining Paper.js with PinePaper Features
|
|
2186
|
+
|
|
2187
|
+
### Register Paper.js Items with PinePaper
|
|
2188
|
+
|
|
2189
|
+
After creating items with Paper.js, register them to use PinePaper's relation system:
|
|
2190
|
+
|
|
2191
|
+
\`\`\`javascript
|
|
2192
|
+
// Create with Paper.js
|
|
2193
|
+
var planet = new Path.Circle({
|
|
2194
|
+
center: new Point(400, 300),
|
|
2195
|
+
radius: 20,
|
|
2196
|
+
fillColor: '#3b82f6'
|
|
2197
|
+
});
|
|
2198
|
+
|
|
2199
|
+
// Register with PinePaper (enables relations, training data export)
|
|
2200
|
+
var itemId = app.registerItem(planet, 'circle', { source: 'paperjs' });
|
|
2201
|
+
|
|
2202
|
+
// Now you can use relations
|
|
2203
|
+
app.addRelation(itemId, 'item_1', 'orbits', { radius: 100, speed: 0.5 });
|
|
2204
|
+
\`\`\`
|
|
2205
|
+
|
|
2206
|
+
### Access PinePaper's App Object
|
|
2207
|
+
|
|
2208
|
+
\`\`\`javascript
|
|
2209
|
+
// app is the PinePaper application instance
|
|
2210
|
+
app.setBackgroundColor('#0f172a');
|
|
2211
|
+
app.getItemById('item_1');
|
|
2212
|
+
app.addRelation(sourceId, targetId, 'follows', { smoothing: 0.1 });
|
|
2213
|
+
app.exportAnimatedSVG();
|
|
2214
|
+
\`\`\`
|
|
2215
|
+
|
|
2216
|
+
## Common Patterns
|
|
2217
|
+
|
|
2218
|
+
### Animated Background
|
|
2219
|
+
|
|
2220
|
+
\`\`\`javascript
|
|
2221
|
+
var circles = [];
|
|
2222
|
+
for (var i = 0; i < 20; i++) {
|
|
2223
|
+
var circle = new Path.Circle({
|
|
2224
|
+
center: new Point(
|
|
2225
|
+
Math.random() * view.size.width,
|
|
2226
|
+
Math.random() * view.size.height
|
|
2227
|
+
),
|
|
2228
|
+
radius: Math.random() * 30 + 10,
|
|
2229
|
+
fillColor: new Color(Math.random(), Math.random(), Math.random(), 0.5)
|
|
2230
|
+
});
|
|
2231
|
+
circles.push({
|
|
2232
|
+
item: circle,
|
|
2233
|
+
speed: Math.random() * 2 + 0.5
|
|
2234
|
+
});
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2237
|
+
function onFrame(event) {
|
|
2238
|
+
for (var i = 0; i < circles.length; i++) {
|
|
2239
|
+
circles[i].item.position.y -= circles[i].speed;
|
|
2240
|
+
if (circles[i].item.position.y < -50) {
|
|
2241
|
+
circles[i].item.position.y = view.size.height + 50;
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
\`\`\`
|
|
2246
|
+
|
|
2247
|
+
### Interactive Drawing
|
|
2248
|
+
|
|
2249
|
+
\`\`\`javascript
|
|
2250
|
+
var path;
|
|
2251
|
+
|
|
2252
|
+
function onMouseDown(event) {
|
|
2253
|
+
path = new Path({
|
|
2254
|
+
strokeColor: '#22c55e',
|
|
2255
|
+
strokeWidth: 3
|
|
2256
|
+
});
|
|
2257
|
+
path.add(event.point);
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
function onMouseDrag(event) {
|
|
2261
|
+
path.add(event.point);
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
function onMouseUp(event) {
|
|
2265
|
+
path.smooth();
|
|
2266
|
+
}
|
|
2267
|
+
\`\`\`
|
|
2268
|
+
|
|
2269
|
+
### Morphing Shapes
|
|
2270
|
+
|
|
2271
|
+
\`\`\`javascript
|
|
2272
|
+
var shape1 = new Path.Circle({
|
|
2273
|
+
center: view.center,
|
|
2274
|
+
radius: 50,
|
|
2275
|
+
fillColor: '#3b82f6'
|
|
2276
|
+
});
|
|
2277
|
+
|
|
2278
|
+
var shape2 = new Path.Star({
|
|
2279
|
+
center: view.center,
|
|
2280
|
+
points: 5,
|
|
2281
|
+
radius1: 80,
|
|
2282
|
+
radius2: 40,
|
|
2283
|
+
fillColor: '#ef4444',
|
|
2284
|
+
visible: false
|
|
2285
|
+
});
|
|
2286
|
+
|
|
2287
|
+
var morphing = false;
|
|
2288
|
+
var t = 0;
|
|
2289
|
+
|
|
2290
|
+
shape1.onClick = function() {
|
|
2291
|
+
morphing = !morphing;
|
|
2292
|
+
};
|
|
2293
|
+
|
|
2294
|
+
function onFrame(event) {
|
|
2295
|
+
if (morphing) {
|
|
2296
|
+
t = Math.min(t + 0.02, 1);
|
|
2297
|
+
} else {
|
|
2298
|
+
t = Math.max(t - 0.02, 0);
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
// Interpolate between shapes
|
|
2302
|
+
for (var i = 0; i < shape1.segments.length; i++) {
|
|
2303
|
+
var seg1 = shape1.segments[i];
|
|
2304
|
+
var seg2 = shape2.segments[i % shape2.segments.length];
|
|
2305
|
+
seg1.point = seg1.point.add(
|
|
2306
|
+
seg2.point.subtract(seg1.point).multiply(t * 0.1)
|
|
2307
|
+
);
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2310
|
+
\`\`\`
|
|
2311
|
+
|
|
2312
|
+
## Paper.js Resources
|
|
2313
|
+
|
|
2314
|
+
- **Official Docs**: http://paperjs.org/reference/
|
|
2315
|
+
- **Tutorials**: http://paperjs.org/tutorials/
|
|
2316
|
+
- **Examples**: http://paperjs.org/examples/
|
|
2317
|
+
|
|
2318
|
+
## When to Use Paper.js vs MCP Tools
|
|
2319
|
+
|
|
2320
|
+
| Use Paper.js When | Use MCP Tools When |
|
|
2321
|
+
|-------------------|-------------------|
|
|
2322
|
+
| Need frame-by-frame animation control | Want declarative animation (orbits, follows) |
|
|
2323
|
+
| Complex procedural generation | Creating standard shapes |
|
|
2324
|
+
| Interactive mouse/keyboard handling | AI-driven content creation |
|
|
2325
|
+
| Custom path manipulation algorithms | Building compositions with relations |
|
|
2326
|
+
| Porting existing Paper.js code | Generating training data |
|
|
2327
|
+
| Need maximum performance | Want simpler, higher-level API |
|
|
2328
|
+
`,
|
|
2329
|
+
'pinepaper://examples/logo-animation': `# Logo Animation Example
|
|
2330
|
+
|
|
2331
|
+
Create a professional animated logo with entrance effects and continuous motion.
|
|
2332
|
+
|
|
2333
|
+
## What You'll Build
|
|
2334
|
+
|
|
2335
|
+
An animated company logo featuring:
|
|
2336
|
+
- Geometric shapes assembling together
|
|
2337
|
+
- Text reveal with typewriter effect
|
|
2338
|
+
- Continuous subtle animations
|
|
2339
|
+
- Professional polish with effects
|
|
2340
|
+
|
|
2341
|
+
## Step 1: Canvas Setup
|
|
2342
|
+
|
|
2343
|
+
\`\`\`
|
|
2344
|
+
pinepaper_browser_connect
|
|
2345
|
+
pinepaper_clear_canvas
|
|
2346
|
+
pinepaper_set_background_color color: "#0f172a"
|
|
2347
|
+
pinepaper_set_canvas_size width: 800 height: 600
|
|
2348
|
+
\`\`\`
|
|
2349
|
+
|
|
2350
|
+
## Step 2: Create Logo Mark (Geometric Icon)
|
|
2351
|
+
|
|
2352
|
+
Build an abstract logo from shapes:
|
|
2353
|
+
|
|
2354
|
+
\`\`\`
|
|
2355
|
+
// Main hexagon
|
|
2356
|
+
pinepaper_create_item
|
|
2357
|
+
itemType: "polygon"
|
|
2358
|
+
position: {x: 300, y: 280}
|
|
2359
|
+
properties:
|
|
2360
|
+
sides: 6
|
|
2361
|
+
radius: 70
|
|
2362
|
+
color: "#3b82f6"
|
|
2363
|
+
→ hex_main
|
|
2364
|
+
|
|
2365
|
+
// Inner triangle pointing up
|
|
2366
|
+
pinepaper_create_item
|
|
2367
|
+
itemType: "path"
|
|
2368
|
+
position: {x: 300, y: 280}
|
|
2369
|
+
properties:
|
|
2370
|
+
segments: [[0, -35], [30, 20], [-30, 20]]
|
|
2371
|
+
closed: true
|
|
2372
|
+
fillColor: "#1e40af"
|
|
2373
|
+
strokeWidth: 0
|
|
2374
|
+
→ triangle_inner
|
|
2375
|
+
|
|
2376
|
+
// Accent circle
|
|
2377
|
+
pinepaper_create_item
|
|
2378
|
+
itemType: "circle"
|
|
2379
|
+
position: {x: 300, y: 255}
|
|
2380
|
+
properties:
|
|
2381
|
+
radius: 12
|
|
2382
|
+
color: "#60a5fa"
|
|
2383
|
+
→ accent_dot
|
|
2384
|
+
\`\`\`
|
|
2385
|
+
|
|
2386
|
+
## Step 3: Animate Logo Assembly
|
|
2387
|
+
|
|
2388
|
+
Use keyframe animation to assemble the logo:
|
|
2389
|
+
|
|
2390
|
+
\`\`\`
|
|
2391
|
+
// Hexagon scales in from nothing
|
|
2392
|
+
pinepaper_keyframe_animate
|
|
2393
|
+
itemId: "hex_main"
|
|
2394
|
+
keyframes:
|
|
2395
|
+
- time: 0
|
|
2396
|
+
properties: {scale: 0, opacity: 0}
|
|
2397
|
+
easing: "easeOut"
|
|
2398
|
+
- time: 0.5
|
|
2399
|
+
properties: {scale: 1.1, opacity: 1}
|
|
2400
|
+
easing: "easeInOut"
|
|
2401
|
+
- time: 0.7
|
|
2402
|
+
properties: {scale: 1, opacity: 1}
|
|
2403
|
+
duration: 0.7
|
|
2404
|
+
|
|
2405
|
+
// Triangle fades in and slides up
|
|
2406
|
+
pinepaper_keyframe_animate
|
|
2407
|
+
itemId: "triangle_inner"
|
|
2408
|
+
keyframes:
|
|
2409
|
+
- time: 0
|
|
2410
|
+
properties: {opacity: 0, y: 300}
|
|
2411
|
+
- time: 0.3
|
|
2412
|
+
properties: {opacity: 0, y: 300}
|
|
2413
|
+
- time: 0.6
|
|
2414
|
+
properties: {opacity: 1, y: 280}
|
|
2415
|
+
easing: "easeOut"
|
|
2416
|
+
duration: 0.6
|
|
2417
|
+
|
|
2418
|
+
// Accent dot pops in
|
|
2419
|
+
pinepaper_keyframe_animate
|
|
2420
|
+
itemId: "accent_dot"
|
|
2421
|
+
keyframes:
|
|
2422
|
+
- time: 0
|
|
2423
|
+
properties: {scale: 0}
|
|
2424
|
+
- time: 0.5
|
|
2425
|
+
properties: {scale: 0}
|
|
2426
|
+
- time: 0.7
|
|
2427
|
+
properties: {scale: 1.3}
|
|
2428
|
+
easing: "elastic"
|
|
2429
|
+
- time: 0.9
|
|
2430
|
+
properties: {scale: 1}
|
|
2431
|
+
duration: 0.9
|
|
2432
|
+
\`\`\`
|
|
2433
|
+
|
|
2434
|
+
## Step 4: Add Company Name
|
|
2435
|
+
|
|
2436
|
+
\`\`\`
|
|
2437
|
+
// Company name with typewriter effect
|
|
2438
|
+
pinepaper_create_item
|
|
2439
|
+
itemType: "text"
|
|
2440
|
+
position: {x: 480, y: 260}
|
|
2441
|
+
properties:
|
|
2442
|
+
content: "ACME"
|
|
2443
|
+
fontSize: 56
|
|
2444
|
+
fontFamily: "Arial Black, sans-serif"
|
|
2445
|
+
fontWeight: "bold"
|
|
2446
|
+
color: "#ffffff"
|
|
2447
|
+
→ company_name
|
|
2448
|
+
|
|
2449
|
+
// Tagline
|
|
2450
|
+
pinepaper_create_item
|
|
2451
|
+
itemType: "text"
|
|
2452
|
+
position: {x: 480, y: 310}
|
|
2453
|
+
properties:
|
|
2454
|
+
content: "Innovation Labs"
|
|
2455
|
+
fontSize: 20
|
|
2456
|
+
fontFamily: "Arial, sans-serif"
|
|
2457
|
+
color: "#94a3b8"
|
|
2458
|
+
→ tagline
|
|
2459
|
+
|
|
2460
|
+
// Typewriter effect on company name
|
|
2461
|
+
pinepaper_animate_item
|
|
2462
|
+
itemId: "company_name"
|
|
2463
|
+
animationType: "typewriter"
|
|
2464
|
+
speed: 3
|
|
2465
|
+
\`\`\`
|
|
2466
|
+
|
|
2467
|
+
## Step 5: Add Continuous Motion
|
|
2468
|
+
|
|
2469
|
+
Subtle animations that loop forever:
|
|
2470
|
+
|
|
2471
|
+
\`\`\`
|
|
2472
|
+
// Hexagon has gentle pulse
|
|
2473
|
+
pinepaper_animate_item
|
|
2474
|
+
itemId: "hex_main"
|
|
2475
|
+
animationType: "pulse"
|
|
2476
|
+
speed: 0.3
|
|
2477
|
+
|
|
2478
|
+
// Accent dot orbits slightly
|
|
2479
|
+
pinepaper_add_relation
|
|
2480
|
+
sourceId: "accent_dot"
|
|
2481
|
+
targetId: "hex_main"
|
|
2482
|
+
relationType: "orbits"
|
|
2483
|
+
params: {radius: 3, speed: 0.5}
|
|
2484
|
+
|
|
2485
|
+
// Triangle has subtle rotation
|
|
2486
|
+
pinepaper_animate_item
|
|
2487
|
+
itemId: "triangle_inner"
|
|
2488
|
+
animationType: "wobble"
|
|
2489
|
+
speed: 0.2
|
|
2490
|
+
\`\`\`
|
|
2491
|
+
|
|
2492
|
+
## Step 6: Add Sparkle Effect
|
|
2493
|
+
|
|
2494
|
+
\`\`\`
|
|
2495
|
+
// Sparkle on accent dot
|
|
2496
|
+
pinepaper_apply_effect
|
|
2497
|
+
itemId: "accent_dot"
|
|
2498
|
+
effectType: "sparkle"
|
|
2499
|
+
params:
|
|
2500
|
+
color: "#93c5fd"
|
|
2501
|
+
speed: 0.8
|
|
2502
|
+
size: 2
|
|
2503
|
+
\`\`\`
|
|
2504
|
+
|
|
2505
|
+
## Step 7: Add Decorative Elements
|
|
2506
|
+
|
|
2507
|
+
\`\`\`
|
|
2508
|
+
// Subtle line under text
|
|
2509
|
+
pinepaper_create_item
|
|
2510
|
+
itemType: "line"
|
|
2511
|
+
properties:
|
|
2512
|
+
from: [400, 340]
|
|
2513
|
+
to: [560, 340]
|
|
2514
|
+
strokeColor: "#3b82f6"
|
|
2515
|
+
strokeWidth: 2
|
|
2516
|
+
→ underline
|
|
2517
|
+
|
|
2518
|
+
// Animated line reveal
|
|
2519
|
+
pinepaper_keyframe_animate
|
|
2520
|
+
itemId: "underline"
|
|
2521
|
+
keyframes:
|
|
2522
|
+
- time: 0
|
|
2523
|
+
properties: {opacity: 0, scaleX: 0}
|
|
2524
|
+
- time: 0.8
|
|
2525
|
+
properties: {opacity: 0, scaleX: 0}
|
|
2526
|
+
- time: 1.2
|
|
2527
|
+
properties: {opacity: 1, scaleX: 1}
|
|
2528
|
+
easing: "easeOut"
|
|
2529
|
+
duration: 1.2
|
|
2530
|
+
\`\`\`
|
|
2531
|
+
|
|
2532
|
+
## Step 8: Apply Film Look (Optional)
|
|
2533
|
+
|
|
2534
|
+
\`\`\`
|
|
2535
|
+
pinepaper_add_filter filterType: "vignette" params: {intensity: 0.3, radius: 0.8}
|
|
2536
|
+
\`\`\`
|
|
2537
|
+
|
|
2538
|
+
## Step 9: Verify and Export
|
|
2539
|
+
|
|
2540
|
+
\`\`\`
|
|
2541
|
+
pinepaper_browser_screenshot
|
|
2542
|
+
|
|
2543
|
+
pinepaper_export_svg animated: true
|
|
2544
|
+
\`\`\`
|
|
2545
|
+
|
|
2546
|
+
## Result
|
|
2547
|
+
|
|
2548
|
+
A professional logo animation with:
|
|
2549
|
+
- Shapes assembling from nothing
|
|
2550
|
+
- Text typing in
|
|
2551
|
+
- Continuous subtle motion
|
|
2552
|
+
- Sparkle accents
|
|
2553
|
+
- Cinematic vignette
|
|
2554
|
+
|
|
2555
|
+
## Variations
|
|
2556
|
+
|
|
2557
|
+
### Minimalist Version
|
|
2558
|
+
Remove sparkle and reduce animation speeds by 50%.
|
|
2559
|
+
|
|
2560
|
+
### Energetic Version
|
|
2561
|
+
Increase all speeds, add more orbiting elements, use blast effect.
|
|
2562
|
+
|
|
2563
|
+
### Corporate Version
|
|
2564
|
+
Use grayscale filter, slower animations, no sparkle.
|
|
2565
|
+
|
|
2566
|
+
## Key Techniques
|
|
2567
|
+
|
|
2568
|
+
| Effect | Technique |
|
|
2569
|
+
|--------|-----------|
|
|
2570
|
+
| Assembly animation | Keyframes with scale 0→1 |
|
|
2571
|
+
| Text reveal | typewriter animation type |
|
|
2572
|
+
| Bounce overshoot | elastic easing |
|
|
2573
|
+
| Subtle motion | Low speed pulse/wobble |
|
|
2574
|
+
| Polish | sparkle effect, vignette filter |
|
|
2575
|
+
`,
|
|
2576
|
+
'pinepaper://examples/data-visualization': `# Data Visualization Example
|
|
2577
|
+
|
|
2578
|
+
Create animated charts and infographics that bring data to life.
|
|
2579
|
+
|
|
2580
|
+
## Animated Bar Chart
|
|
2581
|
+
|
|
2582
|
+
### Step 1: Setup
|
|
2583
|
+
\`\`\`
|
|
2584
|
+
pinepaper_browser_connect
|
|
2585
|
+
pinepaper_clear_canvas
|
|
2586
|
+
pinepaper_set_background_color color: "#1f2937"
|
|
2587
|
+
\`\`\`
|
|
2588
|
+
|
|
2589
|
+
### Step 2: Create Axes
|
|
2590
|
+
\`\`\`
|
|
2591
|
+
// Y-axis
|
|
2592
|
+
pinepaper_create_item itemType: "line"
|
|
2593
|
+
properties: {from: [100, 450], to: [100, 100], strokeColor: "#6b7280", strokeWidth: 2}
|
|
2594
|
+
|
|
2595
|
+
// X-axis
|
|
2596
|
+
pinepaper_create_item itemType: "line"
|
|
2597
|
+
properties: {from: [100, 450], to: [700, 450], strokeColor: "#6b7280", strokeWidth: 2}
|
|
2598
|
+
|
|
2599
|
+
// Y-axis labels
|
|
2600
|
+
pinepaper_create_item itemType: "text" position: {x: 70, y: 450}
|
|
2601
|
+
properties: {content: "0", fontSize: 14, color: "#9ca3af"}
|
|
2602
|
+
pinepaper_create_item itemType: "text" position: {x: 70, y: 350}
|
|
2603
|
+
properties: {content: "25", fontSize: 14, color: "#9ca3af"}
|
|
2604
|
+
pinepaper_create_item itemType: "text" position: {x: 70, y: 250}
|
|
2605
|
+
properties: {content: "50", fontSize: 14, color: "#9ca3af"}
|
|
2606
|
+
pinepaper_create_item itemType: "text" position: {x: 70, y: 150}
|
|
2607
|
+
properties: {content: "75", fontSize: 14, color: "#9ca3af"}
|
|
2608
|
+
\`\`\`
|
|
2609
|
+
|
|
2610
|
+
### Step 3: Create Animated Bars
|
|
2611
|
+
Data: Q1=45, Q2=62, Q3=38, Q4=71
|
|
2612
|
+
|
|
2613
|
+
\`\`\`
|
|
2614
|
+
// Q1 Bar (height: 45% of 300px = 135px)
|
|
2615
|
+
pinepaper_create_item itemType: "rectangle" position: {x: 200, y: 382}
|
|
2616
|
+
properties: {width: 60, height: 135, color: "#3b82f6"}
|
|
2617
|
+
→ bar_q1
|
|
2618
|
+
|
|
2619
|
+
// Q2 Bar (height: 62% = 186px)
|
|
2620
|
+
pinepaper_create_item itemType: "rectangle" position: {x: 320, y: 357}
|
|
2621
|
+
properties: {width: 60, height: 186, color: "#8b5cf6"}
|
|
2622
|
+
→ bar_q2
|
|
2623
|
+
|
|
2624
|
+
// Q3 Bar (height: 38% = 114px)
|
|
2625
|
+
pinepaper_create_item itemType: "rectangle" position: {x: 440, y: 393}
|
|
2626
|
+
properties: {width: 60, height: 114, color: "#ec4899"}
|
|
2627
|
+
→ bar_q3
|
|
2628
|
+
|
|
2629
|
+
// Q4 Bar (height: 71% = 213px)
|
|
2630
|
+
pinepaper_create_item itemType: "rectangle" position: {x: 560, y: 343}
|
|
2631
|
+
properties: {width: 60, height: 213, color: "#f59e0b"}
|
|
2632
|
+
→ bar_q4
|
|
2633
|
+
|
|
2634
|
+
// X-axis labels
|
|
2635
|
+
pinepaper_create_item itemType: "text" position: {x: 200, y: 480}
|
|
2636
|
+
properties: {content: "Q1", fontSize: 16, color: "#ffffff"}
|
|
2637
|
+
pinepaper_create_item itemType: "text" position: {x: 320, y: 480}
|
|
2638
|
+
properties: {content: "Q2", fontSize: 16, color: "#ffffff"}
|
|
2639
|
+
pinepaper_create_item itemType: "text" position: {x: 440, y: 480}
|
|
2640
|
+
properties: {content: "Q3", fontSize: 16, color: "#ffffff"}
|
|
2641
|
+
pinepaper_create_item itemType: "text" position: {x: 560, y: 480}
|
|
2642
|
+
properties: {content: "Q4", fontSize: 16, color: "#ffffff"}
|
|
2643
|
+
\`\`\`
|
|
2644
|
+
|
|
2645
|
+
### Step 4: Animate Bars Growing
|
|
2646
|
+
\`\`\`
|
|
2647
|
+
// Bars grow from bottom
|
|
2648
|
+
pinepaper_keyframe_animate itemId: "bar_q1"
|
|
2649
|
+
keyframes:
|
|
2650
|
+
- time: 0
|
|
2651
|
+
properties: {scaleY: 0}
|
|
2652
|
+
- time: 0.5
|
|
2653
|
+
properties: {scaleY: 1}
|
|
2654
|
+
easing: "easeOut"
|
|
2655
|
+
duration: 0.5
|
|
2656
|
+
|
|
2657
|
+
pinepaper_keyframe_animate itemId: "bar_q2"
|
|
2658
|
+
keyframes:
|
|
2659
|
+
- time: 0
|
|
2660
|
+
properties: {scaleY: 0}
|
|
2661
|
+
- time: 0.2
|
|
2662
|
+
properties: {scaleY: 0}
|
|
2663
|
+
- time: 0.7
|
|
2664
|
+
properties: {scaleY: 1}
|
|
2665
|
+
easing: "easeOut"
|
|
2666
|
+
duration: 0.7
|
|
2667
|
+
|
|
2668
|
+
pinepaper_keyframe_animate itemId: "bar_q3"
|
|
2669
|
+
keyframes:
|
|
2670
|
+
- time: 0
|
|
2671
|
+
properties: {scaleY: 0}
|
|
2672
|
+
- time: 0.4
|
|
2673
|
+
properties: {scaleY: 0}
|
|
2674
|
+
- time: 0.9
|
|
2675
|
+
properties: {scaleY: 1}
|
|
2676
|
+
easing: "easeOut"
|
|
2677
|
+
duration: 0.9
|
|
2678
|
+
|
|
2679
|
+
pinepaper_keyframe_animate itemId: "bar_q4"
|
|
2680
|
+
keyframes:
|
|
2681
|
+
- time: 0
|
|
2682
|
+
properties: {scaleY: 0}
|
|
2683
|
+
- time: 0.6
|
|
2684
|
+
properties: {scaleY: 0}
|
|
2685
|
+
- time: 1.1
|
|
2686
|
+
properties: {scaleY: 1}
|
|
2687
|
+
easing: "easeOut"
|
|
2688
|
+
duration: 1.1
|
|
2689
|
+
\`\`\`
|
|
2690
|
+
|
|
2691
|
+
---
|
|
2692
|
+
|
|
2693
|
+
## Animated Pie Chart
|
|
2694
|
+
|
|
2695
|
+
### Step 1: Create Pie Slices
|
|
2696
|
+
Using arc paths for pie segments:
|
|
2697
|
+
|
|
2698
|
+
\`\`\`
|
|
2699
|
+
pinepaper_set_background_color color: "#1e293b"
|
|
2700
|
+
|
|
2701
|
+
// Center point for reference
|
|
2702
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 300}
|
|
2703
|
+
properties: {radius: 5, color: null}
|
|
2704
|
+
→ center
|
|
2705
|
+
|
|
2706
|
+
// Slice 1: 40% (144 degrees) - Blue
|
|
2707
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 300}
|
|
2708
|
+
properties:
|
|
2709
|
+
pathData: "M 0 0 L 0 -100 A 100 100 0 0 1 95 31 Z"
|
|
2710
|
+
fillColor: "#3b82f6"
|
|
2711
|
+
strokeColor: "#1e293b"
|
|
2712
|
+
strokeWidth: 2
|
|
2713
|
+
→ slice1
|
|
2714
|
+
|
|
2715
|
+
// Slice 2: 25% (90 degrees) - Purple
|
|
2716
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 300}
|
|
2717
|
+
properties:
|
|
2718
|
+
pathData: "M 0 0 L 95 31 A 100 100 0 0 1 0 100 Z"
|
|
2719
|
+
fillColor: "#8b5cf6"
|
|
2720
|
+
strokeColor: "#1e293b"
|
|
2721
|
+
strokeWidth: 2
|
|
2722
|
+
→ slice2
|
|
2723
|
+
|
|
2724
|
+
// Slice 3: 20% (72 degrees) - Pink
|
|
2725
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 300}
|
|
2726
|
+
properties:
|
|
2727
|
+
pathData: "M 0 0 L 0 100 A 100 100 0 0 1 -95 31 Z"
|
|
2728
|
+
fillColor: "#ec4899"
|
|
2729
|
+
strokeColor: "#1e293b"
|
|
2730
|
+
strokeWidth: 2
|
|
2731
|
+
→ slice3
|
|
2732
|
+
|
|
2733
|
+
// Slice 4: 15% (54 degrees) - Orange
|
|
2734
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 300}
|
|
2735
|
+
properties:
|
|
2736
|
+
pathData: "M 0 0 L -95 31 A 100 100 0 0 1 0 -100 Z"
|
|
2737
|
+
fillColor: "#f59e0b"
|
|
2738
|
+
strokeColor: "#1e293b"
|
|
2739
|
+
strokeWidth: 2
|
|
2740
|
+
→ slice4
|
|
2741
|
+
\`\`\`
|
|
2742
|
+
|
|
2743
|
+
### Step 2: Animate Pie Spinning In
|
|
2744
|
+
\`\`\`
|
|
2745
|
+
// Entire pie rotates in
|
|
2746
|
+
pinepaper_animate_item itemId: "slice1" animationType: "rotate" speed: 0.1
|
|
2747
|
+
pinepaper_keyframe_animate itemId: "slice1"
|
|
2748
|
+
keyframes:
|
|
2749
|
+
- time: 0
|
|
2750
|
+
properties: {scale: 0, rotation: -180}
|
|
2751
|
+
- time: 1
|
|
2752
|
+
properties: {scale: 1, rotation: 0}
|
|
2753
|
+
easing: "easeOut"
|
|
2754
|
+
duration: 1
|
|
2755
|
+
\`\`\`
|
|
2756
|
+
|
|
2757
|
+
### Step 3: Add Labels
|
|
2758
|
+
\`\`\`
|
|
2759
|
+
pinepaper_create_item itemType: "text" position: {x: 440, y: 240}
|
|
2760
|
+
properties: {content: "40%", fontSize: 18, fontWeight: "bold", color: "#ffffff"}
|
|
2761
|
+
→ label1
|
|
2762
|
+
pinepaper_add_relation sourceId: "label1" targetId: "slice1" relationType: "attached_to"
|
|
2763
|
+
params: {offset: [40, -60]}
|
|
2764
|
+
\`\`\`
|
|
2765
|
+
|
|
2766
|
+
---
|
|
2767
|
+
|
|
2768
|
+
## Animated Line Graph
|
|
2769
|
+
|
|
2770
|
+
### Create Data Points and Line
|
|
2771
|
+
\`\`\`
|
|
2772
|
+
// Data points: (100,350), (200,280), (300,320), (400,200), (500,180), (600,250)
|
|
2773
|
+
|
|
2774
|
+
// Line connecting points
|
|
2775
|
+
pinepaper_create_item itemType: "path" position: {x: 350, y: 265}
|
|
2776
|
+
properties:
|
|
2777
|
+
segments: [[-250, 85], [-150, 15], [-50, 55], [50, -65], [150, -85], [250, -15]]
|
|
2778
|
+
smooth: true
|
|
2779
|
+
closed: false
|
|
2780
|
+
strokeColor: "#22c55e"
|
|
2781
|
+
strokeWidth: 3
|
|
2782
|
+
fillColor: null
|
|
2783
|
+
→ data_line
|
|
2784
|
+
|
|
2785
|
+
// Data points as circles
|
|
2786
|
+
pinepaper_create_item itemType: "circle" position: {x: 100, y: 350}
|
|
2787
|
+
properties: {radius: 6, color: "#22c55e"}
|
|
2788
|
+
→ point1
|
|
2789
|
+
|
|
2790
|
+
pinepaper_create_item itemType: "circle" position: {x: 200, y: 280}
|
|
2791
|
+
properties: {radius: 6, color: "#22c55e"}
|
|
2792
|
+
→ point2
|
|
2793
|
+
|
|
2794
|
+
pinepaper_create_item itemType: "circle" position: {x: 300, y: 320}
|
|
2795
|
+
properties: {radius: 6, color: "#22c55e"}
|
|
2796
|
+
→ point3
|
|
2797
|
+
|
|
2798
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 200}
|
|
2799
|
+
properties: {radius: 6, color: "#22c55e"}
|
|
2800
|
+
→ point4
|
|
2801
|
+
|
|
2802
|
+
pinepaper_create_item itemType: "circle" position: {x: 500, y: 180}
|
|
2803
|
+
properties: {radius: 6, color: "#22c55e"}
|
|
2804
|
+
→ point5
|
|
2805
|
+
|
|
2806
|
+
pinepaper_create_item itemType: "circle" position: {x: 600, y: 250}
|
|
2807
|
+
properties: {radius: 6, color: "#22c55e"}
|
|
2808
|
+
→ point6
|
|
2809
|
+
\`\`\`
|
|
2810
|
+
|
|
2811
|
+
### Animate Points Appearing
|
|
2812
|
+
\`\`\`
|
|
2813
|
+
// Points pop in sequentially
|
|
2814
|
+
pinepaper_keyframe_animate itemId: "point1"
|
|
2815
|
+
keyframes:
|
|
2816
|
+
- time: 0
|
|
2817
|
+
properties: {scale: 0}
|
|
2818
|
+
- time: 0.2
|
|
2819
|
+
properties: {scale: 1.3}
|
|
2820
|
+
easing: "easeOut"
|
|
2821
|
+
- time: 0.3
|
|
2822
|
+
properties: {scale: 1}
|
|
2823
|
+
duration: 0.3
|
|
2824
|
+
|
|
2825
|
+
pinepaper_keyframe_animate itemId: "point2"
|
|
2826
|
+
keyframes:
|
|
2827
|
+
- time: 0
|
|
2828
|
+
properties: {scale: 0}
|
|
2829
|
+
- time: 0.15
|
|
2830
|
+
properties: {scale: 0}
|
|
2831
|
+
- time: 0.35
|
|
2832
|
+
properties: {scale: 1.3}
|
|
2833
|
+
- time: 0.45
|
|
2834
|
+
properties: {scale: 1}
|
|
2835
|
+
duration: 0.45
|
|
2836
|
+
|
|
2837
|
+
// ... continue for remaining points with staggered delays
|
|
2838
|
+
\`\`\`
|
|
2839
|
+
|
|
2840
|
+
---
|
|
2841
|
+
|
|
2842
|
+
## Gauge/Meter Chart
|
|
2843
|
+
|
|
2844
|
+
\`\`\`
|
|
2845
|
+
// Gauge background arc
|
|
2846
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 350}
|
|
2847
|
+
properties:
|
|
2848
|
+
pathData: "M -120 0 A 120 120 0 0 1 120 0"
|
|
2849
|
+
strokeColor: "#374151"
|
|
2850
|
+
strokeWidth: 20
|
|
2851
|
+
fillColor: null
|
|
2852
|
+
→ gauge_bg
|
|
2853
|
+
|
|
2854
|
+
// Gauge value arc (75% = 135 degrees)
|
|
2855
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 350}
|
|
2856
|
+
properties:
|
|
2857
|
+
pathData: "M -120 0 A 120 120 0 0 1 85 -85"
|
|
2858
|
+
strokeColor: "#22c55e"
|
|
2859
|
+
strokeWidth: 20
|
|
2860
|
+
fillColor: null
|
|
2861
|
+
→ gauge_value
|
|
2862
|
+
|
|
2863
|
+
// Center label
|
|
2864
|
+
pinepaper_create_item itemType: "text" position: {x: 400, y: 350}
|
|
2865
|
+
properties: {content: "75%", fontSize: 48, fontWeight: "bold", color: "#ffffff"}
|
|
2866
|
+
→ gauge_label
|
|
2867
|
+
|
|
2868
|
+
// Needle
|
|
2869
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 350}
|
|
2870
|
+
properties:
|
|
2871
|
+
segments: [[0, 10], [-5, 0], [0, -90], [5, 0]]
|
|
2872
|
+
closed: true
|
|
2873
|
+
fillColor: "#ef4444"
|
|
2874
|
+
→ needle
|
|
2875
|
+
|
|
2876
|
+
// Animate needle sweeping to value
|
|
2877
|
+
pinepaper_keyframe_animate itemId: "needle"
|
|
2878
|
+
keyframes:
|
|
2879
|
+
- time: 0
|
|
2880
|
+
properties: {rotation: -90}
|
|
2881
|
+
- time: 1.5
|
|
2882
|
+
properties: {rotation: 45}
|
|
2883
|
+
easing: "easeOut"
|
|
2884
|
+
duration: 1.5
|
|
2885
|
+
\`\`\`
|
|
2886
|
+
|
|
2887
|
+
## Key Techniques for Data Viz
|
|
2888
|
+
|
|
2889
|
+
| Visualization | Key Techniques |
|
|
2890
|
+
|---------------|----------------|
|
|
2891
|
+
| Bar Chart | Rectangles + scaleY keyframes |
|
|
2892
|
+
| Pie Chart | Arc paths + rotation |
|
|
2893
|
+
| Line Graph | Smooth path + point circles |
|
|
2894
|
+
| Gauge | Arc paths + needle rotation |
|
|
2895
|
+
| Animation | Staggered keyframes, easeOut |
|
|
2896
|
+
| Labels | Text with attached_to relations |
|
|
2897
|
+
`,
|
|
2898
|
+
'pinepaper://examples/particle-systems': `# Particle Systems Example
|
|
2899
|
+
|
|
2900
|
+
Build dynamic particle effects like fireworks, starfields, snow, and fire.
|
|
2901
|
+
|
|
2902
|
+
## Starfield / Space Background
|
|
2903
|
+
|
|
2904
|
+
### Step 1: Create Background
|
|
2905
|
+
\`\`\`
|
|
2906
|
+
pinepaper_browser_connect
|
|
2907
|
+
pinepaper_clear_canvas
|
|
2908
|
+
pinepaper_set_background_color color: "#000011"
|
|
2909
|
+
\`\`\`
|
|
2910
|
+
|
|
2911
|
+
### Step 2: Create Star Layers (Parallax Depth)
|
|
2912
|
+
\`\`\`
|
|
2913
|
+
// Far stars (small, slow)
|
|
2914
|
+
pinepaper_create_item itemType: "circle" position: {x: 100, y: 150} properties: {radius: 1, color: "#6b7280"}
|
|
2915
|
+
pinepaper_create_item itemType: "circle" position: {x: 250, y: 80} properties: {radius: 1, color: "#6b7280"}
|
|
2916
|
+
pinepaper_create_item itemType: "circle" position: {x: 450, y: 200} properties: {radius: 1, color: "#6b7280"}
|
|
2917
|
+
pinepaper_create_item itemType: "circle" position: {x: 600, y: 120} properties: {radius: 1, color: "#6b7280"}
|
|
2918
|
+
pinepaper_create_item itemType: "circle" position: {x: 700, y: 250} properties: {radius: 1, color: "#6b7280"}
|
|
2919
|
+
|
|
2920
|
+
// Mid stars (medium)
|
|
2921
|
+
pinepaper_create_item itemType: "circle" position: {x: 150, y: 300} properties: {radius: 2, color: "#9ca3af"}
|
|
2922
|
+
→ mid1
|
|
2923
|
+
pinepaper_create_item itemType: "circle" position: {x: 350, y: 400} properties: {radius: 2, color: "#9ca3af"}
|
|
2924
|
+
→ mid2
|
|
2925
|
+
pinepaper_create_item itemType: "circle" position: {x: 550, y: 350} properties: {radius: 2, color: "#9ca3af"}
|
|
2926
|
+
→ mid3
|
|
2927
|
+
|
|
2928
|
+
// Near stars (larger, twinkling)
|
|
2929
|
+
pinepaper_create_item itemType: "circle" position: {x: 200, y: 250} properties: {radius: 3, color: "#e5e7eb"}
|
|
2930
|
+
→ near1
|
|
2931
|
+
pinepaper_create_item itemType: "circle" position: {x: 500, y: 180} properties: {radius: 3, color: "#e5e7eb"}
|
|
2932
|
+
→ near2
|
|
2933
|
+
pinepaper_create_item itemType: "circle" position: {x: 650, y: 400} properties: {radius: 3, color: "#e5e7eb"}
|
|
2934
|
+
→ near3
|
|
2935
|
+
\`\`\`
|
|
2936
|
+
|
|
2937
|
+
### Step 3: Add Twinkle Animation
|
|
2938
|
+
\`\`\`
|
|
2939
|
+
pinepaper_animate_item itemId: "near1" animationType: "fade" speed: 2
|
|
2940
|
+
pinepaper_animate_item itemId: "near2" animationType: "fade" speed: 1.5
|
|
2941
|
+
pinepaper_animate_item itemId: "near3" animationType: "fade" speed: 2.5
|
|
2942
|
+
|
|
2943
|
+
pinepaper_animate_item itemId: "mid1" animationType: "pulse" speed: 0.5
|
|
2944
|
+
pinepaper_animate_item itemId: "mid2" animationType: "pulse" speed: 0.7
|
|
2945
|
+
\`\`\`
|
|
2946
|
+
|
|
2947
|
+
### Step 4: Add Shooting Star
|
|
2948
|
+
\`\`\`
|
|
2949
|
+
// Shooting star head
|
|
2950
|
+
pinepaper_create_item itemType: "circle" position: {x: 100, y: 100} properties: {radius: 4, color: "#fef3c7"}
|
|
2951
|
+
→ shooting_star
|
|
2952
|
+
|
|
2953
|
+
// Shooting star tail
|
|
2954
|
+
pinepaper_create_item itemType: "path" position: {x: 100, y: 100}
|
|
2955
|
+
properties:
|
|
2956
|
+
segments: [[0, 0], [-30, 15], [-80, 40], [-150, 75]]
|
|
2957
|
+
smooth: true
|
|
2958
|
+
strokeColor: "#fef3c7"
|
|
2959
|
+
strokeWidth: 2
|
|
2960
|
+
opacity: 0.5
|
|
2961
|
+
fillColor: null
|
|
2962
|
+
→ star_tail
|
|
2963
|
+
|
|
2964
|
+
// Tail follows star
|
|
2965
|
+
pinepaper_add_relation sourceId: "star_tail" targetId: "shooting_star" relationType: "attached_to"
|
|
2966
|
+
params: {offset: [0, 0]}
|
|
2967
|
+
|
|
2968
|
+
// Animate shooting star across screen
|
|
2969
|
+
pinepaper_keyframe_animate itemId: "shooting_star"
|
|
2970
|
+
keyframes:
|
|
2971
|
+
- time: 0
|
|
2972
|
+
properties: {x: 100, y: 100, opacity: 1}
|
|
2973
|
+
- time: 2
|
|
2974
|
+
properties: {x: 700, y: 400, opacity: 0}
|
|
2975
|
+
duration: 2
|
|
2976
|
+
loop: true
|
|
2977
|
+
\`\`\`
|
|
2978
|
+
|
|
2979
|
+
---
|
|
2980
|
+
|
|
2981
|
+
## Snowfall Effect
|
|
2982
|
+
|
|
2983
|
+
\`\`\`
|
|
2984
|
+
pinepaper_set_background_color color: "#1e3a5f"
|
|
2985
|
+
|
|
2986
|
+
// Create snowflakes at different sizes and speeds
|
|
2987
|
+
// Large, slow flakes (foreground)
|
|
2988
|
+
pinepaper_create_item itemType: "circle" position: {x: 150, y: 50} properties: {radius: 5, color: "#ffffff"}
|
|
2989
|
+
→ snow1
|
|
2990
|
+
pinepaper_animate_item itemId: "snow1" animationType: "bounce" speed: 0.3
|
|
2991
|
+
pinepaper_animate_item itemId: "snow1" animationType: "wobble" speed: 0.5
|
|
2992
|
+
|
|
2993
|
+
pinepaper_create_item itemType: "circle" position: {x: 400, y: 100} properties: {radius: 4, color: "#ffffff"}
|
|
2994
|
+
→ snow2
|
|
2995
|
+
pinepaper_animate_item itemId: "snow2" animationType: "bounce" speed: 0.35
|
|
2996
|
+
pinepaper_animate_item itemId: "snow2" animationType: "wobble" speed: 0.6
|
|
2997
|
+
|
|
2998
|
+
pinepaper_create_item itemType: "circle" position: {x: 650, y: 30} properties: {radius: 5, color: "#ffffff"}
|
|
2999
|
+
→ snow3
|
|
3000
|
+
pinepaper_animate_item itemId: "snow3" animationType: "bounce" speed: 0.25
|
|
3001
|
+
pinepaper_animate_item itemId: "snow3" animationType: "wobble" speed: 0.4
|
|
3002
|
+
|
|
3003
|
+
// Medium flakes
|
|
3004
|
+
pinepaper_create_item itemType: "circle" position: {x: 250, y: 150} properties: {radius: 3, color: "#e5e7eb"}
|
|
3005
|
+
→ snow4
|
|
3006
|
+
pinepaper_animate_item itemId: "snow4" animationType: "bounce" speed: 0.4
|
|
3007
|
+
|
|
3008
|
+
pinepaper_create_item itemType: "circle" position: {x: 500, y: 80} properties: {radius: 3, color: "#e5e7eb"}
|
|
3009
|
+
→ snow5
|
|
3010
|
+
pinepaper_animate_item itemId: "snow5" animationType: "bounce" speed: 0.45
|
|
3011
|
+
|
|
3012
|
+
// Small, fast flakes (background)
|
|
3013
|
+
pinepaper_create_item itemType: "circle" position: {x: 100, y: 200} properties: {radius: 2, color: "#d1d5db"}
|
|
3014
|
+
→ snow6
|
|
3015
|
+
pinepaper_animate_item itemId: "snow6" animationType: "bounce" speed: 0.6
|
|
3016
|
+
|
|
3017
|
+
pinepaper_create_item itemType: "circle" position: {x: 350, y: 250} properties: {radius: 2, color: "#d1d5db"}
|
|
3018
|
+
→ snow7
|
|
3019
|
+
pinepaper_animate_item itemId: "snow7" animationType: "bounce" speed: 0.55
|
|
3020
|
+
\`\`\`
|
|
3021
|
+
|
|
3022
|
+
---
|
|
3023
|
+
|
|
3024
|
+
## Fireworks Display
|
|
3025
|
+
|
|
3026
|
+
\`\`\`
|
|
3027
|
+
pinepaper_set_background_color color: "#0a0a1a"
|
|
3028
|
+
|
|
3029
|
+
// Firework 1: Red burst
|
|
3030
|
+
pinepaper_create_item itemType: "circle" position: {x: 250, y: 200} properties: {radius: 8, color: "#ef4444"}
|
|
3031
|
+
→ fw1_center
|
|
3032
|
+
|
|
3033
|
+
pinepaper_apply_effect itemId: "fw1_center" effectType: "blast"
|
|
3034
|
+
params: {color: "#fca5a5", radius: 120, count: 25}
|
|
3035
|
+
|
|
3036
|
+
// Animate burst
|
|
3037
|
+
pinepaper_keyframe_animate itemId: "fw1_center"
|
|
3038
|
+
keyframes:
|
|
3039
|
+
- time: 0
|
|
3040
|
+
properties: {scale: 0, y: 500}
|
|
3041
|
+
- time: 0.5
|
|
3042
|
+
properties: {scale: 0.5, y: 200}
|
|
3043
|
+
- time: 0.7
|
|
3044
|
+
properties: {scale: 1, y: 200}
|
|
3045
|
+
- time: 1.5
|
|
3046
|
+
properties: {scale: 0, opacity: 0}
|
|
3047
|
+
duration: 1.5
|
|
3048
|
+
loop: true
|
|
3049
|
+
|
|
3050
|
+
// Firework 2: Gold burst
|
|
3051
|
+
pinepaper_create_item itemType: "circle" position: {x: 500, y: 180} properties: {radius: 8, color: "#fbbf24"}
|
|
3052
|
+
→ fw2_center
|
|
3053
|
+
|
|
3054
|
+
pinepaper_apply_effect itemId: "fw2_center" effectType: "blast"
|
|
3055
|
+
params: {color: "#fef3c7", radius: 100, count: 20}
|
|
3056
|
+
|
|
3057
|
+
// Sparkle on bursts
|
|
3058
|
+
pinepaper_apply_effect itemId: "fw1_center" effectType: "sparkle"
|
|
3059
|
+
params: {color: "#fca5a5", speed: 2, size: 3}
|
|
3060
|
+
pinepaper_apply_effect itemId: "fw2_center" effectType: "sparkle"
|
|
3061
|
+
params: {color: "#fef3c7", speed: 2, size: 3}
|
|
3062
|
+
\`\`\`
|
|
3063
|
+
|
|
3064
|
+
---
|
|
3065
|
+
|
|
3066
|
+
## Fire/Flame Effect
|
|
3067
|
+
|
|
3068
|
+
\`\`\`
|
|
3069
|
+
pinepaper_set_background_color color: "#1a1a2e"
|
|
3070
|
+
|
|
3071
|
+
// Fire base (log)
|
|
3072
|
+
pinepaper_create_item itemType: "rectangle" position: {x: 400, y: 480}
|
|
3073
|
+
properties: {width: 120, height: 30, color: "#78350f", cornerRadius: 5}
|
|
3074
|
+
|
|
3075
|
+
// Flame layers (outer to inner)
|
|
3076
|
+
// Outer red glow
|
|
3077
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 400}
|
|
3078
|
+
properties:
|
|
3079
|
+
pathData: "M 0 60 Q -50 30 -40 -20 Q -20 -60 0 -80 Q 20 -60 40 -20 Q 50 30 0 60"
|
|
3080
|
+
fillColor: "#dc2626"
|
|
3081
|
+
opacity: 0.6
|
|
3082
|
+
→ flame_outer
|
|
3083
|
+
|
|
3084
|
+
// Middle orange
|
|
3085
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 410}
|
|
3086
|
+
properties:
|
|
3087
|
+
pathData: "M 0 45 Q -35 20 -28 -15 Q -14 -45 0 -60 Q 14 -45 28 -15 Q 35 20 0 45"
|
|
3088
|
+
fillColor: "#f59e0b"
|
|
3089
|
+
opacity: 0.8
|
|
3090
|
+
→ flame_mid
|
|
3091
|
+
|
|
3092
|
+
// Inner yellow
|
|
3093
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 420}
|
|
3094
|
+
properties:
|
|
3095
|
+
pathData: "M 0 30 Q -20 10 -15 -10 Q -8 -30 0 -40 Q 8 -30 15 -10 Q 20 10 0 30"
|
|
3096
|
+
fillColor: "#fbbf24"
|
|
3097
|
+
→ flame_inner
|
|
3098
|
+
|
|
3099
|
+
// Core white
|
|
3100
|
+
pinepaper_create_item itemType: "path" position: {x: 400, y: 430}
|
|
3101
|
+
properties:
|
|
3102
|
+
pathData: "M 0 15 Q -8 5 -5 -5 Q -3 -15 0 -20 Q 3 -15 5 -5 Q 8 5 0 15"
|
|
3103
|
+
fillColor: "#fef3c7"
|
|
3104
|
+
→ flame_core
|
|
3105
|
+
|
|
3106
|
+
// Animate flames
|
|
3107
|
+
pinepaper_animate_item itemId: "flame_outer" animationType: "wobble" speed: 3
|
|
3108
|
+
pinepaper_animate_item itemId: "flame_mid" animationType: "wobble" speed: 3.5
|
|
3109
|
+
pinepaper_animate_item itemId: "flame_inner" animationType: "wobble" speed: 4
|
|
3110
|
+
pinepaper_animate_item itemId: "flame_core" animationType: "wobble" speed: 4.5
|
|
3111
|
+
|
|
3112
|
+
// Add flickering
|
|
3113
|
+
pinepaper_animate_item itemId: "flame_outer" animationType: "fade" speed: 5
|
|
3114
|
+
pinepaper_animate_item itemId: "flame_mid" animationType: "fade" speed: 6
|
|
3115
|
+
|
|
3116
|
+
// Sparks rising
|
|
3117
|
+
pinepaper_create_item itemType: "circle" position: {x: 390, y: 380} properties: {radius: 2, color: "#fbbf24"}
|
|
3118
|
+
→ spark1
|
|
3119
|
+
pinepaper_animate_item itemId: "spark1" animationType: "bounce" speed: 2
|
|
3120
|
+
pinepaper_animate_item itemId: "spark1" animationType: "fade" speed: 3
|
|
3121
|
+
|
|
3122
|
+
pinepaper_create_item itemType: "circle" position: {x: 410, y: 370} properties: {radius: 2, color: "#f59e0b"}
|
|
3123
|
+
→ spark2
|
|
3124
|
+
pinepaper_animate_item itemId: "spark2" animationType: "bounce" speed: 2.2
|
|
3125
|
+
pinepaper_animate_item itemId: "spark2" animationType: "fade" speed: 2.5
|
|
3126
|
+
\`\`\`
|
|
3127
|
+
|
|
3128
|
+
---
|
|
3129
|
+
|
|
3130
|
+
## Bubble Float Effect
|
|
3131
|
+
|
|
3132
|
+
\`\`\`
|
|
3133
|
+
pinepaper_set_background_color color: "#0ea5e9"
|
|
3134
|
+
|
|
3135
|
+
// Create bubbles with different sizes
|
|
3136
|
+
pinepaper_create_item itemType: "circle" position: {x: 150, y: 500}
|
|
3137
|
+
properties: {radius: 20, fillColor: null, strokeColor: "#ffffff", strokeWidth: 2, opacity: 0.6}
|
|
3138
|
+
→ bubble1
|
|
3139
|
+
|
|
3140
|
+
pinepaper_create_item itemType: "circle" position: {x: 300, y: 520}
|
|
3141
|
+
properties: {radius: 15, fillColor: null, strokeColor: "#ffffff", strokeWidth: 2, opacity: 0.5}
|
|
3142
|
+
→ bubble2
|
|
3143
|
+
|
|
3144
|
+
pinepaper_create_item itemType: "circle" position: {x: 450, y: 480}
|
|
3145
|
+
properties: {radius: 25, fillColor: null, strokeColor: "#ffffff", strokeWidth: 2, opacity: 0.7}
|
|
3146
|
+
→ bubble3
|
|
3147
|
+
|
|
3148
|
+
pinepaper_create_item itemType: "circle" position: {x: 600, y: 510}
|
|
3149
|
+
properties: {radius: 12, fillColor: null, strokeColor: "#ffffff", strokeWidth: 2, opacity: 0.5}
|
|
3150
|
+
→ bubble4
|
|
3151
|
+
|
|
3152
|
+
// Add highlight to each bubble
|
|
3153
|
+
pinepaper_create_item itemType: "circle" position: {x: 145, y: 490}
|
|
3154
|
+
properties: {radius: 4, color: "#ffffff", opacity: 0.8}
|
|
3155
|
+
→ highlight1
|
|
3156
|
+
pinepaper_add_relation sourceId: "highlight1" targetId: "bubble1" relationType: "attached_to"
|
|
3157
|
+
params: {offset: [-5, -10]}
|
|
3158
|
+
|
|
3159
|
+
// Animate bubbles floating up with wobble
|
|
3160
|
+
pinepaper_animate_item itemId: "bubble1" animationType: "bounce" speed: 0.3
|
|
3161
|
+
pinepaper_animate_item itemId: "bubble1" animationType: "wobble" speed: 0.5
|
|
3162
|
+
|
|
3163
|
+
pinepaper_animate_item itemId: "bubble2" animationType: "bounce" speed: 0.35
|
|
3164
|
+
pinepaper_animate_item itemId: "bubble2" animationType: "wobble" speed: 0.6
|
|
3165
|
+
|
|
3166
|
+
pinepaper_animate_item itemId: "bubble3" animationType: "bounce" speed: 0.25
|
|
3167
|
+
pinepaper_animate_item itemId: "bubble3" animationType: "wobble" speed: 0.4
|
|
3168
|
+
|
|
3169
|
+
pinepaper_animate_item itemId: "bubble4" animationType: "bounce" speed: 0.4
|
|
3170
|
+
pinepaper_animate_item itemId: "bubble4" animationType: "wobble" speed: 0.7
|
|
3171
|
+
\`\`\`
|
|
306
3172
|
|
|
307
|
-
##
|
|
3173
|
+
## Particle System Techniques
|
|
308
3174
|
|
|
309
|
-
|
|
310
|
-
|
|
3175
|
+
| Effect | Key Techniques |
|
|
3176
|
+
|--------|----------------|
|
|
3177
|
+
| Stars | Multiple sizes, fade animation, parallax layers |
|
|
3178
|
+
| Snow | bounce + wobble, size variation, opacity variation |
|
|
3179
|
+
| Fireworks | blast effect + sparkle, keyframe rise animation |
|
|
3180
|
+
| Fire | Layered paths, wobble + fade, warm color gradient |
|
|
3181
|
+
| Bubbles | Stroke-only circles, attached highlights, bounce |
|
|
3182
|
+
| Rain | Lines at angle, fast bounce, blue tints |
|
|
3183
|
+
| Dust | Tiny circles, slow fade, random positions |
|
|
3184
|
+
| Confetti | Small rectangles, rotate + bounce, rainbow colors |
|
|
311
3185
|
`,
|
|
312
3186
|
};
|
|
313
3187
|
// =============================================================================
|