jaml-ui 0.14.1 → 0.14.3
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/components/AnalyzerExplorer.js +0 -11
- package/dist/components/JamlAestheticSelector.js +1 -3
- package/dist/components/JamlAnalyzerFullscreen.js +3 -3
- package/dist/components/JamlIde.js +0 -2
- package/dist/components/JamlSeedInput.js +1 -2
- package/dist/components/JamlSpeedometer.js +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/ui/codeBlock.js +1 -1
- package/dist/ui/jimboCopyRow.js +1 -2
- package/dist/ui/jimboFilterBar.js +2 -4
- package/dist/ui/showcase.js +4 -4
- package/package.json +5 -3
- package/dist/components/PlayingCard.d.ts +0 -18
- package/dist/components/PlayingCard.js +0 -80
- package/dist/data/balatro-jokers.json +0 -1241
- package/dist/r3f/BalatroJokerMesh3D.d.ts +0 -8
- package/dist/r3f/BalatroJokerMesh3D.js +0 -98
- package/dist/r3f/BalatroJokerPreview3D.d.ts +0 -14
- package/dist/r3f/BalatroJokerPreview3D.js +0 -30
- package/dist/r3f/BalatroPlayingCard3D.d.ts +0 -22
- package/dist/r3f/BalatroPlayingCard3D.js +0 -62
- package/dist/r3f/cardConstants.d.ts +0 -16
- package/dist/r3f/cardConstants.js +0 -14
- package/dist/r3f/compositedAtlas.d.ts +0 -5
- package/dist/r3f/compositedAtlas.js +0 -56
- package/dist/r3f/gridUV.d.ts +0 -22
- package/dist/r3f/gridUV.js +0 -30
- package/dist/r3f/index.d.ts +0 -12
- package/dist/r3f/index.js +0 -13
- package/dist/r3f/jokerRegistry.d.ts +0 -28
- package/dist/r3f/jokerRegistry.js +0 -40
- package/dist/r3f/jokerTilt.d.ts +0 -8
- package/dist/r3f/jokerTilt.js +0 -41
- package/dist/r3f/magneticTilt.d.ts +0 -18
- package/dist/r3f/magneticTilt.js +0 -34
- package/dist/r3f/playingCardTypes.d.ts +0 -24
- package/dist/r3f/playingCardTypes.js +0 -32
- package/dist/r3f/playingCardVisuals.d.ts +0 -7
- package/dist/r3f/playingCardVisuals.js +0 -45
- package/dist/r3f/usePlayingCardTexture.d.ts +0 -7
- package/dist/r3f/usePlayingCardTexture.js +0 -92
- package/dist/utils/fileSystem.d.ts +0 -1
- package/dist/utils/fileSystem.js +0 -23
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export interface BalatroJokerMesh3DProps {
|
|
2
|
-
displayName: string;
|
|
3
|
-
onAtlasOk?: () => void;
|
|
4
|
-
onAtlasMissing?: () => void;
|
|
5
|
-
/** Override joker sheet URL (default: resolveJamlAssetUrl("jokers")). */
|
|
6
|
-
jokersImageUrl?: string;
|
|
7
|
-
}
|
|
8
|
-
export declare function BalatroJokerMesh3D({ displayName, onAtlasOk, onAtlasMissing, jokersImageUrl, }: BalatroJokerMesh3DProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
-
import { useFrame } from "@react-three/fiber";
|
|
5
|
-
import * as THREE from "three";
|
|
6
|
-
import { applyBalatroGridUV, getLoadedTexturePixelSize } from "./gridUV.js";
|
|
7
|
-
import { findJokerByDisplayName, getJokerAtlasGridSize, getJokerAtlasImageUrl, } from "./jokerRegistry.js";
|
|
8
|
-
import { createZeroMagneticTarget, resetMagneticTarget } from "./magneticTilt.js";
|
|
9
|
-
import { jokerAmbientTiltAtTime, jokerPointerTiltFromUv, JOKER_TILT_LERP_IN, JOKER_TILT_LERP_OUT, stableIdFraction, } from "./jokerTilt.js";
|
|
10
|
-
export function BalatroJokerMesh3D({ displayName, onAtlasOk, onAtlasMissing, jokersImageUrl, }) {
|
|
11
|
-
const center = useMemo(() => findJokerByDisplayName(displayName), [displayName]);
|
|
12
|
-
const grid = useMemo(() => getJokerAtlasGridSize(), []);
|
|
13
|
-
const atlasUrl = jokersImageUrl ?? getJokerAtlasImageUrl();
|
|
14
|
-
const tiltGroupRef = useRef(null);
|
|
15
|
-
const magneticTarget = useRef(createZeroMagneticTarget());
|
|
16
|
-
const [map, setMap] = useState(null);
|
|
17
|
-
const [hovered, setHovered] = useState(false);
|
|
18
|
-
const loadSerial = useRef(0);
|
|
19
|
-
const idFrac = useMemo(() => stableIdFraction(displayName), [displayName]);
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
if (!center)
|
|
22
|
-
return;
|
|
23
|
-
const serial = ++loadSerial.current;
|
|
24
|
-
let cancelled = false;
|
|
25
|
-
let loadedTex = null;
|
|
26
|
-
const loader = new THREE.TextureLoader();
|
|
27
|
-
loader.load(atlasUrl, (tex) => {
|
|
28
|
-
if (cancelled || serial !== loadSerial.current) {
|
|
29
|
-
tex.dispose();
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
loadedTex = tex;
|
|
33
|
-
tex.colorSpace = THREE.SRGBColorSpace;
|
|
34
|
-
tex.magFilter = THREE.NearestFilter;
|
|
35
|
-
tex.minFilter = THREE.NearestFilter;
|
|
36
|
-
const { width: tw, height: th } = getLoadedTexturePixelSize(tex.image);
|
|
37
|
-
const cellW = tw / grid.cols;
|
|
38
|
-
const cellH = th / grid.rows;
|
|
39
|
-
applyBalatroGridUV(tex, center.pos, {
|
|
40
|
-
cellW,
|
|
41
|
-
cellH,
|
|
42
|
-
textureWidth: tw,
|
|
43
|
-
textureHeight: th,
|
|
44
|
-
});
|
|
45
|
-
setMap(tex);
|
|
46
|
-
onAtlasOk?.();
|
|
47
|
-
}, undefined, () => {
|
|
48
|
-
if (!cancelled && serial === loadSerial.current) {
|
|
49
|
-
setMap(null);
|
|
50
|
-
onAtlasMissing?.();
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
return () => {
|
|
54
|
-
cancelled = true;
|
|
55
|
-
loadedTex?.dispose();
|
|
56
|
-
setMap(null);
|
|
57
|
-
};
|
|
58
|
-
}, [center, displayName, grid.cols, grid.rows, atlasUrl, onAtlasMissing, onAtlasOk]);
|
|
59
|
-
useFrame((state, dt) => {
|
|
60
|
-
const g = tiltGroupRef.current;
|
|
61
|
-
if (!g)
|
|
62
|
-
return;
|
|
63
|
-
if (!hovered) {
|
|
64
|
-
jokerAmbientTiltAtTime(state.clock.elapsedTime, idFrac, magneticTarget.current);
|
|
65
|
-
}
|
|
66
|
-
const tr = magneticTarget.current;
|
|
67
|
-
const a = 1 - Math.exp(-(hovered ? JOKER_TILT_LERP_IN : JOKER_TILT_LERP_OUT) * dt);
|
|
68
|
-
g.rotation.x = THREE.MathUtils.lerp(g.rotation.x, tr.rx, a);
|
|
69
|
-
g.rotation.y = THREE.MathUtils.lerp(g.rotation.y, tr.ry, a);
|
|
70
|
-
g.rotation.z = THREE.MathUtils.lerp(g.rotation.z, tr.rz, a);
|
|
71
|
-
g.position.x = THREE.MathUtils.lerp(g.position.x, tr.ox, a);
|
|
72
|
-
g.position.y = THREE.MathUtils.lerp(g.position.y, tr.oy, a);
|
|
73
|
-
});
|
|
74
|
-
if (!center || !map)
|
|
75
|
-
return null;
|
|
76
|
-
const { width: tw, height: th } = getLoadedTexturePixelSize(map.image);
|
|
77
|
-
const cellW = tw / grid.cols;
|
|
78
|
-
const cellH = th / grid.rows;
|
|
79
|
-
const aspect = cellW / cellH;
|
|
80
|
-
const h = 2.4;
|
|
81
|
-
const w = aspect * h;
|
|
82
|
-
return (_jsx("group", { ref: tiltGroupRef, children: _jsxs("mesh", { onPointerMove: (e) => {
|
|
83
|
-
e.stopPropagation();
|
|
84
|
-
const uv = e.uv;
|
|
85
|
-
if (!uv)
|
|
86
|
-
return;
|
|
87
|
-
jokerPointerTiltFromUv(uv, magneticTarget.current);
|
|
88
|
-
}, onPointerEnter: (e) => {
|
|
89
|
-
e.stopPropagation();
|
|
90
|
-
setHovered(true);
|
|
91
|
-
document.body.style.cursor = "pointer";
|
|
92
|
-
}, onPointerLeave: (e) => {
|
|
93
|
-
e.stopPropagation();
|
|
94
|
-
setHovered(false);
|
|
95
|
-
resetMagneticTarget(magneticTarget.current);
|
|
96
|
-
document.body.style.cursor = "auto";
|
|
97
|
-
}, children: [_jsx("planeGeometry", { args: [w, h] }), _jsx("meshBasicMaterial", { map: map, transparent: true, toneMapped: false })] }) }));
|
|
98
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { CSSProperties } from "react";
|
|
2
|
-
export interface BalatroJokerPreview3DProps {
|
|
3
|
-
displayName: string;
|
|
4
|
-
className?: string;
|
|
5
|
-
style?: CSSProperties;
|
|
6
|
-
canvasHeight?: number;
|
|
7
|
-
jokersImageUrl?: string;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Self-contained Canvas + joker plane with magnetic tilt (for classifier / tool previews).
|
|
11
|
-
*/
|
|
12
|
-
export declare function BalatroJokerPreview3D({ displayName, className, style, canvasHeight, jokersImageUrl, }: BalatroJokerPreview3DProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
-
/** @deprecated Use {@link BalatroJokerPreview3D}; kept for existing imports. */
|
|
14
|
-
export declare const BalatroJokerThreePreview: typeof BalatroJokerPreview3D;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { Canvas } from "@react-three/fiber";
|
|
4
|
-
import { Suspense, useMemo, useState } from "react";
|
|
5
|
-
import { findJokerByDisplayName, getJokerAtlasGridSize } from "./jokerRegistry.js";
|
|
6
|
-
import { BalatroJokerMesh3D } from "./BalatroJokerMesh3D.js";
|
|
7
|
-
/**
|
|
8
|
-
* Self-contained Canvas + joker plane with magnetic tilt (for classifier / tool previews).
|
|
9
|
-
*/
|
|
10
|
-
export function BalatroJokerPreview3D({ displayName, className, style, canvasHeight = 272, jokersImageUrl, }) {
|
|
11
|
-
const center = useMemo(() => findJokerByDisplayName(displayName), [displayName]);
|
|
12
|
-
const grid = useMemo(() => getJokerAtlasGridSize(), []);
|
|
13
|
-
const [atlasMissing, setAtlasMissing] = useState(false);
|
|
14
|
-
const onOk = useMemo(() => () => setAtlasMissing(false), []);
|
|
15
|
-
const onMissing = useMemo(() => () => setAtlasMissing(true), []);
|
|
16
|
-
if (!center) {
|
|
17
|
-
return (_jsx("div", { className: className, style: style, children: _jsxs("div", { style: { color: "#555", fontSize: 11, padding: 8 }, children: ["No P_CENTERS match for \u201C", displayName, "\u201D. Align the row name with the in-game joker name or add an alias in jaml-ui joker registry data."] }) }));
|
|
18
|
-
}
|
|
19
|
-
return (_jsxs("div", { className: className, style: style, children: [_jsx("div", { style: {
|
|
20
|
-
width: "100%",
|
|
21
|
-
height: 300,
|
|
22
|
-
padding: "14px 20px",
|
|
23
|
-
boxSizing: "border-box",
|
|
24
|
-
borderRadius: 6,
|
|
25
|
-
overflow: "visible",
|
|
26
|
-
background: "#0a0a0a",
|
|
27
|
-
}, children: _jsxs(Canvas, { camera: { position: [0, 0, 3.2], fov: 45 }, gl: { alpha: true, antialias: true }, style: { width: "100%", height: canvasHeight, touchAction: "none", display: "block" }, children: [_jsx("ambientLight", { intensity: 0.6 }), _jsx(Suspense, { fallback: null, children: _jsx(BalatroJokerMesh3D, { displayName: displayName, onAtlasOk: onOk, onAtlasMissing: onMissing, jokersImageUrl: jokersImageUrl }) })] }) }), atlasMissing ? (_jsxs("div", { style: { color: "#886644", fontSize: 11, lineHeight: 1.45, marginTop: 8 }, children: ["Add ", _jsx("strong", { children: "Jokers.png" }), " to your public assets or call", " ", _jsx("code", { style: { color: "#aaa" }, children: "setJamlAssetBaseUrl" }), " so", " ", _jsx("code", { style: { color: "#aaa" }, children: "resolveJamlAssetUrl(\"jokers\")" }), " loads. Key", " ", _jsx("code", { style: { color: "#aaa" }, children: center.key }), " \u2192 grid (", center.pos.x, ",", center.pos.y, "); sheet grid ", grid.cols, "\u00D7", grid.rows, "."] })) : null, _jsxs("p", { style: { fontSize: 10, color: "#444", marginTop: 8, marginBottom: 0 }, children: ["UVs from bundled ", _jsx("code", { style: { color: "#555" }, children: "balatro-jokers.json" }), " (grid cells) \u00B7 magnetic tilt approximates Balatro card/sprite hover behavior."] })] }));
|
|
28
|
-
}
|
|
29
|
-
/** @deprecated Use {@link BalatroJokerPreview3D}; kept for existing imports. */
|
|
30
|
-
export const BalatroJokerThreePreview = BalatroJokerPreview3D;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { type CardBoxOptions, type CardMagnetOptions } from "./cardConstants.js";
|
|
2
|
-
import type { PlayingCard3DModel } from "./playingCardTypes.js";
|
|
3
|
-
export interface BalatroPlayingCard3DProps {
|
|
4
|
-
card: PlayingCard3DModel;
|
|
5
|
-
position?: [number, number, number];
|
|
6
|
-
rotation?: [number, number, number];
|
|
7
|
-
selected?: boolean;
|
|
8
|
-
highlighted?: boolean;
|
|
9
|
-
onClick?: () => void;
|
|
10
|
-
onPointerEnter?: () => void;
|
|
11
|
-
onPointerLeave?: () => void;
|
|
12
|
-
/** Reserved for future flip animation */
|
|
13
|
-
faceDown?: boolean;
|
|
14
|
-
magnet?: CardMagnetOptions;
|
|
15
|
-
box?: CardBoxOptions;
|
|
16
|
-
/** Extra idle phase for subtle sway (e.g. hand index). */
|
|
17
|
-
idlePhase?: number;
|
|
18
|
-
deckUrl?: string;
|
|
19
|
-
enhancersUrl?: string;
|
|
20
|
-
}
|
|
21
|
-
export declare const BalatroPlayingCard3D: import("react").NamedExoticComponent<BalatroPlayingCard3DProps>;
|
|
22
|
-
export default BalatroPlayingCard3D;
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { memo, useMemo, useRef, useState } from "react";
|
|
4
|
-
import { useFrame } from "@react-three/fiber";
|
|
5
|
-
import { useSpring, animated } from "@react-spring/three";
|
|
6
|
-
import { DEFAULT_CARD_BOX, DEFAULT_CARD_MAGNET } from "./cardConstants.js";
|
|
7
|
-
import { createZeroMagneticTarget, lerpMagneticGroup, magneticTargetFromUvPlayingCard, resetMagneticTarget, } from "./magneticTilt.js";
|
|
8
|
-
import { editionMaterialProps, enhancementGlowHex, sealColorHex } from "./playingCardVisuals.js";
|
|
9
|
-
import { useCardBackTexture, usePlayingCardFaceTexture } from "./usePlayingCardTexture.js";
|
|
10
|
-
export const BalatroPlayingCard3D = memo(function BalatroPlayingCard3D({ card, position = [0, 0, 0], rotation = [0, 0, 0], selected = false, highlighted = false, onClick, onPointerEnter, onPointerLeave, faceDown: _faceDown = false, magnet: magnetOverrides, box: boxOverrides, idlePhase = 0, deckUrl, enhancersUrl, }) {
|
|
11
|
-
const magnet = { ...DEFAULT_CARD_MAGNET, ...magnetOverrides };
|
|
12
|
-
const box = { ...DEFAULT_CARD_BOX, ...boxOverrides };
|
|
13
|
-
const tiltGroupRef = useRef(null);
|
|
14
|
-
const magneticTarget = useRef(createZeroMagneticTarget());
|
|
15
|
-
const [hovered, setHovered] = useState(false);
|
|
16
|
-
const cardTexture = usePlayingCardFaceTexture(card.suit, card.rank, { deckUrl, enhancersUrl });
|
|
17
|
-
const backTexture = useCardBackTexture();
|
|
18
|
-
const { posY, scale, glowIntensity } = useSpring({
|
|
19
|
-
posY: selected ? 0.3 : hovered ? 0.15 : 0,
|
|
20
|
-
scale: hovered ? 1.08 : selected ? 1.05 : 1,
|
|
21
|
-
glowIntensity: highlighted ? 1 : hovered ? 0.5 : 0,
|
|
22
|
-
config: { tension: 300, friction: 20 },
|
|
23
|
-
});
|
|
24
|
-
useFrame((state, dt) => {
|
|
25
|
-
const g = tiltGroupRef.current;
|
|
26
|
-
if (!g)
|
|
27
|
-
return;
|
|
28
|
-
const idleZ = Math.sin(state.clock.elapsedTime * 0.55 + position[0] * 2.1 + idlePhase) * 0.018;
|
|
29
|
-
lerpMagneticGroup(g, magneticTarget.current, dt, magnet.LERP_IN, magnet.LERP_OUT, hovered, idleZ);
|
|
30
|
-
});
|
|
31
|
-
const editionProps = useMemo(() => editionMaterialProps(card.edition), [card.edition]);
|
|
32
|
-
const enhancementColor = useMemo(() => enhancementGlowHex(card, highlighted), [card, highlighted]);
|
|
33
|
-
const onCardPointerMove = (e) => {
|
|
34
|
-
e.stopPropagation();
|
|
35
|
-
const uv = e.uv;
|
|
36
|
-
if (!uv)
|
|
37
|
-
return;
|
|
38
|
-
Object.assign(magneticTarget.current, magneticTargetFromUvPlayingCard(uv, magnet));
|
|
39
|
-
};
|
|
40
|
-
const onLeave = (e) => {
|
|
41
|
-
e.stopPropagation();
|
|
42
|
-
setHovered(false);
|
|
43
|
-
resetMagneticTarget(magneticTarget.current);
|
|
44
|
-
onPointerLeave?.();
|
|
45
|
-
document.body.style.cursor = "auto";
|
|
46
|
-
};
|
|
47
|
-
if (!cardTexture)
|
|
48
|
-
return null;
|
|
49
|
-
return (_jsx(animated.group, { "position-x": position[0], "position-y": posY.to((y) => position[1] + y), "position-z": position[2], "rotation-x": rotation[0], "rotation-y": rotation[1], "rotation-z": rotation[2], scale: scale, children: _jsxs("group", { ref: tiltGroupRef, children: [_jsx(animated.pointLight, { color: enhancementColor, intensity: glowIntensity.to((i) => i * 2), distance: 1, position: [0, 0, 0.1] }), _jsxs("mesh", { onClick: (e) => {
|
|
50
|
-
e.stopPropagation();
|
|
51
|
-
const hit = e.intersections[0];
|
|
52
|
-
if (!hit || hit.object !== e.object)
|
|
53
|
-
return;
|
|
54
|
-
onClick?.();
|
|
55
|
-
}, onPointerMove: onCardPointerMove, onPointerEnter: (e) => {
|
|
56
|
-
e.stopPropagation();
|
|
57
|
-
setHovered(true);
|
|
58
|
-
onPointerEnter?.();
|
|
59
|
-
document.body.style.cursor = "pointer";
|
|
60
|
-
}, onPointerLeave: onLeave, castShadow: true, receiveShadow: true, children: [_jsx("boxGeometry", { args: [box.WIDTH, box.HEIGHT, box.DEPTH] }), _jsx("meshBasicMaterial", { attach: "material-4", map: cardTexture, toneMapped: false }), _jsx("meshStandardMaterial", { attach: "material-5", map: backTexture, ...editionProps }), _jsx("meshStandardMaterial", { attach: "material-0", color: "#f5f5dc" }), _jsx("meshStandardMaterial", { attach: "material-1", color: "#f5f5dc" }), _jsx("meshStandardMaterial", { attach: "material-2", color: "#f5f5dc" }), _jsx("meshStandardMaterial", { attach: "material-3", color: "#f5f5dc" })] }), selected ? (_jsxs("mesh", { position: [0, 0, -box.DEPTH], children: [_jsx("ringGeometry", { args: [0.45, 0.5, 32] }), _jsx("meshBasicMaterial", { color: "#f1c40f", transparent: true, opacity: 0.8 })] })) : null, card.enhancement ? (_jsxs("mesh", { position: [box.WIDTH / 2 - 0.1, box.HEIGHT / 2 - 0.1, box.DEPTH + 0.01], children: [_jsx("circleGeometry", { args: [0.08, 16] }), _jsx("meshBasicMaterial", { color: enhancementColor })] })) : null, card.seal ? (_jsxs("mesh", { position: [-box.WIDTH / 2 + 0.1, -box.HEIGHT / 2 + 0.1, box.DEPTH + 0.01], children: [_jsx("circleGeometry", { args: [0.06, 6] }), _jsx("meshBasicMaterial", { color: sealColorHex(card.seal) })] })) : null] }) }));
|
|
61
|
-
});
|
|
62
|
-
export default BalatroPlayingCard3D;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/** Default magnetic tilt / parallax matching Balatro-style card hover. */
|
|
2
|
-
export declare const DEFAULT_CARD_MAGNET: {
|
|
3
|
-
readonly MAX_TILT_X: 0.36;
|
|
4
|
-
readonly MAX_TILT_Y: 0.42;
|
|
5
|
-
readonly MAX_SHIFT: 0.038;
|
|
6
|
-
readonly TWIST_Z: 0.11;
|
|
7
|
-
readonly LERP_IN: 18;
|
|
8
|
-
readonly LERP_OUT: 10;
|
|
9
|
-
};
|
|
10
|
-
export type CardMagnetOptions = Partial<typeof DEFAULT_CARD_MAGNET>;
|
|
11
|
-
export declare const DEFAULT_CARD_BOX: {
|
|
12
|
-
readonly WIDTH: 0.7;
|
|
13
|
-
readonly HEIGHT: 0.95;
|
|
14
|
-
readonly DEPTH: 0.02;
|
|
15
|
-
};
|
|
16
|
-
export type CardBoxOptions = Partial<typeof DEFAULT_CARD_BOX>;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/** Default magnetic tilt / parallax matching Balatro-style card hover. */
|
|
2
|
-
export const DEFAULT_CARD_MAGNET = {
|
|
3
|
-
MAX_TILT_X: 0.36,
|
|
4
|
-
MAX_TILT_Y: 0.42,
|
|
5
|
-
MAX_SHIFT: 0.038,
|
|
6
|
-
TWIST_Z: 0.11,
|
|
7
|
-
LERP_IN: 18,
|
|
8
|
-
LERP_OUT: 10,
|
|
9
|
-
};
|
|
10
|
-
export const DEFAULT_CARD_BOX = {
|
|
11
|
-
WIDTH: 0.7,
|
|
12
|
-
HEIGHT: 0.95,
|
|
13
|
-
DEPTH: 0.02,
|
|
14
|
-
};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Composite transparent 8Bit deck pips onto Enhancers card fronts (per-cell).
|
|
3
|
-
* Output canvas matches atlas pixel size so UV math is unchanged.
|
|
4
|
-
*/
|
|
5
|
-
export declare function loadCompositedPlayingAtlas(atlasUrl: string, cols: number, rows: number, enhancersUrl?: string): Promise<HTMLCanvasElement>;
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Composite transparent 8Bit deck pips onto Enhancers card fronts (per-cell).
|
|
3
|
-
* Output canvas matches atlas pixel size so UV math is unchanged.
|
|
4
|
-
*/
|
|
5
|
-
import { resolveJamlAssetUrl } from "../assets.js";
|
|
6
|
-
const CELL_W = 71;
|
|
7
|
-
const CELL_H = 95;
|
|
8
|
-
const DEFAULT_BASE_POS = { x: 1, y: 0 };
|
|
9
|
-
const cache = new Map();
|
|
10
|
-
const pending = new Map();
|
|
11
|
-
function loadImage(src) {
|
|
12
|
-
return new Promise((resolve, reject) => {
|
|
13
|
-
const img = new Image();
|
|
14
|
-
img.crossOrigin = "anonymous";
|
|
15
|
-
img.onload = () => resolve(img);
|
|
16
|
-
img.onerror = reject;
|
|
17
|
-
img.src = src;
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
export function loadCompositedPlayingAtlas(atlasUrl, cols, rows, enhancersUrl) {
|
|
21
|
-
const enh = enhancersUrl ?? resolveJamlAssetUrl("enhancers");
|
|
22
|
-
const cacheKey = `${atlasUrl}|${enh}|${cols}x${rows}`;
|
|
23
|
-
const cached = cache.get(cacheKey);
|
|
24
|
-
if (cached)
|
|
25
|
-
return Promise.resolve(cached);
|
|
26
|
-
const inflight = pending.get(cacheKey);
|
|
27
|
-
if (inflight)
|
|
28
|
-
return inflight;
|
|
29
|
-
const promise = (async () => {
|
|
30
|
-
const [atlasImg, enhancersImg] = await Promise.all([
|
|
31
|
-
loadImage(atlasUrl),
|
|
32
|
-
loadImage(enh),
|
|
33
|
-
]);
|
|
34
|
-
const canvas = document.createElement("canvas");
|
|
35
|
-
canvas.width = atlasImg.naturalWidth;
|
|
36
|
-
canvas.height = atlasImg.naturalHeight;
|
|
37
|
-
const ctx = canvas.getContext("2d");
|
|
38
|
-
if (!ctx)
|
|
39
|
-
throw new Error("2d context unavailable");
|
|
40
|
-
const baseSx = DEFAULT_BASE_POS.x * CELL_W;
|
|
41
|
-
const baseSy = DEFAULT_BASE_POS.y * CELL_H;
|
|
42
|
-
for (let row = 0; row < rows; row++) {
|
|
43
|
-
for (let col = 0; col < cols; col++) {
|
|
44
|
-
const dx = col * CELL_W;
|
|
45
|
-
const dy = row * CELL_H;
|
|
46
|
-
ctx.drawImage(enhancersImg, baseSx, baseSy, CELL_W, CELL_H, dx, dy, CELL_W, CELL_H);
|
|
47
|
-
ctx.drawImage(atlasImg, dx, dy, CELL_W, CELL_H, dx, dy, CELL_W, CELL_H);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
cache.set(cacheKey, canvas);
|
|
51
|
-
pending.delete(cacheKey);
|
|
52
|
-
return canvas;
|
|
53
|
-
})();
|
|
54
|
-
pending.set(cacheKey, promise);
|
|
55
|
-
return promise;
|
|
56
|
-
}
|
package/dist/r3f/gridUV.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import * as THREE from "three";
|
|
2
|
-
export type GridPos = {
|
|
3
|
-
x: number;
|
|
4
|
-
y: number;
|
|
5
|
-
};
|
|
6
|
-
type TexImage = THREE.Texture["image"];
|
|
7
|
-
/** Pixel size of a loaded texture (image, canvas, or ImageBitmap). */
|
|
8
|
-
export declare function getLoadedTexturePixelSize(image: TexImage): {
|
|
9
|
-
width: number;
|
|
10
|
-
height: number;
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Balatro / Love2D-style atlas: top-left origin, y grows downward.
|
|
14
|
-
* Maps one grid cell to UV repeat/offset on the full texture.
|
|
15
|
-
*/
|
|
16
|
-
export declare function applyBalatroGridUV(tex: THREE.Texture, pos: GridPos, opts: {
|
|
17
|
-
cellW: number;
|
|
18
|
-
cellH: number;
|
|
19
|
-
textureWidth: number;
|
|
20
|
-
textureHeight: number;
|
|
21
|
-
}): void;
|
|
22
|
-
export {};
|
package/dist/r3f/gridUV.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import * as THREE from "three";
|
|
2
|
-
/** Pixel size of a loaded texture (image, canvas, or ImageBitmap). */
|
|
3
|
-
export function getLoadedTexturePixelSize(image) {
|
|
4
|
-
if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement) {
|
|
5
|
-
return {
|
|
6
|
-
width: image.naturalWidth || image.width,
|
|
7
|
-
height: image.naturalHeight || image.height,
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
if (typeof HTMLCanvasElement !== "undefined" && image instanceof HTMLCanvasElement) {
|
|
11
|
-
return { width: image.width, height: image.height };
|
|
12
|
-
}
|
|
13
|
-
if (typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap) {
|
|
14
|
-
return { width: image.width, height: image.height };
|
|
15
|
-
}
|
|
16
|
-
return { width: 0, height: 0 };
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Balatro / Love2D-style atlas: top-left origin, y grows downward.
|
|
20
|
-
* Maps one grid cell to UV repeat/offset on the full texture.
|
|
21
|
-
*/
|
|
22
|
-
export function applyBalatroGridUV(tex, pos, opts) {
|
|
23
|
-
const cols = opts.textureWidth / opts.cellW;
|
|
24
|
-
const rows = opts.textureHeight / opts.cellH;
|
|
25
|
-
tex.wrapS = THREE.ClampToEdgeWrapping;
|
|
26
|
-
tex.wrapT = THREE.ClampToEdgeWrapping;
|
|
27
|
-
tex.repeat.set(1 / cols, 1 / rows);
|
|
28
|
-
tex.offset.set(pos.x / cols, 1 - (pos.y + 1) / rows);
|
|
29
|
-
tex.needsUpdate = true;
|
|
30
|
-
}
|
package/dist/r3f/index.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export { applyBalatroGridUV, getLoadedTexturePixelSize, type GridPos } from "./gridUV.js";
|
|
2
|
-
export { loadCompositedPlayingAtlas } from "./compositedAtlas.js";
|
|
3
|
-
export { BALATRO_JOKER_ATLAS_META, BALATRO_JOKERS, findJokerByDisplayName, findJokerByKey, getJokerAtlasGridSize, getJokerAtlasImageUrl, type BalatroJokerCenter, } from "./jokerRegistry.js";
|
|
4
|
-
export { DEFAULT_CARD_BOX, DEFAULT_CARD_MAGNET, type CardBoxOptions, type CardMagnetOptions, } from "./cardConstants.js";
|
|
5
|
-
export { magneticTargetFromUvPlayingCard, lerpMagneticGroup, createZeroMagneticTarget, resetMagneticTarget, type MagneticTarget, } from "./magneticTilt.js";
|
|
6
|
-
export { PLAYING_CARD_ATLAS, RANK_COLUMN, SUIT_COLORS, SUIT_ROW, type PlayingCard3DModel, type PlayingCardEdition, type PlayingCardEnhancement, type PlayingCardRank, type PlayingCardSeal, type PlayingCardSuit, } from "./playingCardTypes.js";
|
|
7
|
-
export { editionMaterialProps, enhancementGlowHex, sealColorHex } from "./playingCardVisuals.js";
|
|
8
|
-
export { usePlayingCardFaceTexture, useCardBackTexture } from "./usePlayingCardTexture.js";
|
|
9
|
-
export { BalatroPlayingCard3D, type BalatroPlayingCard3DProps } from "./BalatroPlayingCard3D.js";
|
|
10
|
-
export { BalatroJokerMesh3D, type BalatroJokerMesh3DProps } from "./BalatroJokerMesh3D.js";
|
|
11
|
-
export { BalatroJokerPreview3D, BalatroJokerThreePreview, type BalatroJokerPreview3DProps, } from "./BalatroJokerPreview3D.js";
|
|
12
|
-
export { jokerAmbientTiltAtTime, jokerPointerTiltFromUv, JOKER_TILT_LERP_IN, JOKER_TILT_LERP_OUT, stableIdFraction, } from "./jokerTilt.js";
|
package/dist/r3f/index.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
export { applyBalatroGridUV, getLoadedTexturePixelSize } from "./gridUV.js";
|
|
3
|
-
export { loadCompositedPlayingAtlas } from "./compositedAtlas.js";
|
|
4
|
-
export { BALATRO_JOKER_ATLAS_META, BALATRO_JOKERS, findJokerByDisplayName, findJokerByKey, getJokerAtlasGridSize, getJokerAtlasImageUrl, } from "./jokerRegistry.js";
|
|
5
|
-
export { DEFAULT_CARD_BOX, DEFAULT_CARD_MAGNET, } from "./cardConstants.js";
|
|
6
|
-
export { magneticTargetFromUvPlayingCard, lerpMagneticGroup, createZeroMagneticTarget, resetMagneticTarget, } from "./magneticTilt.js";
|
|
7
|
-
export { PLAYING_CARD_ATLAS, RANK_COLUMN, SUIT_COLORS, SUIT_ROW, } from "./playingCardTypes.js";
|
|
8
|
-
export { editionMaterialProps, enhancementGlowHex, sealColorHex } from "./playingCardVisuals.js";
|
|
9
|
-
export { usePlayingCardFaceTexture, useCardBackTexture } from "./usePlayingCardTexture.js";
|
|
10
|
-
export { BalatroPlayingCard3D } from "./BalatroPlayingCard3D.js";
|
|
11
|
-
export { BalatroJokerMesh3D } from "./BalatroJokerMesh3D.js";
|
|
12
|
-
export { BalatroJokerPreview3D, BalatroJokerThreePreview, } from "./BalatroJokerPreview3D.js";
|
|
13
|
-
export { jokerAmbientTiltAtTime, jokerPointerTiltFromUv, JOKER_TILT_LERP_IN, JOKER_TILT_LERP_OUT, stableIdFraction, } from "./jokerTilt.js";
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export type BalatroJokerCenter = {
|
|
2
|
-
key: string;
|
|
3
|
-
name: string;
|
|
4
|
-
pos: {
|
|
5
|
-
x: number;
|
|
6
|
-
y: number;
|
|
7
|
-
};
|
|
8
|
-
soulPos?: {
|
|
9
|
-
x: number;
|
|
10
|
-
y: number;
|
|
11
|
-
};
|
|
12
|
-
};
|
|
13
|
-
export declare const BALATRO_JOKER_ATLAS_META: {
|
|
14
|
-
publicPath: string;
|
|
15
|
-
cellPx: {
|
|
16
|
-
x: number;
|
|
17
|
-
y: number;
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
export declare const BALATRO_JOKERS: BalatroJokerCenter[];
|
|
21
|
-
/** Prefer bundled asset resolver so hosts can override base URL. */
|
|
22
|
-
export declare function getJokerAtlasImageUrl(): string;
|
|
23
|
-
export declare function getJokerAtlasGridSize(): {
|
|
24
|
-
cols: number;
|
|
25
|
-
rows: number;
|
|
26
|
-
};
|
|
27
|
-
export declare function findJokerByDisplayName(displayName: string): BalatroJokerCenter | undefined;
|
|
28
|
-
export declare function findJokerByKey(key: string): BalatroJokerCenter | undefined;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import jokersPayload from "../data/balatro-jokers.json";
|
|
2
|
-
import { resolveJamlAssetUrl } from "../assets.js";
|
|
3
|
-
const payload = jokersPayload;
|
|
4
|
-
export const BALATRO_JOKER_ATLAS_META = payload.atlas;
|
|
5
|
-
export const BALATRO_JOKERS = payload.jokers;
|
|
6
|
-
/** Prefer bundled asset resolver so hosts can override base URL. */
|
|
7
|
-
export function getJokerAtlasImageUrl() {
|
|
8
|
-
return resolveJamlAssetUrl("jokers");
|
|
9
|
-
}
|
|
10
|
-
export function getJokerAtlasGridSize() {
|
|
11
|
-
let mx = 0;
|
|
12
|
-
let my = 0;
|
|
13
|
-
for (const j of BALATRO_JOKERS) {
|
|
14
|
-
mx = Math.max(mx, j.pos.x);
|
|
15
|
-
my = Math.max(my, j.pos.y);
|
|
16
|
-
if (j.soulPos) {
|
|
17
|
-
mx = Math.max(mx, j.soulPos.x);
|
|
18
|
-
my = Math.max(my, j.soulPos.y);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return { cols: mx + 1, rows: my + 1 };
|
|
22
|
-
}
|
|
23
|
-
const NAME_ALIASES = {
|
|
24
|
-
canio: "Caino",
|
|
25
|
-
séance: "Seance",
|
|
26
|
-
seance: "Seance",
|
|
27
|
-
};
|
|
28
|
-
function normalizeLookup(name) {
|
|
29
|
-
const t = name.trim();
|
|
30
|
-
const alias = NAME_ALIASES[t.toLowerCase()];
|
|
31
|
-
return alias ?? t;
|
|
32
|
-
}
|
|
33
|
-
export function findJokerByDisplayName(displayName) {
|
|
34
|
-
const needle = normalizeLookup(displayName).toLowerCase();
|
|
35
|
-
return BALATRO_JOKERS.find((j) => j.name.toLowerCase() === needle);
|
|
36
|
-
}
|
|
37
|
-
export function findJokerByKey(key) {
|
|
38
|
-
const k = key.trim().toLowerCase();
|
|
39
|
-
return BALATRO_JOKERS.find((j) => j.key.toLowerCase() === k);
|
|
40
|
-
}
|
package/dist/r3f/jokerTilt.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import * as THREE from "three";
|
|
2
|
-
import type { MagneticTarget } from "./magneticTilt.js";
|
|
3
|
-
export declare const JOKER_TILT_LERP_IN = 20;
|
|
4
|
-
export declare const JOKER_TILT_LERP_OUT = 11;
|
|
5
|
-
export declare function stableIdFraction(s: string): number;
|
|
6
|
-
export declare function applyJokerTiltFromNormalized(nx: number, ny: number, amtScale: number, target: MagneticTarget): void;
|
|
7
|
-
export declare function jokerPointerTiltFromUv(uv: THREE.Vector2, target: MagneticTarget): void;
|
|
8
|
-
export declare function jokerAmbientTiltAtTime(t: number, idFrac: number, target: MagneticTarget): void;
|
package/dist/r3f/jokerTilt.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import * as THREE from "three";
|
|
2
|
-
const AMBIENT_TILT = 0.2;
|
|
3
|
-
const TILT_FACTOR = 0.3;
|
|
4
|
-
const MAGNET_MAX_RX = 0.34;
|
|
5
|
-
const MAGNET_MAX_RY = 0.4;
|
|
6
|
-
const MAGNET_MAX_SHIFT = 0.05;
|
|
7
|
-
const MAGNET_TWIST_Z = 0.1;
|
|
8
|
-
export const JOKER_TILT_LERP_IN = 20;
|
|
9
|
-
export const JOKER_TILT_LERP_OUT = 11;
|
|
10
|
-
export function stableIdFraction(s) {
|
|
11
|
-
let h = 2166136261;
|
|
12
|
-
for (let i = 0; i < s.length; i++) {
|
|
13
|
-
h ^= s.charCodeAt(i);
|
|
14
|
-
h = Math.imul(h, 16777619);
|
|
15
|
-
}
|
|
16
|
-
return ((h >>> 0) % 100000) / 100000;
|
|
17
|
-
}
|
|
18
|
-
export function applyJokerTiltFromNormalized(nx, ny, amtScale, target) {
|
|
19
|
-
const clampedX = THREE.MathUtils.clamp(nx, -1, 1);
|
|
20
|
-
const clampedY = THREE.MathUtils.clamp(ny, -1, 1);
|
|
21
|
-
target.ry = -clampedX * MAGNET_MAX_RY * amtScale;
|
|
22
|
-
target.rx = clampedY * MAGNET_MAX_RX * amtScale;
|
|
23
|
-
target.rz = -clampedX * clampedY * MAGNET_TWIST_Z * amtScale;
|
|
24
|
-
target.ox = clampedX * MAGNET_MAX_SHIFT * amtScale;
|
|
25
|
-
target.oy = -clampedY * MAGNET_MAX_SHIFT * 0.65 * amtScale;
|
|
26
|
-
}
|
|
27
|
-
export function jokerPointerTiltFromUv(uv, target) {
|
|
28
|
-
const nx = (uv.x - 0.5) * 2;
|
|
29
|
-
const ny = (uv.y - 0.5) * 2;
|
|
30
|
-
const amt = Math.abs(ny + nx - 1) * TILT_FACTOR;
|
|
31
|
-
applyJokerTiltFromNormalized(nx, ny, THREE.MathUtils.clamp(amt * 1.15, 0.35, 1.25), target);
|
|
32
|
-
}
|
|
33
|
-
export function jokerAmbientTiltAtTime(t, idFrac, target) {
|
|
34
|
-
const tiltAngle = t * (1.56 + ((idFrac / 1.14212) % 1)) + idFrac / 1.35122;
|
|
35
|
-
const nu = 0.5 + 0.5 * AMBIENT_TILT * Math.cos(tiltAngle);
|
|
36
|
-
const nv = 0.5 + 0.5 * AMBIENT_TILT * Math.sin(tiltAngle);
|
|
37
|
-
const nx = (nu - 0.5) * 2;
|
|
38
|
-
const ny = (nv - 0.5) * 2;
|
|
39
|
-
const amt = AMBIENT_TILT * (0.5 + Math.cos(tiltAngle)) * TILT_FACTOR;
|
|
40
|
-
applyJokerTiltFromNormalized(nx, ny, THREE.MathUtils.clamp(amt * 2.2, 0.2, 1), target);
|
|
41
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import * as THREE from "three";
|
|
2
|
-
export type MagneticTarget = {
|
|
3
|
-
rx: number;
|
|
4
|
-
ry: number;
|
|
5
|
-
rz: number;
|
|
6
|
-
ox: number;
|
|
7
|
-
oy: number;
|
|
8
|
-
};
|
|
9
|
-
export declare function createZeroMagneticTarget(): MagneticTarget;
|
|
10
|
-
/** Map pointer UV on card face to rotation + in-plane shift (Balatro-style). */
|
|
11
|
-
export declare function magneticTargetFromUvPlayingCard(uv: THREE.Vector2, magnet: {
|
|
12
|
-
MAX_TILT_X: number;
|
|
13
|
-
MAX_TILT_Y: number;
|
|
14
|
-
MAX_SHIFT: number;
|
|
15
|
-
TWIST_Z: number;
|
|
16
|
-
}): MagneticTarget;
|
|
17
|
-
export declare function resetMagneticTarget(t: MagneticTarget): void;
|
|
18
|
-
export declare function lerpMagneticGroup(group: THREE.Group, target: MagneticTarget, dt: number, lerpIn: number, lerpOut: number, hovered: boolean, extraRz: number): void;
|
package/dist/r3f/magneticTilt.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import * as THREE from "three";
|
|
2
|
-
export function createZeroMagneticTarget() {
|
|
3
|
-
return { rx: 0, ry: 0, rz: 0, ox: 0, oy: 0 };
|
|
4
|
-
}
|
|
5
|
-
/** Map pointer UV on card face to rotation + in-plane shift (Balatro-style). */
|
|
6
|
-
export function magneticTargetFromUvPlayingCard(uv, magnet) {
|
|
7
|
-
const nx = (uv.x - 0.5) * 2;
|
|
8
|
-
const ny = (uv.y - 0.5) * 2;
|
|
9
|
-
const clampedX = THREE.MathUtils.clamp(nx, -1, 1);
|
|
10
|
-
const clampedY = THREE.MathUtils.clamp(ny, -1, 1);
|
|
11
|
-
return {
|
|
12
|
-
ry: -clampedX * magnet.MAX_TILT_Y,
|
|
13
|
-
rx: clampedY * magnet.MAX_TILT_X,
|
|
14
|
-
rz: -clampedX * clampedY * magnet.TWIST_Z,
|
|
15
|
-
ox: clampedX * magnet.MAX_SHIFT,
|
|
16
|
-
oy: -clampedY * magnet.MAX_SHIFT * 0.65,
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
export function resetMagneticTarget(t) {
|
|
20
|
-
t.rx = 0;
|
|
21
|
-
t.ry = 0;
|
|
22
|
-
t.rz = 0;
|
|
23
|
-
t.ox = 0;
|
|
24
|
-
t.oy = 0;
|
|
25
|
-
}
|
|
26
|
-
export function lerpMagneticGroup(group, target, dt, lerpIn, lerpOut, hovered, extraRz) {
|
|
27
|
-
const rate = hovered ? lerpIn : lerpOut;
|
|
28
|
-
const a = 1 - Math.exp(-rate * dt);
|
|
29
|
-
group.rotation.x = THREE.MathUtils.lerp(group.rotation.x, target.rx, a);
|
|
30
|
-
group.rotation.y = THREE.MathUtils.lerp(group.rotation.y, target.ry, a);
|
|
31
|
-
group.rotation.z = THREE.MathUtils.lerp(group.rotation.z, target.rz + extraRz, a);
|
|
32
|
-
group.position.x = THREE.MathUtils.lerp(group.position.x, target.ox, a);
|
|
33
|
-
group.position.y = THREE.MathUtils.lerp(group.position.y, target.oy, a);
|
|
34
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export type PlayingCardSuit = "hearts" | "diamonds" | "clubs" | "spades";
|
|
2
|
-
export type PlayingCardRank = "A" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "10" | "J" | "Q" | "K";
|
|
3
|
-
export type PlayingCardEnhancement = "bonus" | "mult" | "wild" | "glass" | "steel" | "stone" | "gold" | "lucky";
|
|
4
|
-
export type PlayingCardSeal = "gold" | "red" | "blue" | "purple";
|
|
5
|
-
export type PlayingCardEdition = "foil" | "holographic" | "polychrome" | "negative";
|
|
6
|
-
/** Minimal card model for 3D mesh (game-specific id/chips optional). */
|
|
7
|
-
export interface PlayingCard3DModel {
|
|
8
|
-
suit: PlayingCardSuit;
|
|
9
|
-
rank: PlayingCardRank;
|
|
10
|
-
enhancement?: PlayingCardEnhancement;
|
|
11
|
-
seal?: PlayingCardSeal;
|
|
12
|
-
edition?: PlayingCardEdition;
|
|
13
|
-
}
|
|
14
|
-
export declare const PLAYING_CARD_ATLAS: {
|
|
15
|
-
readonly columns: 13;
|
|
16
|
-
readonly rows: 4;
|
|
17
|
-
readonly cellPx: {
|
|
18
|
-
readonly x: 71;
|
|
19
|
-
readonly y: 95;
|
|
20
|
-
};
|
|
21
|
-
};
|
|
22
|
-
export declare const SUIT_ROW: Record<PlayingCardSuit, number>;
|
|
23
|
-
export declare const RANK_COLUMN: Record<PlayingCardRank, number>;
|
|
24
|
-
export declare const SUIT_COLORS: Record<PlayingCardSuit, string>;
|