holding cards, kinda

This commit is contained in:
2025-08-27 23:00:01 -04:00
parent 686529507e
commit d69336027a
6 changed files with 43 additions and 20 deletions

View File

@@ -1,7 +1,7 @@
import { Component, Suspense } from "solid-js";
import type { Card } from "@games/shared/cards";
import { Clickable, Stylable } from "./toolbox";
import { Clickable, Sizable, Stylable } from "./toolbox";
const cardToSvgFilename = (card: Card) => {
if (card.kind == "joker") {
@@ -25,7 +25,8 @@ export default ((props) => {
draggable={false}
class={props.class}
style={props.style}
width="100px"
width={props.width ?? "100px"}
height={props.height}
src={
props.face == "down"
? "/views/back.svg"
@@ -43,5 +44,6 @@ export default ((props) => {
| { card?: Card; face: "down" }
) &
Stylable &
Clickable
Clickable &
Sizable
>;

View File

@@ -4,18 +4,26 @@ import Card from "./Card";
export default (props: { handCount: number }) => {
return (
<div class="flex">
<For each={Array(props.handCount)}>
{() => (
<For each={Array(props.handCount)}>
{(_, i) => {
const midOffset = i() + 0.5 - props.handCount / 2;
return (
<Card
face="down"
width="40px"
style={{
"margin-left": "-15px",
transform: "translate(0, 40px)",
"margin-left": "-10px",
"margin-right": "-10px",
transform: `rotate(${
midOffset * 0.2
}rad) translate(0px, ${
2 ** Math.abs(midOffset) * 2
}px)`,
"box-shadow": "-4px 4px 4px rgba(0, 0, 0, 0.7)",
}}
/>
)}
</For>
</div>
);
}}
</For>
);
};

View File

@@ -49,13 +49,22 @@ export default () => {
Quit
</button>
<For each={Object.entries(view().playerHandCounts)}>
{([playerKey, handCount]) => (
{([playerKey, handCount], i) => (
<Portal
mount={document.getElementById(`player-${playerKey}`)!}
ref={(ref) => {
const midOffset =
i() +
0.5 -
Object.values(view().playerHandCounts).length /
2;
ref.style = `position: absolute; display: flex; justify-content: center; top: 65%; transform: translate(${Math.abs(
midOffset * 0
)}px, 0px) rotate(${midOffset * 1}rad)`;
}}
>
<div class="absolute center">
<FannedHand handCount={handCount} />
</div>
<FannedHand handCount={handCount} />
</Portal>
)}
</For>

View File

@@ -65,7 +65,7 @@ export default (props: { tableKey: string }) => {
view,
}}
>
<div class="flex justify-around p-t-10">
<div class="flex justify-around p-t-14">
<For each={players().filter((p) => p != me())}>
{(player, i) => {
const verticalOffset = () => {

View File

@@ -14,3 +14,8 @@ export type Clickable = {
>
| undefined;
};
export type Sizable = {
width?: string;
height?: string;
};

View File

@@ -10,7 +10,6 @@ import dayjs from "dayjs";
import db from "./db";
import { liveTable, WsOut, WsIn } from "./table";
import { Human } from "@prisma/client";
import _ from "lodash";
import { combine } from "kefir";
const api = new Elysia({ prefix: "/api" })
@@ -89,9 +88,9 @@ const api = new Elysia({ prefix: "/api" })
send({ players })
);
table.outputs.playersReady.onValue((readys) =>
send({ playersReady: readys })
);
table.outputs.playersReady
.skipDuplicates()
.onValue((readys) => send({ playersReady: readys }));
combine(
[table.outputs.gameState],