fix : square renderer performance issue
This commit is contained in:
@@ -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",
|
|
||||||
};
|
|
||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
65
src/sections/analysis/board/squareRenderer.tsx
Normal file
65
src/sections/analysis/board/squareRenderer.tsx
Normal 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",
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user