fix : square renderer performance issue

This commit is contained in:
GuillaumeSD
2024-03-07 22:01:33 +01:00
parent 99a90def9c
commit e47ce83ebe
3 changed files with 67 additions and 79 deletions

View File

@@ -1,73 +0,0 @@
import { showPlayerMoveIconAtom } from "@/sections/analysis/states";
import { MoveClassification } from "@/types/enums";
import { CurrentPosition } from "@/types/eval";
import { useAtomValue } from "jotai";
import Image from "next/image";
import { CSSProperties, forwardRef, useMemo } from "react";
import { CustomSquareProps } from "react-chessboard/dist/chessboard/types";
export const useSquareRenderer = (position: CurrentPosition) => {
const showPlayerMoveIcon = useAtomValue(showPlayerMoveIconAtom);
const CustomSquareRenderer = useMemo(() => {
const fromSquare = position.lastMove?.from;
const toSquare = position.lastMove?.to;
const moveClassification = position?.eval?.moveClassification;
if (!showPlayerMoveIcon || !moveClassification || !fromSquare || !toSquare)
return undefined;
const squareRenderer = forwardRef<HTMLDivElement, CustomSquareProps>(
(props, ref) => {
const { children, square, style } = props;
const customSquareStyle: CSSProperties | undefined =
fromSquare === square || toSquare === square
? {
position: "absolute",
width: "100%",
height: "100%",
backgroundColor: moveClassificationColors[moveClassification],
opacity: 0.5,
}
: undefined;
return (
<div ref={ref} style={{ ...style, position: "relative" }}>
{children}
{customSquareStyle && <div style={customSquareStyle} />}
{square === toSquare && (
<Image
src={`/icons/${moveClassification}.png`}
alt="move-icon"
width={40}
height={40}
style={{
position: "absolute",
top: -12,
right: -12,
}}
/>
)}
</div>
);
}
);
squareRenderer.displayName = "CustomSquareRenderer";
return squareRenderer;
}, [showPlayerMoveIcon, position]);
return CustomSquareRenderer;
};
export const moveClassificationColors: Record<MoveClassification, string> = {
[MoveClassification.Best]: "#3aab18",
[MoveClassification.Book]: "#d5a47d",
[MoveClassification.Excellent]: "#3aab18",
[MoveClassification.Good]: "#81b64c",
[MoveClassification.Inaccuracy]: "#f7c631",
[MoveClassification.Mistake]: "#ffa459",
[MoveClassification.Blunder]: "#fa412d",
};

View File

@@ -14,10 +14,7 @@ import PlayerInfo from "./playerInfo";
import EvaluationBar from "./evaluationBar"; import EvaluationBar from "./evaluationBar";
import { useScreenSize } from "@/hooks/useScreenSize"; import { useScreenSize } from "@/hooks/useScreenSize";
import { MoveClassification } from "@/types/enums"; import { MoveClassification } from "@/types/enums";
import { import SquareRenderer, { moveClassificationColors } from "./squareRenderer";
moveClassificationColors,
useSquareRenderer,
} from "@/hooks/useSquareRenderer";
export default function Board() { export default function Board() {
const boardRef = useRef<HTMLDivElement>(null); const boardRef = useRef<HTMLDivElement>(null);
@@ -27,7 +24,6 @@ export default function Board() {
const showBestMoveArrow = useAtomValue(showBestMoveArrowAtom); const showBestMoveArrow = useAtomValue(showBestMoveArrowAtom);
const { makeMove: makeBoardMove } = useChessActions(boardAtom); const { makeMove: makeBoardMove } = useChessActions(boardAtom);
const position = useAtomValue(currentPositionAtom); const position = useAtomValue(currentPositionAtom);
const squareRenderer = useSquareRenderer(position);
const onPieceDrop = ( const onPieceDrop = (
source: Square, source: Square,
@@ -108,7 +104,7 @@ export default function Board() {
borderRadius: "5px", borderRadius: "5px",
boxShadow: "0 2px 10px rgba(0, 0, 0, 0.5)", boxShadow: "0 2px 10px rgba(0, 0, 0, 0.5)",
}} }}
customSquare={squareRenderer} customSquare={SquareRenderer}
/> />
</Grid> </Grid>

View File

@@ -0,0 +1,65 @@
import { currentPositionAtom, showPlayerMoveIconAtom } from "../states";
import { MoveClassification } from "@/types/enums";
import { useAtomValue } from "jotai";
import Image from "next/image";
import { CSSProperties, forwardRef } from "react";
import { CustomSquareProps } from "react-chessboard/dist/chessboard/types";
const SquareRenderer = forwardRef<HTMLDivElement, CustomSquareProps>(
(props, ref) => {
const { children, square, style } = props;
const showPlayerMoveIcon = useAtomValue(showPlayerMoveIconAtom);
const position = useAtomValue(currentPositionAtom);
const fromSquare = position.lastMove?.from;
const toSquare = position.lastMove?.to;
const moveClassification = position?.eval?.moveClassification;
const showPlayerMove = moveClassification && showPlayerMoveIcon;
const customSquareStyle: CSSProperties | undefined =
showPlayerMove && (fromSquare === square || toSquare === square)
? {
position: "absolute",
width: "100%",
height: "100%",
backgroundColor: moveClassificationColors[moveClassification],
opacity: 0.5,
}
: undefined;
return (
<div ref={ref} style={{ ...style, position: "relative" }}>
{children}
{customSquareStyle && <div style={customSquareStyle} />}
{showPlayerMove && square === toSquare && (
<Image
src={`/icons/${moveClassification}.png`}
alt="move-icon"
width={40}
height={40}
style={{
position: "absolute",
top: -15,
right: -15,
}}
/>
)}
</div>
);
}
);
SquareRenderer.displayName = "CustomSquareRenderer";
export default SquareRenderer;
export const moveClassificationColors: Record<MoveClassification, string> = {
[MoveClassification.Best]: "#3aab18",
[MoveClassification.Book]: "#d5a47d",
[MoveClassification.Excellent]: "#3aab18",
[MoveClassification.Good]: "#81b64c",
[MoveClassification.Inaccuracy]: "#f7c631",
[MoveClassification.Mistake]: "#ffa459",
[MoveClassification.Blunder]: "#fa412d",
};