You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Application-Web/front/components/editor/CourtPlayer.tsx

83 lines
2.5 KiB

import { ReactNode, RefObject, useRef } from "react"
import "../../style/player.css"
import Draggable from "react-draggable"
import { PlayerPiece } from "./PlayerPiece"
import { Player } from "../../model/tactic/Player"
import { NULL_POS, ratioWithinBase } from "../arrows/Pos"
export interface PlayerProps {
player: Player
onDrag: () => void
onChange: (p: Player) => void
onRemove: () => void
courtRef: RefObject<HTMLElement>
availableActions: (ro: HTMLElement) => ReactNode[]
}
/**
* A player that is placed on the court, which can be selected, and moved in the associated bounds
* */
export default function CourtPlayer({
player,
onDrag,
onChange,
onRemove,
courtRef,
availableActions,
}: PlayerProps) {
const hasBall = player.hasBall
const x = player.rightRatio
const y = player.bottomRatio
const pieceRef = useRef<HTMLDivElement>(null)
return (
<Draggable
handle=".player-piece"
nodeRef={pieceRef}
onDrag={onDrag}
//The piece is positioned using top/bottom style attributes instead
position={NULL_POS}
onStop={() => {
const pieceBounds = pieceRef.current!.getBoundingClientRect()
const parentBounds = courtRef.current!.getBoundingClientRect()
const { x, y } = ratioWithinBase(pieceBounds, parentBounds)
onChange({
id: player.id,
rightRatio: x,
bottomRatio: y,
team: player.team,
role: player.role,
hasBall: player.hasBall,
})
}}>
<div
id={player.id}
ref={pieceRef}
className="player"
style={{
position: "absolute",
left: `${x * 100}%`,
top: `${y * 100}%`,
}}>
<div
tabIndex={0}
className="player-content"
onKeyUp={(e) => {
if (e.key == "Delete") onRemove()
}}>
<div className="player-actions">
{availableActions(pieceRef.current!)}
</div>
<PlayerPiece
team={player.team}
text={player.role}
hasBall={hasBall}
/>
</div>
</div>
</Draggable>
)
}