feat : add board hue
This commit is contained in:
17
package-lock.json
generated
17
package-lock.json
generated
@@ -26,13 +26,15 @@
|
|||||||
"react": "18.3.1",
|
"react": "18.3.1",
|
||||||
"react-chessboard": "^4.7.3",
|
"react-chessboard": "^4.7.3",
|
||||||
"react-dom": "18.3.1",
|
"react-dom": "18.3.1",
|
||||||
"recharts": "^2.15.0"
|
"recharts": "^2.15.0",
|
||||||
|
"tinycolor2": "^1.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tanstack/eslint-plugin-query": "^5.74.7",
|
"@tanstack/eslint-plugin-query": "^5.74.7",
|
||||||
"@types/node": "^22.10.2",
|
"@types/node": "^22.10.2",
|
||||||
"@types/react": "18.2.11",
|
"@types/react": "18.2.11",
|
||||||
"@types/react-dom": "^18.3.5",
|
"@types/react-dom": "^18.3.5",
|
||||||
|
"@types/tinycolor2": "^1.4.6",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.18.2",
|
"@typescript-eslint/eslint-plugin": "^8.18.2",
|
||||||
"@typescript-eslint/parser": "^8.18.2",
|
"@typescript-eslint/parser": "^8.18.2",
|
||||||
"aws-cdk": "^2.1007.0",
|
"aws-cdk": "^2.1007.0",
|
||||||
@@ -3903,6 +3905,13 @@
|
|||||||
"@types/node": "*"
|
"@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": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "8.18.2",
|
"version": "8.18.2",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.2.tgz",
|
"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==",
|
"integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
|
||||||
"license": "MIT"
|
"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": {
|
"node_modules/to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
|||||||
@@ -28,13 +28,15 @@
|
|||||||
"react": "18.3.1",
|
"react": "18.3.1",
|
||||||
"react-chessboard": "^4.7.3",
|
"react-chessboard": "^4.7.3",
|
||||||
"react-dom": "18.3.1",
|
"react-dom": "18.3.1",
|
||||||
"recharts": "^2.15.0"
|
"recharts": "^2.15.0",
|
||||||
|
"tinycolor2": "^1.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tanstack/eslint-plugin-query": "^5.74.7",
|
"@tanstack/eslint-plugin-query": "^5.74.7",
|
||||||
"@types/node": "^22.10.2",
|
"@types/node": "^22.10.2",
|
||||||
"@types/react": "18.2.11",
|
"@types/react": "18.2.11",
|
||||||
"@types/react-dom": "^18.3.5",
|
"@types/react-dom": "^18.3.5",
|
||||||
|
"@types/tinycolor2": "^1.4.6",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.18.2",
|
"@typescript-eslint/eslint-plugin": "^8.18.2",
|
||||||
"@typescript-eslint/parser": "^8.18.2",
|
"@typescript-eslint/parser": "^8.18.2",
|
||||||
"aws-cdk": "^2.1007.0",
|
"aws-cdk": "^2.1007.0",
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ import { moveClassificationColors } from "@/lib/chess";
|
|||||||
import { Player } from "@/types/game";
|
import { Player } from "@/types/game";
|
||||||
import PlayerHeader from "./playerHeader";
|
import PlayerHeader from "./playerHeader";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { pieceSetAtom } from "./states";
|
import { boardHueAtom, pieceSetAtom } from "./states";
|
||||||
|
import tinycolor from "tinycolor2";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -61,6 +62,7 @@ export default function Board({
|
|||||||
const [moveClickFrom, setMoveClickFrom] = useState<Square | null>(null);
|
const [moveClickFrom, setMoveClickFrom] = useState<Square | null>(null);
|
||||||
const [moveClickTo, setMoveClickTo] = useState<Square | null>(null);
|
const [moveClickTo, setMoveClickTo] = useState<Square | null>(null);
|
||||||
const pieceSet = useAtomValue(pieceSetAtom);
|
const pieceSet = useAtomValue(pieceSetAtom);
|
||||||
|
const boardHue = useAtomValue(boardHueAtom);
|
||||||
|
|
||||||
const gameFen = game.fen();
|
const gameFen = game.fen();
|
||||||
|
|
||||||
@@ -196,19 +198,24 @@ export default function Board({
|
|||||||
if (
|
if (
|
||||||
bestMove &&
|
bestMove &&
|
||||||
showBestMoveArrow &&
|
showBestMoveArrow &&
|
||||||
moveClassification !== MoveClassification.Book
|
moveClassification !== MoveClassification.Best &&
|
||||||
|
moveClassification !== MoveClassification.Book &&
|
||||||
|
moveClassification !== MoveClassification.Forced &&
|
||||||
|
moveClassification !== MoveClassification.Great
|
||||||
) {
|
) {
|
||||||
const bestMoveArrow = [
|
const bestMoveArrow = [
|
||||||
bestMove.slice(0, 2),
|
bestMove.slice(0, 2),
|
||||||
bestMove.slice(2, 4),
|
bestMove.slice(2, 4),
|
||||||
moveClassificationColors[MoveClassification.Best],
|
tinycolor(moveClassificationColors[MoveClassification.Best])
|
||||||
|
.spin(-boardHue)
|
||||||
|
.toHexString(),
|
||||||
] as Arrow;
|
] as Arrow;
|
||||||
|
|
||||||
return [bestMoveArrow];
|
return [bestMoveArrow];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
}, [position, showBestMoveArrow]);
|
}, [position, showBestMoveArrow, boardHue]);
|
||||||
|
|
||||||
const SquareRenderer: CustomSquareRenderer = useMemo(() => {
|
const SquareRenderer: CustomSquareRenderer = useMemo(() => {
|
||||||
return getSquareRenderer({
|
return getSquareRenderer({
|
||||||
@@ -292,6 +299,7 @@ export default function Board({
|
|||||||
customBoardStyle={{
|
customBoardStyle={{
|
||||||
borderRadius: "5px",
|
borderRadius: "5px",
|
||||||
boxShadow: "0 2px 10px rgba(0, 0, 0, 0.5)",
|
boxShadow: "0 2px 10px rgba(0, 0, 0, 0.5)",
|
||||||
|
filter: `hue-rotate(${boardHue}deg)`,
|
||||||
}}
|
}}
|
||||||
customArrows={customArrows}
|
customArrows={customArrows}
|
||||||
isDraggablePiece={isPiecePlayable}
|
isDraggablePiece={isPiecePlayable}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
Square,
|
Square,
|
||||||
} from "react-chessboard/dist/chessboard/types";
|
} from "react-chessboard/dist/chessboard/types";
|
||||||
import { moveClassificationColors } from "@/lib/chess";
|
import { moveClassificationColors } from "@/lib/chess";
|
||||||
|
import { boardHueAtom } from "./states";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
currentPositionAtom: PrimitiveAtom<CurrentPosition>;
|
currentPositionAtom: PrimitiveAtom<CurrentPosition>;
|
||||||
@@ -29,6 +30,7 @@ export function getSquareRenderer({
|
|||||||
const position = useAtomValue(currentPositionAtom);
|
const position = useAtomValue(currentPositionAtom);
|
||||||
const clickedSquares = useAtomValue(clickedSquaresAtom);
|
const clickedSquares = useAtomValue(clickedSquaresAtom);
|
||||||
const playableSquares = useAtomValue(playableSquaresAtom);
|
const playableSquares = useAtomValue(playableSquaresAtom);
|
||||||
|
const boardHue = useAtomValue(boardHueAtom);
|
||||||
|
|
||||||
const fromSquare = position.lastMove?.from;
|
const fromSquare = position.lastMove?.from;
|
||||||
const toSquare = position.lastMove?.to;
|
const toSquare = position.lastMove?.to;
|
||||||
@@ -45,7 +47,14 @@ export function getSquareRenderer({
|
|||||||
playableSquares.includes(square) ? playableSquareStyles : undefined;
|
playableSquares.includes(square) ? playableSquareStyles : undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref} style={{ ...style, position: "relative" }}>
|
<div
|
||||||
|
ref={ref}
|
||||||
|
style={{
|
||||||
|
...style,
|
||||||
|
position: "relative",
|
||||||
|
filter: `hue-rotate(-${boardHue}deg)`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
{highlightSquareStyle && <div style={highlightSquareStyle} />}
|
{highlightSquareStyle && <div style={highlightSquareStyle} />}
|
||||||
{playableSquareStyle && <div style={playableSquareStyle} />}
|
{playableSquareStyle && <div style={playableSquareStyle} />}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
import { atomWithStorage } from "jotai/utils";
|
import { atomWithStorage } from "jotai/utils";
|
||||||
|
|
||||||
export const pieceSetAtom = atomWithStorage("pieceSet", "cburnett");
|
export const pieceSetAtom = atomWithStorage("pieceSet", "cburnett");
|
||||||
|
export const boardHueAtom = atomWithStorage("boardHue", 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user