basic drawing
This commit is contained in:
BIN
assets/sources/Card_back_01.svg
LFS
Normal file
BIN
assets/sources/Card_back_01.svg
LFS
Normal file
Binary file not shown.
1
assets/views/back.svg
Symbolic link
1
assets/views/back.svg
Symbolic link
@@ -0,0 +1 @@
|
||||
../sources/Card_back_01.svg
|
||||
@@ -28,6 +28,10 @@ body::before {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, createResource, Suspense } from "solid-js";
|
||||
import { Component, createResource, JSX, Suspense } from "solid-js";
|
||||
import { Card } from "../types/cards";
|
||||
|
||||
const cardToSvgFilename = (card: Card) => {
|
||||
@@ -7,24 +7,43 @@ const cardToSvgFilename = (card: Card) => {
|
||||
}
|
||||
|
||||
const value =
|
||||
{ ace: 1, jack: 11, queen: 12, king: 13 }[card.rank] ??
|
||||
(card.rank as number);
|
||||
{ ace: 1, jack: 11, queen: 12, king: 13 }[
|
||||
card.rank as "ace" | "jack" | "queen" | "king" // fuck you typescript
|
||||
] ?? (card.rank as number);
|
||||
return `${card.suit.toUpperCase()}-${value}${
|
||||
value >= 11 ? "-" + (card.rank as string).toUpperCase() : ""
|
||||
}`;
|
||||
};
|
||||
|
||||
export default ((props) => {
|
||||
const [svgPath] = createResource(
|
||||
() =>
|
||||
import(
|
||||
`~/../assets/views/cards/${cardToSvgFilename(props.card)}.svg`
|
||||
const [svgPath] = createResource(() =>
|
||||
props.face == "down"
|
||||
? // @ts-ignore
|
||||
import("~/../assets/views/back.svg")
|
||||
: import(
|
||||
`~/../assets/views/cards/${cardToSvgFilename(
|
||||
props.card
|
||||
)}.svg`
|
||||
)
|
||||
);
|
||||
|
||||
return (
|
||||
<Suspense>
|
||||
<img src={svgPath()?.default} />
|
||||
<img
|
||||
draggable={false}
|
||||
class={props.class}
|
||||
style={{
|
||||
"border-radius": "5px",
|
||||
...props.style,
|
||||
}}
|
||||
width="100px"
|
||||
src={svgPath()?.default}
|
||||
/>
|
||||
</Suspense>
|
||||
);
|
||||
}) satisfies Component<{ card: Card }>;
|
||||
}) satisfies Component<{
|
||||
class?: string;
|
||||
style?: JSX.CSSProperties;
|
||||
card: Card;
|
||||
face?: "up" | "down";
|
||||
}>;
|
||||
|
||||
@@ -1,15 +1,40 @@
|
||||
import { JSX } from "solid-js";
|
||||
import { createContext, JSX } from "solid-js";
|
||||
import Card from "./Card";
|
||||
import Hand from "./Hand";
|
||||
import Pile from "./Pile";
|
||||
import { newDeck, shuffle, Hand as THand } from "../types/cards";
|
||||
import { createStore, produce } from "solid-js/store";
|
||||
|
||||
const GameContext = createContext();
|
||||
|
||||
export default () => {
|
||||
const [gameState, setGameState] = createStore({
|
||||
pile: shuffle(newDeck()),
|
||||
hand: [] as THand,
|
||||
});
|
||||
|
||||
return (
|
||||
<GameContext.Provider value={{ gameState, setGameState }}>
|
||||
<div
|
||||
class="full center column"
|
||||
onClick={() => {}}
|
||||
class="full column"
|
||||
style={{ "row-gap": "20px", "font-size": "32px" }}
|
||||
>
|
||||
games
|
||||
<Card card={{ kind: "joker", color: "red" }} />
|
||||
coming soon
|
||||
<div class="full center">
|
||||
<Pile
|
||||
pile={gameState.pile}
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={() =>
|
||||
setGameState(
|
||||
produce((state) => {
|
||||
state.hand.push(state.pile.pop()!);
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Hand hand={gameState.hand} />
|
||||
</div>
|
||||
</GameContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { Component, For } from "solid-js";
|
||||
import Card from "./Card";
|
||||
import { Hand } from "../types/cards";
|
||||
|
||||
export default ((props) => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
border: "2px dashed white",
|
||||
"border-radius": "12px",
|
||||
margin: "10px",
|
||||
"margin-bottom": "25px",
|
||||
padding: "10px",
|
||||
height: "200px",
|
||||
overflow: "scroll",
|
||||
"scrollbar-width": "none",
|
||||
display: "flex",
|
||||
gap: "5px",
|
||||
}}
|
||||
>
|
||||
<For each={props.hand}>{(card) => <Card card={card} />}</For>
|
||||
</div>
|
||||
);
|
||||
}) satisfies Component<{ hand: Hand }>;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { Component, For, JSX } from "solid-js";
|
||||
import Card from "./Card";
|
||||
import { Pile } from "../types/cards";
|
||||
|
||||
export default ((props) => {
|
||||
return (
|
||||
<div
|
||||
class="center"
|
||||
style={{ width: "200px", height: "400px", ...props.style }}
|
||||
onClick={props.onClick}
|
||||
>
|
||||
<For each={props.pile}>
|
||||
{(card, i) => (
|
||||
<Card
|
||||
card={card}
|
||||
face="down"
|
||||
style={{
|
||||
position: "absolute",
|
||||
transform: `translate(${i() * 0.8}px, ${
|
||||
-i() * 0.4
|
||||
}px)`,
|
||||
"z-index": 100 - i(),
|
||||
border: `0.1px solid rgb(${
|
||||
60 - i() + Math.random() * 10
|
||||
}, ${60 - i() + Math.random() * 10}, ${
|
||||
60 - i() + Math.random() * 10
|
||||
});`,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
);
|
||||
}) satisfies Component<{
|
||||
pile: Pile;
|
||||
style?: JSX.CSSProperties;
|
||||
onClick?:
|
||||
| JSX.EventHandlerUnion<
|
||||
HTMLDivElement,
|
||||
MouseEvent,
|
||||
JSX.EventHandler<HTMLDivElement, MouseEvent>
|
||||
>
|
||||
| undefined;
|
||||
}>;
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
export type Suit = "heart" | "diamond" | "spade" | "club";
|
||||
const suits = ["heart", "diamond", "spade", "club"] as const;
|
||||
export type Suit = (typeof suits)[number];
|
||||
|
||||
const ranks = [
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
"jack",
|
||||
"queen",
|
||||
"king",
|
||||
"ace",
|
||||
] as const;
|
||||
export type Rank = (typeof ranks)[number];
|
||||
|
||||
type Rank = number | "jack" | "queen" | "king" | "ace";
|
||||
export type Card =
|
||||
| {
|
||||
kind: "normal";
|
||||
@@ -13,3 +30,28 @@ export type Pile = Card[];
|
||||
export type Stack = Card[];
|
||||
export type Hand = Card[];
|
||||
export type Board = Card[];
|
||||
|
||||
export const newDeck = (withJokers = false): Pile =>
|
||||
suits
|
||||
.map((suit) =>
|
||||
ranks.map((rank) => ({ kind: "normal", suit, rank } as Card))
|
||||
)
|
||||
.flat()
|
||||
.concat(
|
||||
withJokers
|
||||
? [
|
||||
{ kind: "joker", color: "red" },
|
||||
{ kind: "joker", color: "black" },
|
||||
]
|
||||
: []
|
||||
);
|
||||
|
||||
export const shuffle = (cards: Card[]) => {
|
||||
let i = cards.length;
|
||||
while (i > 0) {
|
||||
const j = Math.floor(Math.random() * i);
|
||||
i--;
|
||||
[cards[i], cards[j]] = [cards[j], cards[i]];
|
||||
}
|
||||
return cards;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user