@rydr/game-sdk 8.11.0 → 8.12.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 +26 -2
- package/dist/client/PlatformClient.d.ts.map +1 -1
- package/dist/client/PlatformClient.js +14 -2
- package/dist/client/PlatformClient.js.map +1 -1
- package/dist/client/Room.d.ts +9 -4
- package/dist/client/Room.d.ts.map +1 -1
- package/dist/client/Room.js +8 -5
- package/dist/client/Room.js.map +1 -1
- package/dist/host/PlatformHost.d.ts +4 -2
- package/dist/host/PlatformHost.d.ts.map +1 -1
- package/dist/host/PlatformHost.js +5 -3
- package/dist/host/PlatformHost.js.map +1 -1
- package/dist/protocol/messages.d.ts +11 -4
- package/dist/protocol/messages.d.ts.map +1 -1
- package/dist/protocol/room.d.ts +26 -0
- package/dist/protocol/room.d.ts.map +1 -1
- package/dist/protocol/version.d.ts +2 -2
- package/dist/protocol/version.d.ts.map +1 -1
- package/dist/protocol/version.js +23 -2
- package/dist/protocol/version.js.map +1 -1
- package/dist/three/README.md +111 -0
- package/dist/three/character/index.d.ts +14 -0
- package/dist/three/character/index.d.ts.map +1 -0
- package/dist/three/character/index.js +14 -0
- package/dist/three/character/index.js.map +1 -0
- package/dist/three/character/kit.d.ts +74 -0
- package/dist/three/character/kit.d.ts.map +1 -0
- package/dist/three/character/kit.js +254 -0
- package/dist/three/character/kit.js.map +1 -0
- package/dist/three/character/riders.d.ts +20 -0
- package/dist/three/character/riders.d.ts.map +1 -0
- package/dist/three/character/riders.js +383 -0
- package/dist/three/character/riders.js.map +1 -0
- package/dist/three/character/skeleton.d.ts +105 -0
- package/dist/three/character/skeleton.d.ts.map +1 -0
- package/dist/three/character/skeleton.js +57 -0
- package/dist/three/character/skeleton.js.map +1 -0
- package/dist/three/controller/glyph-texture.d.ts +29 -0
- package/dist/three/controller/glyph-texture.d.ts.map +1 -0
- package/dist/three/controller/glyph-texture.js +68 -0
- package/dist/three/controller/glyph-texture.js.map +1 -0
- package/dist/three/controller/index.d.ts +12 -0
- package/dist/three/controller/index.d.ts.map +1 -0
- package/dist/three/controller/index.js +12 -0
- package/dist/three/controller/index.js.map +1 -0
- package/dist/three/controller/joycon-designs.d.ts +49 -0
- package/dist/three/controller/joycon-designs.d.ts.map +1 -0
- package/dist/three/controller/joycon-designs.js +742 -0
- package/dist/three/controller/joycon-designs.js.map +1 -0
- package/dist/three/controller/joycon-shoulder-mesh.d.ts +41 -0
- package/dist/three/controller/joycon-shoulder-mesh.d.ts.map +1 -0
- package/dist/three/controller/joycon-shoulder-mesh.js +527 -0
- package/dist/three/controller/joycon-shoulder-mesh.js.map +1 -0
- package/dist/three/controller/joycon-spec.d.ts +233 -0
- package/dist/three/controller/joycon-spec.d.ts.map +1 -0
- package/dist/three/controller/joycon-spec.js +285 -0
- package/dist/three/controller/joycon-spec.js.map +1 -0
- package/dist/three/controller/three-pad-renderer.d.ts +81 -0
- package/dist/three/controller/three-pad-renderer.d.ts.map +1 -0
- package/dist/three/controller/three-pad-renderer.js +433 -0
- package/dist/three/controller/three-pad-renderer.js.map +1 -0
- package/dist/three/index.d.ts +2 -0
- package/dist/three/index.d.ts.map +1 -1
- package/dist/three/index.js +2 -0
- package/dist/three/index.js.map +1 -1
- package/dist/three/rider/cyclist-pose.d.ts +62 -0
- package/dist/three/rider/cyclist-pose.d.ts.map +1 -0
- package/dist/three/rider/cyclist-pose.js +173 -0
- package/dist/three/rider/cyclist-pose.js.map +1 -0
- package/dist/three/rider/index.d.ts +8 -0
- package/dist/three/rider/index.d.ts.map +1 -0
- package/dist/three/rider/index.js +8 -0
- package/dist/three/rider/index.js.map +1 -0
- package/dist/three/rider/three-rider-rig.d.ts +80 -0
- package/dist/three/rider/three-rider-rig.d.ts.map +1 -0
- package/dist/three/rider/three-rider-rig.js +418 -0
- package/dist/three/rider/three-rider-rig.js.map +1 -0
- package/dist/ui/README.md +153 -1
- package/dist/ui/controller/combo-demo.d.ts +9 -0
- package/dist/ui/controller/combo-demo.d.ts.map +1 -1
- package/dist/ui/controller/combo-demo.js +1 -0
- package/dist/ui/controller/combo-demo.js.map +1 -1
- package/dist/ui/controller/control-spotlight.d.ts +10 -1
- package/dist/ui/controller/control-spotlight.d.ts.map +1 -1
- package/dist/ui/controller/control-spotlight.js +42 -42
- package/dist/ui/controller/control-spotlight.js.map +1 -1
- package/dist/ui/controller/control-trainer.d.ts +14 -0
- package/dist/ui/controller/control-trainer.d.ts.map +1 -1
- package/dist/ui/controller/control-trainer.js +6 -0
- package/dist/ui/controller/control-trainer.js.map +1 -1
- package/dist/ui/controller/controller-map.d.ts +9 -0
- package/dist/ui/controller/controller-map.d.ts.map +1 -1
- package/dist/ui/controller/controller-map.js +8 -6
- package/dist/ui/controller/controller-map.js.map +1 -1
- package/dist/ui/controller/controller-pad.d.ts +35 -2
- package/dist/ui/controller/controller-pad.d.ts.map +1 -1
- package/dist/ui/controller/controller-pad.js +47 -7
- package/dist/ui/controller/controller-pad.js.map +1 -1
- package/dist/ui/controller/index.d.ts +1 -0
- package/dist/ui/controller/index.d.ts.map +1 -1
- package/dist/ui/controller/index.js +1 -0
- package/dist/ui/controller/index.js.map +1 -1
- package/dist/ui/controller/renderer.d.ts +118 -0
- package/dist/ui/controller/renderer.d.ts.map +1 -0
- package/dist/ui/controller/renderer.js +93 -0
- package/dist/ui/controller/renderer.js.map +1 -0
- package/dist/ui/controller/styles.js +30 -0
- package/dist/ui/controller/styles.js.map +1 -1
- package/dist/ui/index.d.ts +6 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +6 -0
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/rider-rig.d.ts +315 -0
- package/dist/ui/rider-rig.d.ts.map +1 -0
- package/dist/ui/rider-rig.js +1000 -0
- package/dist/ui/rider-rig.js.map +1 -0
- package/dist/ui/showcase/index.d.ts +11 -0
- package/dist/ui/showcase/index.d.ts.map +1 -1
- package/dist/ui/showcase/index.js +109 -1
- package/dist/ui/showcase/index.js.map +1 -1
- package/package.json +8 -4
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RIDER RIG — a rider on their trainer, pedalling, with their watts rising out of the machine.
|
|
3
|
+
*
|
|
4
|
+
* The one drawing in this kit whose subject is **the bike itself**. Everything else in
|
|
5
|
+
* `@rydr/game-sdk/ui` teaches the rider about the *pad* — which button, which combination, which
|
|
6
|
+
* lesson — and a game built from those pieces alone would tell a new player that the controller is
|
|
7
|
+
* the thing in their hands. It isn't, or not only: the trainer is half of it. This component is the
|
|
8
|
+
* picture that says so, and it exists to be put on the screens where that has to land — an
|
|
9
|
+
* onboarding beat, a "how this game works" panel, a store page, the pause screen of a game whose
|
|
10
|
+
* whole mechanic is effort.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* const rig = mountRiderRig(panel, { design: "solid", ftp: session.identity.ftp });
|
|
14
|
+
*
|
|
15
|
+
* // each frame:
|
|
16
|
+
* rig.setPower(session.hardware.current.power);
|
|
17
|
+
* rig.setCadence(session.hardware.current.cadence);
|
|
18
|
+
* rig.tick(dt);
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* ⚠️ **Not to be confused with {@link mountControlTrainer}**, which lives one folder over in
|
|
22
|
+
* `./controller/`. English "trainer" means both the *turbo trainer* and the *coach*, and the SDK has
|
|
23
|
+
* one of each: `mountControlTrainer` is the COACH — a guided lesson that watches the rider perform a
|
|
24
|
+
* combination. This is the TURBO TRAINER — the physical machine, drawn. They share no code and
|
|
25
|
+
* answer different questions. If you want to teach a control, you want the other one.
|
|
26
|
+
*
|
|
27
|
+
* ## There is no rear wheel, and that is the point
|
|
28
|
+
*
|
|
29
|
+
* This is a **direct-drive** trainer, the kind RYDR runs on. The rear wheel comes OFF and the bike's
|
|
30
|
+
* dropouts bolt straight onto the trainer's own axle, so the chain drives the trainer's cassette
|
|
31
|
+
* directly — that junction is where the connection to the platform physically happens. Drawing a
|
|
32
|
+
* wheel-on trainer instead (a tyre pressed onto a spinning roller) would be a picture of a different,
|
|
33
|
+
* older machine, and would quietly teach a newcomer that the trainer is an accessory the bike sits on
|
|
34
|
+
* top of rather than a part of the drivetrain.
|
|
35
|
+
*
|
|
36
|
+
* It also settles what may move. **The bike is still.** It is bolted to a fixed machine: the frame
|
|
37
|
+
* does not sway, and the front wheel — parked on the floor, driven by nothing — does not turn. The
|
|
38
|
+
* only things that rotate are the ones the rider's legs actually drive: the crank, the trainer's
|
|
39
|
+
* cassette, and its flywheel. A drawing whose frame rocked or whose front wheel spun would be
|
|
40
|
+
* describing a bike going somewhere, which is the one thing this bike is not doing.
|
|
41
|
+
*
|
|
42
|
+
* ## Two engines, deliberately separate
|
|
43
|
+
*
|
|
44
|
+
* **Cadence turns the legs. Power fills the gauge.** Nothing crosses over, and that separation is the
|
|
45
|
+
* entire pedagogical content of the animation:
|
|
46
|
+
*
|
|
47
|
+
* · `setCadence(rpm)` drives the crank, the legs, the cassette and the flywheel. It is the
|
|
48
|
+
* *movement*.
|
|
49
|
+
* · `setPower(watts)` drives the gauge and the rider's posture — the torso folding down onto the
|
|
50
|
+
* bars, and past ~110% FTP a rise out of the saddle. It is the *effort*.
|
|
51
|
+
*
|
|
52
|
+
* Driving both from watts would be less code and would teach the opposite of the truth: that a rider
|
|
53
|
+
* spinning fast against no resistance is doing something. Two riders at 90 rpm, one at 100 W and one
|
|
54
|
+
* at 300 W, have identical legs and nothing else in common — and which of them the game is reading is
|
|
55
|
+
* exactly what a newcomer has to understand. So the legs say "you are pedalling" and only the gauge
|
|
56
|
+
* and the posture say "you are pushing".
|
|
57
|
+
*
|
|
58
|
+
* ## The gauge is FTP-relative, and it leaves the machine
|
|
59
|
+
*
|
|
60
|
+
* The scale runs `0 → 1.5 × ftp`, so the rider's own threshold sits at two thirds of the way up with
|
|
61
|
+
* headroom above it for a sprint, and it carries a labelled FTP reference mark. A 150 W rider and a
|
|
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}). Zone colours are computed from %FTP and
|
|
64
|
+
* are **local to this component**: they are deliberately NOT `@rydr/game-sdk/difficulty`'s ramp, which
|
|
65
|
+
* colours the rider's *chosen calibration level* and would be a different quantity wearing the same
|
|
66
|
+
* paint.
|
|
67
|
+
*
|
|
68
|
+
* It is presented as a **glass tooltip leaving the machine** — a bubble with a pointer into the
|
|
69
|
+
* trainer's shoulder, the watts printed large at the top and the bar below them. The bar's
|
|
70
|
+
* orientation drives the shape of the box: a landscape bubble where it fills left → right, a portrait
|
|
71
|
+
* one where it fills bottom → top. Two reasons, and
|
|
72
|
+
* neither is decoration. Where the number comes from is part of what the picture says: these watts
|
|
73
|
+
* are measured by *that* machine, not floating beside the bike. And the bubble is what gives every
|
|
74
|
+
* label somewhere to live: the number, its unit and the FTP mark all sit INSIDE the glass, so none of
|
|
75
|
+
* them is ever printed over the frame, the rider or the trainer. The version before it stood a bare
|
|
76
|
+
* column next to the machine and hung the FTP label off its side, where it landed on the gauge's own
|
|
77
|
+
* rungs.
|
|
78
|
+
*
|
|
79
|
+
* Feed it raw `power`, not `smoothedPower`. It keeps both: the numeric readout shows the true
|
|
80
|
+
* instantaneous value, while the bar itself follows an internal EMA so it climbs smoothly between the
|
|
81
|
+
* trainer's sparse (~1–4 Hz) updates. That is the split `HardwareSnapshot.power` documents, resolved
|
|
82
|
+
* here once so no caller has to hold two numbers.
|
|
83
|
+
*
|
|
84
|
+
* ## One geometry, three paints
|
|
85
|
+
*
|
|
86
|
+
* `design` picks the look; the skeleton, the joint solving and the timing are shared. Three art
|
|
87
|
+
* directions because a component this decorative has to sit inside games that look nothing alike:
|
|
88
|
+
*
|
|
89
|
+
* Every gauge is a CONTINUOUS fill; what changes is the paint and the tooltip's orientation.
|
|
90
|
+
*
|
|
91
|
+
* · `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
|
+
* · `blueprint` — thin technical linework; a PORTRAIT tooltip whose bar runs vertically and which
|
|
94
|
+
* carries NO figure at all, only the title and a tall bar marked at FTP. On that variant the bar
|
|
95
|
+
* IS the reading: a rider glancing at a trainer screen reads a fill long before three digits, and
|
|
96
|
+
* a number beside it competes with the thing it annotates.
|
|
97
|
+
* · `neon` — glowing outline; a landscape tooltip whose fill carries a bright leading edge.
|
|
98
|
+
*
|
|
99
|
+
* ## SVG for the drawing, CSS for the tooltip
|
|
100
|
+
*
|
|
101
|
+
* The rider, the bike and the trainer are one inline SVG: they are a picture, made of coordinates and
|
|
102
|
+
* joints. The watts tooltip is an HTML element positioned over it, because it is a box with rows of
|
|
103
|
+
* text — and that is the kit's own split, the one `controller-map.ts` already makes when it draws its
|
|
104
|
+
* callout cards in HTML and only the LINES between them in SVG. Boxes are CSS; shapes are SVG.
|
|
105
|
+
*
|
|
106
|
+
* The tooltip being CSS is what buys real `backdrop-filter` glass, and it removes a whole class of
|
|
107
|
+
* bug: its FTP label is placed off one custom property with a -50% translate, so it is centred on its
|
|
108
|
+
* own tick by construction rather than by a coordinate computed twice.
|
|
109
|
+
*
|
|
110
|
+
* Self-contained like the rest of the kit: it injects its own scoped `.rrig-*` stylesheet once into
|
|
111
|
+
* `<head>`, pulls in no three.js, and reads no global CSS. It also never renders per frame — the SVG
|
|
112
|
+
* is built once and a driver mutates cached nodes behind a dirty guard, exactly as `pad-svg.ts` does,
|
|
113
|
+
* so an idle rig costs no DOM writes at 60 Hz.
|
|
114
|
+
*
|
|
115
|
+
* ── Sizing contract (same as the rest of the kit) ──────────────────────────────────────────────
|
|
116
|
+
* Tuned for a trainer screen read from a few feet away while pedalling. Pick a `size` preset; don't
|
|
117
|
+
* override the `.rrig-*` dimensions or wrap it in `transform: scale()`.
|
|
118
|
+
* ────────────────────────────────────────────────────────────────────────────────────────────────
|
|
119
|
+
*/
|
|
120
|
+
/** The three art directions. See the module header for when to reach for which. */
|
|
121
|
+
export type RiderRigDesign = "solid" | "blueprint" | "neon";
|
|
122
|
+
export interface RiderRigOptions {
|
|
123
|
+
/** Which look. Default `"solid"` — the highest-contrast of the three. */
|
|
124
|
+
design?: RiderRigDesign;
|
|
125
|
+
/**
|
|
126
|
+
* The rider's FTP in watts, which is what the gauge is a proportion of. Default 200.
|
|
127
|
+
*
|
|
128
|
+
* Pass `session.identity.ftp`. Getting this wrong doesn't break the drawing, it just mis-scales the
|
|
129
|
+
* gauge — a 350 W rider against a 200 W scale would sit pinned at the top.
|
|
130
|
+
*/
|
|
131
|
+
ftp?: number;
|
|
132
|
+
/** Width preset. Default `"md"`. */
|
|
133
|
+
size?: "sm" | "md" | "lg";
|
|
134
|
+
/** Show the numeric watts readout. Default `true`. */
|
|
135
|
+
readout?: boolean;
|
|
136
|
+
/** The caption under the readout. Default `"WATTS"`. */
|
|
137
|
+
label?: string;
|
|
138
|
+
/**
|
|
139
|
+
* Turn the legs before any cadence arrives, so a static screenshot or a page with no trainer still
|
|
140
|
+
* shows the idea rather than a frozen rider. Default 0 (still).
|
|
141
|
+
*/
|
|
142
|
+
idleCadence?: number;
|
|
143
|
+
/**
|
|
144
|
+
* Override where the watts tooltip sits, when the renderer's own anchor is not what you want.
|
|
145
|
+
*
|
|
146
|
+
* Every field is optional and falls back to the anchor {@link RigRenderer.anchor} reports, so
|
|
147
|
+
* `{ y: 0.7 }` nudges it up without disturbing the rest. Positions are FRACTIONS of the drawing's
|
|
148
|
+
* box (x from the left, y from the top) and `arrow` is in em from the tooltip's own left edge — the
|
|
149
|
+
* same units the renderer answers in, so a value found by eye can be pasted straight in.
|
|
150
|
+
*/
|
|
151
|
+
tip?: TipPlacement;
|
|
152
|
+
/**
|
|
153
|
+
* What DRAWS the rig. Default: the flat SVG drawing.
|
|
154
|
+
*
|
|
155
|
+
* Pass `createThreeRiderRig` from `@rydr/game-sdk/three` to render it in 3D. The component works
|
|
156
|
+
* against it unchanged, because it never draws the rig itself — see the renderer seam below.
|
|
157
|
+
*/
|
|
158
|
+
renderer?: RigRendererFactory;
|
|
159
|
+
}
|
|
160
|
+
/** Where the watts tooltip sits. See {@link RiderRigOptions.tip}. */
|
|
161
|
+
export interface TipPlacement {
|
|
162
|
+
/** Fraction of the width, from the left, where the pointer's tip should land. */
|
|
163
|
+
x?: number;
|
|
164
|
+
/** Fraction of the height, from the TOP, where the pointer's tip should land. */
|
|
165
|
+
y?: number;
|
|
166
|
+
/** How far along the tooltip's own bottom edge the pointer hangs, in em. */
|
|
167
|
+
arrow?: number;
|
|
168
|
+
}
|
|
169
|
+
export interface RiderRig {
|
|
170
|
+
readonly root: HTMLDivElement;
|
|
171
|
+
/**
|
|
172
|
+
* Move the tooltip after mounting — the same fields as {@link RiderRigOptions.tip}, merged over
|
|
173
|
+
* what is already set.
|
|
174
|
+
*
|
|
175
|
+
* Exists so a placement can be found by eye rather than by arithmetic: a dev panel drives this
|
|
176
|
+
* live, and the values it lands on are the values you pass to `tip`. See `examples/ui/rig3d.ts`.
|
|
177
|
+
*/
|
|
178
|
+
setTipPlacement(next: TipPlacement): void;
|
|
179
|
+
/** Latest raw watts — drives the readout, the posture, and (smoothed) the gauge. */
|
|
180
|
+
setPower(watts: number): void;
|
|
181
|
+
/** Latest cadence in rpm — drives the crank, the legs, the cassette and the flywheel. */
|
|
182
|
+
setCadence(rpm: number): void;
|
|
183
|
+
/** Re-scale the gauge in place, for a rider who retunes their FTP mid-session. */
|
|
184
|
+
setFtp(ftp: number): void;
|
|
185
|
+
/** Advance the animation. `dt` in seconds. */
|
|
186
|
+
tick(dt: number): void;
|
|
187
|
+
dispose(): void;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* The default renderer: the flat SVG drawing, which is exactly what the component did inline before
|
|
191
|
+
* the seam existed. Nothing about the flat rig changed.
|
|
192
|
+
*
|
|
193
|
+
* It keeps its OWN dirty guards. Skipping a DOM write is the cheap win here, so the guards belong
|
|
194
|
+
* next to the writes rather than in the component — and a WebGL renderer's idea of "nothing to do" is
|
|
195
|
+
* a different question entirely (whether to draw a frame at all), which is its business, not ours.
|
|
196
|
+
*
|
|
197
|
+
* Seeded to `-Infinity`, NOT `NaN`: every guard is a `Math.abs(next - last) > eps` test, and any
|
|
198
|
+
* comparison against `NaN` is false, so a `NaN` seed silently suppresses the FIRST paint — and with
|
|
199
|
+
* it every write that never becomes dirty again.
|
|
200
|
+
*/
|
|
201
|
+
export declare function createSvgRigRenderer({ design }: {
|
|
202
|
+
design: RiderRigDesign;
|
|
203
|
+
}): RigRenderer;
|
|
204
|
+
/** A point in the shared 200×200 drawing space, y DOWN. */
|
|
205
|
+
export interface RigPoint {
|
|
206
|
+
x: number;
|
|
207
|
+
y: number;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* The drawing space every renderer works in: a 200×200 box with y pointing DOWN and the floor at
|
|
211
|
+
* `GROUND`. A 3D renderer maps it once (x − 100, GROUND − y) and is done.
|
|
212
|
+
*/
|
|
213
|
+
export declare const RIG_GEOMETRY: {
|
|
214
|
+
readonly VB_W: 200;
|
|
215
|
+
readonly VB_H: 200;
|
|
216
|
+
readonly GROUND: 178;
|
|
217
|
+
readonly WHEEL_R: 26;
|
|
218
|
+
readonly AXLE: {
|
|
219
|
+
x: number;
|
|
220
|
+
y: number;
|
|
221
|
+
};
|
|
222
|
+
readonly FRONT: {
|
|
223
|
+
x: number;
|
|
224
|
+
y: number;
|
|
225
|
+
};
|
|
226
|
+
readonly BB: {
|
|
227
|
+
x: number;
|
|
228
|
+
y: number;
|
|
229
|
+
};
|
|
230
|
+
readonly CRANK_R: 15;
|
|
231
|
+
readonly CHAINRING_R: 8;
|
|
232
|
+
readonly CASSETTE_R: 7;
|
|
233
|
+
readonly SEAT_CLUSTER: {
|
|
234
|
+
x: number;
|
|
235
|
+
y: number;
|
|
236
|
+
};
|
|
237
|
+
readonly SADDLE: {
|
|
238
|
+
x: number;
|
|
239
|
+
y: number;
|
|
240
|
+
};
|
|
241
|
+
readonly HEADTUBE_TOP: {
|
|
242
|
+
x: number;
|
|
243
|
+
y: number;
|
|
244
|
+
};
|
|
245
|
+
readonly HEADTUBE_BOT: {
|
|
246
|
+
x: number;
|
|
247
|
+
y: number;
|
|
248
|
+
};
|
|
249
|
+
readonly BAR: {
|
|
250
|
+
x: number;
|
|
251
|
+
y: number;
|
|
252
|
+
};
|
|
253
|
+
readonly FLY: {
|
|
254
|
+
x: number;
|
|
255
|
+
y: number;
|
|
256
|
+
r: number;
|
|
257
|
+
};
|
|
258
|
+
/** The rider's rest hip and shoulder — a renderer building a skeleton needs the spine's length. */
|
|
259
|
+
readonly HIP0: {
|
|
260
|
+
x: number;
|
|
261
|
+
y: number;
|
|
262
|
+
};
|
|
263
|
+
readonly SHOULDER0: {
|
|
264
|
+
x: number;
|
|
265
|
+
y: number;
|
|
266
|
+
};
|
|
267
|
+
/**
|
|
268
|
+
* The point on the trainer the watts tooltip points at — its top face, where the machine is tall
|
|
269
|
+
* enough for a pointer to meet it. Both renderers answer {@link RigRenderer.anchor} from this.
|
|
270
|
+
*/
|
|
271
|
+
readonly TRAINER_ANCHOR: RigPoint;
|
|
272
|
+
};
|
|
273
|
+
/** One frame of the rig, fully solved. Everything a renderer needs and nothing it has to work out. */
|
|
274
|
+
export interface RigPose {
|
|
275
|
+
hip: RigPoint;
|
|
276
|
+
shoulder: RigPoint;
|
|
277
|
+
head: RigPoint;
|
|
278
|
+
elbow: RigPoint;
|
|
279
|
+
kneeNear: RigPoint;
|
|
280
|
+
kneeFar: RigPoint;
|
|
281
|
+
pedalNear: RigPoint;
|
|
282
|
+
pedalFar: RigPoint;
|
|
283
|
+
/** Degrees. The crank, and the two things the chain turns. */
|
|
284
|
+
crankAngle: number;
|
|
285
|
+
cassetteAngle: number;
|
|
286
|
+
flyAngle: number;
|
|
287
|
+
/** 0→1 motion-blur strength for the spinning parts, from cadence. */
|
|
288
|
+
streak: number;
|
|
289
|
+
/** power / ftp, for anything a renderer wants to drive off effort. */
|
|
290
|
+
effort: number;
|
|
291
|
+
}
|
|
292
|
+
export interface RigRenderer {
|
|
293
|
+
/** The node to put in the rig's root: an `<svg>` for the default, a `<canvas>` for three.js. */
|
|
294
|
+
readonly node: Element;
|
|
295
|
+
setPose(pose: RigPose): void;
|
|
296
|
+
/**
|
|
297
|
+
* Where the tooltip's pointer should land, as fractions of the node's box (x from the left, y from
|
|
298
|
+
* the TOP). This is {@link RIG_GEOMETRY.TRAINER_ANCHOR} expressed in the renderer's own frame.
|
|
299
|
+
*
|
|
300
|
+
* It has to be the renderer's answer, not the component's: the flat drawing is an orthographic side
|
|
301
|
+
* view where the anchor is a fixed percentage, while a 3D renderer projects it through a camera and
|
|
302
|
+
* lands it somewhere else entirely. Hard-coding the flat percentages put the tooltip clean across
|
|
303
|
+
* the middle of the 3D machine. Same reason `PadRenderer.partRect` exists.
|
|
304
|
+
*/
|
|
305
|
+
anchor(): {
|
|
306
|
+
x: number;
|
|
307
|
+
y: number;
|
|
308
|
+
};
|
|
309
|
+
dispose(): void;
|
|
310
|
+
}
|
|
311
|
+
export type RigRendererFactory = (opts: {
|
|
312
|
+
design: RiderRigDesign;
|
|
313
|
+
}) => RigRenderer;
|
|
314
|
+
export declare function mountRiderRig(host: HTMLElement, opts?: RiderRigOptions): RiderRig;
|
|
315
|
+
//# sourceMappingURL=rider-rig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rider-rig.d.ts","sourceRoot":"","sources":["../../src/ui/rider-rig.ts"],"names":[],"mappings":"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"}
|