diff --git a/front/components/editor/BallPiece.tsx b/front/components/editor/BallPiece.tsx index b798532..be4057f 100644 --- a/front/components/editor/BallPiece.tsx +++ b/front/components/editor/BallPiece.tsx @@ -1,7 +1,7 @@ import "../../style/ball.css" import BallSvg from "../../assets/icon/ball.svg?react" -import {Ball} from "../../tactic/CourtObjects"; +import { Ball } from "../../tactic/CourtObjects" export interface CourtBallProps { onMoved: (rect: DOMRect) => void @@ -10,8 +10,5 @@ export interface CourtBallProps { } export function BallPiece() { - return ( - - ) + return } - diff --git a/front/components/editor/BasketCourt.tsx b/front/components/editor/BasketCourt.tsx index 9950775..4545f9a 100644 --- a/front/components/editor/BasketCourt.tsx +++ b/front/components/editor/BasketCourt.tsx @@ -1,10 +1,10 @@ import "../../style/basket_court.css" -import {RefObject} from "react" +import { RefObject } from "react" import CourtPlayer from "./CourtPlayer" -import {Player} from "../../tactic/Player" -import {CourtObject} from "../../tactic/CourtObjects"; -import {CourtBall} from "./CourtBall"; +import { Player } from "../../tactic/Player" +import { CourtObject } from "../../tactic/CourtObjects" +import { CourtBall } from "./CourtBall" export interface BasketCourtProps { players: Player[] @@ -13,31 +13,30 @@ export interface BasketCourtProps { onPlayerRemove: (p: Player) => void onPlayerChange: (p: Player) => void - onBallRemove : () => void + onBallRemove: () => void - onBallMoved: (ball: DOMRect) => void, + onBallMoved: (ball: DOMRect) => void courtImage: string courtRef: RefObject } export function BasketCourt({ - players, - objects, - onPlayerRemove, - onBallRemove, - onBallMoved, - onPlayerChange, - courtImage, - courtRef, - }: BasketCourtProps) { - + players, + objects, + onPlayerRemove, + onBallRemove, + onBallMoved, + onPlayerChange, + courtImage, + courtRef, +}: BasketCourtProps) { return (
- {"court"} + style={{ position: "relative" }}> + {"court"} {players.map((player) => { return ( { + {objects.map((object) => { if (object.type == "ball") { - return + return ( + + ) } throw new Error("unknown court object", object.type) })}
) } - - diff --git a/front/components/editor/CourtBall.tsx b/front/components/editor/CourtBall.tsx index 8d0c9be..f2c32e6 100644 --- a/front/components/editor/CourtBall.tsx +++ b/front/components/editor/CourtBall.tsx @@ -1,9 +1,8 @@ -import React, {useRef} from "react"; -import Draggable from "react-draggable"; -import {BallPiece, CourtBallProps} from "./BallPiece"; +import React, { useRef } from "react" +import Draggable from "react-draggable" +import { BallPiece, CourtBallProps } from "./BallPiece" - -export function CourtBall({onMoved, ball, onRemove}: CourtBallProps) { +export function CourtBall({ onMoved, ball, onRemove }: CourtBallProps) { const pieceRef = useRef(null) const x = ball.rightRatio @@ -12,22 +11,21 @@ export function CourtBall({onMoved, ball, onRemove}: CourtBallProps) { return ( onMoved(pieceRef.current!.getBoundingClientRect())} - nodeRef={pieceRef} - > -
{ - if (e.key == "Delete") onRemove() - }} - style={{ - position: "absolute", - left: `${x * 100}%`, - top: `${y * 100}%`, - }} - > - + nodeRef={pieceRef}> +
{ + if (e.key == "Delete") onRemove() + }} + style={{ + position: "absolute", + left: `${x * 100}%`, + top: `${y * 100}%`, + }}> +
) -} \ No newline at end of file +} diff --git a/front/components/editor/CourtPlayer.tsx b/front/components/editor/CourtPlayer.tsx index 045d5d0..8299050 100644 --- a/front/components/editor/CourtPlayer.tsx +++ b/front/components/editor/CourtPlayer.tsx @@ -1,10 +1,10 @@ -import {RefObject, useRef} from "react" +import { RefObject, useRef } from "react" import "../../style/player.css" -import {BallPiece} from "./BallPiece" +import { BallPiece } from "./BallPiece" import Draggable from "react-draggable" -import {PlayerPiece} from "./PlayerPiece" -import {Player} from "../../tactic/Player" -import {calculateRatio} from "../../Utils" +import { PlayerPiece } from "./PlayerPiece" +import { Player } from "../../tactic/Player" +import { calculateRatio } from "../../Utils" export interface PlayerProps { player: Player @@ -68,13 +68,20 @@ export default function CourtPlayer({ if (e.key == "Delete") onRemove() }}>
- {hasBall && ( onBallDrop(ballPiece.current!.getBoundingClientRect())} - position={{x:0, y: 0}}> -
- -
-
)} + {hasBall && ( + + onBallDrop( + ballPiece.current!.getBoundingClientRect(), + ) + } + position={{ x: 0, y: 0 }}> +
+ +
+
+ )}
r.ok, ) }} - courtType={courtType}/> + courtType={courtType} + /> ) } function EditorView({ - tactic: {id, name, content: initialContent}, - onContentChange, - onNameChange, - courtType, - }: EditorViewProps) { - + tactic: { id, name, content: initialContent }, + onContentChange, + onNameChange, + courtType, +}: EditorViewProps) { const isInGuestMode = id == -1 const [titleStyle, setTitleStyle] = useState({}) @@ -128,12 +137,14 @@ function EditorView({ getRackPlayers(Team.Opponents, content.players), ) - const [objects, setObjects] = useState(isBallOnCourt(content) ? [] : [{key: "ball"}]) + const [objects, setObjects] = useState( + isBallOnCourt(content) ? [] : [{ key: "ball" }], + ) const courtDivContentRef = useRef(null) - const canDetach = (bounds: DOMRect) => { + const isBoundsOnCourt = (bounds: DOMRect) => { const courtBounds = courtDivContentRef.current!.getBoundingClientRect() // check if refBounds overlaps courtBounds @@ -145,8 +156,6 @@ function EditorView({ ) } - - const onPieceDetach = (ref: HTMLDivElement, element: RackedPlayer) => { const refBounds = ref.getBoundingClientRect() const courtBounds = courtDivContentRef.current!.getBoundingClientRect() @@ -171,33 +180,40 @@ function EditorView({ }) } - const onObjectDetach = (ref: HTMLDivElement, rackedObject: RackedCourtObject) => { + const onObjectDetach = ( + ref: HTMLDivElement, + rackedObject: RackedCourtObject, + ) => { const refBounds = ref.getBoundingClientRect() const courtBounds = courtDivContentRef.current!.getBoundingClientRect() - const {x, y} = calculateRatio(refBounds, courtBounds) + const { x, y } = calculateRatio(refBounds, courtBounds) let courtObject: CourtObject switch (rackedObject.key) { case "ball": - const ballObj = content.objects.findIndex(o => o.type == "ball") - const playerCollidedIdx = getPlayerCollided(refBounds, content.players) - if(playerCollidedIdx != -1) { + const ballObj = content.objects.findIndex( + (o) => o.type == "ball", + ) + const playerCollidedIdx = getPlayerCollided( + refBounds, + content.players, + ) + if (playerCollidedIdx != -1) { onBallDropOnPlayer(playerCollidedIdx) setContent((content) => { - return{ + return { ...content, - objects : content.objects.toSpliced(ballObj, 1) + objects: content.objects.toSpliced(ballObj, 1), } }) return - } - else { + } else { courtObject = { type: "ball", rightRatio: x, - bottomRatio: y + bottomRatio: y, } } break @@ -207,81 +223,100 @@ function EditorView({ } setContent((content) => { - return ({ + return { ...content, - objects: [ - ...content.objects, - courtObject, - ] - }) + objects: [...content.objects, courtObject], + } }) } - const getPlayerCollided = (bounds: DOMRect, players: Player[]): number | -1 => { + const getPlayerCollided = ( + bounds: DOMRect, + players: Player[], + ): number | -1 => { for (let i = 0; i < players.length; i++) { const player = players[i] - const playerBounds = document.getElementById(player.id)!.getBoundingClientRect() + const playerBounds = document + .getElementById(player.id)! + .getBoundingClientRect() const doesOverlap = !( bounds.top > playerBounds.bottom || bounds.right < playerBounds.left || bounds.bottom < playerBounds.top || bounds.left > playerBounds.right ) - if(doesOverlap) { + if (doesOverlap) { return i } } return -1 } - - const onBallDropOnPlayer = (playerCollidedIdx : number) => { + const onBallDropOnPlayer = (playerCollidedIdx: number) => { setContent((content) => { - const ballObj = content.objects.findIndex(o => o.type == "ball") + const ballObj = content.objects.findIndex((o) => o.type == "ball") let player = content.players.at(playerCollidedIdx) as Player return { ...content, - players: content.players.toSpliced(playerCollidedIdx, 1, {...player, hasBall: true}), - objects : content.objects.toSpliced(ballObj, 1) + players: content.players.toSpliced(playerCollidedIdx, 1, { + ...player, + hasBall: true, + }), + objects: content.objects.toSpliced(ballObj, 1), } }) } const onBallDrop = (refBounds: DOMRect) => { + if (!isBoundsOnCourt(refBounds)) { + setContent((content) => { + const ballObj = content.objects.findIndex( + (o) => o.type == "ball", + ) + return { + ...content, + objects: content.objects.toSpliced(ballObj, 1), + } + }) + setObjects([{ key: "ball" }]) + } const playerCollidedIdx = getPlayerCollided(refBounds, content.players) - if(playerCollidedIdx != -1) { + if (playerCollidedIdx != -1) { setContent((content) => { return { ...content, - players: content.players.map((player) => ({...player, hasBall: false})), + players: content.players.map((player) => ({ + ...player, + hasBall: false, + })), } }) onBallDropOnPlayer(playerCollidedIdx) return } - if(content.objects.findIndex(o => o.type == "ball") != -1) { + if (content.objects.findIndex((o) => o.type == "ball") != -1) { return } const courtBounds = courtDivContentRef.current!.getBoundingClientRect() - const {x, y} = calculateRatio(refBounds, courtBounds) + const { x, y } = calculateRatio(refBounds, courtBounds) let courtObject: CourtObject courtObject = { type: "ball", rightRatio: x, - bottomRatio: y + bottomRatio: y, } setContent((content) => { return { ...content, - players: content.players.map((player) => ({...player, hasBall: false})), - objects: [ - ...content.objects, - courtObject, - ] + players: content.players.map((player) => ({ + ...player, + hasBall: false, + })), + objects: [...content.objects, courtObject], } }) } @@ -292,7 +327,7 @@ function EditorView({
- +
canDetach(div.getBoundingClientRect())} + canDetach={(div) => + isBoundsOnCourt(div.getBoundingClientRect()) + } onElementDetached={onPieceDetach} render={({ team, key }) => ( - canDetach(div.getBoundingClientRect())} - onElementDetached={onObjectDetach} - render={renderCourtObject}/> + + isBoundsOnCourt(div.getBoundingClientRect()) + } + onElementDetached={onObjectDetach} + render={renderCourtObject} + /> canDetach(div.getBoundingClientRect())} + canDetach={(div) => + isBoundsOnCourt(div.getBoundingClientRect()) + } onElementDetached={onPieceDetach} render={({ team, key }) => ( [ ...players, @@ -402,13 +443,18 @@ function EditorView({ }} onBallRemove={() => { setContent((content) => { - const ballObj = content.objects.findIndex(o => o.type == "ball") + const ballObj = content.objects.findIndex( + (o) => o.type == "ball", + ) return { ...content, - objects: content.objects.toSpliced(ballObj, 1) + objects: content.objects.toSpliced( + ballObj, + 1, + ), } }) - setObjects([{key: "ball"}]) + setObjects([{ key: "ball" }]) }} />
@@ -418,16 +464,16 @@ function EditorView({ ) } -function isBallOnCourt(content : TacticContent) { - if(content.players.findIndex(p => p.hasBall) != -1) { +function isBallOnCourt(content: TacticContent) { + if (content.players.findIndex((p) => p.hasBall) != -1) { return true } - return content.objects.findIndex(o => o.type == "ball") != -1 + return content.objects.findIndex((o) => o.type == "ball") != -1 } function renderCourtObject(courtObject: RackedCourtObject) { if (courtObject.key == "ball") { - return + return } throw new Error("unknown racked court object ", courtObject.key) }