Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "route-graphics",
"version": "1.1.5",
"version": "1.1.6",
"description": "A 2D graphics rendering interface that takes JSON input and renders pixels using PixiJS",
"main": "dist/RouteGraphics.js",
"type": "module",
Expand Down
67 changes: 47 additions & 20 deletions playground/pages/docs/nodes/slider.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,34 @@ Try it in the [Playground](/playground/?template=slider-demo).

## Field Reference

| Field | Type | Required | Default | Notes |
| -------------- | -------------------------- | ------------- | ------------ | --------------------------------- |
| `id` | string | Yes | - | Element id. |
| `type` | string | Yes | - | Must be `slider`. |
| `x` | number | Yes | - | Position before anchor transform. |
| `y` | number | Yes | - | Position before anchor transform. |
| `width` | number | Yes (runtime) | - | Required by parser. |
| `height` | number | Yes (runtime) | - | Required by parser. |
| `direction` | `horizontal` \| `vertical` | Yes | `horizontal` | Track direction. |
| `thumbSrc` | string | Yes | `""` | Thumb texture alias. |
| `barSrc` | string | Yes | `""` | Bar texture alias. |
| `initialValue` | number | Yes (runtime) | - | Must be between `min` and `max`. |
| `min` | number | No | `0` | Range min. |
| `max` | number | No | `100` | Must be `>` `min`. |
| `step` | number | No | `1` | If `> 0`, value snaps by step. |
| `anchorX` | number | No | `0` | Anchor offset ratio. |
| `anchorY` | number | No | `0` | Anchor offset ratio. |
| `alpha` | number | No | `1` | Opacity `0..1`. |
| `hover` | object | No | - | Hover textures/sound/cursor. |
| `change` | object | No | - | Event payload on value changes. |
| Field | Type | Required | Default | Notes |
| ---------------- | -------------------------- | ------------- | ------------ | -------------------------------------------------------------------------------- |
| `id` | string | Yes | - | Element id. |
| `type` | string | Yes | - | Must be `slider`. |
| `x` | number | Yes | - | Position before anchor transform. |
| `y` | number | Yes | - | Position before anchor transform. |
| `width` | number | Yes (runtime) | - | Required by parser. |
| `height` | number | Yes (runtime) | - | Required by parser. |
| `direction` | `horizontal` \| `vertical` | Yes | `horizontal` | Track direction. |
| `thumbSrc` | string | Yes | `""` | Thumb texture alias. |
| `barSrc` | string | Yes | `""` | Bar texture alias. If `inactiveBarSrc` is set, this is the active track texture. |
| `inactiveBarSrc` | string | No | - | Optional inactive track texture rendered underneath `barSrc`. |
| `initialValue` | number | Yes (runtime) | - | Must be between `min` and `max`. |
| `min` | number | No | `0` | Range min. |
| `max` | number | No | `100` | Must be `>` `min`. |
| `step` | number | No | `1` | If `> 0`, value snaps by step. |
| `anchorX` | number | No | `0` | Anchor offset ratio. |
| `anchorY` | number | No | `0` | Anchor offset ratio. |
| `alpha` | number | No | `1` | Opacity `0..1`. |
| `hover` | object | No | - | Hover textures/sound/cursor. |
| `change` | object | No | - | Event payload on value changes. |

## Runtime Validation

- `max` must be strictly larger than `min`.
- `initialValue` is required by parser and must be a valid number.
- `initialValue` must be within `[min, max]`.
- When `inactiveBarSrc` is set, the active track reveal follows the current slider value.

## Emitted Events

Expand Down Expand Up @@ -91,6 +93,31 @@ elements:
action: setSfxVolume
```

## Example: Split Track

```yaml
elements:
- id: music-volume
type: slider
x: 90
y: 680
width: 420
height: 44
direction: horizontal
thumbSrc: horizontal-idle-thumb
barSrc: horizontal-hover-bar
inactiveBarSrc: horizontal-idle-bar
min: 0
max: 100
step: 5
initialValue: 35
hover:
thumbSrc: horizontal-hover-thumb
barSrc: horizontal-idle-bar
inactiveBarSrc: horizontal-hover-bar
cursor: pointer
```

## Example: Vertical Slider

```yaml
Expand Down
8 changes: 7 additions & 1 deletion playground/static/public/playground/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,13 @@ const recursivelyLoadAssets = (objects) => {
);
}

for (const key of ["src", "thumbSrc", "barSrc", "spritesheetSrc"]) {
for (const key of [
"src",
"thumbSrc",
"barSrc",
"inactiveBarSrc",
"spritesheetSrc",
]) {
if (key === "src" && obj.type === "sound") continue;
if (obj[key] && typeof obj[key] === "string") {
const defaultType = obj.type === "video" ? "video/mp4" : "image/png";
Expand Down
37 changes: 37 additions & 0 deletions spec/parser/parseSlider.test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ in:
id: volume-slider
type: slider
barSrc: file:slider-bar
inactiveBarSrc: file:slider-track
thumbSrc: file:slider-thumb
direction: horizontal
alpha: 0.8
Expand All @@ -30,6 +31,7 @@ in:
hover:
thumbSrc: file:thumb-hover
barSrc: file:bar-hover
inactiveBarSrc: file:track-hover
soundSrc: sound-1
cursor: cursor-1
payload:
Expand All @@ -49,6 +51,7 @@ out:
originY: 40
alpha: 0.8
barSrc: file:slider-bar
inactiveBarSrc: file:slider-track
thumbSrc: file:slider-thumb
direction: horizontal
min: 10
Expand All @@ -58,6 +61,7 @@ out:
hover:
thumbSrc: file:thumb-hover
barSrc: file:bar-hover
inactiveBarSrc: file:track-hover
soundSrc: sound-1
cursor: cursor-1
payload:
Expand Down Expand Up @@ -130,6 +134,39 @@ out:
originX: 0
originY: 0
---
case: Test parsing split slider without hover
in:
- state:
id: split-slider
type: slider
barSrc: file:bar-active
inactiveBarSrc: file:bar-inactive
thumbSrc: file:thumb-minimal
direction: horizontal
width: 120
height: 16
x: 10
"y": 20
initialValue: 50
out:
id: split-slider
type: slider
barSrc: file:bar-active
inactiveBarSrc: file:bar-inactive
thumbSrc: file:thumb-minimal
direction: horizontal
alpha: 1
min: 0
max: 100
width: 120
height: 16
step: 1
initialValue: 50
x: 10
"y": 20
originX: 0
originY: 0
---
case: Test parsing slider throws when initialValue is missing
in:
- state:
Expand Down
33 changes: 32 additions & 1 deletion src/RouteGraphics.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ const createRouteGraphics = () => {
*/
let debugAnimationListener;

/**
* Drives animation updates and presents the current frame.
* @type {Function|undefined}
*/
let frameTickerListener;

/**
* @type {(event: MouseEvent) => void | undefined}
*/
Expand Down Expand Up @@ -258,6 +264,12 @@ const createRouteGraphics = () => {

state = nextState;

// Present the updated stage immediately instead of relying on Pixi's
// implicit auto-render loop, which can fail in VT/manual browser runs.
if (typeof appInstance.render === "function") {
appInstance.render();
}

// Fire stateComplete immediately if no animations/reveals to track
completionTracker.completeIfEmpty();

Expand Down Expand Up @@ -351,6 +363,9 @@ const createRouteGraphics = () => {
backgroundColor,
preference: "webgl",
});
if (typeof app.ticker?.remove === "function") {
app.ticker.remove(app.render, app);
}
app.debug = debug;
canvasContextMenuListener = (event) => {
event.preventDefault();
Expand All @@ -368,11 +383,20 @@ const createRouteGraphics = () => {
// Create animation bus and attach to ticker
animationBus = createAnimationBus();
if (!debug) {
app.ticker.add((time) => animationBus.tick(time.deltaMS));
frameTickerListener = (time) => {
animationBus.tick(time.deltaMS);
if (typeof app.render === "function") {
app.render();
}
};
app.ticker.add(frameTickerListener);
} else {
debugAnimationListener = (event) => {
if (event?.detail?.deltaMS) {
animationBus.tick(Number(event.detail.deltaMS));
if (typeof app.render === "function") {
app.render();
}
}
};
window.addEventListener("snapShotKeyFrame", debugAnimationListener);
Expand All @@ -390,6 +414,10 @@ const createRouteGraphics = () => {
window.removeEventListener("snapShotKeyFrame", debugAnimationListener);
debugAnimationListener = undefined;
}
if (frameTickerListener && typeof app?.ticker?.remove === "function") {
app.ticker.remove(frameTickerListener);
frameTickerListener = undefined;
}
if (canvasContextMenuListener && app?.canvas) {
app.canvas.removeEventListener(
"contextmenu",
Expand Down Expand Up @@ -564,6 +592,9 @@ const createRouteGraphics = () => {
color,
);
}
if (typeof app.render === "function") {
app.render();
}
},

/**
Expand Down
Loading
Loading