@joystyk/arcade 0.0.0 → 0.2.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/CHANGELOG.md +21 -0
- package/README.md +21 -2
- package/dist/game.d.ts +33 -0
- package/dist/game.js +334 -0
- package/dist/game.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -0
- package/dist/input.d.ts +28 -0
- package/dist/input.js +226 -0
- package/dist/input.js.map +1 -0
- package/dist/legacy.d.ts +28 -0
- package/dist/legacy.js +66 -0
- package/dist/legacy.js.map +1 -0
- package/dist/panel.d.ts +41 -0
- package/dist/panel.js +356 -0
- package/dist/panel.js.map +1 -0
- package/dist/pause.d.ts +13 -0
- package/dist/pause.js +36 -0
- package/dist/pause.js.map +1 -0
- package/dist/records.d.ts +19 -0
- package/dist/records.js +105 -0
- package/dist/records.js.map +1 -0
- package/package.json +46 -11
package/dist/input.js
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { swipeDirection } from "./legacy.js";
|
|
2
|
+
//#region src/input.ts
|
|
3
|
+
function bindInput(o) {
|
|
4
|
+
const abort = new AbortController(), { signal } = abort;
|
|
5
|
+
const held = /* @__PURE__ */ new Map();
|
|
6
|
+
const set = (action, on, source) => {
|
|
7
|
+
const sources = held.get(action) ?? /* @__PURE__ */ new Set(), before = sources.size > 0;
|
|
8
|
+
if (on) sources.add(source);
|
|
9
|
+
else sources.delete(source);
|
|
10
|
+
held.set(action, sources);
|
|
11
|
+
if (before !== sources.size > 0) o.emit(action, sources.size > 0);
|
|
12
|
+
};
|
|
13
|
+
const release = (prefix) => {
|
|
14
|
+
for (const [action, sources] of held) for (const source of [...sources]) if (source.startsWith(prefix)) set(action, false, source);
|
|
15
|
+
};
|
|
16
|
+
const key = (e, on) => {
|
|
17
|
+
if (e.target instanceof HTMLElement && e.target.closest("input, select, textarea, button, [contenteditable]")) return;
|
|
18
|
+
const name = e.key.toLowerCase(), action = o.keys[name];
|
|
19
|
+
if (action === void 0 || e.ctrlKey || e.altKey || e.metaKey || name.length === 1 && name.trim() !== "" && !o.shortcuts()) return;
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
if (!e.repeat || !on) set(action, on, `key:${name}`);
|
|
22
|
+
};
|
|
23
|
+
o.surface.addEventListener("keydown", (e) => key(e, true), { signal });
|
|
24
|
+
o.surface.addEventListener("keyup", (e) => key(e, false), { signal });
|
|
25
|
+
window.addEventListener("blur", () => {
|
|
26
|
+
release("");
|
|
27
|
+
o.drag?.(0, 0);
|
|
28
|
+
}, { signal });
|
|
29
|
+
let pointer = null;
|
|
30
|
+
o.surface.addEventListener("pointerdown", (e) => {
|
|
31
|
+
if (e.button !== 0 || e.target instanceof Element && e.target.closest("button, select, input")) return;
|
|
32
|
+
pointer = {
|
|
33
|
+
id: e.pointerId,
|
|
34
|
+
x: e.clientX,
|
|
35
|
+
y: e.clientY
|
|
36
|
+
};
|
|
37
|
+
o.surface.focus();
|
|
38
|
+
try {
|
|
39
|
+
o.surface.setPointerCapture?.(e.pointerId);
|
|
40
|
+
} catch {}
|
|
41
|
+
}, { signal });
|
|
42
|
+
o.surface.addEventListener("pointermove", (e) => {
|
|
43
|
+
if (pointer?.id !== e.pointerId || o.gesture !== "drag") return;
|
|
44
|
+
const x = e.clientX - pointer.x, y = e.clientY - pointer.y;
|
|
45
|
+
if (Math.hypot(x, y) >= (o.deadZone ?? 16)) o.drag?.(x, y);
|
|
46
|
+
else o.drag?.(0, 0);
|
|
47
|
+
}, { signal });
|
|
48
|
+
const end = (e) => {
|
|
49
|
+
if (pointer?.id !== e.pointerId) return;
|
|
50
|
+
const x = e.clientX - pointer.x, y = e.clientY - pointer.y;
|
|
51
|
+
pointer = null;
|
|
52
|
+
if (o.gesture === "drag") {
|
|
53
|
+
o.drag?.(0, 0);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const action = o.gesture === "swipe" ? swipeDirection(x, y) ?? "main" : "main";
|
|
57
|
+
o.emit(action, true);
|
|
58
|
+
o.emit(action, false);
|
|
59
|
+
};
|
|
60
|
+
o.surface.addEventListener("pointerup", end, { signal });
|
|
61
|
+
o.surface.addEventListener("pointercancel", () => {
|
|
62
|
+
pointer = null;
|
|
63
|
+
o.drag?.(0, 0);
|
|
64
|
+
}, { signal });
|
|
65
|
+
let controller = null, last = /* @__PURE__ */ new Set(), raf = 0;
|
|
66
|
+
const frame = o.frame ?? requestAnimationFrame, cancel = o.cancelFrame ?? cancelAnimationFrame;
|
|
67
|
+
const poll = () => {
|
|
68
|
+
const pads = [...o.gamepads?.() ?? navigator.getGamepads?.() ?? []].filter((p) => p !== null && p.connected && p.mapping === "standard");
|
|
69
|
+
const pad = pads.find((p) => p.index === controller) ?? pads[0];
|
|
70
|
+
if ((pad?.index ?? null) !== controller) {
|
|
71
|
+
release("pad:");
|
|
72
|
+
last = /* @__PURE__ */ new Set();
|
|
73
|
+
controller = pad?.index ?? null;
|
|
74
|
+
o.announce(pad === void 0 ? "Controller disconnected." : "Controller connected.");
|
|
75
|
+
}
|
|
76
|
+
const next = /* @__PURE__ */ new Set();
|
|
77
|
+
if (pad !== void 0) {
|
|
78
|
+
const b = (i) => pad.buttons[i]?.pressed === true;
|
|
79
|
+
const x = pad.axes[0] ?? 0, y = pad.axes[1] ?? 0;
|
|
80
|
+
if (b(12) || o.gesture !== "drag" && y < -.3) next.add("up");
|
|
81
|
+
if (b(13) || o.gesture !== "drag" && y > .3) next.add("down");
|
|
82
|
+
if (b(14) || o.gesture !== "drag" && x < -.3) next.add("left");
|
|
83
|
+
if (b(15) || o.gesture !== "drag" && x > .3) next.add("right");
|
|
84
|
+
if (b(0) || b(7)) next.add("main");
|
|
85
|
+
if (b(9)) next.add("pause");
|
|
86
|
+
if (o.gesture === "drag") o.drag?.(Math.hypot(x, y) > .3 ? x : 0, Math.hypot(x, y) > .3 ? y : 0);
|
|
87
|
+
}
|
|
88
|
+
for (const action of /* @__PURE__ */ new Set([...last, ...next])) set(action, next.has(action), `pad:${action}`);
|
|
89
|
+
last = next;
|
|
90
|
+
raf = frame(poll);
|
|
91
|
+
};
|
|
92
|
+
raf = frame(poll);
|
|
93
|
+
return () => {
|
|
94
|
+
abort.abort();
|
|
95
|
+
cancel(raf);
|
|
96
|
+
release("");
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/** Native hold buttons also support keyboard and switch activation. */
|
|
100
|
+
function bindHold(button, emit) {
|
|
101
|
+
const abort = new AbortController(), { signal } = abort;
|
|
102
|
+
let down = false;
|
|
103
|
+
const set = (value) => {
|
|
104
|
+
if (down !== value) {
|
|
105
|
+
down = value;
|
|
106
|
+
emit(value);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
button.addEventListener("pointerdown", (e) => {
|
|
110
|
+
if (e.button === 0) {
|
|
111
|
+
try {
|
|
112
|
+
button.setPointerCapture?.(e.pointerId);
|
|
113
|
+
} catch {}
|
|
114
|
+
set(true);
|
|
115
|
+
}
|
|
116
|
+
}, { signal });
|
|
117
|
+
button.addEventListener("pointerup", () => set(false), { signal });
|
|
118
|
+
button.addEventListener("pointercancel", () => set(false), { signal });
|
|
119
|
+
button.addEventListener("keydown", (e) => {
|
|
120
|
+
if (e.key === " " || e.key === "Enter") {
|
|
121
|
+
e.preventDefault();
|
|
122
|
+
set(true);
|
|
123
|
+
}
|
|
124
|
+
}, { signal });
|
|
125
|
+
button.addEventListener("keyup", () => set(false), { signal });
|
|
126
|
+
button.addEventListener("blur", () => set(false), { signal });
|
|
127
|
+
return () => {
|
|
128
|
+
abort.abort();
|
|
129
|
+
set(false);
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/** Delegated holds survive Gyral updates that add or replace native pad buttons. */
|
|
133
|
+
function bindHoldPad(root, selector, emit, signal) {
|
|
134
|
+
const abort = new AbortController(), held = /* @__PURE__ */ new Map();
|
|
135
|
+
const find = (target) => {
|
|
136
|
+
const button = target instanceof Element ? target.closest(selector) : null;
|
|
137
|
+
return button instanceof HTMLButtonElement && !button.disabled ? button : null;
|
|
138
|
+
};
|
|
139
|
+
const release = (source) => {
|
|
140
|
+
const button = held.get(source);
|
|
141
|
+
if (button !== void 0) {
|
|
142
|
+
held.delete(source);
|
|
143
|
+
emit(button, false, source);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const press = (button, source) => {
|
|
147
|
+
if (held.has(source)) return;
|
|
148
|
+
held.set(source, button);
|
|
149
|
+
emit(button, true, source);
|
|
150
|
+
};
|
|
151
|
+
root.addEventListener("pointerdown", (event) => {
|
|
152
|
+
if (!(event instanceof PointerEvent) || event.button !== 0) return;
|
|
153
|
+
const button = find(event.target);
|
|
154
|
+
if (button === null) return;
|
|
155
|
+
event.preventDefault();
|
|
156
|
+
button.focus({ preventScroll: true });
|
|
157
|
+
try {
|
|
158
|
+
button.setPointerCapture(event.pointerId);
|
|
159
|
+
} catch {}
|
|
160
|
+
press(button, `pointer:${event.pointerId}`);
|
|
161
|
+
}, { signal: abort.signal });
|
|
162
|
+
for (const type of [
|
|
163
|
+
"pointerup",
|
|
164
|
+
"pointercancel",
|
|
165
|
+
"lostpointercapture"
|
|
166
|
+
]) root.addEventListener(type, (event) => {
|
|
167
|
+
if (event instanceof PointerEvent) release(`pointer:${event.pointerId}`);
|
|
168
|
+
}, { signal: abort.signal });
|
|
169
|
+
root.addEventListener("keydown", (event) => {
|
|
170
|
+
if (!(event instanceof KeyboardEvent) || ![" ", "Enter"].includes(event.key)) return;
|
|
171
|
+
const button = find(event.target);
|
|
172
|
+
if (button === null) return;
|
|
173
|
+
event.preventDefault();
|
|
174
|
+
if (!event.repeat) press(button, `key:${event.code || event.key}`);
|
|
175
|
+
}, { signal: abort.signal });
|
|
176
|
+
root.addEventListener("keyup", (event) => {
|
|
177
|
+
if (event instanceof KeyboardEvent && [" ", "Enter"].includes(event.key)) release(`key:${event.code || event.key}`);
|
|
178
|
+
}, { signal: abort.signal });
|
|
179
|
+
root.addEventListener("focusout", (event) => {
|
|
180
|
+
for (const [source, button] of held) if (event.target === button) release(source);
|
|
181
|
+
}, { signal: abort.signal });
|
|
182
|
+
window.addEventListener("blur", () => {
|
|
183
|
+
for (const source of [...held.keys()]) release(source);
|
|
184
|
+
}, { signal: abort.signal });
|
|
185
|
+
const stop = () => {
|
|
186
|
+
abort.abort();
|
|
187
|
+
for (const source of [...held.keys()]) release(source);
|
|
188
|
+
};
|
|
189
|
+
signal?.addEventListener("abort", stop, { once: true });
|
|
190
|
+
return stop;
|
|
191
|
+
}
|
|
192
|
+
/** Absolute dragging for paddles; games own projection into their court's units. */
|
|
193
|
+
function bindDrag(surface, o, signal) {
|
|
194
|
+
const abort = new AbortController();
|
|
195
|
+
let pointer = null;
|
|
196
|
+
surface.addEventListener("pointerdown", (event) => {
|
|
197
|
+
if (o.primaryOnly !== false && !event.isPrimary || event.button !== 0 || o.start(event) === false) return;
|
|
198
|
+
pointer = event.pointerId;
|
|
199
|
+
if (o.capture !== false) try {
|
|
200
|
+
surface.setPointerCapture(event.pointerId);
|
|
201
|
+
} catch {}
|
|
202
|
+
}, { signal: abort.signal });
|
|
203
|
+
surface.addEventListener("pointermove", (event) => {
|
|
204
|
+
if (pointer === event.pointerId || o.hoverMouse && event.pointerType === "mouse") o.move(event);
|
|
205
|
+
}, { signal: abort.signal });
|
|
206
|
+
for (const type of [
|
|
207
|
+
"pointerup",
|
|
208
|
+
"pointercancel",
|
|
209
|
+
"lostpointercapture"
|
|
210
|
+
]) surface.addEventListener(type, () => {
|
|
211
|
+
pointer = null;
|
|
212
|
+
}, { signal: abort.signal });
|
|
213
|
+
window.addEventListener("blur", () => {
|
|
214
|
+
pointer = null;
|
|
215
|
+
}, { signal: abort.signal });
|
|
216
|
+
const stop = () => {
|
|
217
|
+
abort.abort();
|
|
218
|
+
pointer = null;
|
|
219
|
+
};
|
|
220
|
+
signal?.addEventListener("abort", stop, { once: true });
|
|
221
|
+
return stop;
|
|
222
|
+
}
|
|
223
|
+
//#endregion
|
|
224
|
+
export { bindDrag, bindHold, bindHoldPad, bindInput };
|
|
225
|
+
|
|
226
|
+
//# sourceMappingURL=input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.js","names":[],"sources":["../src/input.ts"],"sourcesContent":["import { swipeDirection } from './legacy.ts';\n/** All sources share the same actions. A held action is released on blur or disconnect. */\nexport type InputAction = 'up' | 'down' | 'left' | 'right' | 'main' | 'pause' | 'auxiliary';\nexport type InputOptions = {\n readonly surface: HTMLElement;\n readonly keys: Readonly<Record<string, InputAction>>;\n readonly shortcuts: () => boolean;\n readonly emit: (action: InputAction, held: boolean) => void;\n readonly announce: (text: string) => void;\n readonly gesture?: 'swipe' | 'tap' | 'drag';\n readonly drag?: (x: number, y: number) => void;\n readonly deadZone?: number;\n readonly gamepads?: () => readonly (Gamepad | null)[];\n readonly frame?: (callback: FrameRequestCallback) => number;\n readonly cancelFrame?: (id: number) => void;\n};\nexport function bindInput(o: InputOptions): () => void {\n const abort = new AbortController(),\n { signal } = abort;\n const held = new Map<InputAction, Set<string>>();\n const set = (action: InputAction, on: boolean, source: string): void => {\n const sources = held.get(action) ?? new Set<string>(),\n before = sources.size > 0;\n if (on) sources.add(source);\n else sources.delete(source);\n held.set(action, sources);\n if (before !== sources.size > 0) o.emit(action, sources.size > 0);\n };\n const release = (prefix: string): void => {\n for (const [action, sources] of held)\n for (const source of [...sources]) if (source.startsWith(prefix)) set(action, false, source);\n };\n const key = (e: KeyboardEvent, on: boolean): void => {\n if (e.target instanceof HTMLElement && e.target.closest('input, select, textarea, button, [contenteditable]'))\n return;\n const name = e.key.toLowerCase(),\n action = o.keys[name];\n if (\n action === undefined ||\n e.ctrlKey ||\n e.altKey ||\n e.metaKey ||\n (name.length === 1 && name.trim() !== '' && !o.shortcuts())\n )\n return;\n e.preventDefault();\n if (!e.repeat || !on) set(action, on, `key:${name}`);\n };\n o.surface.addEventListener('keydown', (e) => key(e, true), { signal });\n o.surface.addEventListener('keyup', (e) => key(e, false), { signal });\n window.addEventListener(\n 'blur',\n () => {\n release('');\n o.drag?.(0, 0);\n },\n { signal },\n );\n let pointer: {\n id: number;\n x: number;\n y: number;\n } | null = null;\n o.surface.addEventListener(\n 'pointerdown',\n (e) => {\n if (e.button !== 0 || (e.target instanceof Element && e.target.closest('button, select, input'))) return;\n pointer = { id: e.pointerId, x: e.clientX, y: e.clientY };\n o.surface.focus();\n try {\n o.surface.setPointerCapture?.(e.pointerId);\n } catch {\n /* Pointer released before capture. */\n }\n },\n { signal },\n );\n o.surface.addEventListener(\n 'pointermove',\n (e) => {\n if (pointer?.id !== e.pointerId || o.gesture !== 'drag') return;\n const x = e.clientX - pointer.x,\n y = e.clientY - pointer.y;\n if (Math.hypot(x, y) >= (o.deadZone ?? 16)) o.drag?.(x, y);\n else o.drag?.(0, 0);\n },\n { signal },\n );\n const end = (e: PointerEvent): void => {\n if (pointer?.id !== e.pointerId) return;\n const x = e.clientX - pointer.x,\n y = e.clientY - pointer.y;\n pointer = null;\n if (o.gesture === 'drag') {\n o.drag?.(0, 0);\n return;\n }\n const action = o.gesture === 'swipe' ? (swipeDirection(x, y) ?? 'main') : 'main';\n o.emit(action, true);\n o.emit(action, false);\n };\n o.surface.addEventListener('pointerup', end, { signal });\n o.surface.addEventListener(\n 'pointercancel',\n () => {\n pointer = null;\n o.drag?.(0, 0);\n },\n { signal },\n );\n let controller: number | null = null,\n last = new Set<InputAction>(),\n raf = 0;\n const frame = o.frame ?? requestAnimationFrame,\n cancel = o.cancelFrame ?? cancelAnimationFrame;\n const poll = (): void => {\n const pads = [...(o.gamepads?.() ?? navigator.getGamepads?.() ?? [])].filter(\n (p): p is Gamepad => p !== null && p.connected && p.mapping === 'standard',\n );\n const pad = pads.find((p) => p.index === controller) ?? pads[0];\n if ((pad?.index ?? null) !== controller) {\n release('pad:');\n last = new Set();\n controller = pad?.index ?? null;\n o.announce(pad === undefined ? 'Controller disconnected.' : 'Controller connected.');\n }\n const next = new Set<InputAction>();\n if (pad !== undefined) {\n const b = (i: number): boolean => pad.buttons[i]?.pressed === true;\n const x = pad.axes[0] ?? 0,\n y = pad.axes[1] ?? 0;\n if (b(12) || (o.gesture !== 'drag' && y < -0.3)) next.add('up');\n if (b(13) || (o.gesture !== 'drag' && y > 0.3)) next.add('down');\n if (b(14) || (o.gesture !== 'drag' && x < -0.3)) next.add('left');\n if (b(15) || (o.gesture !== 'drag' && x > 0.3)) next.add('right');\n if (b(0) || b(7)) next.add('main');\n if (b(9)) next.add('pause');\n if (o.gesture === 'drag') o.drag?.(Math.hypot(x, y) > 0.3 ? x : 0, Math.hypot(x, y) > 0.3 ? y : 0);\n }\n for (const action of new Set([...last, ...next])) set(action, next.has(action), `pad:${action}`);\n last = next;\n raf = frame(poll);\n };\n raf = frame(poll);\n return () => {\n abort.abort();\n cancel(raf);\n release('');\n };\n}\n/** Native hold buttons also support keyboard and switch activation. */\nexport function bindHold(button: HTMLButtonElement, emit: (held: boolean) => void): () => void {\n const abort = new AbortController(),\n { signal } = abort;\n let down = false;\n const set = (value: boolean): void => {\n if (down !== value) {\n down = value;\n emit(value);\n }\n };\n button.addEventListener(\n 'pointerdown',\n (e) => {\n if (e.button === 0) {\n try {\n button.setPointerCapture?.(e.pointerId);\n } catch {\n /* Pointer released before capture. */\n }\n set(true);\n }\n },\n { signal },\n );\n button.addEventListener('pointerup', () => set(false), { signal });\n button.addEventListener('pointercancel', () => set(false), { signal });\n button.addEventListener(\n 'keydown',\n (e) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n set(true);\n }\n },\n { signal },\n );\n button.addEventListener('keyup', () => set(false), { signal });\n button.addEventListener('blur', () => set(false), { signal });\n return () => {\n abort.abort();\n set(false);\n };\n}\n\n/** Delegated holds survive Gyral updates that add or replace native pad buttons. */\nexport function bindHoldPad(\n root: HTMLElement | ShadowRoot,\n selector: string,\n emit: (button: HTMLButtonElement, on: boolean, source: string) => void,\n signal?: AbortSignal,\n): () => void {\n const abort = new AbortController(),\n held = new Map<string, HTMLButtonElement>();\n const find = (target: EventTarget | null): HTMLButtonElement | null => {\n const button = target instanceof Element ? target.closest(selector) : null;\n return button instanceof HTMLButtonElement && !button.disabled ? button : null;\n };\n const release = (source: string): void => {\n const button = held.get(source);\n if (button !== undefined) {\n held.delete(source);\n emit(button, false, source);\n }\n };\n const press = (button: HTMLButtonElement, source: string): void => {\n if (held.has(source)) return;\n held.set(source, button);\n emit(button, true, source);\n };\n root.addEventListener(\n 'pointerdown',\n (event) => {\n if (!(event instanceof PointerEvent) || event.button !== 0) return;\n const button = find(event.target);\n if (button === null) return;\n event.preventDefault();\n button.focus({ preventScroll: true });\n try {\n button.setPointerCapture(event.pointerId);\n } catch {\n /* The pointer may already be released. */\n }\n press(button, `pointer:${event.pointerId}`);\n },\n { signal: abort.signal },\n );\n for (const type of ['pointerup', 'pointercancel', 'lostpointercapture'])\n root.addEventListener(\n type,\n (event) => {\n if (event instanceof PointerEvent) release(`pointer:${event.pointerId}`);\n },\n { signal: abort.signal },\n );\n root.addEventListener(\n 'keydown',\n (event) => {\n if (!(event instanceof KeyboardEvent) || ![' ', 'Enter'].includes(event.key)) return;\n const button = find(event.target);\n if (button === null) return;\n event.preventDefault();\n if (!event.repeat) press(button, `key:${event.code || event.key}`);\n },\n { signal: abort.signal },\n );\n root.addEventListener(\n 'keyup',\n (event) => {\n if (event instanceof KeyboardEvent && [' ', 'Enter'].includes(event.key))\n release(`key:${event.code || event.key}`);\n },\n { signal: abort.signal },\n );\n root.addEventListener(\n 'focusout',\n (event) => {\n for (const [source, button] of held) if (event.target === button) release(source);\n },\n { signal: abort.signal },\n );\n window.addEventListener(\n 'blur',\n () => {\n for (const source of [...held.keys()]) release(source);\n },\n { signal: abort.signal },\n );\n const stop = (): void => {\n abort.abort();\n for (const source of [...held.keys()]) release(source);\n };\n signal?.addEventListener('abort', stop, { once: true });\n return stop;\n}\n\n/** Absolute dragging for paddles; games own projection into their court's units. */\nexport function bindDrag(\n surface: HTMLElement,\n o: {\n start(event: PointerEvent): boolean | void;\n move(event: PointerEvent): void;\n hoverMouse?: boolean;\n capture?: boolean;\n primaryOnly?: boolean;\n },\n signal?: AbortSignal,\n): () => void {\n const abort = new AbortController();\n let pointer: number | null = null;\n surface.addEventListener(\n 'pointerdown',\n (event) => {\n if ((o.primaryOnly !== false && !event.isPrimary) || event.button !== 0 || o.start(event) === false) return;\n pointer = event.pointerId;\n if (o.capture !== false)\n try {\n surface.setPointerCapture(event.pointerId);\n } catch {\n /* Released before capture. */\n }\n },\n { signal: abort.signal },\n );\n surface.addEventListener(\n 'pointermove',\n (event) => {\n if (pointer === event.pointerId || (o.hoverMouse && event.pointerType === 'mouse')) o.move(event);\n },\n { signal: abort.signal },\n );\n for (const type of ['pointerup', 'pointercancel', 'lostpointercapture'])\n surface.addEventListener(\n type,\n () => {\n pointer = null;\n },\n { signal: abort.signal },\n );\n window.addEventListener(\n 'blur',\n () => {\n pointer = null;\n },\n { signal: abort.signal },\n );\n const stop = (): void => {\n abort.abort();\n pointer = null;\n };\n signal?.addEventListener('abort', stop, { once: true });\n return stop;\n}\n"],"mappings":"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"}
|
package/dist/legacy.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type DriverOverrides } from '@gyral/core';
|
|
2
|
+
/** Shared driver adapter; callers keep their public driver names and typed HUD projection. */
|
|
3
|
+
export declare function createControlDrivers<Snapshot, Hud, Action>(o: {
|
|
4
|
+
hud: string;
|
|
5
|
+
action: string;
|
|
6
|
+
subscribe: (emit: (snapshot: Snapshot) => void) => () => void;
|
|
7
|
+
project: (snapshot: Snapshot) => Hud;
|
|
8
|
+
same: (a: Hud, b: Hud) => boolean;
|
|
9
|
+
dispatch: (action: Action) => void;
|
|
10
|
+
}): DriverOverrides;
|
|
11
|
+
/** A countdown handle is a cancellation function, so disposal cannot leave a late resume. */
|
|
12
|
+
export declare function resumeAfter(delay: number, done: () => void): () => void;
|
|
13
|
+
/** Shared automatic pause lifecycle. No resume is inferred from gaining focus. */
|
|
14
|
+
export declare function bindPagePause(pause: () => void, signal?: AbortSignal): () => void;
|
|
15
|
+
export declare const SWIPE_THRESHOLD = 24;
|
|
16
|
+
export declare function swipeDirection(x: number, y: number, threshold?: number): 'up' | 'down' | 'left' | 'right' | null;
|
|
17
|
+
export declare const ARROW_DIRECTIONS: {
|
|
18
|
+
readonly arrowup: "up";
|
|
19
|
+
readonly arrowdown: "down";
|
|
20
|
+
readonly arrowleft: "left";
|
|
21
|
+
readonly arrowright: "right";
|
|
22
|
+
};
|
|
23
|
+
export declare const LETTER_DIRECTIONS: {
|
|
24
|
+
readonly w: "up";
|
|
25
|
+
readonly s: "down";
|
|
26
|
+
readonly a: "left";
|
|
27
|
+
readonly d: "right";
|
|
28
|
+
};
|
package/dist/legacy.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { defineDriver, subscription } from "@gyral/core";
|
|
2
|
+
//#region src/legacy.ts
|
|
3
|
+
/** Shared driver adapter; callers keep their public driver names and typed HUD projection. */
|
|
4
|
+
function createControlDrivers(o) {
|
|
5
|
+
return {
|
|
6
|
+
[o.hud]: subscription(o.hud, (emit) => {
|
|
7
|
+
let last;
|
|
8
|
+
return o.subscribe((snapshot) => {
|
|
9
|
+
const next = o.project(snapshot);
|
|
10
|
+
if (last !== void 0 && o.same(last, next)) return;
|
|
11
|
+
last = next;
|
|
12
|
+
emit(next);
|
|
13
|
+
});
|
|
14
|
+
}),
|
|
15
|
+
[o.action]: defineDriver({
|
|
16
|
+
name: o.action,
|
|
17
|
+
run: o.dispatch
|
|
18
|
+
})
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** A countdown handle is a cancellation function, so disposal cannot leave a late resume. */
|
|
22
|
+
function resumeAfter(delay, done) {
|
|
23
|
+
let active = true;
|
|
24
|
+
const timer = setTimeout(() => {
|
|
25
|
+
if (active) {
|
|
26
|
+
active = false;
|
|
27
|
+
done();
|
|
28
|
+
}
|
|
29
|
+
}, delay);
|
|
30
|
+
return () => {
|
|
31
|
+
active = false;
|
|
32
|
+
clearTimeout(timer);
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Shared automatic pause lifecycle. No resume is inferred from gaining focus. */
|
|
36
|
+
function bindPagePause(pause, signal) {
|
|
37
|
+
const abort = new AbortController();
|
|
38
|
+
signal?.addEventListener("abort", () => abort.abort(), { once: true });
|
|
39
|
+
window.addEventListener("blur", pause, { signal: abort.signal });
|
|
40
|
+
window.addEventListener("pagehide", pause, { signal: abort.signal });
|
|
41
|
+
document.addEventListener("visibilitychange", () => {
|
|
42
|
+
if (document.hidden) pause();
|
|
43
|
+
}, { signal: abort.signal });
|
|
44
|
+
return () => abort.abort();
|
|
45
|
+
}
|
|
46
|
+
var SWIPE_THRESHOLD = 24;
|
|
47
|
+
function swipeDirection(x, y, threshold = 24) {
|
|
48
|
+
if (Math.max(Math.abs(x), Math.abs(y)) < threshold) return null;
|
|
49
|
+
return Math.abs(x) > Math.abs(y) ? x > 0 ? "right" : "left" : y > 0 ? "down" : "up";
|
|
50
|
+
}
|
|
51
|
+
var ARROW_DIRECTIONS = {
|
|
52
|
+
arrowup: "up",
|
|
53
|
+
arrowdown: "down",
|
|
54
|
+
arrowleft: "left",
|
|
55
|
+
arrowright: "right"
|
|
56
|
+
};
|
|
57
|
+
var LETTER_DIRECTIONS = {
|
|
58
|
+
w: "up",
|
|
59
|
+
s: "down",
|
|
60
|
+
a: "left",
|
|
61
|
+
d: "right"
|
|
62
|
+
};
|
|
63
|
+
//#endregion
|
|
64
|
+
export { ARROW_DIRECTIONS, LETTER_DIRECTIONS, SWIPE_THRESHOLD, bindPagePause, createControlDrivers, resumeAfter, swipeDirection };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=legacy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy.js","names":[],"sources":["../src/legacy.ts"],"sourcesContent":["import { defineDriver, subscription, type DriverOverrides } from '@gyral/core';\n/** Shared driver adapter; callers keep their public driver names and typed HUD projection. */\nexport function createControlDrivers<Snapshot, Hud, Action>(o: {\n hud: string;\n action: string;\n subscribe: (emit: (snapshot: Snapshot) => void) => () => void;\n project: (snapshot: Snapshot) => Hud;\n same: (a: Hud, b: Hud) => boolean;\n dispatch: (action: Action) => void;\n}): DriverOverrides {\n return {\n [o.hud]: subscription<Hud>(o.hud, (emit) => {\n let last: Hud | undefined;\n return o.subscribe((snapshot) => {\n const next = o.project(snapshot);\n if (last !== undefined && o.same(last, next)) return;\n last = next;\n emit(next);\n });\n }),\n [o.action]: defineDriver<Action, void>({ name: o.action, run: o.dispatch }),\n };\n}\n/** A countdown handle is a cancellation function, so disposal cannot leave a late resume. */\nexport function resumeAfter(delay: number, done: () => void): () => void {\n let active = true;\n const timer = setTimeout(() => {\n if (active) {\n active = false;\n done();\n }\n }, delay);\n return () => {\n active = false;\n clearTimeout(timer);\n };\n}\n/** Shared automatic pause lifecycle. No resume is inferred from gaining focus. */\nexport function bindPagePause(pause: () => void, signal?: AbortSignal): () => void {\n const abort = new AbortController();\n signal?.addEventListener('abort', () => abort.abort(), { once: true });\n window.addEventListener('blur', pause, { signal: abort.signal });\n window.addEventListener('pagehide', pause, { signal: abort.signal });\n document.addEventListener(\n 'visibilitychange',\n () => {\n if (document.hidden) pause();\n },\n { signal: abort.signal },\n );\n return () => abort.abort();\n}\nexport const SWIPE_THRESHOLD = 24;\nexport function swipeDirection(\n x: number,\n y: number,\n threshold = SWIPE_THRESHOLD,\n): 'up' | 'down' | 'left' | 'right' | null {\n if (Math.max(Math.abs(x), Math.abs(y)) < threshold) return null;\n return Math.abs(x) > Math.abs(y) ? (x > 0 ? 'right' : 'left') : y > 0 ? 'down' : 'up';\n}\nexport const ARROW_DIRECTIONS = { arrowup: 'up', arrowdown: 'down', arrowleft: 'left', arrowright: 'right' } as const;\nexport const LETTER_DIRECTIONS = { w: 'up', s: 'down', a: 'left', d: 'right' } as const;\n"],"mappings":";;;AAEA,SAAgB,qBAA4C,GAOxC;CAClB,OAAO;GACJ,EAAE,MAAM,aAAkB,EAAE,MAAM,SAAS;GAC1C,IAAI;GACJ,OAAO,EAAE,WAAW,aAAa;IAC/B,MAAM,OAAO,EAAE,QAAQ,QAAQ;IAC/B,IAAI,SAAS,KAAA,KAAa,EAAE,KAAK,MAAM,IAAI,GAAG;IAC9C,OAAO;IACP,KAAK,IAAI;GACX,CAAC;EACH,CAAC;GACA,EAAE,SAAS,aAA2B;GAAE,MAAM,EAAE;GAAQ,KAAK,EAAE;EAAS,CAAC;CAC5E;AACF;;AAEA,SAAgB,YAAY,OAAe,MAA8B;CACvE,IAAI,SAAS;CACb,MAAM,QAAQ,iBAAiB;EAC7B,IAAI,QAAQ;GACV,SAAS;GACT,KAAK;EACP;CACF,GAAG,KAAK;CACR,aAAa;EACX,SAAS;EACT,aAAa,KAAK;CACpB;AACF;;AAEA,SAAgB,cAAc,OAAmB,QAAkC;CACjF,MAAM,QAAQ,IAAI,gBAAgB;CAClC,QAAQ,iBAAiB,eAAe,MAAM,MAAM,GAAG,EAAE,MAAM,KAAK,CAAC;CACrE,OAAO,iBAAiB,QAAQ,OAAO,EAAE,QAAQ,MAAM,OAAO,CAAC;CAC/D,OAAO,iBAAiB,YAAY,OAAO,EAAE,QAAQ,MAAM,OAAO,CAAC;CACnE,SAAS,iBACP,0BACM;EACJ,IAAI,SAAS,QAAQ,MAAM;CAC7B,GACA,EAAE,QAAQ,MAAM,OAAO,CACzB;CACA,aAAa,MAAM,MAAM;AAC3B;AACA,IAAa,kBAAkB;AAC/B,SAAgB,eACd,GACA,GACA,YAAA,IACyC;CACzC,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,IAAI,WAAW,OAAO;CAC3D,OAAO,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAK,IAAI,IAAI,UAAU,SAAU,IAAI,IAAI,SAAS;AACnF;AACA,IAAa,mBAAmB;CAAE,SAAS;CAAM,WAAW;CAAQ,WAAW;CAAQ,YAAY;AAAQ;AAC3G,IAAa,oBAAoB;CAAE,GAAG;CAAM,GAAG;CAAQ,GAAG;CAAQ,GAAG;AAAQ"}
|
package/dist/panel.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type DriverOverrides } from '@gyral/core';
|
|
2
|
+
import type { Pace } from './records.js';
|
|
3
|
+
export type Hud = {
|
|
4
|
+
title: string;
|
|
5
|
+
status: string;
|
|
6
|
+
phase: string;
|
|
7
|
+
paused: boolean;
|
|
8
|
+
resuming: boolean;
|
|
9
|
+
pace: Pace;
|
|
10
|
+
daily: boolean;
|
|
11
|
+
best: number;
|
|
12
|
+
race: boolean;
|
|
13
|
+
pad: boolean;
|
|
14
|
+
tone: boolean;
|
|
15
|
+
autoFire: boolean;
|
|
16
|
+
graphics: string;
|
|
17
|
+
loaded: boolean;
|
|
18
|
+
alignment: boolean;
|
|
19
|
+
shooter: boolean;
|
|
20
|
+
};
|
|
21
|
+
export type PanelAction = {
|
|
22
|
+
type: 'primary' | 'race' | 'pad' | 'tone' | 'fire';
|
|
23
|
+
} | {
|
|
24
|
+
type: 'pace';
|
|
25
|
+
pace: Pace;
|
|
26
|
+
} | {
|
|
27
|
+
type: 'graphics';
|
|
28
|
+
value: 'auto' | 'low' | 'medium' | 'high';
|
|
29
|
+
};
|
|
30
|
+
type Msg = {
|
|
31
|
+
_tag: 'Changed';
|
|
32
|
+
hud: Hud;
|
|
33
|
+
} | {
|
|
34
|
+
_tag: 'Action';
|
|
35
|
+
action: PanelAction;
|
|
36
|
+
};
|
|
37
|
+
export declare const ArcadePanel: import("@gyral/core").GyralElementClass<{
|
|
38
|
+
hud: Hud;
|
|
39
|
+
}, Msg, object, never, "Primary" | "Race" | "Pad" | "Tone" | "Fire" | "Pace" | "Graphics">;
|
|
40
|
+
export declare const panelDrivers: (listen: (emit: (hud: Hud) => void) => () => void, perform: (action: PanelAction) => void) => DriverOverrides;
|
|
41
|
+
export {};
|