Skip to content

Commit

Permalink
Merge pull request #8 from JollyGrin/feat/tap
Browse files Browse the repository at this point in the history
Feat/tap
  • Loading branch information
JollyGrin authored Sep 9, 2024
2 parents f6ec17c + 5f99914 commit c329dc3
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 32 deletions.
Binary file added public/mock-cards/arid_desert.webp
Binary file not shown.
Binary file added public/mock-cards/death_dealer.webp
Binary file not shown.
Binary file added public/mock-cards/infernal_legion.webp
Binary file not shown.
Binary file added public/mock-cards/jihad.webp
Binary file not shown.
Binary file added public/mock-cards/sorcerer.webp
Binary file not shown.
Binary file added public/mock-cards/wayfaring_pilgrim.webp
Binary file not shown.
5 changes: 3 additions & 2 deletions src/components/atoms/mock-cards/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,14 @@ export const CardImage = ({
position={show ? "absolute" : "unset"}
h="310px"
w="100%"
bgImage={`url(/mock-cards/${img})`}
backgroundPosition="top"
backgroundSize="cover"
backgroundRepeat="no-repeat"
transform={show ? "scale(1.5)" : "unset"}
transition="all 0.25s ease"
// bg="gray.400"
style={{
backgroundImage: `url(/mock-cards/${img})`,
}}
/>{" "}
</Box>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/organisms/GameBoard/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const GameLayout = (
}}
>
<p style={{ width: "fit-content" }}>
Right click cards to view in full
Playtest cards on a grid. Click to tap. Right click to view big.
</p>
</div>
<Box position="relative" h="100%" w="100%" maxW="1200px" m="0 auto">
Expand Down
49 changes: 39 additions & 10 deletions src/components/organisms/GameBoard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
DragOverlay,
} from "@dnd-kit/core";
import { useHandleDrag } from "./useHandleDrag";
import { SorceryCard } from "@/types/card";
import { CardImage } from "@/components/atoms/mock-cards/card";
import { CardImage as FullCard } from "@/components/atoms/card-view/card";
import { SortableItem } from "@/components/molecules/SortItem";
Expand All @@ -19,15 +18,15 @@ import { Modal } from "@/components/atoms/Modal";

import { Dispatch, SetStateAction, useState } from "react";
import { FullCardAtlas } from "@/components/atoms/card-view/atlas";
import { GameCard } from "@/pages/game";

type GameCard = SorceryCard & { id: string }; // for game position
type Cards = GameCard[][];
export type GameStateActions = {
gridItems: Cards;
setGridItems: Dispatch<SetStateAction<Cards>>;
};
export const GameBoard = ({ gridItems, setGridItems }: GameStateActions) => {
const { handleDragEnd, handleDragStart, activeId, activeCard } =
const { sensors, handleDragEnd, handleDragStart, activeId, activeCard } =
useHandleDrag({
gridItems,
setGridItems,
Expand Down Expand Up @@ -57,14 +56,15 @@ export const GameBoard = ({ gridItems, setGridItems }: GameStateActions) => {
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
collisionDetection={collision}
sensors={sensors}
>
<GameLayout gridItems={gridItems} setGridItems={setGridItems}>
{gridItems?.slice(0, 20)?.map((cards, gridIndex) => (
<DroppableGridItem
key={"grid-" + gridIndex}
id={gridIndex.toString()}
gridIndex={gridIndex}
style={{ overflowY: "auto" }}
style={{ overflowY: "auto", overflowX: "clip" }}
>
<SortableContext
id={`grid-${gridIndex}`}
Expand All @@ -75,6 +75,7 @@ export const GameBoard = ({ gridItems, setGridItems }: GameStateActions) => {
<SortItemWrapper
key={card.id}
amountOfCards={cards?.length}
{...{ gridItems, setGridItems }}
{...{ card, gridIndex, cardIndex }}
/>
))}
Expand All @@ -99,27 +100,55 @@ const SortItemWrapper = ({
card,
gridIndex,
cardIndex,
...props
}: {
card: GameCard;
gridIndex: number;
cardIndex: number;
amountOfCards?: number;
}) => {
} & GameStateActions) => {
const [preview, setPreview] = useState(false);
const heightCalc = 90 - Math.min(amountOfCards, 4) * 15;
const height = `${heightCalc}px`;

const heightCalc = () => {
if (amountOfCards === 1) return 120;
if (amountOfCards === 2) return 75;
if (amountOfCards === 3) return 65;

return 90 - Math.min(amountOfCards, 4) * 15;
};
const height = `${heightCalc()}px`;

const isTapped = card.isTapped;
function toggleTap() {
props.setGridItems(() => {
const newGrid = [...props.gridItems];
const card = newGrid[gridIndex][cardIndex];
newGrid[gridIndex][cardIndex] = {
...card,
isTapped: !card.isTapped,
} as GameCard;

return newGrid;
});
}

return (
<div
onDoubleClick={(e) => {
onClick={(e) => {
e.preventDefault();
setPreview(true);
e.stopPropagation();
toggleTap();
}}
onContextMenu={(e) => {
e.preventDefault();
setPreview(true);
}}
style={{ height: heightCalc + 7 + "px" }}
style={{
height: heightCalc() + 7 + "px",
transform: isTapped ? "rotate(5deg)" : "",
filter: isTapped ? "saturate(0)" : "",
transition: "all 0.25s ease",
}}
>
<SortableItem
key={`card-${gridIndex}-${cardIndex}`}
Expand Down
27 changes: 26 additions & 1 deletion src/components/organisms/GameBoard/useHandleDrag.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { SorceryCard } from "@/types/card";
import { DragEndEvent } from "@dnd-kit/core";
import {
DragEndEvent,
KeyboardSensor,
MouseSensor,
PointerSensor,
TouchSensor,
useSensor,
useSensors,
} from "@dnd-kit/core";
import { useState } from "react";

type GameCard = SorceryCard & { id: string }; // for game position
Expand All @@ -14,6 +22,22 @@ export const useHandleDrag = ({
}) => {
const [active, setActive] = useState<DragEndEvent["active"] | null>(null);

const pointerSensor = useSensor(PointerSensor, {
activationConstraint: {
distance: 5,
},
});
const mouseSensor = useSensor(MouseSensor);
const touchSensor = useSensor(TouchSensor);
const keyboardSensor = useSensor(KeyboardSensor);

const sensors = useSensors(
pointerSensor,
mouseSensor,
touchSensor,
keyboardSensor,
);

function handleDragStart(event: DragEndEvent) {
setActive(event?.active);
}
Expand Down Expand Up @@ -62,6 +86,7 @@ export const useHandleDrag = ({
}

return {
sensors,
handleDragEnd,
handleDragStart,
activeId: active?.id,
Expand Down
48 changes: 30 additions & 18 deletions src/pages/game.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,57 @@ import { useState } from "react";

const handCards: GameCard[] = [
{
id: "atlas-02",
img: "atlas_cloud_city.webp",
type: "site",
id: "sorcerer-01",
img: "sorcerer.webp",
type: "avatar",
},
];

const deckCards = Array.from({ length: 30 }).map((_, index) => ({
id: "headless-ab-" + index,
img: "headless_haunt.webp",
type: "minion",
}));

const mockDeck: GameCard[] = [
{
id: "headless-02",
img: "headless_haunt.webp",
id: "jihad",
img: "jihad.webp",
type: "aura",
},
{
id: "death_dealer-01",
img: "death_dealer.webp",
type: "minion",
},
{
id: "headless-03",
img: "headless_haunt.webp",
id: "infernal_legion-01",
img: "infernal_legion.webp",
type: "minion",
},
{
id: "headless-04",
img: "headless_haunt.webp",
id: "wayfaring_pilgrim-01",
img: "wayfaring_pilgrim.webp",
type: "minion",
},
];

const deckCards = Array.from({ length: 30 }).map((_, index) => ({
id: "headless-ab-" + index,
img: "headless_haunt.webp",
type: "minion",
}));

const atlasCards = Array.from({ length: 10 }).map((_, index) => ({
id: "atlas-02" + index,
img: "atlas_cloud_city.webp",
img: "arid_desert.webp",
type: "site",
}));

const initCards: GameCard[][] = Array.from({ length: 35 }, () => []);
initCards[GRIDS.HAND] = handCards as GameCard[];
initCards[GRIDS.DECK] = deckCards as GameCard[];
initCards[GRIDS.DECK] = [...deckCards, ...mockDeck] as GameCard[];
initCards[GRIDS.ATLAS_DECK] = atlasCards as GameCard[];

export type GameCard = SorceryCard & { id: string }; // for game position
type GameProps = {
id: string;
isTapped?: boolean;
};
export type GameCard = SorceryCard & GameProps; // for game position
export default function GamePage() {
const [gridItems, setGridItems] = useState<GameCard[][]>(initCards);

Expand Down

0 comments on commit c329dc3

Please sign in to comment.