@joydle/ui 0.1.0 → 0.1.1
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/controls/ActionButton.d.ts +10 -1
- package/dist/controls/ActionButton.d.ts.map +1 -1
- package/dist/controls/ActionButton.js +3 -3
- package/dist/controls/ActionButton.js.map +1 -1
- package/dist/controls/index.d.ts +1 -1
- package/dist/controls/index.d.ts.map +1 -1
- package/dist/controls/index.js.map +1 -1
- package/dist/deps.d.ts +11 -0
- package/dist/deps.d.ts.map +1 -0
- package/dist/deps.js +19 -0
- package/dist/deps.js.map +1 -0
- package/dist/fx/effects.d.ts +163 -0
- package/dist/fx/effects.d.ts.map +1 -0
- package/dist/fx/effects.js +337 -0
- package/dist/fx/effects.js.map +1 -0
- package/dist/fx/hooks.d.ts +100 -0
- package/dist/fx/hooks.d.ts.map +1 -0
- package/dist/fx/hooks.js +116 -0
- package/dist/fx/hooks.js.map +1 -0
- package/dist/fx/index.d.ts +15 -0
- package/dist/fx/index.d.ts.map +1 -0
- package/dist/fx/index.js +22 -0
- package/dist/fx/index.js.map +1 -0
- package/dist/hud/BottomHint.d.ts.map +1 -1
- package/dist/hud/BottomHint.js +1 -9
- package/dist/hud/BottomHint.js.map +1 -1
- package/dist/hud/ComboLabel.d.ts.map +1 -1
- package/dist/hud/ComboLabel.js +1 -9
- package/dist/hud/ComboLabel.js.map +1 -1
- package/dist/hud/Crosshair.d.ts +28 -0
- package/dist/hud/Crosshair.d.ts.map +1 -0
- package/dist/hud/Crosshair.js +93 -0
- package/dist/hud/Crosshair.js.map +1 -0
- package/dist/hud/EntityLabel.d.ts +46 -0
- package/dist/hud/EntityLabel.d.ts.map +1 -0
- package/dist/hud/EntityLabel.js +59 -0
- package/dist/hud/EntityLabel.js.map +1 -0
- package/dist/hud/FloatingNumbers.d.ts +43 -0
- package/dist/hud/FloatingNumbers.d.ts.map +1 -0
- package/dist/hud/FloatingNumbers.js +93 -0
- package/dist/hud/FloatingNumbers.js.map +1 -0
- package/dist/hud/HUD.d.ts +2 -0
- package/dist/hud/HUD.d.ts.map +1 -1
- package/dist/hud/HUD.js +11 -0
- package/dist/hud/HUD.js.map +1 -1
- package/dist/hud/Lives.d.ts +26 -5
- package/dist/hud/Lives.d.ts.map +1 -1
- package/dist/hud/Lives.js +30 -31
- package/dist/hud/Lives.js.map +1 -1
- package/dist/hud/Meter.d.ts +10 -1
- package/dist/hud/Meter.d.ts.map +1 -1
- package/dist/hud/Meter.js +3 -11
- package/dist/hud/Meter.js.map +1 -1
- package/dist/hud/ResourceDisplay.d.ts +30 -0
- package/dist/hud/ResourceDisplay.d.ts.map +1 -0
- package/dist/hud/ResourceDisplay.js +49 -0
- package/dist/hud/ResourceDisplay.js.map +1 -0
- package/dist/hud/Score.d.ts +12 -1
- package/dist/hud/Score.d.ts.map +1 -1
- package/dist/hud/Score.js +15 -12
- package/dist/hud/Score.js.map +1 -1
- package/dist/hud/StatDisplay.d.ts +33 -0
- package/dist/hud/StatDisplay.d.ts.map +1 -0
- package/dist/hud/StatDisplay.js +56 -0
- package/dist/hud/StatDisplay.js.map +1 -0
- package/dist/hud/Timer.d.ts.map +1 -1
- package/dist/hud/Timer.js +1 -9
- package/dist/hud/Timer.js.map +1 -1
- package/dist/hud/WaveLabel.d.ts.map +1 -1
- package/dist/hud/WaveLabel.js +1 -9
- package/dist/hud/WaveLabel.js.map +1 -1
- package/dist/hud/index.d.ts +8 -3
- package/dist/hud/index.d.ts.map +1 -1
- package/dist/hud/index.js +5 -0
- package/dist/hud/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/screens/GameOverScreen.d.ts.map +1 -1
- package/dist/screens/GameOverScreen.js +3 -10
- package/dist/screens/GameOverScreen.js.map +1 -1
- package/dist/screens/LoadingScreen.d.ts.map +1 -1
- package/dist/screens/LoadingScreen.js +1 -9
- package/dist/screens/LoadingScreen.js.map +1 -1
- package/dist/screens/LobbyScreen.d.ts.map +1 -1
- package/dist/screens/LobbyScreen.js +1 -9
- package/dist/screens/LobbyScreen.js.map +1 -1
- package/dist/screens/PauseOverlay.d.ts.map +1 -1
- package/dist/screens/PauseOverlay.js +1 -9
- package/dist/screens/PauseOverlay.js.map +1 -1
- package/dist/screens/TitleScreen.d.ts.map +1 -1
- package/dist/screens/TitleScreen.js +3 -10
- package/dist/screens/TitleScreen.js.map +1 -1
- package/dist/screens/index.d.ts +1 -0
- package/dist/screens/index.d.ts.map +1 -1
- package/dist/screens/index.js +1 -0
- package/dist/screens/index.js.map +1 -1
- package/dist/screens/primitives.d.ts +101 -0
- package/dist/screens/primitives.d.ts.map +1 -0
- package/dist/screens/primitives.js +239 -0
- package/dist/screens/primitives.js.map +1 -0
- package/dist/transitions/ScreenTransition.d.ts.map +1 -1
- package/dist/transitions/ScreenTransition.js +31 -40
- package/dist/transitions/ScreenTransition.js.map +1 -1
- package/package.json +13 -2
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple on/off trigger with automatic reset after `duration` ms.
|
|
3
|
+
*
|
|
4
|
+
* ```ts
|
|
5
|
+
* const { active, trigger } = useTriggerEffect(250);
|
|
6
|
+
* // active becomes true on trigger(), resets after 250ms
|
|
7
|
+
* ```
|
|
8
|
+
*/
|
|
9
|
+
export declare function useTriggerEffect(duration?: number): {
|
|
10
|
+
active: boolean;
|
|
11
|
+
trigger: () => void;
|
|
12
|
+
};
|
|
13
|
+
/** Alert state managed by useAlerts. */
|
|
14
|
+
export interface AlertState {
|
|
15
|
+
/** Primary text (large, bold). */
|
|
16
|
+
main: string;
|
|
17
|
+
/** Secondary text (smaller). */
|
|
18
|
+
sub?: string;
|
|
19
|
+
/** Localised / decorative text. */
|
|
20
|
+
jp?: string;
|
|
21
|
+
/** Internal id for deduplication. */
|
|
22
|
+
id: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Queue-based alert system with auto-dismiss.
|
|
26
|
+
*
|
|
27
|
+
* ```tsx
|
|
28
|
+
* const { alert, showAlert } = useAlerts();
|
|
29
|
+
* showAlert('WAVE 3', 'ENEMIES INCOMING', '第3波');
|
|
30
|
+
* // ...
|
|
31
|
+
* <AlertBanner alert={alert} />
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function useAlerts(): {
|
|
35
|
+
alert: AlertState | null;
|
|
36
|
+
showAlert: (main: string, sub?: string, jp?: string) => void;
|
|
37
|
+
};
|
|
38
|
+
/** Banner state managed by useWaveBanner. */
|
|
39
|
+
export interface BannerState {
|
|
40
|
+
/** Wave number to display. */
|
|
41
|
+
wave: number;
|
|
42
|
+
/** Optional enemy/item count. */
|
|
43
|
+
count?: number;
|
|
44
|
+
/** Internal id. */
|
|
45
|
+
id: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Wave announcement banner with auto-dismiss.
|
|
49
|
+
*
|
|
50
|
+
* ```tsx
|
|
51
|
+
* const { banner, showWave } = useWaveBanner();
|
|
52
|
+
* showWave(3, 8); // "WAVE 3 — 8 ENEMIES"
|
|
53
|
+
* <WaveBanner banner={banner} />
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare function useWaveBanner(): {
|
|
57
|
+
banner: BannerState | null;
|
|
58
|
+
showWave: (wave: number, count?: number) => void;
|
|
59
|
+
};
|
|
60
|
+
/** Individual kill marker state. */
|
|
61
|
+
export interface KillState {
|
|
62
|
+
id: number;
|
|
63
|
+
/** Horizontal % from left. */
|
|
64
|
+
x: number;
|
|
65
|
+
/** Vertical % from top. */
|
|
66
|
+
y: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Spawns kill-confirmation markers at random screen positions.
|
|
70
|
+
*
|
|
71
|
+
* ```tsx
|
|
72
|
+
* const { kills, addKill } = useKillConfirm();
|
|
73
|
+
* <KillConfirm kills={kills} />
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare function useKillConfirm(): {
|
|
77
|
+
kills: KillState[];
|
|
78
|
+
addKill: () => void;
|
|
79
|
+
};
|
|
80
|
+
/** Beam / energy ray state. */
|
|
81
|
+
export interface BeamState {
|
|
82
|
+
id: number;
|
|
83
|
+
/** Vertical % position from top. */
|
|
84
|
+
top: number;
|
|
85
|
+
/** Width in pixels. */
|
|
86
|
+
width: number;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Horizontal beam flash effects (enemy attacks, explosions, etc.).
|
|
90
|
+
*
|
|
91
|
+
* ```tsx
|
|
92
|
+
* const { beams, addBeam } = useBeamEffect();
|
|
93
|
+
* <ScreenBeam beams={beams} />
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function useBeamEffect(): {
|
|
97
|
+
beams: BeamState[];
|
|
98
|
+
addBeam: () => void;
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/fx/hooks.ts"],"names":[],"mappings":"AAQA;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,SAAM,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAiBzF;AAID,wCAAwC;AACxC,MAAM,WAAW,UAAU;IACzB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;CACZ;AAID;;;;;;;;;GASG;AACH,wBAAgB,SAAS,IAAI;IAC3B,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9D,CAUA;AAID,6CAA6C;AAC7C,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mBAAmB;IACnB,EAAE,EAAE,MAAM,CAAC;CACZ;AAID;;;;;;;;GAQG;AACH,wBAAgB,aAAa,IAAI;IAC/B,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD,CAUA;AAID,oCAAoC;AACpC,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,8BAA8B;IAC9B,CAAC,EAAE,MAAM,CAAC;IACV,2BAA2B;IAC3B,CAAC,EAAE,MAAM,CAAC;CACX;AAID;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI;IAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAe5E;AAID,+BAA+B;AAC/B,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,oCAAoC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAID;;;;;;;GAOG;AACH,wBAAgB,aAAa,IAAI;IAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAe3E"}
|
package/dist/fx/hooks.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// @joydle/ui/fx — Reusable effect lifecycle hooks
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
import { useState, useRef, useEffect, useCallback } from 'preact/hooks';
|
|
5
|
+
// ---- Generic timed trigger ------------------------------------------------
|
|
6
|
+
/**
|
|
7
|
+
* Simple on/off trigger with automatic reset after `duration` ms.
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* const { active, trigger } = useTriggerEffect(250);
|
|
11
|
+
* // active becomes true on trigger(), resets after 250ms
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export function useTriggerEffect(duration = 250) {
|
|
15
|
+
const [active, setActive] = useState(false);
|
|
16
|
+
const timerRef = useRef(null);
|
|
17
|
+
const trigger = useCallback(() => {
|
|
18
|
+
if (timerRef.current)
|
|
19
|
+
clearTimeout(timerRef.current);
|
|
20
|
+
setActive(true);
|
|
21
|
+
timerRef.current = setTimeout(() => setActive(false), duration);
|
|
22
|
+
}, [duration]);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
return () => {
|
|
25
|
+
if (timerRef.current)
|
|
26
|
+
clearTimeout(timerRef.current);
|
|
27
|
+
};
|
|
28
|
+
}, []);
|
|
29
|
+
return { active, trigger };
|
|
30
|
+
}
|
|
31
|
+
let _alertId = 0;
|
|
32
|
+
/**
|
|
33
|
+
* Queue-based alert system with auto-dismiss.
|
|
34
|
+
*
|
|
35
|
+
* ```tsx
|
|
36
|
+
* const { alert, showAlert } = useAlerts();
|
|
37
|
+
* showAlert('WAVE 3', 'ENEMIES INCOMING', '第3波');
|
|
38
|
+
* // ...
|
|
39
|
+
* <AlertBanner alert={alert} />
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export function useAlerts() {
|
|
43
|
+
const [alert, setAlert] = useState(null);
|
|
44
|
+
const showAlert = useCallback((main, sub, jp) => {
|
|
45
|
+
const id = ++_alertId;
|
|
46
|
+
setAlert({ main, sub, jp, id });
|
|
47
|
+
setTimeout(() => setAlert(prev => (prev?.id === id ? null : prev)), 1800);
|
|
48
|
+
}, []);
|
|
49
|
+
return { alert, showAlert };
|
|
50
|
+
}
|
|
51
|
+
let _bannerId = 0;
|
|
52
|
+
/**
|
|
53
|
+
* Wave announcement banner with auto-dismiss.
|
|
54
|
+
*
|
|
55
|
+
* ```tsx
|
|
56
|
+
* const { banner, showWave } = useWaveBanner();
|
|
57
|
+
* showWave(3, 8); // "WAVE 3 — 8 ENEMIES"
|
|
58
|
+
* <WaveBanner banner={banner} />
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export function useWaveBanner() {
|
|
62
|
+
const [banner, setBanner] = useState(null);
|
|
63
|
+
const showWave = useCallback((wave, count) => {
|
|
64
|
+
const id = ++_bannerId;
|
|
65
|
+
setBanner({ wave, count, id });
|
|
66
|
+
setTimeout(() => setBanner(prev => (prev?.id === id ? null : prev)), 2800);
|
|
67
|
+
}, []);
|
|
68
|
+
return { banner, showWave };
|
|
69
|
+
}
|
|
70
|
+
let _killId = 0;
|
|
71
|
+
/**
|
|
72
|
+
* Spawns kill-confirmation markers at random screen positions.
|
|
73
|
+
*
|
|
74
|
+
* ```tsx
|
|
75
|
+
* const { kills, addKill } = useKillConfirm();
|
|
76
|
+
* <KillConfirm kills={kills} />
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export function useKillConfirm() {
|
|
80
|
+
const [kills, setKills] = useState([]);
|
|
81
|
+
const addKill = useCallback(() => {
|
|
82
|
+
const id = ++_killId;
|
|
83
|
+
const kill = {
|
|
84
|
+
id,
|
|
85
|
+
x: 45 + Math.random() * 10,
|
|
86
|
+
y: 38 + Math.random() * 12,
|
|
87
|
+
};
|
|
88
|
+
setKills(prev => [...prev, kill]);
|
|
89
|
+
setTimeout(() => setKills(prev => prev.filter(k => k.id !== id)), 1300);
|
|
90
|
+
}, []);
|
|
91
|
+
return { kills, addKill };
|
|
92
|
+
}
|
|
93
|
+
let _beamId = 0;
|
|
94
|
+
/**
|
|
95
|
+
* Horizontal beam flash effects (enemy attacks, explosions, etc.).
|
|
96
|
+
*
|
|
97
|
+
* ```tsx
|
|
98
|
+
* const { beams, addBeam } = useBeamEffect();
|
|
99
|
+
* <ScreenBeam beams={beams} />
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export function useBeamEffect() {
|
|
103
|
+
const [beams, setBeams] = useState([]);
|
|
104
|
+
const addBeam = useCallback(() => {
|
|
105
|
+
const id = ++_beamId;
|
|
106
|
+
const beam = {
|
|
107
|
+
id,
|
|
108
|
+
top: 40 + Math.random() * 20,
|
|
109
|
+
width: Math.min(window.innerWidth, 600 + Math.random() * 400),
|
|
110
|
+
};
|
|
111
|
+
setBeams(prev => [...prev, beam]);
|
|
112
|
+
setTimeout(() => setBeams(prev => prev.filter(b => b.id !== id)), 700);
|
|
113
|
+
}, []);
|
|
114
|
+
return { beams, addBeam };
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/fx/hooks.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,mDAAmD;AACnD,8EAA8E;AAE9E,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAExE,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAQ,GAAG,GAAG;IAC7C,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,MAAM,CAAuC,IAAI,CAAC,CAAC;IAEpE,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE;QAC/B,IAAI,QAAQ,CAAC,OAAO;YAAE,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACrD,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,QAAQ,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC;IAClE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,GAAG,EAAE;YACV,IAAI,QAAQ,CAAC,OAAO;gBAAE,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvD,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC;AAgBD,IAAI,QAAQ,GAAG,CAAC,CAAC;AAEjB;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS;IAIvB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAoB,IAAI,CAAC,CAAC;IAE5D,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,IAAY,EAAE,GAAY,EAAE,EAAW,EAAE,EAAE;QACxE,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC;QACtB,QAAQ,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAChC,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC5E,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAC9B,CAAC;AAcD,IAAI,SAAS,GAAG,CAAC,CAAC;AAElB;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa;IAI3B,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAqB,IAAI,CAAC,CAAC;IAE/D,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,IAAY,EAAE,KAAc,EAAE,EAAE;QAC5D,MAAM,EAAE,GAAG,EAAE,SAAS,CAAC;QACvB,SAAS,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC7E,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC;AAaD,IAAI,OAAO,GAAG,CAAC,CAAC;AAEhB;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAc,EAAE,CAAC,CAAC;IAEpD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE;QAC/B,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC;QACrB,MAAM,IAAI,GAAc;YACtB,EAAE;YACF,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;YAC1B,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;SAC3B,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAClC,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC1E,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5B,CAAC;AAaD,IAAI,OAAO,GAAG,CAAC,CAAC;AAEhB;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAc,EAAE,CAAC,CAAC;IAEpD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE;QAC/B,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC;QACrB,MAAM,IAAI,GAAc;YACtB,EAAE;YACF,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;YAC5B,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC;SAC9D,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAClC,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACzE,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { DamageFlash, type DamageFlashProps, Vignette, type VignetteProps, CRTOverlay, type CRTOverlayProps, AlertBanner, type AlertBannerProps, WaveBanner, type WaveBannerProps, MuzzleFlash, type MuzzleFlashProps, KillConfirm, type KillConfirmProps, WarningStripes, type WarningStripesProps, ScreenBeam, type ScreenBeamProps, } from './effects.js';
|
|
2
|
+
export { useTriggerEffect, useAlerts, type AlertState, useWaveBanner, type BannerState, useKillConfirm, type KillState, useBeamEffect, type BeamState, } from './hooks.js';
|
|
3
|
+
import { DamageFlash, Vignette, CRTOverlay, AlertBanner, WaveBanner, MuzzleFlash, KillConfirm, WarningStripes, ScreenBeam } from './effects.js';
|
|
4
|
+
export declare const ScreenFX: {
|
|
5
|
+
readonly DamageFlash: typeof DamageFlash;
|
|
6
|
+
readonly Vignette: typeof Vignette;
|
|
7
|
+
readonly CRTOverlay: typeof CRTOverlay;
|
|
8
|
+
readonly AlertBanner: typeof AlertBanner;
|
|
9
|
+
readonly WaveBanner: typeof WaveBanner;
|
|
10
|
+
readonly MuzzleFlash: typeof MuzzleFlash;
|
|
11
|
+
readonly KillConfirm: typeof KillConfirm;
|
|
12
|
+
readonly WarningStripes: typeof WarningStripes;
|
|
13
|
+
readonly ScreenBeam: typeof ScreenBeam;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fx/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,WAAW,EACX,KAAK,gBAAgB,EACrB,QAAQ,EACR,KAAK,aAAa,EAClB,UAAU,EACV,KAAK,eAAe,EACpB,WAAW,EACX,KAAK,gBAAgB,EACrB,UAAU,EACV,KAAK,eAAe,EACpB,WAAW,EACX,KAAK,gBAAgB,EACrB,WAAW,EACX,KAAK,gBAAgB,EACrB,cAAc,EACd,KAAK,mBAAmB,EACxB,UAAU,EACV,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,KAAK,UAAU,EACf,aAAa,EACb,KAAK,WAAW,EAChB,cAAc,EACd,KAAK,SAAS,EACd,aAAa,EACb,KAAK,SAAS,GACf,MAAM,YAAY,CAAC;AAKpB,OAAO,EACL,WAAW,EACX,QAAQ,EACR,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACd,UAAU,EACX,MAAM,cAAc,CAAC;AAEtB,eAAO,MAAM,QAAQ;;;;;;;;;;CAUX,CAAC"}
|
package/dist/fx/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// @joydle/ui/fx — Screen effects barrel
|
|
3
|
+
// Exports individual components + ScreenFX namespace + all hooks
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
export { DamageFlash, Vignette, CRTOverlay, AlertBanner, WaveBanner, MuzzleFlash, KillConfirm, WarningStripes, ScreenBeam, } from './effects.js';
|
|
6
|
+
export { useTriggerEffect, useAlerts, useWaveBanner, useKillConfirm, useBeamEffect, } from './hooks.js';
|
|
7
|
+
// Namespaced import for discoverability:
|
|
8
|
+
// import { ScreenFX } from '@joydle/ui/fx';
|
|
9
|
+
// <ScreenFX.DamageFlash active={hit} />
|
|
10
|
+
import { DamageFlash, Vignette, CRTOverlay, AlertBanner, WaveBanner, MuzzleFlash, KillConfirm, WarningStripes, ScreenBeam, } from './effects.js';
|
|
11
|
+
export const ScreenFX = {
|
|
12
|
+
DamageFlash,
|
|
13
|
+
Vignette,
|
|
14
|
+
CRTOverlay,
|
|
15
|
+
AlertBanner,
|
|
16
|
+
WaveBanner,
|
|
17
|
+
MuzzleFlash,
|
|
18
|
+
KillConfirm,
|
|
19
|
+
WarningStripes,
|
|
20
|
+
ScreenBeam,
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fx/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,yCAAyC;AACzC,kEAAkE;AAClE,8EAA8E;AAE9E,OAAO,EACL,WAAW,EAEX,QAAQ,EAER,UAAU,EAEV,WAAW,EAEX,UAAU,EAEV,WAAW,EAEX,WAAW,EAEX,cAAc,EAEd,UAAU,GAEX,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,gBAAgB,EAChB,SAAS,EAET,aAAa,EAEb,cAAc,EAEd,aAAa,GAEd,MAAM,YAAY,CAAC;AAEpB,yCAAyC;AACzC,8CAA8C;AAC9C,0CAA0C;AAC1C,OAAO,EACL,WAAW,EACX,QAAQ,EACR,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACd,UAAU,GACX,MAAM,cAAc,CAAC;AAEtB,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,WAAW;IACX,QAAQ;IACR,UAAU;IACV,WAAW;IACX,UAAU;IACV,WAAW;IACX,WAAW;IACX,cAAc;IACd,UAAU;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomHint.d.ts","sourceRoot":"","sources":["../../src/hud/BottomHint.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"BottomHint.d.ts","sourceRoot":"","sources":["../../src/hud/BottomHint.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAKlC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AAoBD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE,eAAe,GAAG,GAAG,CAAC,OAAO,CAsCrE"}
|
package/dist/hud/BottomHint.js
CHANGED
|
@@ -3,15 +3,7 @@ import { jsx as _jsx } from "preact/jsx-runtime";
|
|
|
3
3
|
// @joydle/ui — Bottom hint text with GSAP fade-in on mount
|
|
4
4
|
// ---------------------------------------------------------------------------
|
|
5
5
|
import { useRef, useEffect } from 'preact/hooks';
|
|
6
|
-
|
|
7
|
-
function getGsap() {
|
|
8
|
-
try {
|
|
9
|
-
return globalThis.gsap ?? require('gsap').default;
|
|
10
|
-
}
|
|
11
|
-
catch {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
6
|
+
import { getGsap } from '../deps.js';
|
|
15
7
|
// ---- Styles ---------------------------------------------------------------
|
|
16
8
|
const HINT_STYLE = {
|
|
17
9
|
gridColumn: '1 / -1',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomHint.js","sourceRoot":"","sources":["../../src/hud/BottomHint.tsx"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,4DAA4D;AAC5D,8EAA8E;AAE9E,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"BottomHint.js","sourceRoot":"","sources":["../../src/hud/BottomHint.tsx"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,4DAA4D;AAC5D,8EAA8E;AAE9E,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAQrC,8EAA8E;AAE9E,MAAM,UAAU,GAAoC;IAClD,UAAU,EAAE,QAAQ;IACpB,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,MAAM;IACf,cAAc,EAAE,QAAQ;IACxB,UAAU,EAAE,UAAU;IACtB,KAAK,EAAE,+CAA+C;IACtD,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE,GAAG;IACf,UAAU,EAAE,MAAM;IAClB,UAAU,EAAE,QAAQ;IACpB,aAAa,EAAE,CAAC;CACjB,CAAC;AAEF,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAmB;IACtD,MAAM,KAAK,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,CAAM,IAAI,CAAC,CAAC;IAEnC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;QACzB,IAAI,CAAC,EAAE;YAAE,OAAO;QAEhB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;QACvB,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAC5B,EAAE,EACF,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EACrB;YACE,OAAO,EAAE,CAAC;YACV,CAAC,EAAE,CAAC;YACJ,QAAQ,EAAE,GAAG;YACb,IAAI,EAAE,YAAY;YAClB,UAAU;gBACR,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;YAC1B,CAAC;SACF,CACF,CAAC;QAEF,OAAO,GAAG,EAAE;YACV,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACrB,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBACxB,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,cAAK,GAAG,EAAE,KAAK,EAAE,KAAK,EAAC,oBAAoB,EAAC,KAAK,EAAE,UAAU,YAC1D,QAAQ,GACL,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComboLabel.d.ts","sourceRoot":"","sources":["../../src/hud/ComboLabel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"ComboLabel.d.ts","sourceRoot":"","sources":["../../src/hud/ComboLabel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAKlC,MAAM,WAAW,eAAe;IAC9B,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAID;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,GAAQ,GACT,EAAE,eAAe,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAoHtC"}
|
package/dist/hud/ComboLabel.js
CHANGED
|
@@ -3,15 +3,7 @@ import { jsxs as _jsxs } from "preact/jsx-runtime";
|
|
|
3
3
|
// @joydle/ui — Combo counter with GSAP scale-in / fade-out
|
|
4
4
|
// ---------------------------------------------------------------------------
|
|
5
5
|
import { useRef, useEffect } from 'preact/hooks';
|
|
6
|
-
|
|
7
|
-
function getGsap() {
|
|
8
|
-
try {
|
|
9
|
-
return globalThis.gsap ?? require('gsap').default;
|
|
10
|
-
}
|
|
11
|
-
catch {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
6
|
+
import { getGsap } from '../deps.js';
|
|
15
7
|
// ---- Component ------------------------------------------------------------
|
|
16
8
|
/**
|
|
17
9
|
* Auto-shows when `combo >= 2` with a GSAP scale entrance. Auto-hides
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComboLabel.js","sourceRoot":"","sources":["../../src/hud/ComboLabel.tsx"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,4DAA4D;AAC5D,8EAA8E;AAE9E,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"ComboLabel.js","sourceRoot":"","sources":["../../src/hud/ComboLabel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { JSX } from 'preact';
|
|
2
|
+
export type CrosshairStyle = 'tactical' | 'cross' | 'dot' | 'circle' | 'none';
|
|
3
|
+
export interface CrosshairProps {
|
|
4
|
+
/** Gap between center and line start, 0-1 scale. Default: 0.18 */
|
|
5
|
+
spread?: number;
|
|
6
|
+
/** Briefly flash hit-confirm color. */
|
|
7
|
+
hit?: boolean;
|
|
8
|
+
/** Trigger fire recoil animation (scale + rotate). */
|
|
9
|
+
fire?: boolean;
|
|
10
|
+
/** Primary color. Default: var(--joydle-primary, #44FF41) */
|
|
11
|
+
color?: string;
|
|
12
|
+
/** Hit-confirm flash color. Default: var(--joydle-gold, #ffd700) */
|
|
13
|
+
hitColor?: string;
|
|
14
|
+
/** Center dot color. Default: var(--joydle-accent, #FF6A00) */
|
|
15
|
+
dotColor?: string;
|
|
16
|
+
/** Reticle style. Default: 'tactical' */
|
|
17
|
+
style?: CrosshairStyle;
|
|
18
|
+
/** Overall size in px. Default: 64 */
|
|
19
|
+
size?: number;
|
|
20
|
+
/** Line thickness in px. Default: 2 */
|
|
21
|
+
thickness?: number;
|
|
22
|
+
/** Show outer ring. Default: true */
|
|
23
|
+
ring?: boolean;
|
|
24
|
+
/** Show center dot. Default: true */
|
|
25
|
+
dot?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare function Crosshair({ spread, hit, fire, color, hitColor, dotColor, style: reticleStyle, size, thickness, ring, dot, }: CrosshairProps): JSX.Element;
|
|
28
|
+
//# sourceMappingURL=Crosshair.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Crosshair.d.ts","sourceRoot":"","sources":["../../src/hud/Crosshair.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAqClC,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE9E,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,sDAAsD;IACtD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,qCAAqC;IACrC,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAID,wBAAgB,SAAS,CAAC,EACxB,MAAa,EACb,GAAW,EACX,IAAY,EACZ,KAAwC,EACxC,QAAwC,EACxC,QAA0C,EAC1C,KAAK,EAAE,YAAyB,EAChC,IAAS,EACT,SAAa,EACb,IAAW,EACX,GAAU,GACX,EAAE,cAAc,GAAG,GAAG,CAAC,OAAO,CAwL9B"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// @joydle/ui — Crosshair: configurable screen-center reticle
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
import { useEffect, useRef } from 'preact/hooks';
|
|
6
|
+
// ---- CSS injection --------------------------------------------------------
|
|
7
|
+
let styleInjected = false;
|
|
8
|
+
function injectStyle() {
|
|
9
|
+
if (styleInjected || typeof document === 'undefined')
|
|
10
|
+
return;
|
|
11
|
+
styleInjected = true;
|
|
12
|
+
const s = document.createElement('style');
|
|
13
|
+
s.textContent = `
|
|
14
|
+
@keyframes joydle-crs-fire {
|
|
15
|
+
0% { transform: translate(-50%, -50%) scale(1) rotate(0deg); }
|
|
16
|
+
30% { transform: translate(-50%, -50%) scale(1.18) rotate(-3deg); }
|
|
17
|
+
70% { transform: translate(-50%, -50%) scale(1.12) rotate(2deg); }
|
|
18
|
+
100% { transform: translate(-50%, -50%) scale(1) rotate(0deg); }
|
|
19
|
+
}
|
|
20
|
+
@keyframes joydle-crs-hit {
|
|
21
|
+
0% { filter: drop-shadow(0 0 6px var(--joydle-crs-hit, #ffd700)) brightness(2); }
|
|
22
|
+
100% { filter: none; }
|
|
23
|
+
}
|
|
24
|
+
@keyframes joydle-crs-ring-pulse {
|
|
25
|
+
0% { r: 22; opacity: 0.35; }
|
|
26
|
+
50% { r: 30; opacity: 0.15; }
|
|
27
|
+
100% { r: 22; opacity: 0.35; }
|
|
28
|
+
}
|
|
29
|
+
.joydle-crs-fire-anim {
|
|
30
|
+
animation: joydle-crs-fire 0.15s ease forwards;
|
|
31
|
+
}
|
|
32
|
+
.joydle-crs-hit-anim {
|
|
33
|
+
animation: joydle-crs-hit 0.18s ease forwards;
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
document.head.appendChild(s);
|
|
37
|
+
}
|
|
38
|
+
// ---- Component ------------------------------------------------------------
|
|
39
|
+
export function Crosshair({ spread = 0.18, hit = false, fire = false, color = 'var(--joydle-primary, #44FF41)', hitColor = 'var(--joydle-gold, #ffd700)', dotColor = 'var(--joydle-accent, #FF6A00)', style: reticleStyle = 'tactical', size = 64, thickness = 2, ring = true, dot = true, }) {
|
|
40
|
+
injectStyle();
|
|
41
|
+
const containerRef = useRef(null);
|
|
42
|
+
const prevHit = useRef(false);
|
|
43
|
+
const prevFire = useRef(false);
|
|
44
|
+
// Fire animation
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (!fire || prevFire.current === fire)
|
|
47
|
+
return;
|
|
48
|
+
prevFire.current = fire;
|
|
49
|
+
const el = containerRef.current;
|
|
50
|
+
if (!el)
|
|
51
|
+
return;
|
|
52
|
+
el.classList.remove('joydle-crs-fire-anim');
|
|
53
|
+
void el.offsetWidth; // reflow
|
|
54
|
+
el.classList.add('joydle-crs-fire-anim');
|
|
55
|
+
const t = setTimeout(() => el.classList.remove('joydle-crs-fire-anim'), 160);
|
|
56
|
+
return () => clearTimeout(t);
|
|
57
|
+
}, [fire]);
|
|
58
|
+
// Hit flash
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
if (!hit || prevHit.current === hit)
|
|
61
|
+
return;
|
|
62
|
+
prevHit.current = hit;
|
|
63
|
+
const el = containerRef.current;
|
|
64
|
+
if (!el)
|
|
65
|
+
return;
|
|
66
|
+
el.style.setProperty('--joydle-crs-hit', hitColor);
|
|
67
|
+
el.classList.remove('joydle-crs-hit-anim');
|
|
68
|
+
void el.offsetWidth;
|
|
69
|
+
el.classList.add('joydle-crs-hit-anim');
|
|
70
|
+
const t = setTimeout(() => el.classList.remove('joydle-crs-hit-anim'), 200);
|
|
71
|
+
return () => clearTimeout(t);
|
|
72
|
+
}, [hit, hitColor]);
|
|
73
|
+
if (reticleStyle === 'none')
|
|
74
|
+
return _jsx(_Fragment, {});
|
|
75
|
+
const half = size / 2;
|
|
76
|
+
const gap = half * spread;
|
|
77
|
+
const lineLen = half * 0.35;
|
|
78
|
+
// Tactical style: corner brackets
|
|
79
|
+
const bSize = size * 0.22; // bracket arm length
|
|
80
|
+
const bOff = half * 0.55; // bracket center offset from center
|
|
81
|
+
const lineColor = hit ? hitColor : color;
|
|
82
|
+
return (_jsx("div", { ref: containerRef, class: "joydle-crosshair", style: {
|
|
83
|
+
position: 'fixed',
|
|
84
|
+
top: '50%',
|
|
85
|
+
left: '50%',
|
|
86
|
+
transform: 'translate(-50%, -50%)',
|
|
87
|
+
zIndex: 15,
|
|
88
|
+
pointerEvents: 'none',
|
|
89
|
+
userSelect: 'none',
|
|
90
|
+
willChange: 'transform',
|
|
91
|
+
}, children: _jsxs("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, fill: "none", style: { overflow: 'visible' }, children: [_jsxs("defs", { children: [_jsxs("filter", { id: "joydle-crs-glow", x: "-50%", y: "-50%", width: "200%", height: "200%", children: [_jsx("feGaussianBlur", { stdDeviation: "1.5", result: "blur" }), _jsxs("feMerge", { children: [_jsx("feMergeNode", { in: "blur" }), _jsx("feMergeNode", { in: "SourceGraphic" })] })] }), _jsxs("filter", { id: "joydle-crs-glow-strong", x: "-80%", y: "-80%", width: "260%", height: "260%", children: [_jsx("feGaussianBlur", { stdDeviation: "3", result: "blur" }), _jsxs("feMerge", { children: [_jsx("feMergeNode", { in: "blur" }), _jsx("feMergeNode", { in: "SourceGraphic" })] })] })] }), _jsxs("g", { filter: "url(#joydle-crs-glow)", children: [reticleStyle === 'tactical' && (_jsxs(_Fragment, { children: [_jsx("line", { x1: half, y1: half - gap - lineLen, x2: half, y2: half - gap, stroke: lineColor, strokeWidth: thickness, strokeLinecap: "square" }), _jsx("line", { x1: half, y1: half + gap, x2: half, y2: half + gap + lineLen, stroke: lineColor, strokeWidth: thickness, strokeLinecap: "square" }), _jsx("line", { x1: half - gap - lineLen, y1: half, x2: half - gap, y2: half, stroke: lineColor, strokeWidth: thickness, strokeLinecap: "square" }), _jsx("line", { x1: half + gap, y1: half, x2: half + gap + lineLen, y2: half, stroke: lineColor, strokeWidth: thickness, strokeLinecap: "square" }), _jsx("polyline", { points: `${half - bOff},${half - bOff + bSize} ${half - bOff},${half - bOff} ${half - bOff + bSize},${half - bOff}`, stroke: lineColor, strokeWidth: thickness * 0.7, fill: "none", opacity: "0.5", strokeLinecap: "square" }), _jsx("polyline", { points: `${half + bOff - bSize},${half - bOff} ${half + bOff},${half - bOff} ${half + bOff},${half - bOff + bSize}`, stroke: lineColor, strokeWidth: thickness * 0.7, fill: "none", opacity: "0.5", strokeLinecap: "square" }), _jsx("polyline", { points: `${half - bOff},${half + bOff - bSize} ${half - bOff},${half + bOff} ${half - bOff + bSize},${half + bOff}`, stroke: lineColor, strokeWidth: thickness * 0.7, fill: "none", opacity: "0.5", strokeLinecap: "square" }), _jsx("polyline", { points: `${half + bOff - bSize},${half + bOff} ${half + bOff},${half + bOff} ${half + bOff},${half + bOff - bSize}`, stroke: lineColor, strokeWidth: thickness * 0.7, fill: "none", opacity: "0.5", strokeLinecap: "square" })] })), reticleStyle === 'cross' && (_jsxs(_Fragment, { children: [_jsx("line", { x1: half, y1: half - gap - lineLen, x2: half, y2: half - gap, stroke: lineColor, strokeWidth: thickness, strokeLinecap: "round" }), _jsx("line", { x1: half, y1: half + gap, x2: half, y2: half + gap + lineLen, stroke: lineColor, strokeWidth: thickness, strokeLinecap: "round" }), _jsx("line", { x1: half - gap - lineLen, y1: half, x2: half - gap, y2: half, stroke: lineColor, strokeWidth: thickness, strokeLinecap: "round" }), _jsx("line", { x1: half + gap, y1: half, x2: half + gap + lineLen, y2: half, stroke: lineColor, strokeWidth: thickness, strokeLinecap: "round" })] })), reticleStyle === 'circle' && (_jsx("circle", { cx: half, cy: half, r: half - thickness * 2, stroke: lineColor, strokeWidth: thickness, fill: "none" }))] }), ring && reticleStyle !== 'dot' && (_jsx("circle", { cx: half, cy: half, r: half * 0.72, stroke: lineColor, strokeWidth: 0.75, fill: "none", opacity: 0.2, strokeDasharray: "3 5" })), dot && reticleStyle !== 'dot' && (_jsx("g", { filter: "url(#joydle-crs-glow-strong)", children: _jsx("circle", { cx: half, cy: half, r: thickness * 1.1, fill: dotColor }) })), reticleStyle === 'dot' && (_jsx("g", { filter: "url(#joydle-crs-glow-strong)", children: _jsx("circle", { cx: half, cy: half, r: thickness + 1.5, fill: lineColor }) }))] }) }));
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=Crosshair.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Crosshair.js","sourceRoot":"","sources":["../../src/hud/Crosshair.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { JSX } from 'preact';
|
|
2
|
+
export interface EntityLabelEntity {
|
|
3
|
+
/** Screen-space X position (pixels from left). */
|
|
4
|
+
x: number;
|
|
5
|
+
/** Screen-space Y position (pixels from top). */
|
|
6
|
+
y: number;
|
|
7
|
+
/** Optional name label shown above the bar. */
|
|
8
|
+
label?: string;
|
|
9
|
+
/** Current HP (0–maxHp). */
|
|
10
|
+
hp: number;
|
|
11
|
+
/** Max HP. Default: 100 */
|
|
12
|
+
maxHp?: number;
|
|
13
|
+
/** Bar fill color. Default: barColor prop */
|
|
14
|
+
color?: string;
|
|
15
|
+
/** Unique key for reconciliation. */
|
|
16
|
+
id?: string | number;
|
|
17
|
+
}
|
|
18
|
+
export interface EntityLabelProps {
|
|
19
|
+
entities: EntityLabelEntity[];
|
|
20
|
+
/** Default bar fill color. Default: var(--joydle-danger, #ff4444) */
|
|
21
|
+
barColor?: string;
|
|
22
|
+
/** Label text color. Default: rgba(255,255,255,0.7) */
|
|
23
|
+
labelColor?: string;
|
|
24
|
+
/** Bar width in px. Default: 48 */
|
|
25
|
+
barWidth?: number;
|
|
26
|
+
/** Bar height in px. Default: 4 */
|
|
27
|
+
barHeight?: number;
|
|
28
|
+
/** Vertical offset above the given y position. Default: 16 */
|
|
29
|
+
yOffset?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Renders HP bars and labels at arbitrary screen-space positions.
|
|
33
|
+
* Use your game engine's world-to-screen projection to get x/y,
|
|
34
|
+
* then pass entities to this component.
|
|
35
|
+
*
|
|
36
|
+
* ```tsx
|
|
37
|
+
* <EntityLabel
|
|
38
|
+
* entities={enemies.map(e => ({
|
|
39
|
+
* id: e.id, x: e.screenX, y: e.screenY,
|
|
40
|
+
* label: e.name, hp: e.hp, maxHp: e.maxHp,
|
|
41
|
+
* }))}
|
|
42
|
+
* />
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function EntityLabel({ entities, barColor, labelColor, barWidth, barHeight, yOffset, }: EntityLabelProps): JSX.Element;
|
|
46
|
+
//# sourceMappingURL=EntityLabel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntityLabel.d.ts","sourceRoot":"","sources":["../../src/hud/EntityLabel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAIlC,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,CAAC,EAAE,MAAM,CAAC;IACV,iDAAiD;IACjD,CAAC,EAAE,MAAM,CAAC;IACV,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,QAA0C,EAC1C,UAAoC,EACpC,QAAa,EACb,SAAa,EACb,OAAY,GACb,EAAE,gBAAgB,GAAG,GAAG,CAAC,OAAO,CAsEhC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
// ---- Component ------------------------------------------------------------
|
|
3
|
+
/**
|
|
4
|
+
* Renders HP bars and labels at arbitrary screen-space positions.
|
|
5
|
+
* Use your game engine's world-to-screen projection to get x/y,
|
|
6
|
+
* then pass entities to this component.
|
|
7
|
+
*
|
|
8
|
+
* ```tsx
|
|
9
|
+
* <EntityLabel
|
|
10
|
+
* entities={enemies.map(e => ({
|
|
11
|
+
* id: e.id, x: e.screenX, y: e.screenY,
|
|
12
|
+
* label: e.name, hp: e.hp, maxHp: e.maxHp,
|
|
13
|
+
* }))}
|
|
14
|
+
* />
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export function EntityLabel({ entities, barColor = 'var(--joydle-danger, #ff4444)', labelColor = 'rgba(255,255,255,0.7)', barWidth = 48, barHeight = 4, yOffset = 16, }) {
|
|
18
|
+
return (_jsx("div", { class: "joydle-entity-labels", style: {
|
|
19
|
+
position: 'absolute',
|
|
20
|
+
inset: 0,
|
|
21
|
+
pointerEvents: 'none',
|
|
22
|
+
overflow: 'hidden',
|
|
23
|
+
zIndex: 12,
|
|
24
|
+
}, children: entities.map((e, i) => {
|
|
25
|
+
const max = e.maxHp ?? 100;
|
|
26
|
+
const pct = Math.max(0, Math.min(1, e.hp / max)) * 100;
|
|
27
|
+
const fill = e.color ?? barColor;
|
|
28
|
+
const key = e.id ?? i;
|
|
29
|
+
return (_jsxs("div", { style: {
|
|
30
|
+
position: 'absolute',
|
|
31
|
+
left: e.x,
|
|
32
|
+
top: e.y - yOffset,
|
|
33
|
+
transform: 'translate(-50%, -100%)',
|
|
34
|
+
display: 'flex',
|
|
35
|
+
flexDirection: 'column',
|
|
36
|
+
alignItems: 'center',
|
|
37
|
+
gap: 2,
|
|
38
|
+
}, children: [e.label && (_jsx("span", { style: {
|
|
39
|
+
fontSize: '0.6rem',
|
|
40
|
+
letterSpacing: '0.04em',
|
|
41
|
+
color: labelColor,
|
|
42
|
+
whiteSpace: 'nowrap',
|
|
43
|
+
textShadow: '0 1px 3px rgba(0,0,0,0.8)',
|
|
44
|
+
}, children: e.label })), _jsx("div", { style: {
|
|
45
|
+
width: barWidth,
|
|
46
|
+
height: barHeight,
|
|
47
|
+
background: 'rgba(0,0,0,0.5)',
|
|
48
|
+
borderRadius: barHeight,
|
|
49
|
+
overflow: 'hidden',
|
|
50
|
+
}, children: _jsx("div", { style: {
|
|
51
|
+
width: `${pct}%`,
|
|
52
|
+
height: '100%',
|
|
53
|
+
background: fill,
|
|
54
|
+
borderRadius: barHeight,
|
|
55
|
+
transition: 'width 0.1s ease',
|
|
56
|
+
} }) })] }, key));
|
|
57
|
+
}) }));
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=EntityLabel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntityLabel.js","sourceRoot":"","sources":["../../src/hud/EntityLabel.tsx"],"names":[],"mappings":";AAuCA,8EAA8E;AAE9E;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,QAAQ,EACR,QAAQ,GAAG,+BAA+B,EAC1C,UAAU,GAAG,uBAAuB,EACpC,QAAQ,GAAG,EAAE,EACb,SAAS,GAAG,CAAC,EACb,OAAO,GAAG,EAAE,GACK;IACjB,OAAO,CACL,cACE,KAAK,EAAC,sBAAsB,EAC5B,KAAK,EAAE;YACL,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,CAAC;YACR,aAAa,EAAE,MAAM;YACrB,QAAQ,EAAE,QAAQ;YAClB,MAAM,EAAE,EAAE;SACX,YAEA,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACrB,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC;YAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;YACvD,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC;YACjC,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YAEtB,OAAO,CACL,eAEE,KAAK,EAAE;oBACL,QAAQ,EAAE,UAAU;oBACpB,IAAI,EAAE,CAAC,CAAC,CAAC;oBACT,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO;oBAClB,SAAS,EAAE,wBAAwB;oBACnC,OAAO,EAAE,MAAM;oBACf,aAAa,EAAE,QAAQ;oBACvB,UAAU,EAAE,QAAQ;oBACpB,GAAG,EAAE,CAAC;iBACP,aAEA,CAAC,CAAC,KAAK,IAAI,CACV,eACE,KAAK,EAAE;4BACL,QAAQ,EAAE,QAAQ;4BAClB,aAAa,EAAE,QAAQ;4BACvB,KAAK,EAAE,UAAU;4BACjB,UAAU,EAAE,QAAQ;4BACpB,UAAU,EAAE,2BAA2B;yBACxC,YAEA,CAAC,CAAC,KAAK,GACH,CACR,EAED,cACE,KAAK,EAAE;4BACL,KAAK,EAAE,QAAQ;4BACf,MAAM,EAAE,SAAS;4BACjB,UAAU,EAAE,iBAAiB;4BAC7B,YAAY,EAAE,SAAS;4BACvB,QAAQ,EAAE,QAAQ;yBACnB,YAED,cACE,KAAK,EAAE;gCACL,KAAK,EAAE,GAAG,GAAG,GAAG;gCAChB,MAAM,EAAE,MAAM;gCACd,UAAU,EAAE,IAAI;gCAChB,YAAY,EAAE,SAAS;gCACvB,UAAU,EAAE,iBAAiB;6BAC9B,GACD,GACE,KA5CD,GAAG,CA6CJ,CACP,CAAC;QACJ,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
|