From 10935c72c5e2fcb5eba78ed59a942fbcebd3d1aa Mon Sep 17 00:00:00 2001 From: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com> Date: Sat, 10 May 2025 18:21:19 +0200 Subject: [PATCH] feat : add board hue --- package-lock.json | 17 ++++++++++++++++- package.json | 4 +++- src/components/board/index.tsx | 16 ++++++++++++---- src/components/board/squareRenderer.tsx | 11 ++++++++++- src/components/board/states.ts | 1 + 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2dd72e1..67177c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,13 +26,15 @@ "react": "18.3.1", "react-chessboard": "^4.7.3", "react-dom": "18.3.1", - "recharts": "^2.15.0" + "recharts": "^2.15.0", + "tinycolor2": "^1.6.0" }, "devDependencies": { "@tanstack/eslint-plugin-query": "^5.74.7", "@types/node": "^22.10.2", "@types/react": "18.2.11", "@types/react-dom": "^18.3.5", + "@types/tinycolor2": "^1.4.6", "@typescript-eslint/eslint-plugin": "^8.18.2", "@typescript-eslint/parser": "^8.18.2", "aws-cdk": "^2.1007.0", @@ -3903,6 +3905,13 @@ "@types/node": "*" } }, + "node_modules/@types/tinycolor2": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.6.tgz", + "integrity": "sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==", + "dev": true, + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.18.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.2.tgz", @@ -10251,6 +10260,12 @@ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", "license": "MIT" }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/package.json b/package.json index deb8f72..5c51c6b 100644 --- a/package.json +++ b/package.json @@ -28,13 +28,15 @@ "react": "18.3.1", "react-chessboard": "^4.7.3", "react-dom": "18.3.1", - "recharts": "^2.15.0" + "recharts": "^2.15.0", + "tinycolor2": "^1.6.0" }, "devDependencies": { "@tanstack/eslint-plugin-query": "^5.74.7", "@types/node": "^22.10.2", "@types/react": "18.2.11", "@types/react-dom": "^18.3.5", + "@types/tinycolor2": "^1.4.6", "@typescript-eslint/eslint-plugin": "^8.18.2", "@typescript-eslint/parser": "^8.18.2", "aws-cdk": "^2.1007.0", diff --git a/src/components/board/index.tsx b/src/components/board/index.tsx index 03fa94c..75ef9ea 100644 --- a/src/components/board/index.tsx +++ b/src/components/board/index.tsx @@ -20,7 +20,8 @@ import { moveClassificationColors } from "@/lib/chess"; import { Player } from "@/types/game"; import PlayerHeader from "./playerHeader"; import Image from "next/image"; -import { pieceSetAtom } from "./states"; +import { boardHueAtom, pieceSetAtom } from "./states"; +import tinycolor from "tinycolor2"; export interface Props { id: string; @@ -61,6 +62,7 @@ export default function Board({ const [moveClickFrom, setMoveClickFrom] = useState(null); const [moveClickTo, setMoveClickTo] = useState(null); const pieceSet = useAtomValue(pieceSetAtom); + const boardHue = useAtomValue(boardHueAtom); const gameFen = game.fen(); @@ -196,19 +198,24 @@ export default function Board({ if ( bestMove && showBestMoveArrow && - moveClassification !== MoveClassification.Book + moveClassification !== MoveClassification.Best && + moveClassification !== MoveClassification.Book && + moveClassification !== MoveClassification.Forced && + moveClassification !== MoveClassification.Great ) { const bestMoveArrow = [ bestMove.slice(0, 2), bestMove.slice(2, 4), - moveClassificationColors[MoveClassification.Best], + tinycolor(moveClassificationColors[MoveClassification.Best]) + .spin(-boardHue) + .toHexString(), ] as Arrow; return [bestMoveArrow]; } return []; - }, [position, showBestMoveArrow]); + }, [position, showBestMoveArrow, boardHue]); const SquareRenderer: CustomSquareRenderer = useMemo(() => { return getSquareRenderer({ @@ -292,6 +299,7 @@ export default function Board({ customBoardStyle={{ borderRadius: "5px", boxShadow: "0 2px 10px rgba(0, 0, 0, 0.5)", + filter: `hue-rotate(${boardHue}deg)`, }} customArrows={customArrows} isDraggablePiece={isPiecePlayable} diff --git a/src/components/board/squareRenderer.tsx b/src/components/board/squareRenderer.tsx index 0f47c92..fb3808f 100644 --- a/src/components/board/squareRenderer.tsx +++ b/src/components/board/squareRenderer.tsx @@ -8,6 +8,7 @@ import { Square, } from "react-chessboard/dist/chessboard/types"; import { moveClassificationColors } from "@/lib/chess"; +import { boardHueAtom } from "./states"; export interface Props { currentPositionAtom: PrimitiveAtom; @@ -29,6 +30,7 @@ export function getSquareRenderer({ const position = useAtomValue(currentPositionAtom); const clickedSquares = useAtomValue(clickedSquaresAtom); const playableSquares = useAtomValue(playableSquaresAtom); + const boardHue = useAtomValue(boardHueAtom); const fromSquare = position.lastMove?.from; const toSquare = position.lastMove?.to; @@ -45,7 +47,14 @@ export function getSquareRenderer({ playableSquares.includes(square) ? playableSquareStyles : undefined; return ( -
+
{children} {highlightSquareStyle &&
} {playableSquareStyle &&
} diff --git a/src/components/board/states.ts b/src/components/board/states.ts index bc9960b..beb9fc0 100644 --- a/src/components/board/states.ts +++ b/src/components/board/states.ts @@ -1,3 +1,4 @@ import { atomWithStorage } from "jotai/utils"; export const pieceSetAtom = atomWithStorage("pieceSet", "cburnett"); +export const boardHueAtom = atomWithStorage("boardHue", 0);