@rydr/game-sdk 8.13.0 → 8.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/protocol/identity.d.ts +39 -0
- package/dist/protocol/identity.d.ts.map +1 -1
- package/dist/protocol/version.d.ts +1 -1
- package/dist/protocol/version.js +1 -1
- package/dist/three/README.md +132 -4
- package/dist/three/character/riders.d.ts.map +1 -1
- package/dist/three/character/riders.js.map +1 -1
- package/dist/three/controller/index.d.ts +2 -0
- package/dist/three/controller/index.d.ts.map +1 -1
- package/dist/three/controller/index.js +2 -0
- package/dist/three/controller/index.js.map +1 -1
- package/dist/three/controller/joycon-designs.d.ts +15 -1
- package/dist/three/controller/joycon-designs.d.ts.map +1 -1
- package/dist/three/controller/joycon-designs.js +302 -60
- package/dist/three/controller/joycon-designs.js.map +1 -1
- package/dist/three/controller/joycon-object.d.ts +216 -0
- package/dist/three/controller/joycon-object.d.ts.map +1 -0
- package/dist/three/controller/joycon-object.js +578 -0
- package/dist/three/controller/joycon-object.js.map +1 -0
- package/dist/three/controller/joycon-spec.d.ts +116 -4
- package/dist/three/controller/joycon-spec.d.ts.map +1 -1
- package/dist/three/controller/joycon-spec.js +128 -22
- package/dist/three/controller/joycon-spec.js.map +1 -1
- package/dist/three/controller/press-pulse.d.ts +89 -0
- package/dist/three/controller/press-pulse.d.ts.map +1 -0
- package/dist/three/controller/press-pulse.js +309 -0
- package/dist/three/controller/press-pulse.js.map +1 -0
- package/dist/three/controller/three-pad-renderer.d.ts +11 -22
- package/dist/three/controller/three-pad-renderer.d.ts.map +1 -1
- package/dist/three/controller/three-pad-renderer.js +44 -258
- package/dist/three/controller/three-pad-renderer.js.map +1 -1
- package/dist/three/rider/three-rider-rig.d.ts +12 -0
- package/dist/three/rider/three-rider-rig.d.ts.map +1 -1
- package/dist/three/rider/three-rider-rig.js +102 -9
- package/dist/three/rider/three-rider-rig.js.map +1 -1
- package/dist/ui/README.md +133 -7
- package/dist/ui/choice-card.d.ts +8 -0
- package/dist/ui/choice-card.d.ts.map +1 -1
- package/dist/ui/choice-card.js +1 -1
- package/dist/ui/choice-card.js.map +1 -1
- package/dist/ui/controller/controller-pad.d.ts +105 -2
- package/dist/ui/controller/controller-pad.d.ts.map +1 -1
- package/dist/ui/controller/controller-pad.js +347 -16
- package/dist/ui/controller/controller-pad.js.map +1 -1
- package/dist/ui/controller/renderer.d.ts +13 -0
- package/dist/ui/controller/renderer.d.ts.map +1 -1
- package/dist/ui/controller/renderer.js.map +1 -1
- package/dist/ui/controller/styles.js +50 -1
- package/dist/ui/controller/styles.js.map +1 -1
- package/dist/ui/dialogue-card.d.ts +8 -0
- package/dist/ui/dialogue-card.d.ts.map +1 -1
- package/dist/ui/dialogue-card.js +1 -1
- package/dist/ui/dialogue-card.js.map +1 -1
- package/dist/ui/hud-placement.d.ts +81 -0
- package/dist/ui/hud-placement.d.ts.map +1 -0
- package/dist/ui/hud-placement.js +74 -0
- package/dist/ui/hud-placement.js.map +1 -0
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +1 -0
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/rider-rig.d.ts +108 -10
- package/dist/ui/rider-rig.d.ts.map +1 -1
- package/dist/ui/rider-rig.js +299 -48
- package/dist/ui/rider-rig.js.map +1 -1
- package/dist/ui/solo-labeled-diamond.d.ts +13 -0
- package/dist/ui/solo-labeled-diamond.d.ts.map +1 -1
- package/dist/ui/solo-labeled-diamond.js +1 -1
- package/dist/ui/solo-labeled-diamond.js.map +1 -1
- package/package.json +4 -2
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { type Card } from "./card.js";
|
|
18
18
|
import { type DiamondButton, type ButtonSource, type Keycap } from "./keycap.js";
|
|
19
|
+
import type { GlyphSet } from "../protocol/glyphs.js";
|
|
19
20
|
/**
|
|
20
21
|
* A structured line: `text` plus an optional per-line speaker `name` (so one card can host a
|
|
21
22
|
* multi-character conversation) and an optional `audioUrl` (voice-over MP3, played when the line
|
|
@@ -38,6 +39,13 @@ export interface DialogueCardOptions {
|
|
|
38
39
|
typeMs?: number;
|
|
39
40
|
/** Wire the continue keycap to real controller input (pressed while its button is held). */
|
|
40
41
|
press?: ButtonSource;
|
|
42
|
+
/**
|
|
43
|
+
* Which controller's lettering to print on the keycap. Defaults to the set reported by `press`
|
|
44
|
+
* (when that's a `session`), else {@link DEFAULT_GLYPH_SET}. Pass it when you hold the rider's
|
|
45
|
+
* glyph set but no session — otherwise the cap silently prints Xbox letters, which name the
|
|
46
|
+
* wrong button on a Switch pad.
|
|
47
|
+
*/
|
|
48
|
+
glyphSet?: GlyphSet;
|
|
41
49
|
/** Box height, in text lines: the line is clipped to this fixed frame so it can't grow (default 3). */
|
|
42
50
|
maxLines?: number;
|
|
43
51
|
/** Soft per-line character budget: a longer line logs a dev warning (default 140). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialogue-card.d.ts","sourceRoot":"","sources":["../../src/ui/dialogue-card.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAgB,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"dialogue-card.d.ts","sourceRoot":"","sources":["../../src/ui/dialogue-card.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAgB,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAC/F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAKtD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,2FAA2F;IAC3F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;iDAC6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,wEAAwE;IACxE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,uGAAuG;IACvG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;8GAC0G;IAC1G,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,WAAW,CAAC;IAClB,mEAAmE;IACnE,IAAI,EAAE,IAAI,CAAC;IACX,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf;2GACuG;IACvG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,YAAY,CAAC,GAAG,IAAI,CAAC;IAC9D,sGAAsG;IACtG,OAAO,IAAI,OAAO,CAAC;IACnB,+BAA+B;IAC/B,KAAK,IAAI,IAAI,CAAC;IACd,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,2GAA2G;AAC3G,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,GAAE,mBAAwB,GAAG,YAAY,CAgGjG"}
|
package/dist/ui/dialogue-card.js
CHANGED
|
@@ -33,7 +33,7 @@ export function mountDialogueCard(host, opts = {}) {
|
|
|
33
33
|
go.className = "rydr-ui-dlg-go";
|
|
34
34
|
const cueEl = document.createElement("span");
|
|
35
35
|
cueEl.className = "rydr-ui-dlg-cue";
|
|
36
|
-
const keycap = createKeycap(opts.button ?? "DIAMOND_DOWN", { variant: "solo", animate: true, press: opts.press });
|
|
36
|
+
const keycap = createKeycap(opts.button ?? "DIAMOND_DOWN", { variant: "solo", animate: true, press: opts.press, glyphSet: opts.glyphSet });
|
|
37
37
|
go.append(cueEl, keycap.el);
|
|
38
38
|
wrap.append(nameEl, lineEl, go);
|
|
39
39
|
const card = mountCard(host, { content: wrap, inline: opts.inline });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialogue-card.js","sourceRoot":"","sources":["../../src/ui/dialogue-card.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,SAAS,EAAa,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,YAAY,EAAsD,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"dialogue-card.js","sourceRoot":"","sources":["../../src/ui/dialogue-card.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HUD PLACEMENT — one way to say "put this in that corner of the game screen" (PLAT-1582).
|
|
3
|
+
*
|
|
4
|
+
* Several components in this kit are pictures a game pins over its own rendering: the rider rig, the
|
|
5
|
+
* controller pad. Each of them was going to grow its own `corner` / `margin` / `zIndex` options, with
|
|
6
|
+
* its own defaults and its own arithmetic, and a game would then have learned the same idea twice in
|
|
7
|
+
* two vocabularies. This is that idea, once.
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* mountControllerPad(gameRoot, {
|
|
11
|
+
* press: session,
|
|
12
|
+
* width: 260,
|
|
13
|
+
* place: { corner: "bottom-right", margin: 24 },
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* **The placed element is click-through.** All of it, `pointer-events: none` — it is a picture the game
|
|
18
|
+
* draws over itself, and a HUD element that swallowed a click on whatever is underneath would be a bug
|
|
19
|
+
* in every game that used one.
|
|
20
|
+
*
|
|
21
|
+
* **What it is pinned TO.** By default the host element, which is what a game wants: the component
|
|
22
|
+
* rides inside the game's own root and inherits its bounds. A host in the CSS default
|
|
23
|
+
* `position: static` cannot anchor a child, so mounting a placed component into one promotes it to
|
|
24
|
+
* `relative` — the one style these components ever write outside their own subtree, and it is
|
|
25
|
+
* announced here because it is observable. Pass `fixed` to pin to the browser viewport instead and
|
|
26
|
+
* leave the host alone entirely.
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* The nine places a pinned component can sit, named the way a HUD is described out loud.
|
|
30
|
+
*
|
|
31
|
+
* They are shorthands over {@link HudPlacement.x}/{@link HudPlacement.y} — `"bottom-right"` IS
|
|
32
|
+
* `{ x: 1, y: 1 }` — so a game can start from a corner and nudge from there without switching
|
|
33
|
+
* vocabulary.
|
|
34
|
+
*/
|
|
35
|
+
export type HudCorner = "top-left" | "top" | "top-right" | "left" | "center" | "right" | "bottom-left" | "bottom" | "bottom-right";
|
|
36
|
+
/** Where a pinned component sits on the game's screen. */
|
|
37
|
+
export interface HudPlacement {
|
|
38
|
+
/** Which of the nine anchors. Default `"bottom-right"`. Overridden per axis by {@link x}/{@link y}. */
|
|
39
|
+
corner?: HudCorner;
|
|
40
|
+
/**
|
|
41
|
+
* Free horizontal position, 0 = flush left … 1 = flush right, overriding {@link corner}'s x.
|
|
42
|
+
*
|
|
43
|
+
* It positions the element's own matching edge, not its centre: at 0 the left edge sits on the left
|
|
44
|
+
* margin, at 1 the right edge on the right margin, and in between it slides proportionally. So the
|
|
45
|
+
* element can never hang off the screen, whatever its width — which is the whole reason this is a
|
|
46
|
+
* fraction rather than a pixel offset.
|
|
47
|
+
*/
|
|
48
|
+
x?: number;
|
|
49
|
+
/** Free vertical position, 0 = top … 1 = bottom, overriding {@link corner}'s y. Same rule as {@link x}. */
|
|
50
|
+
y?: number;
|
|
51
|
+
/** Inset from the edges, in CSS pixels. Default 16. */
|
|
52
|
+
margin?: number;
|
|
53
|
+
/** Pin to the browser viewport rather than to the host element. Default false. */
|
|
54
|
+
fixed?: boolean;
|
|
55
|
+
/** Stacking order against the game's own layers. Default 5. */
|
|
56
|
+
zIndex?: number;
|
|
57
|
+
}
|
|
58
|
+
/** The nine corners as the x/y fractions they are shorthands for. */
|
|
59
|
+
export declare const HUD_CORNER_XY: Readonly<Record<HudCorner, readonly [number, number]>>;
|
|
60
|
+
/**
|
|
61
|
+
* Pin an element per a {@link HudPlacement}.
|
|
62
|
+
*
|
|
63
|
+
* The arithmetic is the whole trick and it is deliberately not `left: x%`: that would place the
|
|
64
|
+
* element's LEFT EDGE at the fraction, so one at x = 1 would start at the right edge and hang entirely
|
|
65
|
+
* off screen. Pairing `left: x%` with `translateX(-x * 100%)` slides the element's own matching edge
|
|
66
|
+
* instead — its left edge at 0, its right edge at 1, its centre at 0.5 — and the margin is then inset
|
|
67
|
+
* from both sides so the same fraction clears the edge at either end.
|
|
68
|
+
*
|
|
69
|
+
* Writes inline styles only; the click-through and the dropped `max-width` belong to the component's
|
|
70
|
+
* own `--placed` class, since only it knows what it normally sizes itself by.
|
|
71
|
+
*/
|
|
72
|
+
export declare function applyHudPlacement(el: HTMLElement, place: HudPlacement): void;
|
|
73
|
+
/**
|
|
74
|
+
* Make `host` able to anchor a placed child, unless the placement pins to the viewport.
|
|
75
|
+
*
|
|
76
|
+
* Separate from {@link applyHudPlacement} because it touches an element the component does not own —
|
|
77
|
+
* see the module header. Returns nothing: it is idempotent and there is nothing to undo (a host left
|
|
78
|
+
* at `position: relative` behaves identically to a static one for everything else in flow).
|
|
79
|
+
*/
|
|
80
|
+
export declare function anchorHudHost(host: HTMLElement, place: HudPlacement): void;
|
|
81
|
+
//# sourceMappingURL=hud-placement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hud-placement.d.ts","sourceRoot":"","sources":["../../src/ui/hud-placement.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GACjB,UAAU,GAAG,KAAK,GAAG,WAAW,GAChC,MAAM,GAAG,QAAQ,GAAG,OAAO,GAC3B,aAAa,GAAG,QAAQ,GAAG,cAAc,CAAC;AAE9C,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,uGAAuG;IACvG,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;;;OAOG;IACH,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,2GAA2G;IAC3G,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qEAAqE;AACrE,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAIhF,CAAC;AAIF;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAc5E;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAG1E"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HUD PLACEMENT — one way to say "put this in that corner of the game screen" (PLAT-1582).
|
|
3
|
+
*
|
|
4
|
+
* Several components in this kit are pictures a game pins over its own rendering: the rider rig, the
|
|
5
|
+
* controller pad. Each of them was going to grow its own `corner` / `margin` / `zIndex` options, with
|
|
6
|
+
* its own defaults and its own arithmetic, and a game would then have learned the same idea twice in
|
|
7
|
+
* two vocabularies. This is that idea, once.
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* mountControllerPad(gameRoot, {
|
|
11
|
+
* press: session,
|
|
12
|
+
* width: 260,
|
|
13
|
+
* place: { corner: "bottom-right", margin: 24 },
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* **The placed element is click-through.** All of it, `pointer-events: none` — it is a picture the game
|
|
18
|
+
* draws over itself, and a HUD element that swallowed a click on whatever is underneath would be a bug
|
|
19
|
+
* in every game that used one.
|
|
20
|
+
*
|
|
21
|
+
* **What it is pinned TO.** By default the host element, which is what a game wants: the component
|
|
22
|
+
* rides inside the game's own root and inherits its bounds. A host in the CSS default
|
|
23
|
+
* `position: static` cannot anchor a child, so mounting a placed component into one promotes it to
|
|
24
|
+
* `relative` — the one style these components ever write outside their own subtree, and it is
|
|
25
|
+
* announced here because it is observable. Pass `fixed` to pin to the browser viewport instead and
|
|
26
|
+
* leave the host alone entirely.
|
|
27
|
+
*/
|
|
28
|
+
/** The nine corners as the x/y fractions they are shorthands for. */
|
|
29
|
+
export const HUD_CORNER_XY = {
|
|
30
|
+
"top-left": [0, 0], top: [0.5, 0], "top-right": [1, 0],
|
|
31
|
+
left: [0, 0.5], center: [0.5, 0.5], right: [1, 0.5],
|
|
32
|
+
"bottom-left": [0, 1], bottom: [0.5, 1], "bottom-right": [1, 1],
|
|
33
|
+
};
|
|
34
|
+
const clamp01 = (v) => Math.min(1, Math.max(0, v));
|
|
35
|
+
/**
|
|
36
|
+
* Pin an element per a {@link HudPlacement}.
|
|
37
|
+
*
|
|
38
|
+
* The arithmetic is the whole trick and it is deliberately not `left: x%`: that would place the
|
|
39
|
+
* element's LEFT EDGE at the fraction, so one at x = 1 would start at the right edge and hang entirely
|
|
40
|
+
* off screen. Pairing `left: x%` with `translateX(-x * 100%)` slides the element's own matching edge
|
|
41
|
+
* instead — its left edge at 0, its right edge at 1, its centre at 0.5 — and the margin is then inset
|
|
42
|
+
* from both sides so the same fraction clears the edge at either end.
|
|
43
|
+
*
|
|
44
|
+
* Writes inline styles only; the click-through and the dropped `max-width` belong to the component's
|
|
45
|
+
* own `--placed` class, since only it knows what it normally sizes itself by.
|
|
46
|
+
*/
|
|
47
|
+
export function applyHudPlacement(el, place) {
|
|
48
|
+
const [cx, cy] = HUD_CORNER_XY[place.corner ?? "bottom-right"];
|
|
49
|
+
const x = clamp01(place.x ?? cx);
|
|
50
|
+
const y = clamp01(place.y ?? cy);
|
|
51
|
+
const m = place.margin ?? 16;
|
|
52
|
+
el.style.position = place.fixed ? "fixed" : "absolute";
|
|
53
|
+
el.style.zIndex = String(place.zIndex ?? 5);
|
|
54
|
+
// The margin is taken out of the travel, not added to it, so x = 1 lands ON the margin rather than
|
|
55
|
+
// past it. `calc` does the work in the browser's own units, which keeps this correct when the host
|
|
56
|
+
// is resized without anything re-running here.
|
|
57
|
+
el.style.left = `calc(${m}px + ${x} * (100% - ${m * 2}px))`;
|
|
58
|
+
el.style.top = `calc(${m}px + ${y} * (100% - ${m * 2}px))`;
|
|
59
|
+
el.style.transform = `translate(${-x * 100}%, ${-y * 100}%)`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Make `host` able to anchor a placed child, unless the placement pins to the viewport.
|
|
63
|
+
*
|
|
64
|
+
* Separate from {@link applyHudPlacement} because it touches an element the component does not own —
|
|
65
|
+
* see the module header. Returns nothing: it is idempotent and there is nothing to undo (a host left
|
|
66
|
+
* at `position: relative` behaves identically to a static one for everything else in flow).
|
|
67
|
+
*/
|
|
68
|
+
export function anchorHudHost(host, place) {
|
|
69
|
+
if (place.fixed)
|
|
70
|
+
return;
|
|
71
|
+
if (getComputedStyle(host).position === "static")
|
|
72
|
+
host.style.position = "relative";
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=hud-placement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hud-placement.js","sourceRoot":"","sources":["../../src/ui/hud-placement.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAqCH,qEAAqE;AACrE,MAAM,CAAC,MAAM,aAAa,GAA2D;IACnF,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IACtD,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC;IACnD,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;CAChE,CAAC;AAEF,MAAM,OAAO,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAEnE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAe,EAAE,KAAmB;IACpE,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,MAAM,IAAI,cAAc,CAAC,CAAC;IAC/D,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;IAE7B,EAAE,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;IACvD,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IAC5C,mGAAmG;IACnG,mGAAmG;IACnG,+CAA+C;IAC/C,EAAE,CAAC,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC;IAC5D,EAAE,CAAC,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC;IAC3D,EAAE,CAAC,KAAK,CAAC,SAAS,GAAG,aAAa,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC;AAC/D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,IAAiB,EAAE,KAAmB;IAClE,IAAI,KAAK,CAAC,KAAK;QAAE,OAAO;IACxB,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ;QAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;AACrF,CAAC"}
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
* If a label doesn't fit, shorten the text, don't shrink the type.
|
|
38
38
|
* ──────────────────────────────────────────────────────────────────────────────────────────────
|
|
39
39
|
*/
|
|
40
|
+
export * from "./hud-placement.js";
|
|
40
41
|
export * from "./keycap.js";
|
|
41
42
|
export * from "./controller/index.js";
|
|
42
43
|
export * from "./card.js";
|
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
package/dist/ui/index.js
CHANGED
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
* If a label doesn't fit, shorten the text, don't shrink the type.
|
|
38
38
|
* ──────────────────────────────────────────────────────────────────────────────────────────────
|
|
39
39
|
*/
|
|
40
|
+
export * from "./hud-placement.js";
|
|
40
41
|
export * from "./keycap.js";
|
|
41
42
|
export * from "./controller/index.js";
|
|
42
43
|
export * from "./card.js";
|
package/dist/ui/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
package/dist/ui/rider-rig.d.ts
CHANGED
|
@@ -60,7 +60,8 @@
|
|
|
60
60
|
* The scale runs `0 → 1.5 × ftp`, so the rider's own threshold sits at two thirds of the way up with
|
|
61
61
|
* headroom above it for a sprint, and it carries a labelled FTP reference mark. A 150 W rider and a
|
|
62
62
|
* 350 W rider therefore see the same gauge do the same thing for the same effort — never hard-code a
|
|
63
|
-
* raw-watt scale (the same rule as {@link createPowerRace}).
|
|
63
|
+
* raw-watt scale (the same rule as {@link createPowerRace}). The effort colour is a continuous ramp
|
|
64
|
+
* over %FTP — grey-blue, blue, violet, pink, red, with no band boundaries to jump at — and is
|
|
64
65
|
* are **local to this component**: they are deliberately NOT `@rydr/game-sdk/difficulty`'s ramp, which
|
|
65
66
|
* colours the rider's *chosen calibration level* and would be a different quantity wearing the same
|
|
66
67
|
* paint.
|
|
@@ -89,11 +90,16 @@
|
|
|
89
90
|
* Every gauge is a CONTINUOUS fill; what changes is the paint and the tooltip's orientation.
|
|
90
91
|
*
|
|
91
92
|
* · `solid` (default) — flat opaque silhouette; a landscape tooltip with the figure beside the
|
|
92
|
-
* title and the bar under both. Most legible; start here.
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
93
|
+
* title and the bar under both. Most legible; start here. Its trainer's FLYWHEEL is the second
|
|
94
|
+
* reading — white, haloed in the gauge's own zone colour at a strength the effort sets, so the
|
|
95
|
+
* watts are legible from across a room without reading a number. The flywheel and not the front
|
|
96
|
+
* wheel: that disc is the one the legs actually drive, while the front wheel is parked on the floor
|
|
97
|
+
* driven by nothing.
|
|
98
|
+
* · `blueprint` — thin technical linework; a PORTRAIT tooltip whose bar runs vertically, with the
|
|
99
|
+
* caption above the figure and both stacked over a tall bar marked at FTP. On that variant the bar
|
|
100
|
+
* is still the reading — a rider glancing at a trainer screen reads a fill long before three
|
|
101
|
+
* digits — so the figure is set smaller than the landscape one: it answers "exactly how much",
|
|
102
|
+
* which the fill cannot, without taking the headline off the bar.
|
|
97
103
|
* · `neon` — glowing outline; a landscape tooltip whose fill carries a bright leading edge.
|
|
98
104
|
*
|
|
99
105
|
* ## SVG for the drawing, CSS for the tooltip
|
|
@@ -112,11 +118,43 @@
|
|
|
112
118
|
* is built once and a driver mutates cached nodes behind a dirty guard, exactly as `pad-svg.ts` does,
|
|
113
119
|
* so an idle rig costs no DOM writes at 60 Hz.
|
|
114
120
|
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
121
|
+
* ## In a game: a HUD piece
|
|
122
|
+
*
|
|
123
|
+
* The rig started as a panel for a page — an onboarding beat, a store page — and a game wants the same
|
|
124
|
+
* picture pinned into a corner of play while the rider rides. Two options cover that, and they are the
|
|
125
|
+
* only two a game needs:
|
|
126
|
+
*
|
|
127
|
+
* ```ts
|
|
128
|
+
* const rig = mountRiderRig(gameRoot, {
|
|
129
|
+
* ftp: session.identity.ftp,
|
|
130
|
+
* width: 300, // any size, not just the three presets
|
|
131
|
+
* place: { corner: "bottom-right", margin: 24 },// pinned, floating, click-through
|
|
132
|
+
* renderer: createThreeRiderRig, // optional: the 3D one
|
|
133
|
+
* });
|
|
134
|
+
* ```
|
|
135
|
+
*
|
|
136
|
+
* `place` is what turns it from a block in flow into a floating overlay; without it nothing about the
|
|
137
|
+
* component changes. Both are adjustable after mounting (`setWidth`, `setPlacement`) so a game can
|
|
138
|
+
* find the size and the corner by eye and paste the numbers back — `examples/ui/rig-hud.ts` is exactly
|
|
139
|
+
* that, a dev page over a fake game screen.
|
|
140
|
+
*
|
|
141
|
+
* **One 3D rig per screen.** `createThreeRiderRig` opens its own WebGL context beside the game's own
|
|
142
|
+
* scene. One HUD widget is a fair price for the picture; three is three contexts the game did not
|
|
143
|
+
* budget for. If the rig is decoration rather than the subject, the flat renderer is free — it is an
|
|
144
|
+
* `<svg>` — and it is the default for that reason.
|
|
145
|
+
*
|
|
146
|
+
* ── Sizing contract (same as the rest of the kit, with ONE exception) ──────────────────────────
|
|
147
|
+
* Tuned for a trainer screen read from a few feet away while pedalling. Don't override the `.rrig-*`
|
|
148
|
+
* dimensions or wrap it in `transform: scale()`.
|
|
149
|
+
*
|
|
150
|
+
* The exception is this component's own `width`, and it is narrow: the rig is a PICTURE, not a label,
|
|
151
|
+
* so it survives being re-sized in a way a keycap or a callout card does not — and a game pinning it
|
|
152
|
+
* into a corner genuinely cannot work from three fixed widths. `width` scales the tooltip's em base
|
|
153
|
+
* with the drawing rather than leaving the type behind, and it floors at 140px, below which the watts
|
|
154
|
+
* stop being readable. That is the whole exception: it licenses nothing elsewhere in the kit.
|
|
118
155
|
* ────────────────────────────────────────────────────────────────────────────────────────────────
|
|
119
156
|
*/
|
|
157
|
+
import { type HudPlacement } from "./hud-placement.js";
|
|
120
158
|
/** The three art directions. See the module header for when to reach for which. */
|
|
121
159
|
export type RiderRigDesign = "solid" | "blueprint" | "neon";
|
|
122
160
|
export interface RiderRigOptions {
|
|
@@ -129,10 +167,43 @@ export interface RiderRigOptions {
|
|
|
129
167
|
* gauge — a 350 W rider against a 200 W scale would sit pinned at the top.
|
|
130
168
|
*/
|
|
131
169
|
ftp?: number;
|
|
132
|
-
/** Width preset. Default `"md"`. */
|
|
170
|
+
/** Width preset. Default `"md"`. Ignored when {@link width} is given. */
|
|
133
171
|
size?: "sm" | "md" | "lg";
|
|
172
|
+
/**
|
|
173
|
+
* Free width in CSS pixels, overriding {@link size}. Clamped to ≥ 140.
|
|
174
|
+
*
|
|
175
|
+
* The sizing contract below forbids scaling the rest of the kit, and this is its ONE exception —
|
|
176
|
+
* see the module header. The tooltip's em base scales with the width (same ratio the three presets
|
|
177
|
+
* share), so the bubble grows with the drawing instead of swamping it at 180px and getting lost at
|
|
178
|
+
* 700px.
|
|
179
|
+
*
|
|
180
|
+
* Reach for it when the rig is a HUD piece a game sizes to its own layout; keep the presets for a
|
|
181
|
+
* panel on a page.
|
|
182
|
+
*/
|
|
183
|
+
width?: number;
|
|
184
|
+
/**
|
|
185
|
+
* Pin the rig somewhere on the game's screen instead of laying it out in flow.
|
|
186
|
+
*
|
|
187
|
+
* Omit it and nothing changes: the rig is a block that fills its host, exactly as before. Pass it
|
|
188
|
+
* and the rig becomes a floating, click-through HUD piece — see {@link HudPlacement}, the
|
|
189
|
+
* placement vocabulary every pinnable component in the kit shares.
|
|
190
|
+
*/
|
|
191
|
+
place?: HudPlacement;
|
|
134
192
|
/** Show the numeric watts readout. Default `true`. */
|
|
135
193
|
readout?: boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Which way the watts bubble runs, overriding the design's own default.
|
|
196
|
+
*
|
|
197
|
+
* Each design ships with the one that suits it — `solid` and `neon` landscape, `blueprint` portrait
|
|
198
|
+
* — and that pairing is a look, not a law. A HUD piece is the case that breaks it: pinned down the
|
|
199
|
+
* side of a play field, a wide bubble eats screen the game wants, while the portrait one is narrow
|
|
200
|
+
* and tall and costs almost none. So the two axes come apart: pick the paint with `design`, pick the
|
|
201
|
+
* shape of the readout with this.
|
|
202
|
+
*
|
|
203
|
+
* `"portrait"` stacks the caption and the figure over a tall bar; `"landscape"` puts the figure
|
|
204
|
+
* beside the caption with the bar under both.
|
|
205
|
+
*/
|
|
206
|
+
gauge?: "portrait" | "landscape";
|
|
136
207
|
/** The caption under the readout. Default `"WATTS"`. */
|
|
137
208
|
label?: string;
|
|
138
209
|
/**
|
|
@@ -176,6 +247,21 @@ export interface RiderRig {
|
|
|
176
247
|
* live, and the values it lands on are the values you pass to `tip`. See `examples/ui/rig3d.ts`.
|
|
177
248
|
*/
|
|
178
249
|
setTipPlacement(next: TipPlacement): void;
|
|
250
|
+
/**
|
|
251
|
+
* Re-size the rig in place, in CSS pixels — the live half of {@link RiderRigOptions.width}.
|
|
252
|
+
*
|
|
253
|
+
* Exists for the same reason {@link setTipPlacement} does: a size is found by eye against the game
|
|
254
|
+
* it sits in, and the number that looks right is the number you then pass as `width`.
|
|
255
|
+
*/
|
|
256
|
+
setWidth(px: number): void;
|
|
257
|
+
/**
|
|
258
|
+
* Move a pinned rig after mounting — the same fields as {@link RiderRigOptions.place}, merged over
|
|
259
|
+
* what is already set.
|
|
260
|
+
*
|
|
261
|
+
* Calling it on a rig mounted WITHOUT `place` pins it from that point on, so a game can drop the rig
|
|
262
|
+
* into flow on one screen and float it on another without rebuilding it.
|
|
263
|
+
*/
|
|
264
|
+
setPlacement(next: HudPlacement): void;
|
|
179
265
|
/** Latest raw watts — drives the readout, the posture, and (smoothed) the gauge. */
|
|
180
266
|
setPower(watts: number): void;
|
|
181
267
|
/** Latest cadence in rpm — drives the crank, the legs, the cassette and the flywheel. */
|
|
@@ -288,6 +374,18 @@ export interface RigPose {
|
|
|
288
374
|
streak: number;
|
|
289
375
|
/** power / ftp, for anything a renderer wants to drive off effort. */
|
|
290
376
|
effort: number;
|
|
377
|
+
/**
|
|
378
|
+
* The effort's zone colours — the SAME pair the gauge is painted in.
|
|
379
|
+
*
|
|
380
|
+
* It is handed over rather than re-derived for the reason the joints are: the zone thresholds are
|
|
381
|
+
* the component's (`ZONES`), and a renderer computing its own would be a second copy free to drift
|
|
382
|
+
* from the bar it is supposed to agree with. A drawing glowing one colour while the gauge reads
|
|
383
|
+
* another is worse than one that does not glow at all.
|
|
384
|
+
*/
|
|
385
|
+
zone: {
|
|
386
|
+
color: string;
|
|
387
|
+
glow: string;
|
|
388
|
+
};
|
|
291
389
|
}
|
|
292
390
|
export interface RigRenderer {
|
|
293
391
|
/** The node to put in the rig's root: an `<svg>` for the default, a `<canvas>` for three.js. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rider-rig.d.ts","sourceRoot":"","sources":["../../src/ui/rider-rig.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"rider-rig.d.ts","sourceRoot":"","sources":["../../src/ui/rider-rig.ts"],"names":[],"mappings":"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"}
|