scaling
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Component, Suspense } from "solid-js";
|
||||
|
||||
import type { Card } from "@games/shared/cards";
|
||||
import { Clickable, Sizable, Stylable } from "./toolbox";
|
||||
import { Clickable, Scalable, Stylable } from "./toolbox";
|
||||
|
||||
const cardToSvgFilename = (card: Card) => {
|
||||
if (card.kind == "joker") {
|
||||
@@ -17,7 +17,12 @@ const cardToSvgFilename = (card: Card) => {
|
||||
}`;
|
||||
};
|
||||
|
||||
export const CARD_RATIO = 1.456730769;
|
||||
export const BASE_CARD_WIDTH = 100;
|
||||
|
||||
export default ((props) => {
|
||||
const width = () => BASE_CARD_WIDTH * (props.scale ?? 1);
|
||||
const height = () => width() * CARD_RATIO;
|
||||
return (
|
||||
<Suspense>
|
||||
<img
|
||||
@@ -25,8 +30,8 @@ export default ((props) => {
|
||||
draggable={false}
|
||||
class={props.class}
|
||||
style={props.style}
|
||||
width={props.width ?? "100px"}
|
||||
height={props.height}
|
||||
width={`${width()}px`}
|
||||
height={`${height()}px`}
|
||||
src={
|
||||
props.face == "down"
|
||||
? "/views/back.svg"
|
||||
@@ -45,5 +50,5 @@ export default ((props) => {
|
||||
) &
|
||||
Stylable &
|
||||
Clickable &
|
||||
Sizable
|
||||
Scalable
|
||||
>;
|
||||
|
||||
@@ -10,7 +10,7 @@ export default (props: { handCount: number }) => {
|
||||
return (
|
||||
<Card
|
||||
face="down"
|
||||
width="40px"
|
||||
scale={0.4}
|
||||
style={{
|
||||
"margin-left": "-12px",
|
||||
"margin-right": "-12px",
|
||||
|
||||
@@ -25,6 +25,7 @@ export default () => {
|
||||
<GameContext.Provider value={{ view, submitAction }}>
|
||||
<Pile
|
||||
count={view().deckCount}
|
||||
scale={0.8}
|
||||
class="cursor-pointer fixed center"
|
||||
onClick={() => submitAction({ type: "draw" })}
|
||||
/>
|
||||
@@ -58,11 +59,16 @@ export default () => {
|
||||
>
|
||||
Quit
|
||||
</button>
|
||||
<For each={Object.entries(view().playerHandCounts)}>
|
||||
<For
|
||||
each={Object.entries(view().playerHandCounts).filter(([key, _]) =>
|
||||
table.players().includes(key)
|
||||
)}
|
||||
>
|
||||
{([playerKey, handCount], i) => (
|
||||
<Portal
|
||||
mount={document.getElementById(`player-${playerKey}`)!}
|
||||
ref={(ref) => {
|
||||
console.log("Setting hand ref");
|
||||
const midOffset =
|
||||
i() + 0.5 - Object.values(view().playerHandCounts).length / 2;
|
||||
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import { Component, createMemo, For, JSX, Show } from "solid-js";
|
||||
import Card from "./Card";
|
||||
import Card, { BASE_CARD_WIDTH, CARD_RATIO } from "./Card";
|
||||
import { desaturate } from "color2k";
|
||||
|
||||
import { Clickable, hashColor, Stylable } from "./toolbox";
|
||||
const cardWidth = 100;
|
||||
const cardHeight = 145;
|
||||
const cardOffset = 0.3; // Small offset for the stack effect
|
||||
import { Clickable, hashColor, Scalable, Stylable } from "./toolbox";
|
||||
|
||||
const cardOffset = 0.35; // Small offset for the stack effect
|
||||
|
||||
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();
|
||||
});
|
||||
const width = () => BASE_CARD_WIDTH * (props.scale ?? 1);
|
||||
const height = () => width() * CARD_RATIO;
|
||||
const offset = () => cardOffset * (props.scale ?? 1);
|
||||
return (
|
||||
<Show when={props.count > 0}>
|
||||
<div
|
||||
@@ -22,24 +24,24 @@ export default ((props) => {
|
||||
>
|
||||
<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
|
||||
width={width() + cards().length * offset()}
|
||||
height={height() + cards().length * offset()}
|
||||
viewBox={`0 0 ${width() + cards().length * offset()} ${
|
||||
height() + cards().length * offset()
|
||||
}`}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<For each={cards()}>
|
||||
{(i) => {
|
||||
const xOffset = (i * cardOffset) / 2;
|
||||
const yOffset = i * cardOffset;
|
||||
const xOffset = (i * offset()) / 2;
|
||||
const yOffset = i * offset();
|
||||
const color = desaturate(hashColor(i), 0.9);
|
||||
return (
|
||||
<rect
|
||||
x={xOffset}
|
||||
y={yOffset}
|
||||
width={cardWidth}
|
||||
height={cardHeight}
|
||||
width={width()}
|
||||
height={height()}
|
||||
rx="5" // Rounded corners
|
||||
ry="5"
|
||||
fill={color}
|
||||
@@ -48,7 +50,7 @@ export default ((props) => {
|
||||
}}
|
||||
</For>
|
||||
</svg>
|
||||
<Card onClick={props.onClick} face="down" />
|
||||
<Card onClick={props.onClick} face="down" scale={props.scale} />
|
||||
</div>
|
||||
</Show>
|
||||
);
|
||||
@@ -56,5 +58,6 @@ export default ((props) => {
|
||||
{
|
||||
count: number;
|
||||
} & Stylable &
|
||||
Clickable
|
||||
Clickable &
|
||||
Scalable
|
||||
>;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createSignal, useContext } from "solid-js";
|
||||
import { createSignal, onMount, useContext } from "solid-js";
|
||||
import { playerColor } from "~/profile";
|
||||
import { TableContext } from "./Table";
|
||||
import { Stylable } from "./toolbox";
|
||||
@@ -16,6 +16,8 @@ export default (props: { playerKey: string } & Stylable) => {
|
||||
|
||||
const game = useContext(GameContext);
|
||||
|
||||
onMount(() => console.log("Player mounted"));
|
||||
|
||||
return (
|
||||
<div
|
||||
id={`player-${props.playerKey}`}
|
||||
|
||||
@@ -28,6 +28,7 @@ export const TableContext = createContext<{
|
||||
sendWs: (msg: TWsIn) => void;
|
||||
wsEvents: Stream<TWsOut, any>;
|
||||
playerNames: Store<{ [key: string]: string }>;
|
||||
players: Accessor<string[]>;
|
||||
}>();
|
||||
|
||||
export default (props: { tableKey: string }) => {
|
||||
@@ -75,7 +76,9 @@ export default (props: { tableKey: string }) => {
|
||||
|
||||
createEffect(() => sendWs({ ready: ready() }));
|
||||
createEffect(() => sendWs({ name: name() }));
|
||||
const view = createObservable(gameEvents.map((evt) => evt.view));
|
||||
const viewProp = gameEvents.map((evt) => evt.view).toProperty();
|
||||
viewProp.log();
|
||||
const view = createObservable(viewProp);
|
||||
const results = createObservable<string>(
|
||||
merge([
|
||||
gameEvents
|
||||
@@ -92,6 +95,7 @@ export default (props: { tableKey: string }) => {
|
||||
wsEvents,
|
||||
view,
|
||||
playerNames,
|
||||
players,
|
||||
}}
|
||||
>
|
||||
<div class="flex justify-around p-t-14">
|
||||
|
||||
@@ -16,9 +16,8 @@ export type Clickable = {
|
||||
| undefined;
|
||||
};
|
||||
|
||||
export type Sizable = {
|
||||
width?: string;
|
||||
height?: string;
|
||||
export type Scalable = {
|
||||
scale?: number;
|
||||
};
|
||||
|
||||
export const hashColor = (obj: NotUndefined) => `#${hash(obj).substring(0, 6)}`;
|
||||
|
||||
Reference in New Issue
Block a user