From e9582f28b2b61c0151ae401f0e85e761a57d47d2 Mon Sep 17 00:00:00 2001 From: Dean Sofer Date: Sun, 13 Oct 2024 00:55:46 +0000 Subject: [PATCH] Refactor Piece and Point components to improve drag and drop functionality --- src/Board/Piece.tsx | 20 ++++++++++++-------- src/Board/Point.tsx | 42 +++++++++++++++++++++++++++--------------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/Board/Piece.tsx b/src/Board/Piece.tsx index 11d6ea5..1b03101 100644 --- a/src/Board/Piece.tsx +++ b/src/Board/Piece.tsx @@ -1,4 +1,4 @@ -import { useCallback, type DragEventHandler } from "react"; +import { useCallback, forwardRef, type DragEventHandler } from "react"; import black from './images/piece-black-2.png'; import white from './images/piece-white-2.png'; import './Piece.css' @@ -11,22 +11,26 @@ type PieceProps = { onSelect?: (position: number|null) => void, } -export default function Piece({ color, position, onSelect }: PieceProps) { +const Piece = forwardRef(({ color, position, onSelect }, ref) => { const onDragStart: DragEventHandler = useCallback((event) => { if (onSelect) onSelect(null) switch (position) { - case undefined: + case undefined: // Home event.preventDefault() break; - case -1: + case -1: // Bar event.dataTransfer?.setData('text', color) + event.stopPropagation() break; - default: + default: // Board event.dataTransfer?.setData('text', position.toString()) + event.stopPropagation() } }, [position, color, onSelect]); - + return
- +
-} \ No newline at end of file +}) + +export default Piece \ No newline at end of file diff --git a/src/Board/Point.tsx b/src/Board/Point.tsx index f2717bb..5755bbb 100644 --- a/src/Board/Point.tsx +++ b/src/Board/Point.tsx @@ -1,4 +1,4 @@ -import { useCallback, useState, type DragEventHandler } from "react"; +import { useCallback, useRef, useState, type DragEventHandler } from "react"; import Piece from './Piece' type PointProps = { @@ -10,38 +10,50 @@ type PointProps = { } export default function Point({ pieces, move, position, onSelect, selected }: PointProps) { - const [isDragging, setIsDragging] = useState(false); + const [dragging, setDragging] = useState(false); + const pieceRef = useRef(null); const onDragOver: DragEventHandler = useCallback((event) => { event.preventDefault(); }, []) const onDrop: DragEventHandler = useCallback((event) => { event.preventDefault(); - // onSelect(null) + onSelect(null) let from = event.dataTransfer?.getData("text")! return move(from, position) }, [move]) const color = pieces > 0 ? 'white' : 'black'; - const handleDragStart = () => { - setIsDragging(true); - }; + const onDragStart: DragEventHandler = useCallback((event) => { + // if (pieces === 0) return; - const handleDragEnd = () => { - setIsDragging(false); - }; + onSelect(null) + setDragging(true) + + if (pieces) + event.dataTransfer?.setDragImage(pieceRef.current, 50, 50); + + // Set drag data + if (position !== undefined || pieces !== 0) + event.dataTransfer?.setData('text/plain', position?.toString()); + }, [position, pieces, pieceRef, onSelect]); + + const onDragEnd = useCallback(() => { + setDragging(false); + }, []); const onPointerUp = useCallback(() => { - if (isDragging) return; + if (dragging) return; if (pieces !== 0 || selected !== null) onSelect(position) - }, [pieces, position, onSelect, isDragging]) + }, [pieces, position, onSelect, dragging]) return
- {Array.from({ length: Math.abs(pieces) }, (_, index) => )} + onDragStart={onDragStart} + onDragEnd={onDragEnd} + > + {Array.from({ length: Math.abs(pieces) }, (_, index) => )}
} \ No newline at end of file