add a way to remove players from the court

pull/11/head
Override-6 1 year ago committed by maxime.batista
parent a7ddad4c67
commit 2a5ece19a9

@ -0,0 +1,5 @@
<svg width="80" height="49" viewBox="0 0 80 49" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24.5 4.5H55.5C66.5457 4.5 75.5 13.4543 75.5 24.5C75.5 35.5457 66.5457 44.5 55.5 44.5H24.5C13.4543 44.5 4.5 35.5457 4.5 24.5C4.5 13.4543 13.4543 4.5 24.5 4.5Z"
stroke="black" stroke-width="9"/>
<line x1="24.5" y1="24.5" x2="55.5" y2="24.5" stroke="black" stroke-width="9" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 427 B

@ -1,6 +1,6 @@
import CourtSvg from '../../assets/basketball_court.svg';
import '../../style/basket_court.css';
import React, {MouseEvent, ReactElement, useRef, useState} from "react";
import React, {MouseEvent, ReactElement, useEffect, useRef, useState} from "react";
import Player from "./Player";
import Draggable from "react-draggable";
@ -15,23 +15,38 @@ export function BasketCourt() {
<CourtSvg
id="court-svg"
onClick={(e: MouseEvent) => {
console.log(e.target)
let bounds = divRef.current!.getBoundingClientRect();
let playerCount = players.length;
const bounds = divRef.current!.getBoundingClientRect();
if (playerCount >= TEAM_MAX_PLAYER) {
if (players.length >= TEAM_MAX_PLAYER) {
return;
}
// find a valid number for the player to place.
let playerIndex = players.findIndex((v, i) =>
v.key !== i.toString()
);
if (playerIndex == -1) {
playerIndex = players.length;
}
const player = (
<Player key={playerCount}
id={playerCount + 1}
<Player key={playerIndex}
id={playerIndex + 1}
x={e.clientX - bounds.x}
y={e.clientY - bounds.y}
bounds={{bottom: bounds.height, top: 0, left: 0, right: bounds.width}}
onRemove={() => {
setPlayers(players => {
// recompute the player's index as it may have been moved if
// previous players were removed and added.
const playerCurrentIndex = players.findIndex(p => p.key === playerIndex.toString())
return players.toSpliced(playerCurrentIndex, 1)
})
}}
/>
);
setPlayers([...players, player])
setPlayers(players => players.toSpliced(playerIndex, 0, player))
}}/>
{players}
</div>

@ -1,33 +1,50 @@
import React, {useEffect, useRef} from "react";
import React, {useRef} from "react";
import "../../style/player.css";
import RemoveIcon from "../../assets/icon/remove.svg";
import Draggable, {DraggableBounds} from "react-draggable";
export default function Player({id, x, y, bounds}: {
export interface PlayerOptions {
id: number,
x: number,
y: number,
bounds: DraggableBounds
}) {
bounds: DraggableBounds,
onRemove: () => void
}
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const playerRect = ref.current!.getBoundingClientRect();
bounds.bottom! -= playerRect.height / 2;
bounds.right! -= playerRect.width / 2;
}, [ref])
export default function Player({id, x, y, bounds, onRemove}: PlayerOptions) {
const ref = useRef<HTMLDivElement>(null);
return (
<Draggable
handle={".player-piece"}
nodeRef={ref}
bounds={bounds}
defaultPosition={{x: x, y: y}}>
defaultPosition={{x: x, y: y}}
>
<div ref={ref}
className="player"
className={"player"}
style={{
position: "absolute",
}}>
<p>{id}</p>
<div tabIndex={0}
className="player-content"
onKeyUp={e => {
if (e.key == "Delete")
onRemove()
}}>
<div className="player-selection-tab">
<RemoveIcon
className="player-selection-tab-remove"
onClick={() => onRemove()}/>
</div>
<div
className="player-piece">
<p>{id}</p>
</div>
</div>
</div>
</Draggable>
)

@ -6,8 +6,8 @@
--background-color: #d2cdd3;
--selected-team-primarycolor: #ffffff;
--selected-team-secondarycolor: #000000;
--selection-color: #3f7fc4
}

@ -1,10 +1,32 @@
/**
as the .player div content is translated,
the real .player div position is not were the user can expect.
Disable pointer events to this div as it may overlap on other components
on the court.
*/
.player {
pointer-events: none;
}
.player-content {
/*apply a translation to center the player piece when placed*/
transform: translate(-50%, -75%);
display: flex;
flex-direction: column;
align-content: center;
align-items: center;
outline: none;
}
.player-piece {
font-family: monospace;
pointer-events: all;
background-color: var(--selected-team-primarycolor);
color: var(--selected-team-secondarycolor);
border-width: 2px;
border-radius: 100px;
border-style: solid;
@ -17,8 +39,41 @@
align-items: center;
justify-content: center;
/*apply a translation to */
transform: translate(-50%, -50%);
user-select: none;
}
.player-selection-tab {
display: flex;
margin-bottom: 10%;
justify-content: center;
visibility: hidden;
}
.player-selection-tab-remove {
pointer-events: all;
width: 25%;
height: 25%;
}
.player-selection-tab-remove * {
stroke: red;
fill: white;
}
.player-selection-tab-remove:hover * {
fill: #f1dbdb;
stroke: #ff331a;
cursor: pointer;
}
.player:focus-within .player-selection-tab {
visibility: visible;
}
.player:focus-within .player-piece {
color: var(--selection-color);
}
.player:focus-within {
z-index: 1000;
}
Loading…
Cancel
Save