route-graphics 0.0.34 → 0.1.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.
Files changed (3) hide show
  1. package/README.md +40 -1171
  2. package/dist/RouteGraphics.js +106 -106
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,1231 +1,100 @@
1
+ # Route Graphics
1
2
 
2
- ## Overview
3
+ Route Graphics is a declarative 2D UI/rendering system built on PixiJS. You describe states with JSON, then Route Graphics handles element lifecycle, animations, audio, and interaction events for you.
3
4
 
4
- Route Graphics is a declarative UI system that enables developers to create rich, interactive 2D interfaces through JSON configurations. Instead of manipulating DOM elements directly, you define your interface structure using JSON, and Route Graphics handles the rendering, animations, audio, and interactions automatically.
5
+ This README stays intentionally short. The hosted docs are the source of truth for setup guides, node reference pages, events, asset loading, plugin authoring, and live examples.
5
6
 
6
- ## Links
7
+ ## Start Here
7
8
 
8
- - [Playground](http://route-graphics.routevn.com/playground)
9
+ - [Documentation](http://route-graphics.routevn.com/docs/introduction/introduction/)
10
+ - [Playground](http://route-graphics.routevn.com/playground/)
9
11
  - [Tasks & Roadmap](http://route-graphics.routevn.com/tasks)
10
12
 
11
- ## Typical Usage Patterns
12
-
13
- ### How It Works
14
-
15
- Route Graphics follows a **render cycle** where:
16
-
17
- 1. **Parser Functions** convert your JSON input into Computed Nodes
18
- 2. **Element Functions** handle the lifecycle:
19
- - **Add Functions**: Create new visual elements when they appear in the state
20
- - **Update Functions**: Modify existing elements when their properties change
21
- - **Delete Functions**: Remove elements when they're no longer in the state
22
- 3. **Animation Functions** apply smooth transitions between states
23
- 4. **Audio Functions** handle sound effects and background music
24
-
25
- ## API Reference
26
-
27
- ### createRouteGraphics()
28
-
29
- Creates and returns a RouteGraphics instance.
30
-
31
- ```javascript
32
- const app = createRouteGraphics();
33
- ```
34
-
35
- ### Instance Methods
36
-
37
- #### `init(options)`
38
-
39
- Initialize the RouteGraphics application.
40
-
41
- **Parameters:**
42
- - `options` (Object)
43
- - `width` (number) - Canvas width
44
- - `height` (number) - Canvas height
45
- - `backgroundColor` (number, optional) - Background color as hex (e.g., `0x000000`)
46
- - `debug` (boolean, optional) - Enable debug mode (default: `false`)
47
- - `eventHandler` (Function) - Callback for events `(eventName, payload) => void`
48
- - `plugins` (Object)
49
- - `elements` (Array) - Element plugins to register
50
- - `animations` (Array) - Animation plugins to register
51
- - `audio` (Array) - Audio plugins to register
52
-
53
- **Returns:** `Promise<RouteGraphicsInstance>`
54
-
55
- ---
56
-
57
- #### `loadAssets(assetBufferMap)`
58
-
59
- Load assets from pre-loaded buffer data.
60
-
61
- **Parameters:**
62
- - `assetBufferMap` (Object) - Map of asset key to `{ buffer: ArrayBuffer, type: string }`
63
- - Example: `{ "hero": { buffer: ArrayBuffer, type: "image/png" } }`
64
-
65
- **Returns:** `Promise<Array>` - Array of loaded assets
66
-
67
- ---
68
-
69
- #### `render(state)`
70
-
71
- Render the UI from a state object.
72
-
73
- **Parameters:**
74
- - `state` (RouteGraphicsState)
75
- - `elements` (Array) - Array of element definitions
76
- - `animations` (Array) - Array of animation definitions
77
- - `audio` (Array) - Array of audio definitions
78
- - `global` (Object, optional) - Global configuration
79
- - `cursorStyles` (Object) - Custom cursor styles
80
- - `keyboard` (Object) - Keyboard hotkey mappings
81
-
82
- **Returns:** `void`
83
-
84
- ---
85
-
86
- #### `parse(state)`
87
-
88
- Parse elements from state object using registered parser plugins (without rendering).
89
-
90
- **Parameters:**
91
- - `state` (RouteGraphicsState) - State object containing element definitions
92
-
93
- **Returns:** `RouteGraphicsState` - Parsed state with computed elements
94
-
95
- ---
96
-
97
- #### `updatedBackgroundColor(color)`
98
-
99
- Update the canvas background color.
100
-
101
- **Parameters:**
102
- - `color` (string) - New background color as hex (e.g., `"0xffffff"`)
103
-
104
- **Returns:** `void`
105
-
106
- ---
107
-
108
- #### `findElementByLabel(targetLabel)`
109
-
110
- Find an element in the stage by its label.
111
-
112
- **Parameters:**
113
- - `targetLabel` (string) - Label to search for
114
-
115
- **Returns:** `DisplayObject | null` - Found element or null
116
-
117
- ---
118
-
119
- #### `extractBase64(element)`
120
-
121
- Extract a base64 representation of an element.
122
-
123
- **Parameters:**
124
- - `element` (DisplayObject) - Element to extract
125
-
126
- **Returns:** `Promise<string>` - Base64 string
127
-
128
- ---
129
-
130
- #### `assignStageEvent(eventType, callback)`
131
-
132
- Assign an event listener to the stage.
133
-
134
- **Parameters:**
135
- - `eventType` (string) - Event type (e.g., `"click"`, `"pointermove"`)
136
- - `callback` (Function) - Event callback function
137
-
138
- **Returns:** `void`
139
-
140
- ---
141
-
142
- #### `destroy()`
143
-
144
- Destroy the application and cleanup resources.
145
-
146
- **Returns:** `void`
147
-
148
- ---
149
-
150
- ### Instance Properties
151
-
152
- #### `canvas`
153
-
154
- The HTML canvas element.
155
-
156
- **Type:** `HTMLCanvasElement` (read-only)
157
-
158
- ---
159
-
160
- ## Architecture Overview
161
-
162
- Route Graphics follows a modular plugin architecture with three main plugin categories:
163
-
164
- 1. **Element Plugins** - Render visual elements with add/update/delete functions
165
- 2. **Audio Plugins** - Handle audio playback
166
- 3. **Animation Plugins** - Handle dynamic content and transitions
167
-
168
- ## Getting Started
169
-
170
- ### Installation
13
+ ## Installation
171
14
 
172
15
  ```bash
173
16
  bun install route-graphics
174
17
  ```
175
18
 
176
- ### Basic Usage
19
+ ## Minimal Usage
177
20
 
178
21
  ```javascript
179
22
  import createRouteGraphics, {
23
+ createAssetBufferManager,
180
24
  textPlugin,
181
25
  rectPlugin,
182
26
  spritePlugin,
183
- sliderPlugin,
184
27
  containerPlugin,
185
- textRevealingPlugin,
186
28
  tweenPlugin,
187
29
  soundPlugin,
188
- createAssetBufferManager,
189
- } from 'route-graphics';
30
+ } from "route-graphics";
190
31
 
191
- // Define assets with URL and type
192
32
  const assets = {
193
- "circle-red": {
194
- url: "/public/circle-red.png",
195
- type: "image/png",
196
- },
197
- "circle-blue": {
198
- url: "/public/circle-blue.png",
199
- type: "image/png",
200
- },
201
- "circle-green": {
202
- url: "/public/circle-green.png",
203
- type: "image/png",
204
- },
205
- "slider": {
206
- url: "/public/slider.png",
207
- type: "image/png",
208
- },
209
- "bgm-1": {
210
- url: "/public/bgm-1.mp3",
211
- type: "audio/mpeg",
212
- },
213
- "bgm-2": {
214
- url: "/public/bgm-2.mp3",
215
- type: "audio/mpeg",
216
- }
33
+ "circle-red": { url: "/public/circle-red.png", type: "image/png" },
34
+ "bgm-1": { url: "/public/bgm-1.mp3", type: "audio/mpeg" },
217
35
  };
218
36
 
219
- // Load assets using asset buffer manager
220
37
  const assetBufferManager = createAssetBufferManager();
221
38
  await assetBufferManager.load(assets);
222
- const assetBufferMap = assetBufferManager.getBufferMap();
223
39
 
224
- // Create and initialize app
225
40
  const app = createRouteGraphics();
226
41
  await app.init({
227
42
  width: 1280,
228
43
  height: 720,
44
+ backgroundColor: 0x000000,
229
45
  plugins: {
230
- elements: [
231
- textPlugin,
232
- rectPlugin,
233
- spritePlugin,
234
- sliderPlugin,
235
- containerPlugin,
236
- textRevealingPlugin
237
- ],
238
- animations: [
239
- tweenPlugin
240
- ],
241
- audio: [
242
- soundPlugin
243
- ],
46
+ elements: [textPlugin, rectPlugin, spritePlugin, containerPlugin],
47
+ animations: [tweenPlugin],
48
+ audio: [soundPlugin],
244
49
  },
245
50
  eventHandler: (eventName, payload) => {
246
- console.log('Event:', eventName, payload);
247
- },
51
+ console.log(eventName, payload);
52
+ },
248
53
  });
249
54
 
250
- // Load assets into the app and add to DOM
251
- await app.loadAssets(assetBufferMap);
55
+ await app.loadAssets(assetBufferManager.getBufferMap());
252
56
  document.body.appendChild(app.canvas);
253
57
 
254
- // Render your UI
255
58
  app.render({
59
+ id: "hello-state",
256
60
  elements: [
257
61
  {
258
- id: "sprite1",
259
- type: "sprite",
260
- src: "file:circle-red",
261
- x: 100,
262
- y: 100,
263
- width: 64,
264
- height: 64,
265
- hover: {
266
- imageSrc: "file:circle-blue",
267
- soundSrc: "file:hover-sound"
62
+ id: "title",
63
+ type: "text",
64
+ x: 40,
65
+ y: 40,
66
+ content: "Hello Route Graphics",
67
+ textStyle: {
68
+ fill: "#ffffff",
69
+ fontSize: 36,
268
70
  },
269
- click: {
270
- action: "handleClick",
271
- soundSrc: "file:click-sound"
272
- }
273
- }
71
+ },
274
72
  ],
275
- animations: [
276
- {
277
- id: "fadeIn",
278
- targetId: "sprite1",
279
- type: "tween",
280
- properties: {
281
- alpha: {
282
- initialValue: 0,
283
- keyframes: [
284
- { duration: 1000, value: 1, easing: "linear" }
285
- ]
286
- }
287
- }
288
- }
289
- ],
290
- audio: [
291
- {
292
- id: "bgMusic",
293
- type: "sound",
294
- src: "file:bgm-1",
295
- volume: 600,
296
- loop: true
297
- }
298
- ]
299
- });
300
- ```
301
-
302
- ## Architecture Overview
303
-
304
- Route Graphics follows a modular plugin architecture with three main plugin categories:
305
-
306
- 1. **Parser Plugins** - Convert JSON to Computed Nodes
307
- 2. **Element Plugins** - Render visual elements (add/update/delete)
308
- 3. **Audio & Animation Plugins** - Handle dynamic content
309
-
310
-
311
- ### The Render Function
312
-
313
- The main `render()` function is called whenever you want to update your interface. It automatically:
314
- - Compares the previous state with the new state
315
- - Determines which elements to add, update, or remove
316
- - Executes the appropriate element functions
317
- - Applies animations and audio effects
318
-
319
- ```javascript
320
- // Initial render
321
- routeGraphics.render(initialState);
322
-
323
- // Update with new elements
324
- routeGraphics.render(updatedState); // Automatically adds/updates/removes elements
325
- ```
326
-
327
- **Example Lifecycle:**
328
- ```javascript
329
- // State 1: Show a button
330
- const state1 = {
331
- elements: [{
332
- id: "button1",
333
- type: "rect",
334
- width: 100, height: 40,
335
- fill: "blue"
336
- }]
337
- };
338
-
339
- // State 2: Button changes color and moves
340
- const state2 = {
341
- elements: [{
342
- id: "button1",
343
- type: "rect",
344
- width: 100, height: 40,
345
- fill: "red", // Update: color changes
346
- x: 50, y: 50 // Update: position moves
347
- }]
348
- };
349
-
350
- // State 3: Button is gone
351
- const state3 = {
352
- elements: [] // Delete: button1 is removed
353
- };
354
- ```
355
-
356
- ## Element Plugins
357
-
358
- Element plugins handle the creation, updating, and deletion of visual elements. Each plugin follows a consistent interface:
359
-
360
- ```javascript
361
- createElementPlugin({
362
- type: "element-type",
363
- add: addFunction, // Create element
364
- update: updateFunction, // Update existing element
365
- delete: deleteFunction // Remove element
73
+ animations: [],
74
+ audio: [],
366
75
  });
367
76
  ```
368
77
 
369
- ### Available Element Plugins
370
-
371
- #### Sprite Plugin
372
- Renders image-based sprites with rich interactions.
373
-
374
- **Required Properties:**
375
- - `id`, `type`, `x`, `y`, `width`, `height`
376
-
377
- **Optional Properties:**
378
- - `src`: Source of the sprite image (asset alias)
379
- - `anchorX`, `anchorY`: Anchor points (default: 0)
380
- - `alpha`: Opacity/transparency (0-1, default: 1)
381
-
382
- **Events:**
383
- - **click**: Triggered when sprite is clicked
384
- - `src` (string, optional): Change sprite image
385
- - `soundSrc` (string, optional): Play sound effect
386
- - `actionPayload` (object, optional): Custom data sent to event handler
387
- - **hover**: Triggered when mouse enters/exits sprite
388
- - `src` (string, optional): Change sprite image
389
- - `soundSrc` (string, optional): Play sound effect
390
- - `cursor` (string, optional): CSS cursor style
391
- - `actionPayload` (object, optional): Custom data sent to event handler
392
-
393
- **Example:**
394
- ```yaml
395
- id: character
396
- type: sprite
397
- x: 100
398
- y: 100
399
- width: 64
400
- height: 64
401
- src: hero-idle
402
- hover:
403
- src: hero-hover
404
- cursor: pointer
405
- soundSrc: hover-sound
406
- actionPayload:
407
- action: hoverHero
408
- click:
409
- src: hero-active
410
- soundSrc: click-sound
411
- actionPayload:
412
- action: activateHero
413
- ```
414
-
415
- **Event Data Structure:**
416
- - **Click Event:**
417
- ```yaml
418
- _event:
419
- id: character
420
- # All actionPayload properties are spread directly here
421
- action: activateHero
422
- ```
423
- - **Hover Event:**
424
- ```yaml
425
- _event:
426
- id: character
427
- # All actionPayload properties are spread directly here
428
- action: hoverHero
429
- ```
430
-
431
- #### Text Plugin
432
- Renders styled text with comprehensive formatting options.
433
-
434
- **Required Properties:**
435
- - `id`, `type`, `x`, `y`
436
-
437
- **Optional Properties:**
438
- - `content`: Text content to display (default: "")
439
- - `width`: Width constraint for text wrapping
440
- - `anchorX`, `anchorY`: Anchor points (default: 0)
441
- - `alpha`: Opacity (0-1, default: 1)
442
- - `textStyle`: Complete text styling object
443
-
444
- **TextStyle Options:**
445
- - `fill`: Text color (default: "black")
446
- - `fontFamily`: Font family
447
- - `fontSize`: Font size in pixels (default: 16)
448
- - `align`: Text alignment ["left", "center", "right"] (default: "left")
449
- - `lineHeight`: Line height (default: 1.2)
450
- - `wordWrap`: Enable word wrapping (default: true)
451
- - `breakWords`: Allow breaking words (default: true)
452
- - `strokeColor`: Text outline color
453
- - `strokeWidth`: Text outline width
454
-
455
- **Events:**
456
- - **click**: Triggered when text is clicked
457
- - `textStyle` (object, optional): Change text styling
458
- - `soundSrc` (string, optional): Play sound effect
459
- - `actionPayload` (object, optional): Custom data sent to event handler
460
- - **hover**: Triggered when mouse enters/exits text
461
- - `textStyle` (object, optional): Change text styling
462
- - `soundSrc` (string, optional): Play sound effect
463
- - `cursor` (string, optional): CSS cursor style
464
- - `actionPayload` (object, optional): Custom data sent to event handler
465
-
466
- **Example:**
467
- ```yaml
468
- id: title
469
- type: text
470
- x: 960
471
- y: 100
472
- content: Welcome to Route Graphics
473
- textStyle:
474
- fill: "#ffffff"
475
- fontFamily: Arial
476
- fontSize: 48
477
- align: center
478
- hover:
479
- textStyle:
480
- fill: "#ffff00"
481
- cursor: pointer
482
- soundSrc: hover-sound
483
- actionPayload:
484
- action: hoverTitle
485
- click:
486
- textStyle:
487
- fill: "#00ff00"
488
- soundSrc: click-sound
489
- actionPayload:
490
- action: clickTitle
491
- ```
492
-
493
- **Event Data Structure:**
494
- - **Click Event:**
495
- ```yaml
496
- _event:
497
- id: title
498
- # All actionPayload properties are spread directly here
499
- action: clickTitle
500
- ```
501
- - **Hover Event:**
502
- ```yaml
503
- _event:
504
- id: title
505
- # All actionPayload properties are spread directly here
506
- action: hoverTitle
507
- ```
508
-
509
- #### Rectangle Plugin
510
- Creates filled and bordered rectangles with rotation support.
78
+ For complete usage details, go to:
511
79
 
512
- **Required Properties:**
513
- - `id`, `type`, `width`, `height`
80
+ - [Getting Started](http://route-graphics.routevn.com/docs/introduction/getting-started/)
81
+ - [Assets & Loading](http://route-graphics.routevn.com/docs/guides/assets-loading/)
82
+ - [Events & Render Complete](http://route-graphics.routevn.com/docs/guides/events-render-complete/)
83
+ - [Custom Plugins](http://route-graphics.routevn.com/docs/guides/custom-plugins/)
514
84
 
515
- **Optional Properties:**
516
- - `x`, `y`: Position (default: 0)
517
- - `anchorX`, `anchorY`: Anchor points (default: 0)
518
- - `alpha`: Opacity (0-1, default: 1)
519
- - `fill`: Fill color (default: "white")
520
- - `rotation`: Rotation in degrees (default: 0)
521
- - `border`: Border styling object
522
-
523
- **Border Options:**
524
- - `width`: Border width in pixels (default: 0)
525
- - `color`: Border color (default: "black")
526
- - `alpha`: Border opacity (0-1, default: 1)
527
-
528
- **Events:**
529
- - **click**: Triggered when rectangle is clicked
530
- - `soundSrc` (string, optional): Play sound effect
531
- - `actionPayload` (object, optional): Custom data sent to event handler
532
- - **hover**: Triggered when mouse enters/exits rectangle
533
- - `soundSrc` (string, optional): Play sound effect
534
- - `cursor` (string, optional): CSS cursor style
535
- - `actionPayload` (object, optional): Custom data sent to event handler
536
-
537
- **Example:**
538
- ```yaml
539
- id: panel
540
- type: rect
541
- x: 50
542
- y: 50
543
- width: 400
544
- height: 300
545
- fill: "0x333333"
546
- border:
547
- width: 2
548
- color: "0xffffff"
549
- alpha: 0.8
550
- alpha: 0.9
551
- hover:
552
- cursor: pointer
553
- soundSrc: hover-sound
554
- actionPayload:
555
- action: hoverPanel
556
- click:
557
- soundSrc: click-sound
558
- actionPayload:
559
- action: clickPanel
560
- ```
561
-
562
- **Event Data Structure:**
563
- For an element with `actionPayload: { action: "clickPanel", panelType: "settings" }`:
564
-
565
- - **Click Event:**
566
- ```yaml
567
- _event:
568
- id: panel
569
- action: clickPanel
570
- panelType: settings
571
- ```
572
-
573
- - **Hover Event:**
574
- ```yaml
575
- _event:
576
- id: panel
577
- action: hoverPanel
578
- panelType: settings
579
- ```
580
-
581
- #### Container Plugin
582
- Groups and manages layout of multiple elements.
583
-
584
- **Required Properties:**
585
- - `id`, `type`, `x`, `y`
586
-
587
- **Optional Properties:**
588
- - `width`, `height`: Container dimensions (calculated from children if not set)
589
- - `anchorX`, `anchorY`: Anchor points (must be 0, 0.5, or 1 for containers)
590
- - `alpha`: Opacity (0-1, default: 1)
591
- - `children`: Array of child elements (default: [])
592
- - `direction`: Layout layout ["absolute", "horizontal", "vertical"] (default: "absolute")
593
- - `gap`: Spacing between children in pixels (default: 0)
594
- - `rotation`: Rotation in degrees (default: 0)
595
- - `scroll`: Enable scrolling for overflow content (default: false)
596
- - `anchorToBottom`: Start overflow content from the bottom/right edge (default: false, only when `scroll: true`)
597
-
598
- **Events:** None
599
-
600
- **Layout Directions:**
601
- - `horizontal`: Left-to-right arrangement
602
- - `vertical`: Top-to-bottom arrangement
603
-
604
- **Example:**
605
- ```yaml
606
- id: menu
607
- type: container
608
- x: 0
609
- y: 0
610
- width: 200
611
- height: 400
612
- direction: vertical
613
- gap: 10
614
- children:
615
- - id: btn1
616
- type: sprite
617
- x: 0
618
- y: 0
619
- width: 200
620
- height: 50
621
- src: button-normal
622
- - id: btn2
623
- type: sprite
624
- x: 0
625
- y: 60
626
- width: 200
627
- height: 50
628
- src: button-normal
629
- ```
630
-
631
- **Message Feed Update Example:**
632
- ```yaml
633
- states:
634
- - elements:
635
- - id: message-log
636
- type: container
637
- x: 50
638
- y: 50
639
- width: 500
640
- height: 220
641
- direction: vertical
642
- gap: 8
643
- scroll: true
644
- anchorToBottom: true
645
- children:
646
- - id: message-1
647
- type: text
648
- x: 0
649
- y: 0
650
- content: "Hello"
651
- - id: message-2
652
- type: text
653
- x: 0
654
- y: 32
655
- content: "How are you?"
656
- - elements:
657
- - id: message-log
658
- type: container
659
- x: 50
660
- y: 50
661
- width: 500
662
- height: 220
663
- direction: vertical
664
- gap: 8
665
- scroll: true
666
- anchorToBottom: true
667
- children:
668
- - id: message-1
669
- type: text
670
- x: 0
671
- y: 0
672
- content: "Hello"
673
- - id: message-2
674
- type: text
675
- x: 0
676
- y: 32
677
- content: "How are you?"
678
- - id: message-3
679
- type: text
680
- x: 0
681
- y: 64
682
- content: "I'm fine."
683
- ```
684
-
685
- #### Text Revealing Plugin
686
- Animated text display with typewriter effects.
687
-
688
- **Required Properties:**
689
- - `id`, `type`, `x`, `y`
690
-
691
- **Optional Properties:**
692
- - `content`: Array of text segments with individual styling
693
- - `width`: Width constraint for text wrapping
694
- - `anchorX`, `anchorY`: Anchor points (default: 0)
695
- - `alpha`: Opacity (0-1, default: 1)
696
- - `textStyle`: Default text styling for all segments
697
- - `speed`: Animation speed (default: 50)
698
- - `revealEffect`: Animation type ["typewriter", "none"] (default: "typewriter")
699
- - `indicator`: Continuation indicator settings
700
-
701
- **Content Structure:**
702
- ```yaml
703
- content:
704
- - text: "Hello "
705
- textStyle: # Optional individual styling
706
- fill: red
707
- furigana: # Optional Japanese annotations
708
- text: "こ"
709
- textStyle:
710
- fontSize: 12
711
- - text: "World!"
712
- ```
713
-
714
- **Indicator Options:**
715
- - `revealing`: `src`, `width`, `height` - indicator during animation
716
- - `complete`: `src`, `width`, `height` - indicator when finished
717
- - `offset`: Distance between text and indicator (default: 12)
718
-
719
- **Events:** None (Text Revealing elements do not support events)
720
-
721
- **Example:**
722
- ```yaml
723
- id: story
724
- type: textRevealing
725
- x: 100
726
- y: 200
727
- content:
728
- - text: "Hello "
729
- textStyle:
730
- fill: red
731
- - text: "World!"
732
- textStyle:
733
- fill: blue
734
- speed: 50
735
- revealEffect: typewriter
736
- ```
737
-
738
- #### Slider Plugin
739
- Interactive slider controls for value input.
740
-
741
- **Required Properties:**
742
- - `id`, `type`, `x`, `y`, `direction`, `thumbSrc`, `barSrc`
743
-
744
- **Optional Properties:**
745
- - `anchorX`, `anchorY`: Anchor points (default: 0)
746
- - `alpha`: Opacity (0-1, default: 1)
747
- - `width`, `height`: Slider dimensions
748
- - `min`: Minimum value (default: 0)
749
- - `max`: Maximum value (default: 100)
750
- - `step`: Value increment (default: 1, minimum: 0)
751
- - `initialValue`: Starting value (default: 0)
752
-
753
- **Events:**
754
- - **hover**: Triggered when mouse enters/exits slider
755
- - `thumbSrc` (string, optional): Change thumb sprite image
756
- - `barSrc` (string, optional): Change bar sprite image
757
- - `soundSrc` (string, optional): Play sound effect
758
- - `cursor` (string, optional): CSS cursor style
759
- - **change**: Triggered during slider drag with current value
760
- - `actionPayload` (object, optional): Custom data sent to event handler
761
-
762
- **Example:**
763
- ```yaml
764
- id: volumeSlider
765
- type: slider
766
- x: 100
767
- y: 500
768
- direction: horizontal
769
- thumbSrc: slider-thumb
770
- barSrc: slider-bar
771
- min: 0
772
- max: 100
773
- step: 1
774
- initialValue: 50
775
- hover:
776
- thumbSrc: slider-thumb-hover
777
- barSrc: slider-bar-hover
778
- cursor: pointer
779
- soundSrc: slider-hover
780
- change:
781
- actionPayload:
782
- action: updateVolume
783
- ```
784
-
785
- **Event Data Structure:**
786
- - **Hover Event:** None (slider hover doesn't trigger event data)
787
- - **Change Event:** For a slider with `actionPayload: { action: "updateVolume" }` and current value of 75:
788
- ```yaml
789
- _event:
790
- id: volumeSlider
791
- value: 75
792
- action: updateVolume
793
- ```
794
-
795
- ## Audio Plugin
796
-
797
- Integrated audio system for sound effects and background music.
798
-
799
- ### Sound Plugin Properties
800
-
801
- **Required Properties:**
802
- - `id`, `type`, `src`
803
-
804
- **Optional Properties:**
805
- - `volume`: Volume level (default: 800, minimum: 0)
806
- - `loop`: Whether to loop the audio (default: false)
807
- - `delay`: Delay before playing in milliseconds (default: 0)
808
-
809
- **Volume Details:**
810
- - 0 = muted
811
- - 1000 = original full volume
812
- - Values above 1000 = amplified (may clip)
813
-
814
- **Example:**
815
- ```yaml
816
- id: bgMusic
817
- type: sound
818
- src: bgm-level1
819
- volume: 800
820
- loop: true
821
- delay: 500
822
- ```
823
-
824
- ### Audio Integration
825
-
826
- Audio integrates seamlessly with element interactions:
827
-
828
- ```yaml
829
- id: button
830
- type: sprite
831
- # ... other properties
832
- hover:
833
- soundSrc: file:hover-sound # Plays on hover
834
- click:
835
- soundSrc: file:click-sound # Plays on click
836
- ```
837
-
838
- ## Animation System
839
-
840
- Keyframe-based animation system for smooth transitions and effects.
841
-
842
- ### Tween Animation Plugin
843
-
844
- **Properties:**
845
- - `id`, `targetId`, `type`, `properties`
846
-
847
- **Animatable Properties:**
848
- - `alpha`, `x`, `y`, `scaleX`, `scaleY`, `rotation`
849
-
850
- **Example:**
851
- ```yaml
852
- id: fadeSlide
853
- targetId: myElement
854
- type: tween
855
- properties:
856
- alpha:
857
- initialValue: 0
858
- keyframes:
859
- - duration: 500
860
- value: 1
861
- easing: linear
862
- - duration: 1000
863
- value: 0.5
864
- easing: linear
865
- x:
866
- initialValue: 100
867
- keyframes:
868
- - duration: 1500
869
- value: 500
870
- easing: linear
871
- ```
872
-
873
- ## Creating Custom Plugins
874
-
875
- The plugin system makes it easy to add new element types, animations, or audio handlers.
876
-
877
- ### Element Plugin Creation
878
-
879
- ```javascript
880
- import { createElementPlugin } from 'route-graphics';
881
-
882
- // Create custom element plugin
883
- const customPlugin = createElementPlugin({
884
- type: "myCustomElement",
885
- add: ({ element, app }) => {
886
- // Creation logic - return a PIXI display object
887
- const graphics = new Graphics();
888
- graphics.beginFill(element.fill || 0xffffff);
889
- graphics.drawRect(element.x, element.y, element.width, element.height);
890
- graphics.endFill();
891
- return graphics;
892
- },
893
- update: ({ element, app, displayObject }) => {
894
- // Update logic - modify the display object
895
- if (displayObject) {
896
- displayObject.x = element.x;
897
- displayObject.y = element.y;
898
- displayObject.alpha = element.alpha ?? 1;
899
- }
900
- },
901
- delete: ({ element, app, displayObject }) => {
902
- // Cleanup logic
903
- if (displayObject) {
904
- displayObject.destroy();
905
- }
906
- },
907
- // Optional: Parse function for JSON to computed conversion
908
- parse: (element) => {
909
- // Parse JSON element to computed format
910
- return {
911
- ...element,
912
- parsed: true
913
- };
914
- }
915
- });
916
-
917
- // Register plugin in your app
918
- await app.init({
919
- // ... other config
920
- plugins: {
921
- elements: [
922
- // ... existing plugins
923
- customPlugin
924
- ],
925
- animations: [/* ... */],
926
- audio: [/* ... */]
927
- }
928
- });
929
- ```
930
-
931
- ### Animation Plugin Creation
932
-
933
- ```javascript
934
- import { createAnimationPlugin } from 'route-graphics';
935
-
936
- const customAnimationPlugin = createAnimationPlugin({
937
- type: "myCustomAnimation",
938
- add: ({ animation, app }) => {
939
- // Animation creation logic
940
- return {
941
- animation,
942
- startTime: Date.now(),
943
- active: true
944
- };
945
- },
946
- update: ({ animation, app, animationData }) => {
947
- // Animation update logic
948
- if (animationData.active) {
949
- const elapsed = Date.now() - animationData.startTime;
950
- if (elapsed >= animation.duration) {
951
- animationData.active = false;
952
- }
953
- }
954
- },
955
- delete: ({ animation, app, animationData }) => {
956
- // Animation cleanup logic
957
- // Stop any ongoing animations
958
- }
959
- });
960
- ```
961
-
962
- ### Audio Plugin Creation
963
-
964
- ```javascript
965
- import { createAudioPlugin } from 'route-graphics';
966
-
967
- const customAudioPlugin = createAudioPlugin({
968
- type: "myCustomAudio",
969
- add: ({ audio, app }) => {
970
- // Audio creation logic
971
- return {
972
- audio,
973
- startTime: Date.now(),
974
- playing: true
975
- };
976
- },
977
- update: ({ audio, app, audioData }) => {
978
- // Audio update logic
979
- if (audioData.playing && Date.now() - audioData.startTime >= audio.delay) {
980
- // Start playing after delay
981
- }
982
- },
983
- delete: ({ audio, app, audioData }) => {
984
- // Audio cleanup logic
985
- // Stop audio playback
986
- }
987
- });
988
- ```
989
-
990
- ## Parser System
991
-
992
- The parser system transforms your JSON input into Computed Nodes that the rendering engine can process. Each element plugin includes its own parser function that converts JSON definitions into the internal computed format.
993
-
994
- ### parseElements Function
995
-
996
- ```javascript
997
- // Main parsing function that processes all elements
998
- const parsedElements = parseElements({
999
- JSONObject: [
1000
- {
1001
- id: "myButton",
1002
- type: "sprite",
1003
- x: 100,
1004
- y: 100,
1005
- width: 64,
1006
- height: 64
1007
- }
1008
- ],
1009
- parserPlugins: [spritePlugin, textPlugin, ...]
1010
- });
1011
- ```
1012
-
1013
- ### Parser Function Properties
1014
-
1015
- **Parameters:**
1016
- - `state`: The raw JSON element definition from the input
1017
- - `parserPlugins`: Array of available parser plugins (useful for nested elements like containers)
1018
-
1019
- **Returns:**
1020
- - Computed node with processed properties ready for rendering
1021
-
1022
- ### Parser Function Example
1023
-
1024
- ```javascript
1025
- const parseMyElement = ({ state, parserPlugins }) => {
1026
- // Validate required properties
1027
- if (!state.id || !state.type) {
1028
- throw new Error('Missing required properties');
1029
- }
1030
-
1031
- // Apply defaults and type conversion
1032
- return {
1033
- id: state.id,
1034
- type: state.type,
1035
- x: Math.round(state.x ?? 0),
1036
- y: Math.round(state.y ?? 0),
1037
- width: Math.round(state.width ?? 100),
1038
- height: Math.round(state.height ?? 50),
1039
- // Custom property with default
1040
- customProperty: state.customProperty ?? "default",
1041
- // Example: Hex color to number conversion
1042
- color: state.color ? parseInt(state.color.replace('#', ''), 16) : 0x000000,
1043
- };
1044
- };
1045
- ```
1046
-
1047
- ## Asset Management
1048
-
1049
- Route Graphics uses a sophisticated asset management system with aliasing.
1050
-
1051
- ### Asset Management
1052
-
1053
- #### Loading Assets
1054
-
1055
- Load assets using the `createAssetBufferManager`:
1056
-
1057
- ```javascript
1058
- import { createAssetBufferManager } from 'route-graphics';
1059
-
1060
- // Define assets with URL and type
1061
- const assets = {
1062
- "hero-sprite": {
1063
- url: "./assets/hero.png",
1064
- type: "image/png",
1065
- },
1066
- "background-image": {
1067
- url: "./assets/background.jpg",
1068
- type: "image/jpeg"
1069
- },
1070
- "bg-music": {
1071
- url: "./audio/background.mp3",
1072
- type: "audio/mpeg",
1073
- },
1074
- "click-sound": {
1075
- url: "./audio/click.wav",
1076
- type: "audio/wav"
1077
- }
1078
- };
1079
-
1080
- // Load assets using asset buffer manager
1081
- const assetBufferManager = createAssetBufferManager();
1082
- await assetBufferManager.load(assets);
1083
- const assetBufferMap = assetBufferManager.getBufferMap();
1084
-
1085
- // Load assets into the app
1086
- await app.loadAssets(assetBufferMap);
1087
- ```
1088
-
1089
- #### Asset Aliases
1090
-
1091
- Once loaded, assets are referenced by their alias keys:
1092
-
1093
- ```yaml
1094
- id: hero
1095
- type: sprite
1096
- src: hero-sprite
1097
- ```
1098
-
1099
- #### Supported Asset Types
1100
-
1101
- - **Images**: PNG, JPG, JPEG, WebP
1102
- - **Audio**: MP3, WAV, OGG
1103
- - **Fonts**: TTF, OTF, WOFF
1104
-
1105
- ## Development & Testing
1106
-
1107
- ### Running Tests
85
+ ## Development
1108
86
 
1109
87
  ```bash
1110
- # Run all tests
88
+ # Run tests
1111
89
  bun run test
1112
- ```
1113
-
1114
- ### Playground (Rettangoli Sites)
1115
-
1116
- The playground is managed as its own local Sites project in `playground/`.
1117
90
 
1118
- ```bash
1119
- # Install playground deps
91
+ # Build the local docs/playground site
1120
92
  cd playground
1121
93
  bun install
1122
-
1123
- # Start watch/dev server (default port 3001)
1124
- bun run watch
1125
-
1126
- # Build static output
1127
94
  bun run build
1128
95
  ```
1129
96
 
1130
- Notes:
1131
-
1132
- - Sites config is YAML-only: `playground/sites.config.yaml`
1133
- - Playground scripts live in `playground/package.json`
1134
- - Template source of truth: `playground/data/templates.yaml`
1135
- - Runtime template catalog: `playground/static/public/playground/templates.yaml`
1136
-
1137
- ### Code Quality
1138
-
1139
- ```bash
1140
- # Build VT pages
1141
- bun run vt:generate
1142
-
1143
- # Capture screenshots with Docker
1144
- bun run vt:screenshot
1145
-
1146
- # Generate visual diff report
1147
- bun run vt:report
1148
-
1149
- # Accept expected diffs
1150
- bun run vt:accept
1151
-
1152
-
1153
- # Fix linting issues
1154
- bun run lint:fix
1155
-
1156
- ```
1157
-
1158
- ## Complete YAML Example
1159
-
1160
- ```yaml
1161
- elements:
1162
- - id: background
1163
- type: sprite
1164
- x: 0
1165
- y: 0
1166
- width: 1920
1167
- height: 1080
1168
- src: file:bg-image
1169
- - id: title
1170
- type: text
1171
- x: 960
1172
- y: 100
1173
- content: Game Title
1174
- textStyle:
1175
- fill: "#ffffff"
1176
- fontFamily: Arial
1177
- fontSize: 64
1178
- align: center
1179
- - id: buttonContainer
1180
- type: container
1181
- x: 960
1182
- y: 400
1183
- width: 200
1184
- height: 300
1185
- direction: vertical
1186
- gap: 20
1187
- children:
1188
- - id: startBtn
1189
- type: sprite
1190
- x: 0
1191
- y: 0
1192
- width: 200
1193
- height: 50
1194
- src: file:btn-normal
1195
- hover:
1196
- imageSrc: file:btn-hover
1197
- soundSrc: file:hover-sound
1198
- click:
1199
- action: startGame
1200
- soundSrc: file:click-sound
1201
- animations:
1202
- - id: titleFadeIn
1203
- targetId: title
1204
- type: tween
1205
- properties:
1206
- alpha:
1207
- initialValue: 0
1208
- keyframes:
1209
- - duration: 2000
1210
- value: 1
1211
- easing: linear
1212
- audio:
1213
- - id: bgMusic
1214
- type: sound
1215
- src: file:background-music
1216
- volume: 600
1217
- loop: true
1218
- ```
1219
-
1220
-
1221
- ## Schemas
1222
-
1223
- All element types are defined with YAML schemas in the `src/schemas/` directory, providing:
1224
-
1225
- - Type definitions and validation
1226
- - Property documentation
1227
- - Default values
1228
- - Required field specifications
97
+ The docs site and playground source live under `playground/`.
1229
98
 
1230
99
  ## Community
1231
100