From 36bf4e086f138327ed7bb3cf75ab940476c6210e Mon Sep 17 00:00:00 2001 From: Dan Bastin Date: Sun, 1 Dec 2024 11:26:24 -0500 Subject: [PATCH] add card images (#24) Adds support for card images from S3 --- .../_sharedcomponents/Cards/CardTypes.ts | 7 +++ .../Cards/GameCard/GameCard.tsx | 50 +++++++------------ .../Cards/LeaderBaseCard/LeaderBaseCard.tsx | 32 ++++++------ .../LeaderBaseBoard/LeaderBase/LeaderBase.tsx | 1 + src/app/_utils/s3Assets.ts | 8 +++ 5 files changed, 48 insertions(+), 50 deletions(-) diff --git a/src/app/_components/_sharedcomponents/Cards/CardTypes.ts b/src/app/_components/_sharedcomponents/Cards/CardTypes.ts index 992bbd7b..91895c45 100644 --- a/src/app/_components/_sharedcomponents/Cards/CardTypes.ts +++ b/src/app/_components/_sharedcomponents/Cards/CardTypes.ts @@ -1,3 +1,8 @@ +interface CardSetId { + set: string; + number: number; +} + export interface CardData { uuid: string; id?: number; @@ -14,6 +19,8 @@ export interface CardData { cost?: number; exhausted?: boolean; damage?: number; + setId: CardSetId; + type: string; } export interface GameCardProps { diff --git a/src/app/_components/_sharedcomponents/Cards/GameCard/GameCard.tsx b/src/app/_components/_sharedcomponents/Cards/GameCard/GameCard.tsx index e9d08ce4..2c938757 100644 --- a/src/app/_components/_sharedcomponents/Cards/GameCard/GameCard.tsx +++ b/src/app/_components/_sharedcomponents/Cards/GameCard/GameCard.tsx @@ -9,8 +9,7 @@ import { import Image from "next/image"; import { GameCardProps, CardData } from "@/app/_components/_sharedcomponents/Cards/CardTypes"; import { useGame } from "@/app/_contexts/Game.context"; -import { wrap } from "module"; -import { text } from "stream/consumers"; +import { s3CardImageURL } from "@/app/_utils/s3Assets"; const GameCard: React.FC = ({ card, @@ -24,15 +23,16 @@ const GameCard: React.FC = ({ const cardBorderColor = (card: CardData) => { if (card.selected) return "yellow"; - if (card.selectable) return "green"; + if (card.selectable) return "limegreen"; if (card.exhausted) return "gray"; return ""; } const styles = { - cardWrapper: { - height: size === "standard" ? "9.36rem" : "8rem", - width: size === "standard" ? "6rem" : "8rem", + cardStyles: { + borderRadius: ".38em", + height: size === "standard" ? "10rem" : "8rem", + width: size === "standard" ? "7.18rem" : "8rem", }, cardContentStyle: { width: "100%", @@ -41,6 +41,12 @@ const GameCard: React.FC = ({ padding: ".5em", textAlign: "center", whiteSpace: "normal", + backgroundColor: "black", + backgroundImage: `url(${s3CardImageURL(card)})`, + backgroundSize: size === "standard" ? "contain" : "cover", + backgroundPosition: size === "standard" ? "center" : "top", + backgroundRepeat: "no-repeat", + border: `2px solid ${cardBorderColor(card)}`, }, imageStyle: { width: "2.5rem", @@ -55,7 +61,7 @@ const GameCard: React.FC = ({ } return ( - { if (card.selectable) { sendGameMessage(["cardClicked", card.uuid]); @@ -63,31 +69,11 @@ const GameCard: React.FC = ({ }} > {isFaceUp ? ( - - - - - - {card.cost} - - - {card.damage} - - - - {card.name} - - - - {card.power} - - - {card.hp} - - - - - + + + + + ) : ( = ({ @@ -20,25 +21,25 @@ const LeaderBaseCard: React.FC = ({ const cardBorderColor = (card: CardData) => { if (!card) return ""; if (card.selected) return "yellow"; - if (card.selectable) return "green"; + if (card.selectable) return "limegreen"; if (card.exhausted) return "gray"; return "black"; }; const cardStyle = { - backgroundColor: cardBorderColor(card), - width: isLobbyView ? "18vw" : "12vw", - height: isLobbyView ? "18vh" : "11vh", + backgroundColor: "black", + backgroundImage: `url(${s3CardImageURL(card)})`, + backgroundSize: "contain", + backgroundPosition: "center", + width: "10rem", + height: "7.18rem", textAlign: "center", color: "white", display: "flex", - backdropFilter: "blur(20px)", - "&:hover": { - backgroundColor: "#708090E6", - }, cursor: "pointer", m: "0em", position: "relative", // Needed for positioning the red box + border: `2px solid ${cardBorderColor(card)}`, }; const typographyStyle = { @@ -102,16 +103,11 @@ const LeaderBaseCard: React.FC = ({ } }} > - - - - {card.damage} - - - {card.name} - - - + + + {card.damage} + + {/* Show title inside a red box at the bottom if not in lobby view and variant is leader */} {variant === "leader" && !isLobbyView && title && ( diff --git a/src/app/_components/_sharedcomponents/LeaderBaseBoard/LeaderBase/LeaderBase.tsx b/src/app/_components/_sharedcomponents/LeaderBaseBoard/LeaderBase/LeaderBase.tsx index e50d0e46..dc17192a 100644 --- a/src/app/_components/_sharedcomponents/LeaderBaseBoard/LeaderBase/LeaderBase.tsx +++ b/src/app/_components/_sharedcomponents/LeaderBaseBoard/LeaderBase/LeaderBase.tsx @@ -3,6 +3,7 @@ import Grid from "@mui/material/Grid2"; import LeaderBaseCard from "../../Cards/LeaderBaseCard/LeaderBaseCard"; import { LeaderBaseProps } from "../LeaderBaseBoardTypes"; import { useGame } from "@/app/_contexts/Game.context"; +import { s3CardImageURL } from "@/app/_utils/s3Assets"; const LeaderBase: React.FC = ({ player, diff --git a/src/app/_utils/s3Assets.ts b/src/app/_utils/s3Assets.ts index 7dfe5987..5beca7dd 100644 --- a/src/app/_utils/s3Assets.ts +++ b/src/app/_utils/s3Assets.ts @@ -1,4 +1,12 @@ +import { CardData } from "../_components/_sharedcomponents/Cards/CardTypes"; + export const s3ImageURL = (path: string) => { const s3Bucket = "https://karabast-assets.s3.amazonaws.com/"; return s3Bucket + path; +}; + +export const s3CardImageURL = (card: CardData) => { + if (!card) return "game/epic-action-token.webp"; + const cardNumber = card.setId.number.toString().padStart(3, "0") + (card.type === "leaderUnit" ? "-portrait" : ""); + return s3ImageURL(`cards/${card.setId.set}/${cardNumber}.webp`); }; \ No newline at end of file