|
|
|
@ -1,4 +1,11 @@
|
|
|
|
|
import {CSSProperties, Dispatch, SetStateAction, useCallback, useRef, useState,} from "react"
|
|
|
|
|
import {
|
|
|
|
|
CSSProperties,
|
|
|
|
|
Dispatch,
|
|
|
|
|
SetStateAction,
|
|
|
|
|
useCallback,
|
|
|
|
|
useRef,
|
|
|
|
|
useState,
|
|
|
|
|
} from "react"
|
|
|
|
|
import "../style/editor.css"
|
|
|
|
|
import TitleInput from "../components/TitleInput"
|
|
|
|
|
import { BasketCourt } from "../components/editor/BasketCourt"
|
|
|
|
@ -7,7 +14,7 @@ import plainCourt from "../assets/court/full_court.svg"
|
|
|
|
|
import halfCourt from "../assets/court/half_court.svg"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import {BallPiece, CourtBall} from "../components/editor/BallPiece";
|
|
|
|
|
import { BallPiece } from "../components/editor/BallPiece"
|
|
|
|
|
|
|
|
|
|
import { Rack } from "../components/Rack"
|
|
|
|
|
import { PlayerPiece } from "../components/editor/PlayerPiece"
|
|
|
|
@ -57,6 +64,7 @@ interface RackedPlayer {
|
|
|
|
|
|
|
|
|
|
type RackedCourtObject = { key: "ball" }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export default function Editor({
|
|
|
|
|
id,
|
|
|
|
|
name,
|
|
|
|
@ -108,12 +116,11 @@ export default function Editor({
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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<CSSProperties>({})
|
|
|
|
@ -129,15 +136,15 @@ function EditorView({
|
|
|
|
|
const [opponents, setOpponents] = useState(
|
|
|
|
|
getRackPlayers(Team.Opponents, content.players),
|
|
|
|
|
)
|
|
|
|
|
const [objects, setObjects] = useState<RackedCourtObject[]>([{key: "ball"}])
|
|
|
|
|
|
|
|
|
|
const [objects, setObjects] = useState<RackedCourtObject[]>(
|
|
|
|
|
isBallOnCourt(content) ? [] : [{ key: "ball" }],
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const courtDivContentRef = useRef<HTMLDivElement>(null)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const isBoundsOnCourt = (bounds: DOMRect) => {
|
|
|
|
|
const courtDivContentRef = useRef<HTMLDivElement>(null)
|
|
|
|
|
|
|
|
|
|
const canDetach = (bounds: DOMRect) => {
|
|
|
|
|
const courtBounds = courtDivContentRef.current!.getBoundingClientRect()
|
|
|
|
|
|
|
|
|
|
// check if refBounds overlaps courtBounds
|
|
|
|
@ -174,6 +181,7 @@ function EditorView({
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const onObjectDetach = (
|
|
|
|
|
ref: HTMLDivElement,
|
|
|
|
|
rackedObject: RackedCourtObject,
|
|
|
|
|
) => {
|
|
|
|
|
const refBounds = ref.getBoundingClientRect()
|
|
|
|
@ -219,38 +227,9 @@ function EditorView({
|
|
|
|
|
...content,
|
|
|
|
|
objects: [...content.objects, courtObject],
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const onObjectDetach = (ref: HTMLDivElement, rackedObject: RackedCourtObject) => {
|
|
|
|
|
const refBounds = ref.getBoundingClientRect()
|
|
|
|
|
const courtBounds = courtDivContentRef.current!.getBoundingClientRect()
|
|
|
|
|
|
|
|
|
|
const {x, y} = calculateRatio(refBounds, courtBounds)
|
|
|
|
|
|
|
|
|
|
let courtObject: CourtObject
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (rackedObject.key) {
|
|
|
|
|
case "ball":
|
|
|
|
|
courtObject = {
|
|
|
|
|
type: "ball",
|
|
|
|
|
rightRatio: x,
|
|
|
|
|
bottomRatio: y
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
default:
|
|
|
|
|
throw new Error("unknown court object ", rackedObject.key)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setContent((content) =>
|
|
|
|
|
({
|
|
|
|
|
...content,
|
|
|
|
|
objects: [
|
|
|
|
|
...content.objects,
|
|
|
|
|
courtObject,
|
|
|
|
|
]
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getPlayerCollided = (
|
|
|
|
|
bounds: DOMRect,
|
|
|
|
|
players: Player[],
|
|
|
|
@ -487,7 +466,6 @@ function EditorView({
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function isBallOnCourt(content: TacticContent) {
|
|
|
|
|
if (content.players.findIndex((p) => p.hasBall) != -1) {
|
|
|
|
|
return true
|
|
|
|
@ -497,7 +475,7 @@ function isBallOnCourt(content: TacticContent) {
|
|
|
|
|
|
|
|
|
|
function renderCourtObject(courtObject: RackedCourtObject) {
|
|
|
|
|
if (courtObject.key == "ball") {
|
|
|
|
|
return <BallPiece/>
|
|
|
|
|
return <BallPiece />
|
|
|
|
|
}
|
|
|
|
|
throw new Error("unknown racked court object ", courtObject.key)
|
|
|
|
|
}
|
|
|
|
@ -552,4 +530,4 @@ function toSplicedPlayers(
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return players.toSpliced(idx, 1, ...(replace ? [player] : []))
|
|
|
|
|
}
|
|
|
|
|
}
|