チームプロジェクト-アニメーションポップアップ選手リスト
19953 ワード
チームプロジェクト-アニメーションポップアップ選手リスト
前回の整理
以前は各院の位置によって位置名を変えていました
今度選手リストを手に入れて、右クリックして、選手リストを載せます.
以降の名前を選択すると、名前が円に表示され、リストから消えます.
インプリメンテーション
まずフロント開発を一緒に行ったチームメンバーがTSを使って開発し、右クリックで選手リストを開くことも実現しました목데이터 (Mock Data)
type Players = {
id: number;
//등번호
name: string;
already?: boolean;
//들어가있는지 유무
//주장 유무랑 포지션 추가 예정
}
export const playersList: Players[] = [
{
id: 1,
name: "1번",
already: true
},
{
id: 2,
name: "2번",
already: true
},
{
id: 3,
name: "3번",
already: true
},
{
id: 4,
name: "4번",
already: true
},
{
id: 5,
name: "5번",
already: true
},
{
id: 6,
name: "6번",
already: true
},
{
id: 7,
name: "7번",
already: true
},
{
id: 8,
name: "8번",
already: true
},
{
id: 9,
name: "9번",
already: true
},
{
id: 10,
name: "10번",
already: true
},
{
id: 11,
name: "11번",
already: true
},
{
id: 12,
name: "12번",
already: false
},
{
id: 13,
name: "13번",
already: false
},
{
id: 14,
name: "14번",
already: false
},
];
-----------------------------------------------------
CSS
.move {
background-color:skyblue;
width:80px;
height:80px;
border-radius:75px;
text-align:center;
margin:0 auto;
font-size:30px;
vertical-align:middle;
line-height:50px;
cursor: grab;
position: absolute;
}
.move:hover {
background-color: pink;
}
.formation {
width: 600px;
height: 950px;
background-image: url(https://velog.velcdn.com/images%2Fqnrl3442%2Fpost%2F733d5e03-5531-4e99-98e6-6f9a05c26c15%2Fformation.png);
}
.GK {
background-color:skyblue;
width:80px;
height:80px;
border-radius:75px;
text-align:center;
margin:0 auto;
font-size:30px;
vertical-align:middle;
line-height:50px;
cursor: not-allowed;
position: absolute;
}
.button {
border-radius:50%;
text-align:center;
font-size:30px;
vertical-align:middle;
line-height:50px;
}
-------------------------------------------------------------------
import React, { useState } from 'react';
import "./Formation.css";
import Draggable, { DraggableData } from 'react-draggable';
import axios from 'axios';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import { Button } from '@mui/material';
import { playersList } from './data';
//s 조심
function Formation() {
type PlayerType = {
id: number;
name: string;
already: boolean;
};
const [playerList, setPlayerList] = useState(playersList);
//s 조심
const [Status, SetStatus] = useState(true)
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
event.preventDefault();
//event.preventDefault() 브라우저 우클릭을 막아준다.
};
const handleClose = () => {
setAnchorEl(null);
};
const onStatusHandler = () => {
SetStatus(!Status)
}
const readDB = () => {
if (Status) {
console.log("read")
axios.get('/api/readUser') // res = axios 이런식으로 해서 res를 가지고 있어야됨 방법 찾아보자
.then(res => {
console.log(res.data)
// const name = res.data.UserName
// const x = res.data.x
// const y = res.data.y
// console.log(name,x,y)
})
console.log("포메이션 원에 위에서 받은 선수 데이터 넣어주기")
} else {
console.log("send")
const body = {
Status: Status,
first_Position: Content1 //첫번째 요소 포지션
}
axios.post('/api/sendUser', body)
.then(res => {
console.log(res.data)
})
}
}
// 포지션 위치 값 보내는 방법
// const [Position1, SetPosition1] = useState({ x: 0, y: 0 });
// const trackPos = (data) => {
// SetPosition1({ x: data.x, y: data.y });
// };
// let body = {
// first: Position1
// }
// axios.post('/api/position', body)
// .then(res => {
// console.log(res.data)
// })
const [Content1, SetContent1] = useState("ST");
------------------------ Content2~9------------
const [Content10, SetContent10] = useState("RB");
const onContentHandler1 = (props: string) => {
SetContent1(props)
}
const onDragHandler1 = (data: DraggableData) => {
if (data.x > 80 && data.y < 120 && data.x < 450) {
onContentHandler1("ST")
} else if (data.x < 80 && data.y < 200) {
onContentHandler1("LW")
} else if (data.x > 450 && data.y < 200) {
onContentHandler1("RW")
} else if (data.x > 80 && data.y > 120 && data.y < 185 && data.x < 450) {
onContentHandler1("CF")
} else if (data.x > 80 && data.y > 185 && data.y < 275 && data.x < 450) {
onContentHandler1("CAM")
} else if (data.x < 80 && data.y > 200 && data.y < 440) {
onContentHandler1("LM")
} else if (data.x > 450 && data.y > 200 && data.y < 440) {
onContentHandler1("RM")
} else if (data.x > 80 && data.y > 275 && data.y < 460 && data.x < 450) {
onContentHandler1("CM")
} else if (data.x < 80 && data.y > 440) {
onContentHandler1("LB")
} else if (data.x > 450 && data.y > 440) {
onContentHandler1("RB")
} else if (data.x > 80 && data.y > 460 && data.y < 560 && data.x < 450) {
onContentHandler1("CDM")
} else if (data.x > 80 && data.y > 560 && data.x < 450) {
onContentHandler1("CB")
}
}
--------------------------- onDragHandler2~9--------------------------------
const onContentHandler10 = (props: string) => {
SetContent10(props)
}
const onDragHandler10 = (data: DraggableData) => {
if (data.x > 80 && data.y < 120 && data.x < 450) {
onContentHandler10("ST")
} else if (data.x < 80 && data.y < 200) {
onContentHandler10("LW")
} else if (data.x > 450 && data.y < 200) {
onContentHandler10("RW")
} else if (data.x > 80 && data.y > 120 && data.y < 185 && data.x < 450) {
onContentHandler10("CF")
} else if (data.x > 80 && data.y > 185 && data.y < 275 && data.x < 450) {
onContentHandler10("CAM")
} else if (data.x < 80 && data.y > 200 && data.y < 440) {
onContentHandler10("LM")
} else if (data.x > 450 && data.y > 200 && data.y < 440) {
onContentHandler10("RM")
} else if (data.x > 80 && data.y > 275 && data.y < 460 && data.x < 450) {
onContentHandler10("CM")
} else if (data.x < 80 && data.y > 440) {
onContentHandler10("LB")
} else if (data.x > 450 && data.y > 440) {
onContentHandler10("RB")
} else if (data.x > 80 && data.y > 460 && data.y < 560 && data.x < 450) {
onContentHandler10("CDM")
} else if (data.x > 80 && data.y > 560 && data.x < 450) {
onContentHandler10("CB")
}
}
return (
<div className="formation">
<button onClick={() => {
onStatusHandler()
readDB()
}}>
{Status ? "편집" : "편집 완료"}
</button>
<Draggable
disabled={Status}
defaultPosition={{ x: 145, y: 80 }}
onDrag={(e, data) => onDragHandler1(data)}
bounds={{ top: 0, left: 0, right: 520, bottom: 740 }}
// onStop={(e, data) => trackPos(data)}
// 포지션 위치 값 보내는 방법
>
<div className="move">
<Button className="button"
disabled={Status}
id="basic-button"
aria-controls={open ? 'basic-menu' : undefined}
aria-haspopup="true"
aria-expanded={open ? 'true' : undefined}
onContextMenu={handleClick}
><div>{Content1}</div>
</Button>
</div>
</Draggable >
<Menu
id="basic-menu"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
'aria-labelledby': 'basic-button',
}}
PaperProps={{
style: {
maxHeight: "200px",
width: '20ch',
},
}}
//스크롤 만드는것
>
{playerList.map((player): JSX.Element => {
return (
// player.already === false &&
<MenuItem onClick={handleClose}>{player.name}</MenuItem>
);
})}
</Menu>
{/* <MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem> */}
<Draggable
disabled={Status}
defaultPosition={{ x: 380, y: 80 }}
onDrag={(e, data) => onDragHandler2(data)}
bounds={{ top: 0, left: 0, right: 520, bottom: 740 }}
>
<div className="move">
<div>{Content2}</div>
</div>
</Draggable>
--------- 3~10번 Draggable------------------
<Draggable
disabled={true}
defaultPosition={{ x: 260, y: 790 }}
>
<div className="GK">
<div>GK</div>
</div>
</Draggable>
</div >
)
}
export default Formation
重ね合わせたコードは――――ここではこれを短く表しています
コードを説明すると首のデータが得られます
次にplaylistにデフォルト値を入れてアンカーelとopenを作成します
私はMenuというものを作って、ドラッグ可能なボタンからmenuをロードさせたと思います.
私が書いたコードではないので、正しいかどうか分かりません.
まずリストに現れて、後で私が体現します
ディレクトリデータにはfalseという値があると聞きましたが、リストに表示するためにコードを生成する必要があります.
だからmenuでmenuitemを作成するときはifで一度フィルタします {playerList.map((player, idx) => {
if(player.already === false){
return (
<MenuItem
onClick={() => {handleClose()}}
key={idx}
>
{player.name}
</MenuItem>
)
}
})}
そしてidx値を与え、各リストにキー値を付けた.
その後首のデータを修正してテストしました
名簿がはっきりしている
後で選んだらもう値段を変えようと思った.
今から見ればMenuitemにはhandleClose()がかかっています
だからそれを使ってみたいと思って、HandleCloseにプレイヤーを道具として入れました.
では、選ばれると、その選ばれた選手が入ってきます. const handleClose = ({id, name, already}) => {
setAnchorEl();
setPlayerList(playerList.map((player) =>
player.id === id ? { ...player, already: !already} : player)
)
}
Flopsを直接構造分解し、setPlayerListを使用して現在受信しているidと比較します.
3つの演算子で1つ書きました.同じidがあれば、既存のものを置き換えます.同じでなければ、自然に任せます.
これで変わり、選択した値がリストから消えてしまいます
しかし、1番を選んで2番を選ぶと、1番のものをfalseに変えるにはどうすればいいのでしょうか.
どう考えても仕方がない
最初は、同じように3つの演算子を使用してtrueをすべてfalseに変換し、選択した値をtrueに再変換できると思います.
一度行っても戻らないわけにはいかない
だからこれを後で実施することにしました.まず選ばれた選手の名前を円の上に置くことにしました.
だから私はまずあなたにconst [Name1, SetName1] = useState("")
を作って、それからName Handlerを作りました.
メニューonClickに掛けて、propsで同じくその選手をゲットしました
そしてNameをDragableに入れると、名前が選ばれた選手に変わりました.
比較のために、2番目の円も同じようにして、Name Handler 2を作って掛けました.
でも1番の値は2番の円です
一人では難しいので、隊員と一緒にディスコで行いますが、二人とも原因が見つからず、次回やることにしました
次の文章につづく
Reference
この問題について(チームプロジェクト-アニメーションポップアップ選手リスト), 我々は、より多くの情報をここで見つけました
https://velog.io/@qnrl3442/asd
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
목데이터 (Mock Data)
type Players = {
id: number;
//등번호
name: string;
already?: boolean;
//들어가있는지 유무
//주장 유무랑 포지션 추가 예정
}
export const playersList: Players[] = [
{
id: 1,
name: "1번",
already: true
},
{
id: 2,
name: "2번",
already: true
},
{
id: 3,
name: "3번",
already: true
},
{
id: 4,
name: "4번",
already: true
},
{
id: 5,
name: "5번",
already: true
},
{
id: 6,
name: "6번",
already: true
},
{
id: 7,
name: "7번",
already: true
},
{
id: 8,
name: "8번",
already: true
},
{
id: 9,
name: "9번",
already: true
},
{
id: 10,
name: "10번",
already: true
},
{
id: 11,
name: "11번",
already: true
},
{
id: 12,
name: "12번",
already: false
},
{
id: 13,
name: "13번",
already: false
},
{
id: 14,
name: "14번",
already: false
},
];
-----------------------------------------------------
CSS
.move {
background-color:skyblue;
width:80px;
height:80px;
border-radius:75px;
text-align:center;
margin:0 auto;
font-size:30px;
vertical-align:middle;
line-height:50px;
cursor: grab;
position: absolute;
}
.move:hover {
background-color: pink;
}
.formation {
width: 600px;
height: 950px;
background-image: url(https://velog.velcdn.com/images%2Fqnrl3442%2Fpost%2F733d5e03-5531-4e99-98e6-6f9a05c26c15%2Fformation.png);
}
.GK {
background-color:skyblue;
width:80px;
height:80px;
border-radius:75px;
text-align:center;
margin:0 auto;
font-size:30px;
vertical-align:middle;
line-height:50px;
cursor: not-allowed;
position: absolute;
}
.button {
border-radius:50%;
text-align:center;
font-size:30px;
vertical-align:middle;
line-height:50px;
}
-------------------------------------------------------------------
import React, { useState } from 'react';
import "./Formation.css";
import Draggable, { DraggableData } from 'react-draggable';
import axios from 'axios';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import { Button } from '@mui/material';
import { playersList } from './data';
//s 조심
function Formation() {
type PlayerType = {
id: number;
name: string;
already: boolean;
};
const [playerList, setPlayerList] = useState(playersList);
//s 조심
const [Status, SetStatus] = useState(true)
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
event.preventDefault();
//event.preventDefault() 브라우저 우클릭을 막아준다.
};
const handleClose = () => {
setAnchorEl(null);
};
const onStatusHandler = () => {
SetStatus(!Status)
}
const readDB = () => {
if (Status) {
console.log("read")
axios.get('/api/readUser') // res = axios 이런식으로 해서 res를 가지고 있어야됨 방법 찾아보자
.then(res => {
console.log(res.data)
// const name = res.data.UserName
// const x = res.data.x
// const y = res.data.y
// console.log(name,x,y)
})
console.log("포메이션 원에 위에서 받은 선수 데이터 넣어주기")
} else {
console.log("send")
const body = {
Status: Status,
first_Position: Content1 //첫번째 요소 포지션
}
axios.post('/api/sendUser', body)
.then(res => {
console.log(res.data)
})
}
}
// 포지션 위치 값 보내는 방법
// const [Position1, SetPosition1] = useState({ x: 0, y: 0 });
// const trackPos = (data) => {
// SetPosition1({ x: data.x, y: data.y });
// };
// let body = {
// first: Position1
// }
// axios.post('/api/position', body)
// .then(res => {
// console.log(res.data)
// })
const [Content1, SetContent1] = useState("ST");
------------------------ Content2~9------------
const [Content10, SetContent10] = useState("RB");
const onContentHandler1 = (props: string) => {
SetContent1(props)
}
const onDragHandler1 = (data: DraggableData) => {
if (data.x > 80 && data.y < 120 && data.x < 450) {
onContentHandler1("ST")
} else if (data.x < 80 && data.y < 200) {
onContentHandler1("LW")
} else if (data.x > 450 && data.y < 200) {
onContentHandler1("RW")
} else if (data.x > 80 && data.y > 120 && data.y < 185 && data.x < 450) {
onContentHandler1("CF")
} else if (data.x > 80 && data.y > 185 && data.y < 275 && data.x < 450) {
onContentHandler1("CAM")
} else if (data.x < 80 && data.y > 200 && data.y < 440) {
onContentHandler1("LM")
} else if (data.x > 450 && data.y > 200 && data.y < 440) {
onContentHandler1("RM")
} else if (data.x > 80 && data.y > 275 && data.y < 460 && data.x < 450) {
onContentHandler1("CM")
} else if (data.x < 80 && data.y > 440) {
onContentHandler1("LB")
} else if (data.x > 450 && data.y > 440) {
onContentHandler1("RB")
} else if (data.x > 80 && data.y > 460 && data.y < 560 && data.x < 450) {
onContentHandler1("CDM")
} else if (data.x > 80 && data.y > 560 && data.x < 450) {
onContentHandler1("CB")
}
}
--------------------------- onDragHandler2~9--------------------------------
const onContentHandler10 = (props: string) => {
SetContent10(props)
}
const onDragHandler10 = (data: DraggableData) => {
if (data.x > 80 && data.y < 120 && data.x < 450) {
onContentHandler10("ST")
} else if (data.x < 80 && data.y < 200) {
onContentHandler10("LW")
} else if (data.x > 450 && data.y < 200) {
onContentHandler10("RW")
} else if (data.x > 80 && data.y > 120 && data.y < 185 && data.x < 450) {
onContentHandler10("CF")
} else if (data.x > 80 && data.y > 185 && data.y < 275 && data.x < 450) {
onContentHandler10("CAM")
} else if (data.x < 80 && data.y > 200 && data.y < 440) {
onContentHandler10("LM")
} else if (data.x > 450 && data.y > 200 && data.y < 440) {
onContentHandler10("RM")
} else if (data.x > 80 && data.y > 275 && data.y < 460 && data.x < 450) {
onContentHandler10("CM")
} else if (data.x < 80 && data.y > 440) {
onContentHandler10("LB")
} else if (data.x > 450 && data.y > 440) {
onContentHandler10("RB")
} else if (data.x > 80 && data.y > 460 && data.y < 560 && data.x < 450) {
onContentHandler10("CDM")
} else if (data.x > 80 && data.y > 560 && data.x < 450) {
onContentHandler10("CB")
}
}
return (
<div className="formation">
<button onClick={() => {
onStatusHandler()
readDB()
}}>
{Status ? "편집" : "편집 완료"}
</button>
<Draggable
disabled={Status}
defaultPosition={{ x: 145, y: 80 }}
onDrag={(e, data) => onDragHandler1(data)}
bounds={{ top: 0, left: 0, right: 520, bottom: 740 }}
// onStop={(e, data) => trackPos(data)}
// 포지션 위치 값 보내는 방법
>
<div className="move">
<Button className="button"
disabled={Status}
id="basic-button"
aria-controls={open ? 'basic-menu' : undefined}
aria-haspopup="true"
aria-expanded={open ? 'true' : undefined}
onContextMenu={handleClick}
><div>{Content1}</div>
</Button>
</div>
</Draggable >
<Menu
id="basic-menu"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
'aria-labelledby': 'basic-button',
}}
PaperProps={{
style: {
maxHeight: "200px",
width: '20ch',
},
}}
//스크롤 만드는것
>
{playerList.map((player): JSX.Element => {
return (
// player.already === false &&
<MenuItem onClick={handleClose}>{player.name}</MenuItem>
);
})}
</Menu>
{/* <MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem> */}
<Draggable
disabled={Status}
defaultPosition={{ x: 380, y: 80 }}
onDrag={(e, data) => onDragHandler2(data)}
bounds={{ top: 0, left: 0, right: 520, bottom: 740 }}
>
<div className="move">
<div>{Content2}</div>
</div>
</Draggable>
--------- 3~10번 Draggable------------------
<Draggable
disabled={true}
defaultPosition={{ x: 260, y: 790 }}
>
<div className="GK">
<div>GK</div>
</div>
</Draggable>
</div >
)
}
export default Formation
{playerList.map((player, idx) => {
if(player.already === false){
return (
<MenuItem
onClick={() => {handleClose()}}
key={idx}
>
{player.name}
</MenuItem>
)
}
})}
const handleClose = ({id, name, already}) => {
setAnchorEl();
setPlayerList(playerList.map((player) =>
player.id === id ? { ...player, already: !already} : player)
)
}
Reference
この問題について(チームプロジェクト-アニメーションポップアップ選手リスト), 我々は、より多くの情報をここで見つけました https://velog.io/@qnrl3442/asdテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol