jaml-ui 2.0.0 → 2.1.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.
@@ -1,13 +1,7 @@
1
1
  export type MotelyRuntimeStatus = "idle" | "booting" | "ready" | "error";
2
- type JimmolateProbe = (seed: string, score: number, tallies: number[]) => boolean;
3
- /** Swap the active Jimmolate predicate and enable filtering. Safe before or after boot. */
4
- export declare function setJimmolateProbe(pred: JimmolateProbe): void;
5
- /** Reset to pass-through and disable filtering (the engine's default: every survivor matches). */
6
- export declare function clearJimmolateProbe(): void;
7
2
  export declare const MOTELY_BIN_PATH = "/motely-wasm/bin";
8
3
  /** True once the optional File System extension was bound before boot. */
9
4
  export declare function isFileSystemReady(): boolean;
10
5
  /** The error from a failed or absent File System init, if any. */
11
6
  export declare function getFileSystemError(): unknown;
12
7
  export declare function ensureMotelyReady(): Promise<void>;
13
- export {};
package/dist/motely.js CHANGED
@@ -1,46 +1,46 @@
1
1
  "use client";
2
- import { b as e, d as t, h as n, r, t as i } from "./chunks/spriteMapper-C2mqQHLj.js";
3
- import { _ as a, a as o, c as s, d as c, f as l, g as u, h as d, i as f, l as p, m, p as h, r as g, s as _, t as v, u as y, v as b, w as x, y as S } from "./chunks/runtime-CW7XHgOy.js";
2
+ import { f as e, g as t, r as n, t as r, x as i } from "./chunks/spriteMapper-C8uYedXB.js";
3
+ import { S as a, _ as o, a as s, c, d as l, f as u, g as d, h as f, i as p, l as m, m as h, n as g, o as _, p as v, r as y, s as b, t as x, u as S } from "./chunks/runtime-DAQf1WrX.js";
4
4
  import { useCallback as C, useState as w } from "react";
5
5
  import { Program as T, Program as E } from "motely-wasm/motely/wasm";
6
6
  import D from "motely-wasm";
7
7
  import { PermissionMode as O } from "motely-wasm/bootsharp/file-system";
8
8
  //#region src/decode/motelySprite.ts
9
9
  function k(a) {
10
- let o = _(a);
10
+ let o = s(a);
11
11
  if (!o) return null;
12
12
  if (o.category === "playing" && o.rank && o.suit) {
13
- let r = t[o.rank], i = n[o.suit];
14
- if (r !== void 0 && i !== void 0) return {
15
- atlasPath: e("deck"),
16
- gridCol: r,
17
- gridRow: i,
13
+ let n = e[o.rank], r = t[o.suit];
14
+ if (n !== void 0 && r !== void 0) return {
15
+ atlasPath: i("deck"),
16
+ gridCol: n,
17
+ gridRow: r,
18
18
  gridCols: 13,
19
19
  gridRows: 4,
20
20
  displayName: o.displayName,
21
21
  category: "playing"
22
22
  };
23
23
  }
24
- let s = r(o.displayName);
25
- if (!s) return null;
26
- let c = i[s.type];
27
- return c ? {
28
- atlasPath: e(c.assetKey),
29
- gridCol: s.pos.x,
30
- gridRow: s.pos.y,
31
- gridCols: c.cols,
32
- gridRows: c.rows,
24
+ let c = n(o.displayName);
25
+ if (!c) return null;
26
+ let l = r[c.type];
27
+ return l ? {
28
+ atlasPath: i(l.assetKey),
29
+ gridCol: c.pos.x,
30
+ gridRow: c.pos.y,
31
+ gridCols: l.cols,
32
+ gridRows: l.rows,
33
33
  displayName: o.displayName,
34
34
  category: o.category
35
35
  } : null;
36
36
  }
37
37
  function A(a, o = "unknown") {
38
38
  if (o === "playing") {
39
- let r = /^(.*?)\s+of\s+(.*?)$/i.exec(a);
40
- if (r) {
41
- let i = r[1], o = r[2], s = t[i], c = n[o];
39
+ let n = /^(.*?)\s+of\s+(.*?)$/i.exec(a);
40
+ if (n) {
41
+ let r = n[1], o = n[2], s = e[r], c = t[o];
42
42
  if (s !== void 0 && c !== void 0) return {
43
- atlasPath: e("deck"),
43
+ atlasPath: i("deck"),
44
44
  gridCol: s,
45
45
  gridRow: c,
46
46
  gridCols: 13,
@@ -50,11 +50,11 @@ function A(a, o = "unknown") {
50
50
  };
51
51
  }
52
52
  }
53
- let s = r(a);
53
+ let s = n(a);
54
54
  if (!s) return null;
55
- let c = i[s.type];
55
+ let c = r[s.type];
56
56
  return c ? {
57
- atlasPath: e(c.assetKey),
57
+ atlasPath: i(c.assetKey),
58
58
  gridCol: s.pos.x,
59
59
  gridRow: s.pos.y,
60
60
  gridCols: c.cols,
@@ -98,7 +98,7 @@ function V(e) {
98
98
  return e;
99
99
  }
100
100
  function H(e) {
101
- return x[e & 65535]?.displayName ?? `item#${e}`;
101
+ return a[e & 65535]?.displayName ?? `item#${e}`;
102
102
  }
103
103
  //#endregion
104
104
  //#region src/hooks/useJamlLibrary.ts
@@ -106,19 +106,19 @@ function U(e) {
106
106
  return e instanceof Error ? e.message : String(e);
107
107
  }
108
108
  function W() {
109
- let [e, t] = w("idle"), [n, r] = w(null), [i, a] = w([]), [s, c] = w(null), l = C(() => {
109
+ let [e, t] = w("idle"), [n, r] = w(null), [i, a] = w([]), [o, s] = w(null), c = C(() => {
110
110
  n && a((e) => [...e]);
111
111
  }, [n]);
112
112
  return {
113
113
  status: e,
114
114
  rootId: n,
115
115
  files: i,
116
- error: s,
116
+ error: o,
117
117
  mount: C(async () => {
118
- t("mounting"), c(null);
118
+ t("mounting"), s(null);
119
119
  try {
120
- if (await g(), !o()) {
121
- t("unsupported"), c(U(f() ?? "Bootsharp FileSystem package is not available."));
120
+ if (await g(), !p()) {
121
+ t("unsupported"), s(U(y() ?? "Bootsharp FileSystem package is not available."));
122
122
  return;
123
123
  }
124
124
  let e = await T.pickRoot({
@@ -131,11 +131,11 @@ function W() {
131
131
  }
132
132
  r(await T.mountRoot(e, { mode: O.ReadWrite })), a([]), t("ready");
133
133
  } catch (e) {
134
- t("error"), c(U(e));
134
+ t("error"), s(U(e));
135
135
  }
136
136
  }, []),
137
137
  unmount: C(async () => {
138
- n && (await g(), await T.unmountRoot(n), r(null), a([]), t(o() ? "idle" : "unsupported"));
138
+ n && (await g(), await T.unmountRoot(n), r(null), a([]), t(p() ? "idle" : "unsupported"));
139
139
  }, [n]),
140
140
  loadFile: C(async (e) => {
141
141
  if (!n) throw Error("JAML library is not mounted.");
@@ -145,10 +145,10 @@ function W() {
145
145
  if (!n) throw Error("JAML library is not mounted.");
146
146
  await g(), await T.writeTextFile(n, e, t), a((t) => (t.includes(e) ? t : [...t, e]).sort((e, t) => e.localeCompare(t)));
147
147
  }, [n]),
148
- refresh: l
148
+ refresh: c
149
149
  };
150
150
  }
151
151
  //#endregion
152
- export { v as MOTELY_BIN_PATH, E as Motely, D as bootsharp, _ as decodeMotelyItem, s as decodeMotelyItemName, p as decodeMotelyItemToJamlCard, g as ensureMotelyReady, A as getMotelySpriteByName, z as motelyBoosterPackDisplayName, B as motelyBoosterPackDisplayNameFromKey, N as motelyBossDisplayName, P as motelyBossDisplayNameFromKey, y as motelyItemCategory, c as motelyItemDisplayName, V as motelyItemDisplayNameFromKey, H as motelyItemDisplayNameFromValue, l as motelyItemEditionName, h as motelyItemEnhancementName, m as motelyItemRenderCategory, d as motelyItemSealName, k as motelyItemToSprite, u as motelyItemTypeName, a as motelyStandardcardRankName, b as motelyStandardcardSuitName, L as motelyTagDisplayName, R as motelyTagDisplayNameFromKey, F as motelyVoucherDisplayName, I as motelyVoucherDisplayNameFromKey, S as resolveMotelyItemType, W as useJamlLibrary };
152
+ export { x as MOTELY_BIN_PATH, E as Motely, D as bootsharp, s as decodeMotelyItem, _ as decodeMotelyItemName, b as decodeMotelyItemToJamlCard, g as ensureMotelyReady, A as getMotelySpriteByName, z as motelyBoosterPackDisplayName, B as motelyBoosterPackDisplayNameFromKey, N as motelyBossDisplayName, P as motelyBossDisplayNameFromKey, c as motelyItemCategory, m as motelyItemDisplayName, V as motelyItemDisplayNameFromKey, H as motelyItemDisplayNameFromValue, S as motelyItemEditionName, l as motelyItemEnhancementName, u as motelyItemRenderCategory, v as motelyItemSealName, k as motelyItemToSprite, h as motelyItemTypeName, f as motelyStandardcardRankName, d as motelyStandardcardSuitName, L as motelyTagDisplayName, R as motelyTagDisplayNameFromKey, F as motelyVoucherDisplayName, I as motelyVoucherDisplayNameFromKey, o as resolveMotelyItemType, W as useJamlLibrary };
153
153
 
154
154
  //# sourceMappingURL=motely.js.map
@@ -11,24 +11,17 @@ export declare const CARD_H: number;
11
11
  export declare function useSpriteTexture(itemName: string, fallbackSheet: SpriteSheetType): THREE.Texture;
12
12
  /** Balatro-style finishes. The card catches light differently per edition. */
13
13
  export type CardEdition = "base" | "foil" | "holo" | "polychrome";
14
- export interface EditionMaterial {
15
- roughness: number;
16
- metalness: number;
17
- emissiveIntensity: number;
18
- /** Whether the emissive hue cycles per-frame (the holographic shimmer). */
19
- animated: boolean;
20
- }
21
14
  /**
22
- * Material tuning per edition. Metalness stays 0 without an env map, metal goes
23
- * black so "shine" comes from a low-roughness specular highlight that rakes
24
- * across as the card tilts under the light. Holo/polychrome add a cycling
25
- * emissive hue on top for the rainbow shimmer.
15
+ * The per-edition card material. Holo/polychrome patch the standard material's
16
+ * fragment shader so the rainbow lives *in the art* and shifts with view angle —
17
+ * not an emissive tint over the whole card.
26
18
  */
27
- export declare function editionMaterial(edition: CardEdition): EditionMaterial;
28
- /** Drive the holographic emissive hue from time + tilt angle. No-op for base/foil. */
29
- export declare function updateEditionEmissive(material: THREE.MeshStandardMaterial | null, edition: CardEdition, t: number, tiltY: number): void;
19
+ export declare function EditionCardMaterial({ texture, edition, }: {
20
+ texture: THREE.Texture;
21
+ edition: CardEdition;
22
+ }): import("react/jsx-runtime").JSX.Element;
30
23
  export declare const MAX_TILT = 0.3;
31
- /** Off-axis key light + soft ambient: the specular that makes foil "catch." */
24
+ /** Off-axis key light + soft ambient + the env map that foil mirrors. */
32
25
  export declare function CardLighting(): import("react/jsx-runtime").JSX.Element;
33
26
  export interface Card3DProps {
34
27
  /** Item name to render — e.g. "Blueprint". Resolved against jaml-ui sprite metadata. */
package/dist/r3f.js ADDED
@@ -0,0 +1,275 @@
1
+ "use client";
2
+ import { d as e, i as t, m as n, t as r, x as i } from "./chunks/spriteMapper-C8uYedXB.js";
3
+ import * as a from "react";
4
+ import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
5
+ import { Canvas as l, useFrame as u, useLoader as d, useThree as f } from "@react-three/fiber";
6
+ import { Float as p } from "@react-three/drei";
7
+ import { animated as m, useSpring as h } from "@react-spring/three";
8
+ import * as g from "three";
9
+ import { RoomEnvironment as _ } from "three/addons/environments/RoomEnvironment.js";
10
+ var v = 95 / 71 * 1;
11
+ function y(e, n) {
12
+ let { pos: o, type: s } = t(e, n), c = r[s], l = i(c.assetKey), u = d(g.TextureLoader, l);
13
+ return a.useMemo(() => {
14
+ let e = u.clone();
15
+ return e.magFilter = g.NearestFilter, e.minFilter = g.NearestFilter, e.colorSpace = g.SRGBColorSpace, e.repeat.set(1 / c.cols, 1 / c.rows), e.offset.set(o.x / c.cols, 1 - (o.y + 1) / c.rows), e.needsUpdate = !0, e;
16
+ }, [
17
+ u,
18
+ c,
19
+ o.x,
20
+ o.y
21
+ ]);
22
+ }
23
+ var b = "\n#include <common>\nuniform float uJamlTime;\nvec3 jamlHue2rgb(float h) {\n vec3 p = abs(fract(h + vec3(0.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0);\n return clamp(p - 1.0, 0.0, 1.0);\n}\nvec3 jamlHueShift(vec3 c, float a) {\n const vec3 k = vec3(0.57735026919);\n float ca = cos(a);\n return c * ca + cross(k, c) * sin(a) + k * dot(k, c) * (1.0 - ca);\n}\n", x = {
24
+ base: {
25
+ roughness: 1,
26
+ metalness: 0,
27
+ envMapIntensity: 0,
28
+ glsl: null
29
+ },
30
+ foil: {
31
+ roughness: .12,
32
+ metalness: .85,
33
+ envMapIntensity: 1.5,
34
+ glsl: null
35
+ },
36
+ holo: {
37
+ roughness: .28,
38
+ metalness: .3,
39
+ envMapIntensity: .6,
40
+ glsl: "\n#include <map_fragment>\n{\n float jNdv = abs(dot(normalize(vNormal), normalize(vViewPosition)));\n float jFres = pow(1.0 - jNdv, 1.5);\n float jPhase = vMapUv.x * 2.2 + vMapUv.y * 0.6 + jFres * 2.0 + uJamlTime * 0.15;\n diffuseColor.rgb += jamlHue2rgb(fract(jPhase)) * (0.12 + 0.55 * jFres);\n}\n"
41
+ },
42
+ polychrome: {
43
+ roughness: .16,
44
+ metalness: .5,
45
+ envMapIntensity: .8,
46
+ glsl: "\n#include <map_fragment>\n{\n float jNdv = abs(dot(normalize(vNormal), normalize(vViewPosition)));\n float jFres = pow(1.0 - jNdv, 1.5);\n float jPhase = uJamlTime * 0.1 + jFres * 0.35 + vMapUv.x * 0.12 + vMapUv.y * 0.08;\n diffuseColor.rgb = jamlHueShift(diffuseColor.rgb, jPhase * 6.2831853);\n diffuseColor.rgb += jamlHue2rgb(fract(jPhase + 0.33)) * (0.06 + 0.3 * jFres);\n}\n"
47
+ }
48
+ };
49
+ function S({ texture: e, edition: t }) {
50
+ let n = x[t], r = a.useMemo(() => ({ value: 0 }), []);
51
+ return u((e) => {
52
+ r.value = e.clock.elapsedTime;
53
+ }), /* @__PURE__ */ s("meshStandardMaterial", {
54
+ customProgramCacheKey: () => `jaml-edition-${t}`,
55
+ onBeforeCompile: a.useMemo(() => {
56
+ if (!n.glsl) return;
57
+ let e = n.glsl;
58
+ return (t) => {
59
+ t.uniforms.uJamlTime = r, t.fragmentShader = t.fragmentShader.replace("#include <common>", b).replace("#include <map_fragment>", e);
60
+ };
61
+ }, [n.glsl, r]),
62
+ map: e,
63
+ transparent: !0,
64
+ alphaTest: .5,
65
+ side: g.DoubleSide,
66
+ toneMapped: !1,
67
+ roughness: n.roughness,
68
+ metalness: n.metalness,
69
+ envMapIntensity: n.envMapIntensity
70
+ }, t);
71
+ }
72
+ function C(e) {
73
+ let t = n.jokers, r = d(g.TextureLoader, t.src);
74
+ return a.useMemo(() => {
75
+ let n = r.clone();
76
+ return n.magFilter = g.NearestFilter, n.minFilter = g.NearestFilter, n.colorSpace = g.SRGBColorSpace, n.repeat.set(1 / t.columns, 1 / t.rows), n.offset.set(e.x / t.columns, 1 - (e.y + 1) / t.rows), n.needsUpdate = !0, n;
77
+ }, [
78
+ r,
79
+ t,
80
+ e.x,
81
+ e.y
82
+ ]);
83
+ }
84
+ function w({ pos: e }) {
85
+ let t = C(e), n = a.useRef(null);
86
+ return u((e) => {
87
+ n.current && (n.current.position.y = .04 * Math.sin(e.clock.elapsedTime * 2));
88
+ }), /* @__PURE__ */ c("mesh", {
89
+ ref: n,
90
+ position: [
91
+ 0,
92
+ 0,
93
+ .06
94
+ ],
95
+ children: [/* @__PURE__ */ s("planeGeometry", { args: [1, v] }), /* @__PURE__ */ s("meshBasicMaterial", {
96
+ map: t,
97
+ transparent: !0,
98
+ alphaTest: .1,
99
+ side: g.DoubleSide,
100
+ toneMapped: !1
101
+ })]
102
+ });
103
+ }
104
+ var T = .3;
105
+ function E({ itemName: t, fallbackSheet: n, edition: r }) {
106
+ let i = y(t, n), o = a.useMemo(() => e.find((e) => e.name === t), [t]), l = a.useRef(null), [d, f] = a.useState(!1), p = h({
107
+ scale: d ? 1.12 : 1,
108
+ config: {
109
+ tension: 260,
110
+ friction: 18
111
+ }
112
+ });
113
+ return u((e, t) => {
114
+ let n = l.current;
115
+ if (!n) return;
116
+ let r = e.pointer.x * T, i = -e.pointer.y * T, a = 1 - Math.exp(-8 * t);
117
+ n.rotation.y += (r - n.rotation.y) * a, n.rotation.x += (i - n.rotation.x) * a;
118
+ }), /* @__PURE__ */ c(m.mesh, {
119
+ ref: l,
120
+ scale: p.scale.to((e) => [
121
+ e,
122
+ e,
123
+ e
124
+ ]),
125
+ onPointerOver: () => f(!0),
126
+ onPointerOut: () => f(!1),
127
+ children: [
128
+ /* @__PURE__ */ s("planeGeometry", { args: [1, v] }),
129
+ /* @__PURE__ */ s(S, {
130
+ texture: i,
131
+ edition: r
132
+ }),
133
+ o && /* @__PURE__ */ s(w, { pos: o.pos })
134
+ ]
135
+ });
136
+ }
137
+ function D() {
138
+ let e = f((e) => e.gl), t = f((e) => e.scene);
139
+ return a.useEffect(() => {
140
+ let n = new g.PMREMGenerator(e), r = n.fromScene(new _(), .04);
141
+ return t.environment = r.texture, () => {
142
+ t.environment = null, r.dispose(), n.dispose();
143
+ };
144
+ }, [e, t]), null;
145
+ }
146
+ function O() {
147
+ return /* @__PURE__ */ c(o, { children: [
148
+ /* @__PURE__ */ s("ambientLight", { intensity: .85 }),
149
+ /* @__PURE__ */ s("pointLight", {
150
+ position: [
151
+ 2.5,
152
+ 3,
153
+ 4
154
+ ],
155
+ intensity: 1.6
156
+ }),
157
+ /* @__PURE__ */ s(D, {})
158
+ ] });
159
+ }
160
+ function k({ itemName: e, fallbackSheet: t = "Jokers", edition: n = "base", height: r = 320, className: i, style: o }) {
161
+ return /* @__PURE__ */ s("div", {
162
+ className: i,
163
+ style: {
164
+ width: "100%",
165
+ height: r,
166
+ ...o
167
+ },
168
+ children: /* @__PURE__ */ c(l, {
169
+ camera: {
170
+ position: [
171
+ 0,
172
+ 0,
173
+ 3
174
+ ],
175
+ fov: 40
176
+ },
177
+ gl: { alpha: !0 },
178
+ dpr: [1, 2],
179
+ children: [/* @__PURE__ */ s(O, {}), /* @__PURE__ */ s(a.Suspense, {
180
+ fallback: null,
181
+ children: /* @__PURE__ */ s(p, {
182
+ speed: 2,
183
+ rotationIntensity: .6,
184
+ floatIntensity: .8,
185
+ children: /* @__PURE__ */ s(E, {
186
+ itemName: e,
187
+ fallbackSheet: t,
188
+ edition: n
189
+ })
190
+ })
191
+ })]
192
+ })
193
+ });
194
+ }
195
+ //#endregion
196
+ //#region src/r3f/CardTable.tsx
197
+ var A = (e, t = 10) => 1 - Math.exp(-t * e), j = .6;
198
+ function M({ itemName: e, fallbackSheet: t, edition: n, homeX: r, dragging: i, onPick: o, onRelease: l }) {
199
+ let d = y(e, t), p = a.useRef(null), [m, h] = a.useState(!1), { camera: _ } = f(), b = a.useMemo(() => new g.Vector3(), []);
200
+ return u((e, t) => {
201
+ let n = p.current;
202
+ if (!n) return;
203
+ let a = A(t);
204
+ if (i) {
205
+ b.set(e.pointer.x, e.pointer.y, .5).unproject(_), b.sub(_.position).normalize();
206
+ let t = (j - _.position.z) / b.z, r = _.position.x + b.x * t, i = _.position.y + b.y * t;
207
+ n.position.x += (r - n.position.x) * a, n.position.y += (i - n.position.y) * a, n.position.z += (j - n.position.z) * a, N(n, e.pointer.x * T, -e.pointer.y * T, a), P(n, 1.18, a);
208
+ } else n.position.x += (r - n.position.x) * a, n.position.y += (0 - n.position.y) * a, n.position.z += (0 - n.position.z) * a, N(n, m ? e.pointer.x * T : 0, m ? -e.pointer.y * T : 0, a), P(n, m ? 1.12 : 1, a);
209
+ }), /* @__PURE__ */ c("mesh", {
210
+ ref: p,
211
+ position: [
212
+ r,
213
+ 0,
214
+ 0
215
+ ],
216
+ onPointerOver: (e) => {
217
+ e.stopPropagation(), h(!0);
218
+ },
219
+ onPointerOut: () => h(!1),
220
+ onPointerDown: (e) => {
221
+ e.stopPropagation(), o();
222
+ },
223
+ onPointerUp: () => l(),
224
+ children: [/* @__PURE__ */ s("planeGeometry", { args: [1, v] }), /* @__PURE__ */ s(S, {
225
+ texture: d,
226
+ edition: n
227
+ })]
228
+ });
229
+ }
230
+ function N(e, t, n, r) {
231
+ e.rotation.y += (t - e.rotation.y) * r, e.rotation.x += (n - e.rotation.x) * r;
232
+ }
233
+ function P(e, t, n) {
234
+ e.scale.x += (t - e.scale.x) * n, e.scale.y += (t - e.scale.y) * n, e.scale.z += (t - e.scale.z) * n;
235
+ }
236
+ function F({ items: e, height: t = 320, gap: n = 1.25, className: r, style: i }) {
237
+ let [o, u] = a.useState(null), d = a.useCallback(() => u(null), []), f = e.length;
238
+ return /* @__PURE__ */ s("div", {
239
+ className: r,
240
+ style: {
241
+ width: "100%",
242
+ height: t,
243
+ ...i
244
+ },
245
+ children: /* @__PURE__ */ c(l, {
246
+ camera: {
247
+ position: [
248
+ 0,
249
+ 0,
250
+ 3
251
+ ],
252
+ fov: 40
253
+ },
254
+ gl: { alpha: !0 },
255
+ dpr: [1, 2],
256
+ onPointerMissed: d,
257
+ children: [/* @__PURE__ */ s(O, {}), /* @__PURE__ */ s(a.Suspense, {
258
+ fallback: null,
259
+ children: e.map((e, t) => /* @__PURE__ */ s(M, {
260
+ itemName: e.itemName,
261
+ fallbackSheet: e.fallbackSheet ?? "Jokers",
262
+ edition: e.edition ?? "base",
263
+ homeX: (t - (f - 1) / 2) * n,
264
+ dragging: o === t,
265
+ onPick: () => u(t),
266
+ onRelease: d
267
+ }, `${e.itemName}-${t}`))
268
+ })]
269
+ })
270
+ });
271
+ }
272
+ //#endregion
273
+ export { k as Card3D, F as CardTable };
274
+
275
+ //# sourceMappingURL=r3f.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"r3f.js","names":[],"sources":["../src/r3f/Card3D.tsx","../src/r3f/CardTable.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Canvas, useLoader, useFrame, useThree } from \"@react-three/fiber\";\nimport { Float } from \"@react-three/drei\";\nimport { useSpring, animated } from \"@react-spring/three\";\nimport * as THREE from \"three\";\nimport { RoomEnvironment } from \"three/addons/environments/RoomEnvironment.js\";\n\nimport { resolveJamlAssetUrl } from \"../assets.js\";\nimport { getSpriteDataOrMystery, SHEET_META, type SpriteSheetType } from \"../sprites/spriteMapper.js\";\nimport { SPRITE_SHEETS, JOKER_FACES, type SpritePos } from \"../sprites/spriteData.js\";\n\n// Balatro cards are 71x95px cells on every sheet — keep the plane at that ratio.\nexport const CARD_W = 1;\nexport const CARD_H = CARD_W * (95 / 71);\n\n/**\n * Load a spritesheet PNG and crop it to a single item's cell via UV repeat/offset.\n * Reuses jaml-ui/core's sprite metadata so the 3D card shows the *real* art,\n * pixel-perfect (NearestFilter), not a placeholder.\n */\nexport function useSpriteTexture(itemName: string, fallbackSheet: SpriteSheetType): THREE.Texture {\n const { pos, type } = getSpriteDataOrMystery(itemName, fallbackSheet);\n const meta = SHEET_META[type];\n const url = resolveJamlAssetUrl(meta.assetKey);\n const base = useLoader(THREE.TextureLoader, url);\n\n // Clone per instance: useLoader caches by URL, so cards sharing a sheet must\n // not mutate a shared texture's offset. Configure the clone, not the cached one.\n return React.useMemo(() => {\n const texture = base.clone();\n texture.magFilter = THREE.NearestFilter;\n texture.minFilter = THREE.NearestFilter;\n texture.colorSpace = THREE.SRGBColorSpace;\n texture.repeat.set(1 / meta.cols, 1 / meta.rows);\n // Three's UV origin is bottom-left; sprite rows are indexed top-down.\n texture.offset.set(pos.x / meta.cols, 1 - (pos.y + 1) / meta.rows);\n texture.needsUpdate = true;\n return texture;\n }, [base, meta, pos.x, pos.y]);\n}\n\n/** Balatro-style finishes. The card catches light differently per edition. */\nexport type CardEdition = \"base\" | \"foil\" | \"holo\" | \"polychrome\";\n\ninterface EditionParams {\n roughness: number;\n metalness: number;\n envMapIntensity: number;\n /** Fragment-shader injection for the iridescent editions; null = stock material. */\n glsl: string | null;\n}\n\n// Helpers + time uniform, spliced in after <common>. jamlHueShift is Rodrigues\n// rotation about the grey axis — a hue rotation without leaving RGB.\nconst EDITION_GLSL_COMMON = /* glsl */ `\n#include <common>\nuniform float uJamlTime;\nvec3 jamlHue2rgb(float h) {\n vec3 p = abs(fract(h + vec3(0.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0);\n return clamp(p - 1.0, 0.0, 1.0);\n}\nvec3 jamlHueShift(vec3 c, float a) {\n const vec3 k = vec3(0.57735026919);\n float ca = cos(a);\n return c * ca + cross(k, c) * sin(a) + k * dot(k, c) * (1.0 - ca);\n}\n`;\n\n// Holo: rainbow bands living in the card face, strongest at glancing angles —\n// the fresnel term is what makes the rainbow rake across as the card tilts.\nconst HOLO_GLSL = /* glsl */ `\n#include <map_fragment>\n{\n float jNdv = abs(dot(normalize(vNormal), normalize(vViewPosition)));\n float jFres = pow(1.0 - jNdv, 1.5);\n float jPhase = vMapUv.x * 2.2 + vMapUv.y * 0.6 + jFres * 2.0 + uJamlTime * 0.15;\n diffuseColor.rgb += jamlHue2rgb(fract(jPhase)) * (0.12 + 0.55 * jFres);\n}\n`;\n\n// Polychrome: the art itself hue-cycles (slow, whole-card), plus a faint\n// angle-driven rainbow sheen on top.\nconst POLY_GLSL = /* glsl */ `\n#include <map_fragment>\n{\n float jNdv = abs(dot(normalize(vNormal), normalize(vViewPosition)));\n float jFres = pow(1.0 - jNdv, 1.5);\n float jPhase = uJamlTime * 0.1 + jFres * 0.35 + vMapUv.x * 0.12 + vMapUv.y * 0.08;\n diffuseColor.rgb = jamlHueShift(diffuseColor.rgb, jPhase * 6.2831853);\n diffuseColor.rgb += jamlHue2rgb(fract(jPhase + 0.33)) * (0.06 + 0.3 * jFres);\n}\n`;\n\nconst EDITION_PARAMS: Record<CardEdition, EditionParams> = {\n base: { roughness: 1, metalness: 0, envMapIntensity: 0, glsl: null },\n // Foil is an actual mirror now: metal + the room env map (see CardLighting).\n foil: { roughness: 0.12, metalness: 0.85, envMapIntensity: 1.5, glsl: null },\n holo: { roughness: 0.28, metalness: 0.3, envMapIntensity: 0.6, glsl: HOLO_GLSL },\n polychrome: { roughness: 0.16, metalness: 0.5, envMapIntensity: 0.8, glsl: POLY_GLSL },\n};\n\n/**\n * The per-edition card material. Holo/polychrome patch the standard material's\n * fragment shader so the rainbow lives *in the art* and shifts with view angle —\n * not an emissive tint over the whole card.\n */\nexport function EditionCardMaterial({\n texture,\n edition,\n}: {\n texture: THREE.Texture;\n edition: CardEdition;\n}) {\n const params = EDITION_PARAMS[edition];\n const timeUniform = React.useMemo(() => ({ value: 0 }), []);\n useFrame((state) => {\n timeUniform.value = state.clock.elapsedTime;\n });\n const onBeforeCompile = React.useMemo(() => {\n if (!params.glsl) return undefined;\n const glsl = params.glsl;\n return (shader: THREE.WebGLProgramParametersWithUniforms) => {\n shader.uniforms.uJamlTime = timeUniform;\n shader.fragmentShader = shader.fragmentShader\n .replace(\"#include <common>\", EDITION_GLSL_COMMON)\n .replace(\"#include <map_fragment>\", glsl);\n };\n }, [params.glsl, timeUniform]);\n\n return (\n <meshStandardMaterial\n // Editions compile different programs — without distinct keys, three's\n // program cache would hand holo's shader to polychrome (same closure source).\n key={edition}\n customProgramCacheKey={() => `jaml-edition-${edition}`}\n onBeforeCompile={onBeforeCompile}\n map={texture}\n transparent\n alphaTest={0.5}\n side={THREE.DoubleSide}\n toneMapped={false}\n roughness={params.roughness}\n metalness={params.metalness}\n envMapIntensity={params.envMapIntensity}\n />\n );\n}\n\n/** Crop the jokers sheet to an explicit grid cell (used for legendary soul faces). */\nfunction useJokersCellTexture(pos: SpritePos): THREE.Texture {\n const sheet = SPRITE_SHEETS.jokers;\n const base = useLoader(THREE.TextureLoader, sheet.src);\n return React.useMemo(() => {\n const t = base.clone();\n t.magFilter = THREE.NearestFilter;\n t.minFilter = THREE.NearestFilter;\n t.colorSpace = THREE.SRGBColorSpace;\n t.repeat.set(1 / sheet.columns, 1 / sheet.rows);\n t.offset.set(pos.x / sheet.columns, 1 - (pos.y + 1) / sheet.rows);\n t.needsUpdate = true;\n return t;\n }, [base, sheet, pos.x, pos.y]);\n}\n\n/**\n * The legendary's soul — its glowing face — hovering on its own depth plane just\n * in front of the card. Bobs independently, so under tilt it parallaxes off the\n * base: the thing DOM compositing can never do, only real depth.\n */\nfunction SoulMesh({ pos }: { pos: SpritePos }) {\n const texture = useJokersCellTexture(pos);\n const ref = React.useRef<THREE.Mesh>(null);\n useFrame((state) => {\n if (ref.current) ref.current.position.y = 0.04 * Math.sin(state.clock.elapsedTime * 2);\n });\n return (\n <mesh ref={ref} position={[0, 0, 0.06]}>\n <planeGeometry args={[CARD_W, CARD_H]} />\n <meshBasicMaterial map={texture} transparent alphaTest={0.1} side={THREE.DoubleSide} toneMapped={false} />\n </mesh>\n );\n}\n\ninterface CardMeshProps {\n itemName: string;\n fallbackSheet: SpriteSheetType;\n edition: CardEdition;\n}\n\n// Max tilt away from facing the camera, in radians (~17°).\nexport const MAX_TILT = 0.3;\n\nfunction CardMesh({ itemName, fallbackSheet, edition }: CardMeshProps) {\n const texture = useSpriteTexture(itemName, fallbackSheet);\n const soul = React.useMemo(() => JOKER_FACES.find((j) => j.name === itemName), [itemName]);\n const meshRef = React.useRef<THREE.Mesh>(null);\n const [hovered, setHovered] = React.useState(false);\n const spring = useSpring({\n scale: hovered ? 1.12 : 1,\n config: { tension: 260, friction: 18 },\n });\n\n // Magnetic tilt: ease the card's rotation toward the pointer every frame.\n // This is the reason for r3f — a GPU transform that DOM can't do smoothly.\n useFrame((state, delta) => {\n const mesh = meshRef.current;\n if (!mesh) return;\n const targetY = state.pointer.x * MAX_TILT;\n const targetX = -state.pointer.y * MAX_TILT;\n const lerp = 1 - Math.exp(-8 * delta); // frame-rate independent easing\n mesh.rotation.y += (targetY - mesh.rotation.y) * lerp;\n mesh.rotation.x += (targetX - mesh.rotation.x) * lerp;\n });\n\n return (\n <animated.mesh\n ref={meshRef}\n scale={spring.scale.to((s) => [s, s, s])}\n onPointerOver={() => setHovered(true)}\n onPointerOut={() => setHovered(false)}\n >\n <planeGeometry args={[CARD_W, CARD_H]} />\n <EditionCardMaterial texture={texture} edition={edition} />\n {soul && <SoulMesh pos={soul.pos} />}\n </animated.mesh>\n );\n}\n\n/**\n * A procedural room env map (PMREM'd, no network fetch) so metal has something\n * to mirror — this is what makes foil actually catch and throw light instead\n * of going black. envMapIntensity 0 on base cards keeps them flat.\n */\nfunction CardEnvironment() {\n const gl = useThree((s) => s.gl);\n const scene = useThree((s) => s.scene);\n React.useEffect(() => {\n const pmrem = new THREE.PMREMGenerator(gl);\n const env = pmrem.fromScene(new RoomEnvironment(), 0.04);\n scene.environment = env.texture;\n return () => {\n scene.environment = null;\n env.dispose();\n pmrem.dispose();\n };\n }, [gl, scene]);\n return null;\n}\n\n/** Off-axis key light + soft ambient + the env map that foil mirrors. */\nexport function CardLighting() {\n return (\n <>\n <ambientLight intensity={0.85} />\n <pointLight position={[2.5, 3, 4]} intensity={1.6} />\n <CardEnvironment />\n </>\n );\n}\n\nexport interface Card3DProps {\n /** Item name to render — e.g. \"Blueprint\". Resolved against jaml-ui sprite metadata. */\n itemName: string;\n /** Which sheet to fall back to when the name doesn't resolve. Default \"Jokers\". */\n fallbackSheet?: SpriteSheetType;\n /** Finish — \"base\" | \"foil\" | \"holo\" | \"polychrome\". Default \"base\". */\n edition?: CardEdition;\n /** Pixel height of the canvas. Default 320. */\n height?: number | string;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * A floating, hover-reactive 3D Balatro card that catches the light.\n *\n * ```tsx\n * import { Card3D } from \"jaml-ui/r3f\";\n * <Card3D itemName=\"Blueprint\" edition=\"holo\" />\n * ```\n *\n * Peer deps: `three`, `@react-three/fiber`, `@react-three/drei`, `@react-spring/three`.\n */\nexport function Card3D({\n itemName,\n fallbackSheet = \"Jokers\",\n edition = \"base\",\n height = 320,\n className,\n style,\n}: Card3DProps) {\n return (\n <div className={className} style={{ width: \"100%\", height, ...style }}>\n <Canvas camera={{ position: [0, 0, 3], fov: 40 }} gl={{ alpha: true }} dpr={[1, 2]}>\n <CardLighting />\n <React.Suspense fallback={null}>\n <Float speed={2} rotationIntensity={0.6} floatIntensity={0.8}>\n <CardMesh itemName={itemName} fallbackSheet={fallbackSheet} edition={edition} />\n </Float>\n </React.Suspense>\n </Canvas>\n </div>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { Canvas, useFrame, useThree, type ThreeEvent } from \"@react-three/fiber\";\nimport * as THREE from \"three\";\n\nimport {\n useSpriteTexture,\n EditionCardMaterial,\n CardLighting,\n CARD_W,\n CARD_H,\n MAX_TILT,\n type CardEdition,\n} from \"./Card3D.js\";\nimport { type SpriteSheetType } from \"../sprites/spriteMapper.js\";\n\n// Frame-rate independent ease: how fast a value chases its target each frame.\nconst ease = (delta: number, rate = 10) => 1 - Math.exp(-rate * delta);\n// How far the card lifts toward the camera while held (world units).\nconst LIFT_Z = 0.6;\n\ninterface DraggableCardProps {\n itemName: string;\n fallbackSheet: SpriteSheetType;\n edition: CardEdition;\n homeX: number;\n dragging: boolean;\n onPick: () => void;\n onRelease: () => void;\n}\n\n/**\n * One Balatro card on the felt. At rest it sits in its slot and leans toward the\n * pointer on hover; picked up, it lifts toward the camera and chases the pointer\n * in world space, dropping back to its slot on release. Catches the light per\n * edition. All the motion is on the GPU per-frame — the reason for r3f.\n */\nfunction DraggableCard({\n itemName,\n fallbackSheet,\n edition,\n homeX,\n dragging,\n onPick,\n onRelease,\n}: DraggableCardProps) {\n const texture = useSpriteTexture(itemName, fallbackSheet);\n const meshRef = React.useRef<THREE.Mesh>(null);\n const [hovered, setHovered] = React.useState(false);\n const { camera } = useThree();\n\n // Scratch vector reused every frame so the drag loop allocates nothing.\n const scratch = React.useMemo(() => new THREE.Vector3(), []);\n\n useFrame((state, delta) => {\n const mesh = meshRef.current;\n if (!mesh) return;\n const k = ease(delta);\n\n if (dragging) {\n // Unproject the pointer (NDC) onto the lifted z-plane and chase it.\n scratch.set(state.pointer.x, state.pointer.y, 0.5).unproject(camera);\n scratch.sub(camera.position).normalize();\n const dist = (LIFT_Z - camera.position.z) / scratch.z;\n const px = camera.position.x + scratch.x * dist;\n const py = camera.position.y + scratch.y * dist;\n mesh.position.x += (px - mesh.position.x) * k;\n mesh.position.y += (py - mesh.position.y) * k;\n mesh.position.z += (LIFT_Z - mesh.position.z) * k;\n tiltTo(mesh, state.pointer.x * MAX_TILT, -state.pointer.y * MAX_TILT, k);\n scaleTo(mesh, 1.18, k);\n } else {\n // Settle back into the slot; lean toward the pointer only while hovered.\n mesh.position.x += (homeX - mesh.position.x) * k;\n mesh.position.y += (0 - mesh.position.y) * k;\n mesh.position.z += (0 - mesh.position.z) * k;\n const ty = hovered ? state.pointer.x * MAX_TILT : 0;\n const tx = hovered ? -state.pointer.y * MAX_TILT : 0;\n tiltTo(mesh, ty, tx, k);\n scaleTo(mesh, hovered ? 1.12 : 1, k);\n }\n });\n\n return (\n <mesh\n ref={meshRef}\n position={[homeX, 0, 0]}\n onPointerOver={(e: ThreeEvent<PointerEvent>) => {\n e.stopPropagation();\n setHovered(true);\n }}\n onPointerOut={() => setHovered(false)}\n onPointerDown={(e: ThreeEvent<PointerEvent>) => {\n e.stopPropagation();\n onPick();\n }}\n onPointerUp={() => onRelease()}\n >\n <planeGeometry args={[CARD_W, CARD_H]} />\n <EditionCardMaterial texture={texture} edition={edition} />\n </mesh>\n );\n}\n\nfunction tiltTo(mesh: THREE.Mesh, targetY: number, targetX: number, k: number) {\n mesh.rotation.y += (targetY - mesh.rotation.y) * k;\n mesh.rotation.x += (targetX - mesh.rotation.x) * k;\n}\n\nfunction scaleTo(mesh: THREE.Mesh, target: number, k: number) {\n mesh.scale.x += (target - mesh.scale.x) * k;\n mesh.scale.y += (target - mesh.scale.y) * k;\n mesh.scale.z += (target - mesh.scale.z) * k;\n}\n\nexport interface CardTableItem {\n /** Item name — e.g. \"Blueprint\". Resolved against jaml-ui sprite metadata. */\n itemName: string;\n /** Sheet to fall back to when the name doesn't resolve. Default \"Jokers\". */\n fallbackSheet?: SpriteSheetType;\n /** Finish — \"base\" | \"foil\" | \"holo\" | \"polychrome\". Default \"base\". */\n edition?: CardEdition;\n}\n\nexport interface CardTableProps {\n /** The cards to lay out in a row, left to right. */\n items: CardTableItem[];\n /** Pixel height of the canvas. Default 320. */\n height?: number | string;\n /** World-space distance between card centers. Default 1.25. */\n gap?: number;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * A row of floating, grabbable 3D Balatro cards in a single Canvas — the shop,\n * not a swatch. Hover to lean a card toward the pointer; press to lift it off\n * the felt and drag it; release to drop it back into its slot. Foil/holo cards\n * catch and throw the light as they move.\n *\n * ```tsx\n * import { CardTable } from \"jaml-ui/r3f\";\n * <CardTable items={[{ itemName: \"Blueprint\", edition: \"holo\" }]} />\n * ```\n *\n * Peer deps: `three`, `@react-three/fiber`, `@react-three/drei`.\n */\nexport function CardTable({\n items,\n height = 320,\n gap = 1.25,\n className,\n style,\n}: CardTableProps) {\n const [dragging, setDragging] = React.useState<number | null>(null);\n const release = React.useCallback(() => setDragging(null), []);\n const n = items.length;\n\n return (\n <div className={className} style={{ width: \"100%\", height, ...style }}>\n <Canvas\n camera={{ position: [0, 0, 3], fov: 40 }}\n gl={{ alpha: true }}\n dpr={[1, 2]}\n onPointerMissed={release}\n >\n <CardLighting />\n <React.Suspense fallback={null}>\n {items.map((item, i) => (\n <DraggableCard\n key={`${item.itemName}-${i}`}\n itemName={item.itemName}\n fallbackSheet={item.fallbackSheet ?? \"Jokers\"}\n edition={item.edition ?? \"base\"}\n homeX={(i - (n - 1) / 2) * gap}\n dragging={dragging === i}\n onPick={() => setDragging(i)}\n onRelease={release}\n />\n ))}\n </React.Suspense>\n </Canvas>\n </div>\n );\n}\n"],"mappings":"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"}