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

80 lines
2.7 KiB

import React, { ReactNode, RefObject, useCallback, useRef } from "react"
import "../../style/player.css"
import Draggable from "react-draggable"
import { PlayerPiece } from "./PlayerPiece"
import { BallState, PlayerInfo } from "../../model/tactic/Player"
import { NULL_POS, Pos, ratioWithinBase } from "../../geo/Pos"
export interface CourtPlayerProps {
playerInfo: PlayerInfo
className?: string
onPositionValidated: (newPos: Pos) => 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({
playerInfo,
className,
onPositionValidated,
onRemove,
courtRef,
availableActions,
}: CourtPlayerProps) {
const usesBall = playerInfo.ballState != BallState.NONE
const x = playerInfo.rightRatio
const y = playerInfo.bottomRatio
const pieceRef = useRef<HTMLDivElement>(null)
return (
<Draggable
handle=".player-piece"
nodeRef={pieceRef}
//The piece is positioned using top/bottom style attributes instead
position={NULL_POS}
onStop={useCallback(() => {
const pieceBounds = pieceRef.current!.getBoundingClientRect()
const parentBounds = courtRef.current!.getBoundingClientRect()
const pos = ratioWithinBase(pieceBounds, parentBounds)
if (pos.x !== x || pos.y != y) onPositionValidated(pos)
}, [courtRef, onPositionValidated, x, y])}>
<div
id={playerInfo.id}
ref={pieceRef}
className={"player " + (className ?? "")}
style={{
position: "absolute",
left: `${x * 100}%`,
top: `${y * 100}%`,
}}>
<div
tabIndex={0}
className="player-content"
onKeyUp={useCallback(
(e: React.KeyboardEvent<HTMLDivElement>) => {
if (e.key == "Delete") onRemove()
},
[onRemove],
)}>
<div className="player-actions">
{availableActions(pieceRef.current!)}
</div>
<PlayerPiece
team={playerInfo.team}
text={playerInfo.role}
hasBall={usesBall}
/>
</div>
</div>
</Draggable>
)
}