depth for card piles

This commit is contained in:
2025-09-02 22:38:04 -04:00
parent 9919b97931
commit 67fdf66cd4
8 changed files with 69 additions and 13 deletions

View File

@@ -11,6 +11,7 @@
"@solid-primitives/scheduled": "^1.5.2", "@solid-primitives/scheduled": "^1.5.2",
"@solid-primitives/storage": "^4.3.3", "@solid-primitives/storage": "^4.3.3",
"@solidjs/router": "^0.15.3", "@solidjs/router": "^0.15.3",
"color2k": "^2.0.3",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"kefir": "^3.8.8", "kefir": "^3.8.8",
"kefir-bus": "^2.3.1", "kefir-bus": "^2.3.1",

View File

@@ -34,7 +34,14 @@ export default () => {
hand={view().myHand} hand={view().myHand}
onClickCard={(card) => submitAction({ type: "discard", card })} onClickCard={(card) => submitAction({ type: "discard", card })}
/> />
<div class="absolute tc text-align-center"> <div
class="absolute tc text-align-center"
style={{
"background-color":
view().playerTurn == me() ? "var(--yellow)" : "transparent",
color: view().playerTurn == me() ? "var(--dark)" : "var(--light)",
}}
>
It's{" "} It's{" "}
<span class="font-bold"> <span class="font-bold">
{view().playerTurn == me() {view().playerTurn == me()

View File

@@ -1,17 +1,55 @@
import { Component, For, JSX, Show } from "solid-js"; import { Component, createMemo, For, JSX, Show } from "solid-js";
import Card from "./Card"; import Card from "./Card";
import { desaturate } from "color2k";
import { Clickable, Stylable } from "./toolbox"; import { Clickable, hashColor, Stylable } from "./toolbox";
const cardWidth = 100;
const cardHeight = 145;
const cardOffset = 0.3; // Small offset for the stack effect
export default ((props) => { export default ((props) => {
const cards = createMemo(() => {
const numCards = Math.max(0, props.count - 1); // Subtract 1 for the top card
return Array.from({ length: numCards }, (_, i) => i).toReversed();
});
return ( return (
<Show when={props.count > 0}> <Show when={props.count > 0}>
<Card <div
onClick={props.onClick} style={{
style={props.style} ...props.style,
class={props.class + " shadow-lg shadow-black"} }}
face="down" class={props.class}
>
<svg
class="absolute z-[-1]"
width={cardWidth + cards().length * cardOffset}
height={cardHeight + cards().length * cardOffset}
viewBox={`0 0 ${cardWidth + cards().length * cardOffset} ${
cardHeight + cards().length * cardOffset
}`}
xmlns="http://www.w3.org/2000/svg"
>
<For each={cards()}>
{(i) => {
const xOffset = (i * cardOffset) / 2;
const yOffset = i * cardOffset;
const color = desaturate(hashColor(i), 0.9);
return (
<rect
x={xOffset}
y={yOffset}
width={cardWidth}
height={cardHeight}
rx="5" // Rounded corners
ry="5"
fill={color}
/> />
);
}}
</For>
</svg>
<Card onClick={props.onClick} face="down" />
</div>
</Show> </Show>
); );
}) satisfies Component< }) satisfies Component<

View File

@@ -129,8 +129,8 @@ export default (props: { tableKey: string }) => {
"top-40", "top-40",
"bottom-20", "bottom-20",
"left-10", "left-[2%]",
"right-10" "right-[2%]"
)} )}
style={{ style={{
"border-radius": "50%", "border-radius": "50%",

View File

@@ -1,3 +1,4 @@
import hash, { NotUndefined } from "object-hash";
import { JSX } from "solid-js"; import { JSX } from "solid-js";
export type Stylable = { export type Stylable = {
@@ -19,3 +20,5 @@ export type Sizable = {
width?: string; width?: string;
height?: string; height?: string;
}; };
export const hashColor = (obj: NotUndefined) => `#${hash(obj).substring(0, 6)}`;

View File

@@ -19,7 +19,6 @@ export const WS = Bus<
const api = new Elysia({ prefix: "/api" }) const api = new Elysia({ prefix: "/api" })
.post("/whoami", async ({ cookie: { token } }) => { .post("/whoami", async ({ cookie: { token } }) => {
console.log("WHOAMI");
let key: string | undefined; let key: string | undefined;
if (token.value == null || (key = resolveToken(token.value)) == null) { if (token.value == null || (key = resolveToken(token.value)) == null) {
const [newToken, newKey] = generateTokenAndKey(); const [newToken, newKey] = generateTokenAndKey();

View File

@@ -116,7 +116,7 @@ export default (config: SimpleConfiguration) =>
resolveQuit: () => null, resolveQuit: () => null,
getResult: (state) => getResult: (state) =>
Object.entries(state.playerHands).find( Object.entries(state.playerHands).find(
([_, hand]) => hand.length === 2 ([_, hand]) => hand.length === 52
)?.[0], )?.[0],
} satisfies Game< } satisfies Game<
SimpleGameState, SimpleGameState,

8
pnpm-lock.yaml generated
View File

@@ -29,6 +29,9 @@ importers:
'@solidjs/router': '@solidjs/router':
specifier: ^0.15.3 specifier: ^0.15.3
version: 0.15.3(solid-js@1.9.9) version: 0.15.3(solid-js@1.9.9)
color2k:
specifier: ^2.0.3
version: 2.0.3
js-cookie: js-cookie:
specifier: ^3.0.5 specifier: ^3.0.5
version: 3.0.5 version: 3.0.5
@@ -927,6 +930,9 @@ packages:
color-name@1.1.4: color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
color2k@2.0.3:
resolution: {integrity: sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==}
colorette@2.0.20: colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
@@ -3238,6 +3244,8 @@ snapshots:
color-name@1.1.4: {} color-name@1.1.4: {}
color2k@2.0.3: {}
colorette@2.0.20: {} colorette@2.0.20: {}
compare-func@2.0.0: compare-func@2.0.0: