route-graphics 0.0.35 → 0.1.1

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