@rydr/game-sdk 5.0.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -18
- package/dist/client/PlatformClient.d.ts +11 -10
- package/dist/client/PlatformClient.d.ts.map +1 -1
- package/dist/client/PlatformClient.js +15 -9
- package/dist/client/PlatformClient.js.map +1 -1
- package/dist/host/PlatformHost.d.ts +10 -7
- package/dist/host/PlatformHost.d.ts.map +1 -1
- package/dist/host/PlatformHost.js.map +1 -1
- package/dist/protocol/buttons.d.ts +60 -31
- package/dist/protocol/buttons.d.ts.map +1 -1
- package/dist/protocol/buttons.js +40 -25
- package/dist/protocol/buttons.js.map +1 -1
- package/dist/protocol/capabilities.d.ts +1 -1
- package/dist/protocol/messages.d.ts +5 -4
- package/dist/protocol/messages.d.ts.map +1 -1
- package/dist/protocol/perf.d.ts +37 -0
- package/dist/protocol/perf.d.ts.map +1 -0
- package/dist/protocol/perf.js +17 -0
- package/dist/protocol/perf.js.map +1 -0
- package/dist/protocol/version.d.ts +2 -2
- package/dist/protocol/version.d.ts.map +1 -1
- package/dist/protocol/version.js +18 -2
- package/dist/protocol/version.js.map +1 -1
- package/dist/three/perf-marks.d.ts +2 -21
- package/dist/three/perf-marks.d.ts.map +1 -1
- package/dist/three/perf-marks.js.map +1 -1
- package/dist/ui/README.md +3 -0
- package/dist/ui/heat-vignette.d.ts +75 -0
- package/dist/ui/heat-vignette.d.ts.map +1 -0
- package/dist/ui/heat-vignette.js +126 -0
- package/dist/ui/heat-vignette.js.map +1 -0
- package/dist/ui/index.d.ts +7 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +7 -0
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/overheat-glitch.d.ts +56 -0
- package/dist/ui/overheat-glitch.d.ts.map +1 -0
- package/dist/ui/overheat-glitch.js +177 -0
- package/dist/ui/overheat-glitch.js.map +1 -0
- package/dist/ui/overheat-hud-bar.d.ts +79 -0
- package/dist/ui/overheat-hud-bar.d.ts.map +1 -0
- package/dist/ui/overheat-hud-bar.js +302 -0
- package/dist/ui/overheat-hud-bar.js.map +1 -0
- package/dist/ui/showcase/index.js +2 -2
- package/dist/ui/showcase/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mountHeatVignette` — the **screen-edge heat vignette**, on its own.
|
|
3
|
+
*
|
|
4
|
+
* A peripheral "you are cooking" cue: a coloured glow bleeding in from the edges of the play area
|
|
5
|
+
* that escalates amber → orange → red as heat rises, pulsing faster at each stage. It reads in
|
|
6
|
+
* peripheral vision while the player's eyes are on the road, which is exactly what a heat mechanic
|
|
7
|
+
* needs — the player should feel the danger without looking at a bar.
|
|
8
|
+
*
|
|
9
|
+
* This is the vignette **alone**, deliberately separable: a game that draws its own heat bar (e.g.
|
|
10
|
+
* the racing game's in-canvas gauge) still wants the peripheral cue. Pair it with
|
|
11
|
+
* {@link mountOverheatGlitch} for the lockout flash, or take the whole pre-assembled package —
|
|
12
|
+
* bar + vignette + glitch — from {@link mountOverheatHudBar}.
|
|
13
|
+
*
|
|
14
|
+
* Self-contained DOM/CSS like the rest of `@rydr/game-sdk/ui`: it injects its own scoped
|
|
15
|
+
* `.rydr-heat-vignette*` stylesheet once into `<head>`, needs no global styles, no CSS variables and
|
|
16
|
+
* no three.js. It takes a **0..1 heat value**, not a `session` — the game owns its heat model and
|
|
17
|
+
* feeds the ratio in.
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* const vignette = mountHeatVignette(hudHost);
|
|
21
|
+
* // every frame:
|
|
22
|
+
* vignette.setHeat(heat.fillRatio, heat.isLocked);
|
|
23
|
+
* // on teardown:
|
|
24
|
+
* vignette.dispose();
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* **Host contract:** the vignette is `position: absolute; inset: 0` and sits at `z-index: 19`, so
|
|
28
|
+
* `host` must be positioned (and ideally `isolation: isolate`, so the z-index doesn't leak past it).
|
|
29
|
+
* A full-viewport `position: fixed; inset: 0; pointer-events: none; isolation: isolate` div over the
|
|
30
|
+
* game canvas is the intended host.
|
|
31
|
+
*/
|
|
32
|
+
/** Discrete escalation stage of a heat cue. Drives the vignette colour + pulse rate. */
|
|
33
|
+
export type HeatStage = "idle" | "warn" | "crit" | "danger";
|
|
34
|
+
/**
|
|
35
|
+
* Default heat levels (0..1) at which each stage kicks in. `heat ∈ [warn, crit)` is a slow amber
|
|
36
|
+
* pulse, `[crit, danger)` a faster orange one, `[danger, 1]` the red panic pulse. Override per-mount
|
|
37
|
+
* with {@link HeatVignetteOptions.thresholds} when a game's own bar escalates on a different curve —
|
|
38
|
+
* keep the two in sync so the peripheral cue and the bar tell the same story.
|
|
39
|
+
*/
|
|
40
|
+
export declare const HEAT_STAGE_THRESHOLDS: Readonly<Record<Exclude<HeatStage, "idle">, number>>;
|
|
41
|
+
/** Classify a 0..1 heat value into a {@link HeatStage} using `thresholds` (default {@link HEAT_STAGE_THRESHOLDS}). */
|
|
42
|
+
export declare function heatStageFor(heat01: number, thresholds?: Readonly<Record<Exclude<HeatStage, "idle">, number>>): HeatStage;
|
|
43
|
+
/** Options for {@link mountHeatVignette}. */
|
|
44
|
+
export interface HeatVignetteOptions {
|
|
45
|
+
/** Stage cut-offs (0..1). Default {@link HEAT_STAGE_THRESHOLDS}. */
|
|
46
|
+
thresholds?: Readonly<Record<Exclude<HeatStage, "idle">, number>>;
|
|
47
|
+
/**
|
|
48
|
+
* Stacking order inside the host. Default `19` — under {@link mountOverheatHudBar}'s bar (20) and
|
|
49
|
+
* glitch overlay (21), so the three compose in the intended order when used together.
|
|
50
|
+
*/
|
|
51
|
+
zIndex?: number;
|
|
52
|
+
}
|
|
53
|
+
/** Live handle to a mounted heat vignette. Returned by {@link mountHeatVignette}. */
|
|
54
|
+
export interface HeatVignette {
|
|
55
|
+
/** The vignette element (already appended to the host). */
|
|
56
|
+
readonly root: HTMLDivElement;
|
|
57
|
+
/**
|
|
58
|
+
* Drive the vignette for one frame.
|
|
59
|
+
*
|
|
60
|
+
* @param heat01 Heat as a 0..1 ratio; classified into a stage via the mount's thresholds.
|
|
61
|
+
* @param locked True while the game is in its overheat lockout — forces the `danger` stage for the
|
|
62
|
+
* whole window, so the peripheral cue stays bright even as heat drains during a forced cooldown.
|
|
63
|
+
*/
|
|
64
|
+
setHeat(heat01: number, locked?: boolean): void;
|
|
65
|
+
/** Force a stage directly, bypassing the heat→stage mapping (for scripted moments/cutscenes). */
|
|
66
|
+
setStage(stage: HeatStage): void;
|
|
67
|
+
/** Remove the vignette from the host. Idempotent. */
|
|
68
|
+
dispose(): void;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Mount a heat vignette into `host`. See the module header for the host contract; drive it every
|
|
72
|
+
* frame with {@link HeatVignette.setHeat}.
|
|
73
|
+
*/
|
|
74
|
+
export declare function mountHeatVignette(host: HTMLElement, opts?: HeatVignetteOptions): HeatVignette;
|
|
75
|
+
//# sourceMappingURL=heat-vignette.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heat-vignette.d.ts","sourceRoot":"","sources":["../../src/ui/heat-vignette.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,wFAAwF;AACxF,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5D;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAChC,CAAC;AAExD,sHAAsH;AACtH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAyB,GACvF,SAAS,CAKX;AAED,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qFAAqF;AACrF,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAChD,iGAAiG;IACjG,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACjC,qDAAqD;IACrD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,WAAW,EACjB,IAAI,GAAE,mBAAwB,GAC7B,YAAY,CA8Bd"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mountHeatVignette` — the **screen-edge heat vignette**, on its own.
|
|
3
|
+
*
|
|
4
|
+
* A peripheral "you are cooking" cue: a coloured glow bleeding in from the edges of the play area
|
|
5
|
+
* that escalates amber → orange → red as heat rises, pulsing faster at each stage. It reads in
|
|
6
|
+
* peripheral vision while the player's eyes are on the road, which is exactly what a heat mechanic
|
|
7
|
+
* needs — the player should feel the danger without looking at a bar.
|
|
8
|
+
*
|
|
9
|
+
* This is the vignette **alone**, deliberately separable: a game that draws its own heat bar (e.g.
|
|
10
|
+
* the racing game's in-canvas gauge) still wants the peripheral cue. Pair it with
|
|
11
|
+
* {@link mountOverheatGlitch} for the lockout flash, or take the whole pre-assembled package —
|
|
12
|
+
* bar + vignette + glitch — from {@link mountOverheatHudBar}.
|
|
13
|
+
*
|
|
14
|
+
* Self-contained DOM/CSS like the rest of `@rydr/game-sdk/ui`: it injects its own scoped
|
|
15
|
+
* `.rydr-heat-vignette*` stylesheet once into `<head>`, needs no global styles, no CSS variables and
|
|
16
|
+
* no three.js. It takes a **0..1 heat value**, not a `session` — the game owns its heat model and
|
|
17
|
+
* feeds the ratio in.
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* const vignette = mountHeatVignette(hudHost);
|
|
21
|
+
* // every frame:
|
|
22
|
+
* vignette.setHeat(heat.fillRatio, heat.isLocked);
|
|
23
|
+
* // on teardown:
|
|
24
|
+
* vignette.dispose();
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* **Host contract:** the vignette is `position: absolute; inset: 0` and sits at `z-index: 19`, so
|
|
28
|
+
* `host` must be positioned (and ideally `isolation: isolate`, so the z-index doesn't leak past it).
|
|
29
|
+
* A full-viewport `position: fixed; inset: 0; pointer-events: none; isolation: isolate` div over the
|
|
30
|
+
* game canvas is the intended host.
|
|
31
|
+
*/
|
|
32
|
+
const STYLE_ID = "rydr-heat-vignette-css";
|
|
33
|
+
/**
|
|
34
|
+
* Default heat levels (0..1) at which each stage kicks in. `heat ∈ [warn, crit)` is a slow amber
|
|
35
|
+
* pulse, `[crit, danger)` a faster orange one, `[danger, 1]` the red panic pulse. Override per-mount
|
|
36
|
+
* with {@link HeatVignetteOptions.thresholds} when a game's own bar escalates on a different curve —
|
|
37
|
+
* keep the two in sync so the peripheral cue and the bar tell the same story.
|
|
38
|
+
*/
|
|
39
|
+
export const HEAT_STAGE_THRESHOLDS = Object.freeze({ warn: 0.5, crit: 0.65, danger: 0.8 });
|
|
40
|
+
/** Classify a 0..1 heat value into a {@link HeatStage} using `thresholds` (default {@link HEAT_STAGE_THRESHOLDS}). */
|
|
41
|
+
export function heatStageFor(heat01, thresholds = HEAT_STAGE_THRESHOLDS) {
|
|
42
|
+
if (heat01 >= thresholds.danger)
|
|
43
|
+
return "danger";
|
|
44
|
+
if (heat01 >= thresholds.crit)
|
|
45
|
+
return "crit";
|
|
46
|
+
if (heat01 >= thresholds.warn)
|
|
47
|
+
return "warn";
|
|
48
|
+
return "idle";
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Mount a heat vignette into `host`. See the module header for the host contract; drive it every
|
|
52
|
+
* frame with {@link HeatVignette.setHeat}.
|
|
53
|
+
*/
|
|
54
|
+
export function mountHeatVignette(host, opts = {}) {
|
|
55
|
+
injectCss();
|
|
56
|
+
const thresholds = opts.thresholds ?? HEAT_STAGE_THRESHOLDS;
|
|
57
|
+
const root = document.createElement("div");
|
|
58
|
+
root.className = "rydr-heat-vignette";
|
|
59
|
+
if (opts.zIndex !== undefined)
|
|
60
|
+
root.style.zIndex = String(opts.zIndex);
|
|
61
|
+
host.appendChild(root);
|
|
62
|
+
// Cache the applied stage so we only touch classList on a transition, not every frame.
|
|
63
|
+
let lastStage = "idle";
|
|
64
|
+
const setStage = (stage) => {
|
|
65
|
+
if (stage === lastStage)
|
|
66
|
+
return;
|
|
67
|
+
root.classList.remove("stage-warn", "stage-crit", "stage-danger");
|
|
68
|
+
if (stage !== "idle")
|
|
69
|
+
root.classList.add(`stage-${stage}`);
|
|
70
|
+
lastStage = stage;
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
root,
|
|
74
|
+
setStage,
|
|
75
|
+
setHeat(heat01, locked = false) {
|
|
76
|
+
const clamped = Math.max(0, Math.min(1, heat01 || 0));
|
|
77
|
+
setStage(locked ? "danger" : heatStageFor(clamped, thresholds));
|
|
78
|
+
},
|
|
79
|
+
dispose() {
|
|
80
|
+
root.remove();
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
let cssInjected = false;
|
|
85
|
+
/** Inject the scoped vignette CSS once per document. */
|
|
86
|
+
function injectCss() {
|
|
87
|
+
if (cssInjected || document.getElementById(STYLE_ID)) {
|
|
88
|
+
cssInjected = true;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const style = document.createElement("style");
|
|
92
|
+
style.id = STYLE_ID;
|
|
93
|
+
style.textContent = CSS;
|
|
94
|
+
document.head.appendChild(style);
|
|
95
|
+
cssInjected = true;
|
|
96
|
+
}
|
|
97
|
+
const CSS = `
|
|
98
|
+
.rydr-heat-vignette {
|
|
99
|
+
position: absolute;
|
|
100
|
+
inset: 0;
|
|
101
|
+
pointer-events: none;
|
|
102
|
+
z-index: 19;
|
|
103
|
+
opacity: 0;
|
|
104
|
+
transition: opacity 0.2s;
|
|
105
|
+
box-shadow: inset 0 0 0 0 transparent;
|
|
106
|
+
}
|
|
107
|
+
.rydr-heat-vignette.stage-warn {
|
|
108
|
+
opacity: 1;
|
|
109
|
+
box-shadow: inset 0 0 80px rgba(251, 191, 36, 0.35);
|
|
110
|
+
}
|
|
111
|
+
.rydr-heat-vignette.stage-crit {
|
|
112
|
+
opacity: 1;
|
|
113
|
+
box-shadow: inset 0 0 120px rgba(249, 115, 22, 0.55);
|
|
114
|
+
animation: rydr-heat-vignette-pulse 0.7s ease-in-out infinite;
|
|
115
|
+
}
|
|
116
|
+
.rydr-heat-vignette.stage-danger {
|
|
117
|
+
opacity: 1;
|
|
118
|
+
box-shadow: inset 0 0 180px rgba(239, 68, 68, 0.85);
|
|
119
|
+
animation: rydr-heat-vignette-pulse 0.3s ease-in-out infinite;
|
|
120
|
+
}
|
|
121
|
+
@keyframes rydr-heat-vignette-pulse {
|
|
122
|
+
0%, 100% { filter: brightness(0.7); }
|
|
123
|
+
50% { filter: brightness(1.25); }
|
|
124
|
+
}
|
|
125
|
+
`;
|
|
126
|
+
//# sourceMappingURL=heat-vignette.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heat-vignette.js","sourceRoot":"","sources":["../../src/ui/heat-vignette.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,MAAM,QAAQ,GAAG,wBAAwB,CAAC;AAK1C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAChC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;AAExD,sHAAsH;AACtH,MAAM,UAAU,YAAY,CAC1B,MAAc,EACd,aAAmE,qBAAqB;IAExF,IAAI,MAAM,IAAI,UAAU,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAC;IACjD,IAAI,MAAM,IAAI,UAAU,CAAC,IAAI;QAAE,OAAO,MAAM,CAAC;IAC7C,IAAI,MAAM,IAAI,UAAU,CAAC,IAAI;QAAE,OAAO,MAAM,CAAC;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC;AA+BD;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAiB,EACjB,OAA4B,EAAE;IAE9B,SAAS,EAAE,CAAC;IACZ,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,qBAAqB,CAAC;IAE5D,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,SAAS,GAAG,oBAAoB,CAAC;IACtC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAEvB,uFAAuF;IACvF,IAAI,SAAS,GAAc,MAAM,CAAC;IAElC,MAAM,QAAQ,GAAG,CAAC,KAAgB,EAAQ,EAAE;QAC1C,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO;QAChC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;QAClE,IAAI,KAAK,KAAK,MAAM;YAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC;QAC3D,SAAS,GAAG,KAAK,CAAC;IACpB,CAAC,CAAC;IAEF,OAAO;QACL,IAAI;QACJ,QAAQ;QACR,OAAO,CAAC,MAAc,EAAE,MAAM,GAAG,KAAK;YACpC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;YACtD,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;QAClE,CAAC;QACD,OAAO;YACL,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,wDAAwD;AACxD,SAAS,SAAS;IAChB,IAAI,WAAW,IAAI,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,WAAW,GAAG,IAAI,CAAC;QACnB,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC;IACpB,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACjC,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BX,CAAC"}
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
* choice menu, a labeled diamond, a solo labeled diamond, and a generic rarity card). Games use it to show "which button to
|
|
6
6
|
* press" in one consistent visual language across the library.
|
|
7
7
|
*
|
|
8
|
+
* It also carries the **overheat HUD family** — the screen-edge heat vignette, the lockout glitch
|
|
9
|
+
* overlay, and the pre-assembled bar that composes both — so every game with a heat mechanic shares
|
|
10
|
+
* one look and can take just the pieces it needs (a game drawing its own bar takes only the cues).
|
|
11
|
+
*
|
|
8
12
|
* Self-contained, like `@rydr/game-sdk/three`'s perf-overlay: it injects its own scoped `.rydr-ui-*`
|
|
9
13
|
* CSS once into `<head>`, depends on no global styles or CSS variables, and pulls in no three.js — so
|
|
10
14
|
* a game gets the look just by constructing a component. Wire any keycap to real input by passing the
|
|
@@ -33,4 +37,7 @@ export * from "./solo-labeled-diamond.js";
|
|
|
33
37
|
export * from "./rarity-card.js";
|
|
34
38
|
export * from "./power-race.js";
|
|
35
39
|
export * from "./admin-nav.js";
|
|
40
|
+
export * from "./heat-vignette.js";
|
|
41
|
+
export * from "./overheat-glitch.js";
|
|
42
|
+
export * from "./overheat-hud-bar.js";
|
|
36
43
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/ui/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
package/dist/ui/index.js
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
* choice menu, a labeled diamond, a solo labeled diamond, and a generic rarity card). Games use it to show "which button to
|
|
6
6
|
* press" in one consistent visual language across the library.
|
|
7
7
|
*
|
|
8
|
+
* It also carries the **overheat HUD family** — the screen-edge heat vignette, the lockout glitch
|
|
9
|
+
* overlay, and the pre-assembled bar that composes both — so every game with a heat mechanic shares
|
|
10
|
+
* one look and can take just the pieces it needs (a game drawing its own bar takes only the cues).
|
|
11
|
+
*
|
|
8
12
|
* Self-contained, like `@rydr/game-sdk/three`'s perf-overlay: it injects its own scoped `.rydr-ui-*`
|
|
9
13
|
* CSS once into `<head>`, depends on no global styles or CSS variables, and pulls in no three.js — so
|
|
10
14
|
* a game gets the look just by constructing a component. Wire any keycap to real input by passing the
|
|
@@ -33,4 +37,7 @@ export * from "./solo-labeled-diamond.js";
|
|
|
33
37
|
export * from "./rarity-card.js";
|
|
34
38
|
export * from "./power-race.js";
|
|
35
39
|
export * from "./admin-nav.js";
|
|
40
|
+
export * from "./heat-vignette.js";
|
|
41
|
+
export * from "./overheat-glitch.js";
|
|
42
|
+
export * from "./overheat-hud-bar.js";
|
|
36
43
|
//# sourceMappingURL=index.js.map
|
package/dist/ui/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mountOverheatGlitch` — the **overheat lockout glitch overlay**, on its own.
|
|
3
|
+
*
|
|
4
|
+
* The "your engine just blew" screen dressing: a one-shot RGB chromatic-aberration burst on the
|
|
5
|
+
* frame the lockout begins (cyan slides left, red slides right, white pops in the middle, ~160 ms),
|
|
6
|
+
* then sustained scanlines + a red noise wash for as long as the lockout lasts. It makes a forced
|
|
7
|
+
* cooldown feel like a hardware failure rather than a stat change.
|
|
8
|
+
*
|
|
9
|
+
* This is the glitch **alone**, deliberately separable: a game that draws its own heat bar (e.g. the
|
|
10
|
+
* racing game's in-canvas gauge) still wants the lockout drama. Pair it with
|
|
11
|
+
* {@link mountHeatVignette} for the peripheral heat cue, or take the whole pre-assembled package —
|
|
12
|
+
* bar + vignette + glitch — from {@link mountOverheatHudBar}.
|
|
13
|
+
*
|
|
14
|
+
* Self-contained DOM/CSS like the rest of `@rydr/game-sdk/ui`: it injects its own scoped
|
|
15
|
+
* `.rydr-heat-glitch*` stylesheet once into `<head>`, needs no global styles, no CSS variables and no
|
|
16
|
+
* three.js. It is driven by a single boolean — the game owns the lockout state.
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* const glitch = mountOverheatGlitch(hudHost);
|
|
20
|
+
* // every frame (edge-detected internally — cheap to call unconditionally):
|
|
21
|
+
* glitch.setLocked(heat.isLocked);
|
|
22
|
+
* // on teardown:
|
|
23
|
+
* glitch.dispose();
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* **Host contract:** the overlay is `position: absolute; inset: 0` at `z-index: 21`, so `host` must
|
|
27
|
+
* be positioned (and ideally `isolation: isolate`, so the z-index doesn't leak past it). A
|
|
28
|
+
* full-viewport `position: fixed; inset: 0; pointer-events: none; isolation: isolate` div over the
|
|
29
|
+
* game canvas is the intended host.
|
|
30
|
+
*/
|
|
31
|
+
/** Options for {@link mountOverheatGlitch}. */
|
|
32
|
+
export interface OverheatGlitchOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Stacking order inside the host. Default `21` — above {@link mountHeatVignette} (19) and
|
|
35
|
+
* {@link mountOverheatHudBar}'s bar (20), so the three compose in the intended order.
|
|
36
|
+
*/
|
|
37
|
+
zIndex?: number;
|
|
38
|
+
}
|
|
39
|
+
/** Live handle to a mounted glitch overlay. Returned by {@link mountOverheatGlitch}. */
|
|
40
|
+
export interface OverheatGlitch {
|
|
41
|
+
/** The overlay element (already appended to the host). */
|
|
42
|
+
readonly root: HTMLDivElement;
|
|
43
|
+
/**
|
|
44
|
+
* Set the lockout state. Safe to call every frame — the entry burst fires only on the
|
|
45
|
+
* `false → true` edge, and the sustained dressing follows the flag.
|
|
46
|
+
*/
|
|
47
|
+
setLocked(locked: boolean): void;
|
|
48
|
+
/** Remove the overlay from the host and cancel any pending entry beat. Idempotent. */
|
|
49
|
+
dispose(): void;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Mount an overheat glitch overlay into `host`. See the module header for the host contract; drive
|
|
53
|
+
* it with {@link OverheatGlitch.setLocked}.
|
|
54
|
+
*/
|
|
55
|
+
export declare function mountOverheatGlitch(host: HTMLElement, opts?: OverheatGlitchOptions): OverheatGlitch;
|
|
56
|
+
//# sourceMappingURL=overheat-glitch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overheat-glitch.d.ts","sourceRoot":"","sources":["../../src/ui/overheat-glitch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAOH,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wFAAwF;AACxF,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,sFAAsF;IACtF,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,WAAW,EACjB,IAAI,GAAE,qBAA0B,GAC/B,cAAc,CAqChB"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mountOverheatGlitch` — the **overheat lockout glitch overlay**, on its own.
|
|
3
|
+
*
|
|
4
|
+
* The "your engine just blew" screen dressing: a one-shot RGB chromatic-aberration burst on the
|
|
5
|
+
* frame the lockout begins (cyan slides left, red slides right, white pops in the middle, ~160 ms),
|
|
6
|
+
* then sustained scanlines + a red noise wash for as long as the lockout lasts. It makes a forced
|
|
7
|
+
* cooldown feel like a hardware failure rather than a stat change.
|
|
8
|
+
*
|
|
9
|
+
* This is the glitch **alone**, deliberately separable: a game that draws its own heat bar (e.g. the
|
|
10
|
+
* racing game's in-canvas gauge) still wants the lockout drama. Pair it with
|
|
11
|
+
* {@link mountHeatVignette} for the peripheral heat cue, or take the whole pre-assembled package —
|
|
12
|
+
* bar + vignette + glitch — from {@link mountOverheatHudBar}.
|
|
13
|
+
*
|
|
14
|
+
* Self-contained DOM/CSS like the rest of `@rydr/game-sdk/ui`: it injects its own scoped
|
|
15
|
+
* `.rydr-heat-glitch*` stylesheet once into `<head>`, needs no global styles, no CSS variables and no
|
|
16
|
+
* three.js. It is driven by a single boolean — the game owns the lockout state.
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* const glitch = mountOverheatGlitch(hudHost);
|
|
20
|
+
* // every frame (edge-detected internally — cheap to call unconditionally):
|
|
21
|
+
* glitch.setLocked(heat.isLocked);
|
|
22
|
+
* // on teardown:
|
|
23
|
+
* glitch.dispose();
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* **Host contract:** the overlay is `position: absolute; inset: 0` at `z-index: 21`, so `host` must
|
|
27
|
+
* be positioned (and ideally `isolation: isolate`, so the z-index doesn't leak past it). A
|
|
28
|
+
* full-viewport `position: fixed; inset: 0; pointer-events: none; isolation: isolate` div over the
|
|
29
|
+
* game canvas is the intended host.
|
|
30
|
+
*/
|
|
31
|
+
const STYLE_ID = "rydr-heat-glitch-css";
|
|
32
|
+
/** How long the one-shot entry burst is allowed to run before its marker class is cleared (ms). */
|
|
33
|
+
const ENTRY_BEAT_MS = 500;
|
|
34
|
+
/**
|
|
35
|
+
* Mount an overheat glitch overlay into `host`. See the module header for the host contract; drive
|
|
36
|
+
* it with {@link OverheatGlitch.setLocked}.
|
|
37
|
+
*/
|
|
38
|
+
export function mountOverheatGlitch(host, opts = {}) {
|
|
39
|
+
injectCss();
|
|
40
|
+
const root = document.createElement("div");
|
|
41
|
+
root.className = "rydr-heat-glitch";
|
|
42
|
+
if (opts.zIndex !== undefined)
|
|
43
|
+
root.style.zIndex = String(opts.zIndex);
|
|
44
|
+
root.innerHTML = `
|
|
45
|
+
<div class="rydr-heat-glitch-scanlines"></div>
|
|
46
|
+
<div class="rydr-heat-glitch-noise"></div>
|
|
47
|
+
<div class="rydr-heat-glitch-flash">
|
|
48
|
+
<div class="flash-cyan"></div>
|
|
49
|
+
<div class="flash-red"></div>
|
|
50
|
+
<div class="flash-white"></div>
|
|
51
|
+
</div>
|
|
52
|
+
`;
|
|
53
|
+
host.appendChild(root);
|
|
54
|
+
let lastLocked = false;
|
|
55
|
+
/** Timer clearing the one-shot `.entry` marker after the entry burst. */
|
|
56
|
+
let entryTimer = 0;
|
|
57
|
+
return {
|
|
58
|
+
root,
|
|
59
|
+
setLocked(locked) {
|
|
60
|
+
if (locked === lastLocked)
|
|
61
|
+
return;
|
|
62
|
+
lastLocked = locked;
|
|
63
|
+
root.classList.toggle("locked", locked);
|
|
64
|
+
if (!locked)
|
|
65
|
+
return;
|
|
66
|
+
root.classList.add("entry");
|
|
67
|
+
clearTimeout(entryTimer);
|
|
68
|
+
entryTimer = window.setTimeout(() => root.classList.remove("entry"), ENTRY_BEAT_MS);
|
|
69
|
+
},
|
|
70
|
+
dispose() {
|
|
71
|
+
clearTimeout(entryTimer);
|
|
72
|
+
root.remove();
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
let cssInjected = false;
|
|
77
|
+
/** Inject the scoped glitch CSS once per document. */
|
|
78
|
+
function injectCss() {
|
|
79
|
+
if (cssInjected || document.getElementById(STYLE_ID)) {
|
|
80
|
+
cssInjected = true;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const style = document.createElement("style");
|
|
84
|
+
style.id = STYLE_ID;
|
|
85
|
+
style.textContent = CSS;
|
|
86
|
+
document.head.appendChild(style);
|
|
87
|
+
cssInjected = true;
|
|
88
|
+
}
|
|
89
|
+
const CSS = `
|
|
90
|
+
.rydr-heat-glitch {
|
|
91
|
+
position: absolute;
|
|
92
|
+
inset: 0;
|
|
93
|
+
pointer-events: none;
|
|
94
|
+
z-index: 21;
|
|
95
|
+
opacity: 0;
|
|
96
|
+
transition: opacity 0.2s;
|
|
97
|
+
}
|
|
98
|
+
.rydr-heat-glitch.locked { opacity: 1; }
|
|
99
|
+
|
|
100
|
+
/* ─── SUSTAINED DRESSING ──────────────────────────────────────── */
|
|
101
|
+
.rydr-heat-glitch-scanlines {
|
|
102
|
+
position: absolute;
|
|
103
|
+
inset: 0;
|
|
104
|
+
background: repeating-linear-gradient(
|
|
105
|
+
0deg,
|
|
106
|
+
rgba(0,0,0,0.18) 0 2px,
|
|
107
|
+
transparent 2px 4px
|
|
108
|
+
);
|
|
109
|
+
animation: rydr-heat-glitch-scan 0.7s linear infinite;
|
|
110
|
+
}
|
|
111
|
+
@keyframes rydr-heat-glitch-scan {
|
|
112
|
+
from { background-position: 0 0; }
|
|
113
|
+
to { background-position: 0 8px; }
|
|
114
|
+
}
|
|
115
|
+
.rydr-heat-glitch-noise {
|
|
116
|
+
position: absolute;
|
|
117
|
+
inset: 0;
|
|
118
|
+
background:
|
|
119
|
+
radial-gradient(at 20% 30%, rgba(239,68,68,0.12), transparent 60%),
|
|
120
|
+
radial-gradient(at 80% 70%, rgba(239,68,68,0.10), transparent 55%),
|
|
121
|
+
radial-gradient(at 50% 90%, rgba(220,38,38,0.08), transparent 50%);
|
|
122
|
+
mix-blend-mode: screen;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* ─── ENTRY BEAT — RGB FLASH ──────────────────────────────────────
|
|
126
|
+
Full-screen chromatic-aberration burst when the lockout begins. Cyan
|
|
127
|
+
layer slides left, red slides right, white pops in the middle. ~160 ms. */
|
|
128
|
+
.rydr-heat-glitch-flash {
|
|
129
|
+
position: absolute;
|
|
130
|
+
inset: 0;
|
|
131
|
+
opacity: 0;
|
|
132
|
+
pointer-events: none;
|
|
133
|
+
}
|
|
134
|
+
.rydr-heat-glitch-flash .flash-cyan,
|
|
135
|
+
.rydr-heat-glitch-flash .flash-red,
|
|
136
|
+
.rydr-heat-glitch-flash .flash-white {
|
|
137
|
+
position: absolute;
|
|
138
|
+
inset: 0;
|
|
139
|
+
mix-blend-mode: screen;
|
|
140
|
+
}
|
|
141
|
+
.rydr-heat-glitch-flash .flash-cyan { background: rgba(0, 220, 255, 0.40); }
|
|
142
|
+
.rydr-heat-glitch-flash .flash-red { background: rgba(255, 0, 80, 0.40); }
|
|
143
|
+
.rydr-heat-glitch-flash .flash-white { background: rgba(255, 255, 255, 0.35); }
|
|
144
|
+
|
|
145
|
+
.rydr-heat-glitch.entry .rydr-heat-glitch-flash {
|
|
146
|
+
animation: rydr-heat-glitch-flash-shell 0.16s ease-out forwards;
|
|
147
|
+
}
|
|
148
|
+
.rydr-heat-glitch.entry .rydr-heat-glitch-flash .flash-cyan {
|
|
149
|
+
animation: rydr-heat-glitch-shift-left 0.16s ease-out forwards;
|
|
150
|
+
}
|
|
151
|
+
.rydr-heat-glitch.entry .rydr-heat-glitch-flash .flash-red {
|
|
152
|
+
animation: rydr-heat-glitch-shift-right 0.16s ease-out forwards;
|
|
153
|
+
}
|
|
154
|
+
.rydr-heat-glitch.entry .rydr-heat-glitch-flash .flash-white {
|
|
155
|
+
animation: rydr-heat-glitch-pop 0.16s ease-out forwards;
|
|
156
|
+
}
|
|
157
|
+
@keyframes rydr-heat-glitch-flash-shell {
|
|
158
|
+
0% { opacity: 0; }
|
|
159
|
+
35% { opacity: 1; }
|
|
160
|
+
100% { opacity: 0; }
|
|
161
|
+
}
|
|
162
|
+
@keyframes rydr-heat-glitch-shift-left {
|
|
163
|
+
0% { transform: translateX(0); }
|
|
164
|
+
35% { transform: translateX(-14px); }
|
|
165
|
+
100% { transform: translateX(0); }
|
|
166
|
+
}
|
|
167
|
+
@keyframes rydr-heat-glitch-shift-right {
|
|
168
|
+
0% { transform: translateX(0); }
|
|
169
|
+
35% { transform: translateX(14px); }
|
|
170
|
+
100% { transform: translateX(0); }
|
|
171
|
+
}
|
|
172
|
+
@keyframes rydr-heat-glitch-pop {
|
|
173
|
+
0%, 100% { opacity: 0; }
|
|
174
|
+
35% { opacity: 1; }
|
|
175
|
+
}
|
|
176
|
+
`;
|
|
177
|
+
//# sourceMappingURL=overheat-glitch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overheat-glitch.js","sourceRoot":"","sources":["../../src/ui/overheat-glitch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,QAAQ,GAAG,sBAAsB,CAAC;AAExC,mGAAmG;AACnG,MAAM,aAAa,GAAG,GAAG,CAAC;AAwB1B;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAiB,EACjB,OAA8B,EAAE;IAEhC,SAAS,EAAE,CAAC;IAEZ,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,SAAS,GAAG,kBAAkB,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvE,IAAI,CAAC,SAAS,GAAG;;;;;;;;GAQhB,CAAC;IACF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAEvB,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,yEAAyE;IACzE,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,OAAO;QACL,IAAI;QACJ,SAAS,CAAC,MAAe;YACvB,IAAI,MAAM,KAAK,UAAU;gBAAE,OAAO;YAClC,UAAU,GAAG,MAAM,CAAC;YACpB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACxC,IAAI,CAAC,MAAM;gBAAE,OAAO;YACpB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC5B,YAAY,CAAC,UAAU,CAAC,CAAC;YACzB,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC;QACtF,CAAC;QACD,OAAO;YACL,YAAY,CAAC,UAAU,CAAC,CAAC;YACzB,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,sDAAsD;AACtD,SAAS,SAAS;IAChB,IAAI,WAAW,IAAI,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,WAAW,GAAG,IAAI,CAAC;QACnB,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC;IACpB,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACjC,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuFX,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mountOverheatHudBar` — the **complete overheat HUD package**: a big centered inferno bar with
|
|
3
|
+
* escalating warning stages, plus the screen-edge vignette and the lockout glitch overlay, wired
|
|
4
|
+
* together and driven by one `update()` call.
|
|
5
|
+
*
|
|
6
|
+
* This is the batteries-included option, and the one to reach for if you just want a heat mechanic
|
|
7
|
+
* to look right. It is assembled from the two separable pieces — {@link mountHeatVignette} and
|
|
8
|
+
* {@link mountOverheatGlitch} — so a game that draws its **own** heat bar (e.g. the racing game's
|
|
9
|
+
* in-canvas gauge) can take just the peripheral cues and skip this module entirely. Same visual
|
|
10
|
+
* language either way.
|
|
11
|
+
*
|
|
12
|
+
* What it renders:
|
|
13
|
+
* · a label that reads `OVERHEATING...` while heat builds and `OVERHEAT` once locked,
|
|
14
|
+
* · a track + fire-gradient fill (amber → orange → red) that pulses faster at each stage
|
|
15
|
+
* ({@link HEAT_STAGE_THRESHOLDS}: slow → fast → panic) and washes solid red near full,
|
|
16
|
+
* · a `COOLING DOWN` block with an optional ticking countdown during the lockout,
|
|
17
|
+
* · the vignette (z 19) and glitch overlay (z 21) around the bar (z 20).
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* const overheat = mountOverheatHudBar(hudHost);
|
|
21
|
+
* // every frame:
|
|
22
|
+
* overheat.update(heat.fillRatio, heat.isLocked, heat.cooldownRemaining);
|
|
23
|
+
* // on teardown:
|
|
24
|
+
* overheat.dispose();
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* Lockouts come in two flavours and both are supported: pass a positive `lockoutRemaining` for a
|
|
28
|
+
* fixed countdown (the digits tick down), or omit it for a continuous/timerless cooldown (the
|
|
29
|
+
* `COOLING DOWN` title and glitch still show, digits hidden).
|
|
30
|
+
*
|
|
31
|
+
* **Host contract:** everything is `position: absolute` inside `host`, which must be positioned and
|
|
32
|
+
* should set `isolation: isolate` so the internal z-indexes (19–21) don't leak. A full-viewport
|
|
33
|
+
* `position: fixed; inset: 0; pointer-events: none; isolation: isolate` div over the game canvas is
|
|
34
|
+
* the intended host.
|
|
35
|
+
*
|
|
36
|
+
* **Fonts:** the bar uses Rajdhani + Share Tech Mono and loads them from Google Fonts on first mount
|
|
37
|
+
* — the one place this kit reaches off-origin. Pass `loadFonts: false` to skip that (the CSS falls
|
|
38
|
+
* back to the local monospace/sans stack) if your page has a strict CSP or ships the faces itself.
|
|
39
|
+
*/
|
|
40
|
+
import type { HeatStage, HeatVignette } from "./heat-vignette.js";
|
|
41
|
+
import type { OverheatGlitch } from "./overheat-glitch.js";
|
|
42
|
+
/** Options for {@link mountOverheatHudBar}. */
|
|
43
|
+
export interface OverheatHudBarOptions {
|
|
44
|
+
/** Stage cut-offs (0..1) for the pulse ramp + vignette. Default {@link HEAT_STAGE_THRESHOLDS}. */
|
|
45
|
+
thresholds?: Readonly<Record<Exclude<HeatStage, "idle">, number>>;
|
|
46
|
+
/** Load Rajdhani + Share Tech Mono from Google Fonts on first mount. Default `true`. */
|
|
47
|
+
loadFonts?: boolean;
|
|
48
|
+
/** Render the screen-edge vignette alongside the bar. Default `true`. */
|
|
49
|
+
vignette?: boolean;
|
|
50
|
+
/** Render the lockout glitch overlay alongside the bar. Default `true`. */
|
|
51
|
+
glitch?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/** Live handle to a mounted overheat HUD. Returned by {@link mountOverheatHudBar}. */
|
|
54
|
+
export interface OverheatHudBar {
|
|
55
|
+
/** The bar element (label + track + COOLING DOWN block). */
|
|
56
|
+
readonly root: HTMLDivElement;
|
|
57
|
+
/** The vignette handle, or `null` when `vignette: false`. */
|
|
58
|
+
readonly vignette: HeatVignette | null;
|
|
59
|
+
/** The glitch-overlay handle, or `null` when `glitch: false`. */
|
|
60
|
+
readonly glitch: OverheatGlitch | null;
|
|
61
|
+
/**
|
|
62
|
+
* Drive the whole package for one frame.
|
|
63
|
+
*
|
|
64
|
+
* @param heat01 Heat as a 0..1 fill ratio.
|
|
65
|
+
* @param locked True while the game is in its overheat lockout — forces the danger vignette +
|
|
66
|
+
* glitch and swaps the label to `OVERHEAT`.
|
|
67
|
+
* @param lockoutRemaining Seconds left in a **fixed** lockout, shown as a ticking countdown. Omit
|
|
68
|
+
* or pass `0` for a continuous (timerless) cooldown — the digits stay hidden.
|
|
69
|
+
*/
|
|
70
|
+
update(heat01: number, locked?: boolean, lockoutRemaining?: number): void;
|
|
71
|
+
/** Remove the bar, vignette and glitch overlay from the host. Idempotent. */
|
|
72
|
+
dispose(): void;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Mount the full overheat HUD (bar + vignette + glitch) into `host`. See the module header for the
|
|
76
|
+
* host contract; drive it every frame with {@link OverheatHudBar.update}.
|
|
77
|
+
*/
|
|
78
|
+
export declare function mountOverheatHudBar(host: HTMLElement, opts?: OverheatHudBarOptions): OverheatHudBar;
|
|
79
|
+
//# sourceMappingURL=overheat-hud-bar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overheat-hud-bar.d.ts","sourceRoot":"","sources":["../../src/ui/overheat-hud-bar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAQ3D,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC,kGAAkG;IAClG,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,sFAAsF;AACtF,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IACvC,iEAAiE;IACjE,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IACvC;;;;;;;;OAQG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1E,6EAA6E;IAC7E,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,WAAW,EACjB,IAAI,GAAE,qBAA0B,GAC/B,cAAc,CA+FhB"}
|