Skip to content

Commit

Permalink
Refactor Piece and Point components to improve drag and drop function…
Browse files Browse the repository at this point in the history
…ality
  • Loading branch information
ProLoser committed Oct 13, 2024
1 parent 8ef649b commit e9582f2
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 23 deletions.
20 changes: 12 additions & 8 deletions src/Board/Piece.tsx
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -11,22 +11,26 @@ type PieceProps = {
onSelect?: (position: number|null) => void,
}

export default function Piece({ color, position, onSelect }: PieceProps) {
const Piece = forwardRef<HTMLImageElement, PieceProps>(({ 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 <div className={`piece ${color}`} onDragStart={onDragStart} draggable={position !== undefined}>
<img src={IMAGES[color]} />
<img ref={ref} src={IMAGES[color]} />
</div>
}
})

export default Piece
42 changes: 27 additions & 15 deletions src/Board/Point.tsx
Original file line number Diff line number Diff line change
@@ -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 = {
Expand All @@ -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<HTMLImageElement>(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 <div className={`point ${selected === position ? 'selected' : ''}`}
draggable={pieces !== 0 || selected !== null}
onPointerUp={onPointerUp}
onDragOver={onDragOver}
onDrop={onDrop}
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
>
{Array.from({ length: Math.abs(pieces) }, (_, index) => <Piece key={index} color={color} position={position} onSelect={onSelect} />)}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
>
{Array.from({ length: Math.abs(pieces) }, (_, index) => <Piece ref={index == 0 ? pieceRef : null} key={index} color={color} position={position} onSelect={onSelect} />)}
</div>
}

0 comments on commit e9582f2

Please sign in to comment.