Skip to content

Commit fa7297f

Browse files
authored
Merge pull request #4 from NHNerd/dev
MPV 08
2 parents 2f198c6 + a51856f commit fa7297f

8 files changed

Lines changed: 266 additions & 181 deletions

File tree

src/components/draggable/Draggable.tsx

Lines changed: 59 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,25 @@
11
import React, { useEffect, useRef, useState } from 'react';
2-
import type {
3-
XYType,
4-
CardType,
5-
CardHistoryType,
6-
BtnType,
7-
DragsStatusType,
8-
DevSpeedControlType,
9-
} from '../../types/types';
2+
import type { XYType, CardType, DragsStatusType, DevSpeedControlType } from '../../types/types';
103
import { fling } from './features/calc';
11-
import { cardOutHndlr, dragCountUpdate } from './features/actions.ts';
4+
import { dragCountUpdate } from './features/actions.ts';
125
// import { cardOutHndlr, CardOutHndlrType } from './features/actions.ts';
13-
import { nameFromImg, devChangeStatus, devInfoCardOut } from '../../dev/debugVisual/features.ts';
6+
import { nameFromImg, devChangeStatus } from '../../dev/debugVisual/features.ts';
7+
import SideGlow from './components/SideGlow.tsx';
148
import DraggableCss from './Draggable.module.css';
159

16-
type RemoveCardType = (deck: CardType[], lastPos: XYType) => CardType[];
17-
1810
type Props = {
1911
children: React.ReactNode;
2012
draggedId: React.RefObject<Set<number>>;
21-
deck: CardType[];
2213
setDeck: React.Dispatch<React.SetStateAction<CardType[]>>;
2314
deckRef: React.RefObject<CardType[]>;
2415
card: CardType;
2516
rotateRand: number;
26-
deckHistory: React.RefObject<CardHistoryType[]>;
27-
deckHistoryTop: React.RefObject<CardHistoryType> | React.RefObject<null>;
2817
setDevDragsStatus: React.Dispatch<React.SetStateAction<DragsStatusType[]>>;
2918
dragCountRef: React.RefObject<number>;
3019
dragCountLimit: React.RefObject<number>;
31-
dragCount: number;
3220
setDragCount: React.Dispatch<React.SetStateAction<number>>;
3321
devSpeed: React.RefObject<DevSpeedControlType>;
22+
cardOutHndlr: any;
3423
};
3524

3625
const flingAddRL = (
@@ -52,19 +41,16 @@ const flingAddRL = (
5241
const Draggable = ({
5342
children,
5443
draggedId,
55-
deck,
5644
setDeck,
5745
deckRef,
5846
card,
5947
rotateRand,
60-
deckHistory,
61-
deckHistoryTop,
6248
setDevDragsStatus,
6349
dragCountRef,
6450
dragCountLimit,
65-
dragCount,
6651
setDragCount,
6752
devSpeed,
53+
cardOutHndlr,
6854
}: Props) => {
6955
const pointerIdRef = useRef<number | null>(null); //* Multi-touch
7056

@@ -78,7 +64,7 @@ const Draggable = ({
7864
const xyMove = useRef<XYType>({ x: 0, y: 0 });
7965
const xyPrev = useRef<XYType>({ x: 0, y: 0 });
8066

81-
const [xy, setXy] = useState<XYType>({ x: 0, y: 0 });
67+
const [xy, setXy] = useState<XYType>(card.comeBack ? card.lastPos : { x: 0, y: 0 });
8268
const xyRef = useRef(xy);
8369

8470
const dragHistory = React.useRef<{ pos: XYType; time: number }[]>([]);
@@ -87,32 +73,12 @@ const Draggable = ({
8773
const comeBackToComeToDeckFlag = React.useRef<boolean>(false);
8874
const comeBackFlag = React.useRef<boolean>(true);
8975
const flingFlag = React.useRef<boolean>(true);
90-
91-
const removeCard: RemoveCardType = (deck, lastPos) => {
92-
return [...deck].filter((cardItem) => {
93-
if (cardItem.id === card.id) {
94-
delete cardItem.btnLR;
95-
deckHistory.current.push({ ...cardItem, lastPos });
96-
}
97-
return cardItem.id !== card.id;
98-
});
99-
};
76+
const outFlag = React.useRef<boolean>(false);
10077

10178
useEffect(() => {
10279
xyRef.current = xy;
10380
}, [xy]);
10481

105-
const isComeBack = useRef<boolean>(false);
106-
useEffect(() => {
107-
isComeBack.current = deckRef.current.some(
108-
(cardItem) => cardItem.id === card.id && cardItem?.comeBack === true
109-
);
110-
111-
if (isComeBack.current && xyRef.current.x === 0 && deckHistoryTop.current?.lastPos) {
112-
setXy(deckHistoryTop.current?.lastPos);
113-
}
114-
}, [deck.length]);
115-
11682
useEffect(() => {
11783
let frameId: number;
11884

@@ -122,26 +88,25 @@ const Draggable = ({
12288
frameId = requestAnimationFrame(animate);
12389

12490
// Не уверен что это хорошо все время обьвлять функцию, но лучше так чем в 3 местах одинаковый код
125-
const flingHndlr = () => {
126-
cardOutHndlr(card.id, deckRef, setDeck, xyRef, setXy, draggedId, removeCard, flingSpeed);
127-
dragCountUpdate(draggedId, dragCountLimit, dragCountRef, dragCount, setDragCount);
128-
//? DEV
129-
devInfoCardOut(setDevDragsStatus, deckRef.current, card, dragCountRef);
91+
const flingHndlr = (codePoint: string) => {
92+
cardOutHndlr(card.id, Math.max(Math.sign(xyPrev.current.x), 0) ? 'r' : 'l', xyPrev.current, codePoint);
93+
13094
flingFlag.current = true;
95+
outFlag.current = true;
13196
};
13297

133-
//!--------------------------------------------------------------
13498
if (
13599
//* Fling BTN
136100
draggedId.current.has(card.id) &&
137101
card?.btnLR &&
138102
!flingSpeed.current
139103
) {
140104
if (isCardOut) {
141-
flingHndlr();
105+
if (outFlag.current) return;
106+
flingHndlr('fling BTN');
142107
return;
143108
}
144-
console.log(2);
109+
145110
setXy((prev) => {
146111
let speedX = (Math.max(window.innerWidth, cardWidth.current * 2) / cardWidth.current) * 3 + 8;
147112
let speedY = 0.92 + speedX / 1600;
@@ -157,11 +122,12 @@ const Draggable = ({
157122
});
158123
xyPrev.current = { ...xyRef.current };
159124

160-
//? DEV
161-
devChangeStatus(setDevDragsStatus, card, 'fling', dragCountRef);
162-
}
163-
//!--------------------------------------------------------------
164-
else if (isDraggingRef.current) {
125+
// if (flingFlag.current) {
126+
// //? DEV
127+
// // devChangeStatus(setDevDragsStatus, card, 'fling', dragCountRef);
128+
// flingFlag.current = false;
129+
// }
130+
} else if (isDraggingRef.current) {
165131
//* Drag
166132
if (xyMove.current.x || xyMove.current.y) {
167133
const dx = xyMove.current.x - xyStart.current.x;
@@ -180,7 +146,8 @@ const Draggable = ({
180146
!card?.comeBack
181147
) {
182148
if (isCardOut) {
183-
flingHndlr();
149+
if (outFlag.current) return;
150+
flingHndlr('fling Edge');
184151
return;
185152
}
186153
let devSpeedControl = 1;
@@ -195,6 +162,9 @@ const Draggable = ({
195162
if (flingFlag.current) {
196163
flingAddRL(card, deckRef, xyRef.current, setDeck);
197164
flingFlag.current = false;
165+
166+
//? DEV
167+
devChangeStatus(setDevDragsStatus, card, 'fling', dragCountRef);
198168
}
199169
} else {
200170
//* Return to deck
@@ -220,22 +190,15 @@ const Draggable = ({
220190
//? DEV
221191
setDevDragsStatus((prev) => {
222192
const fresh = [...prev];
223-
for (let i = 0; i < dragCountRef.current; i++) {
224-
if (!prev[i]) continue;
225-
if (prev[i].id === card.id) {
226-
fresh[i].status = 'sleep';
227-
break;
228-
}
193+
const index = fresh.findIndex((item) => item?.id === card.id);
194+
if (index !== -1) {
195+
fresh[index] = { ...fresh[index], status: 'sleep' };
229196
}
230197
return fresh;
231198
});
232199
comeBackFlag.current = true;
233200

234-
dragCountUpdate(draggedId, dragCountLimit, dragCountRef, dragCount, setDragCount);
235-
236-
//! Bag - now если в very-slow оттащить много карт и потом переключиться в normal
237-
//! то не все карты удаляются из draggedId
238-
//! console.log('💣 trying to remove', card.id, xyRef.current, draggedId.current);
201+
dragCountUpdate(draggedId, dragCountLimit, dragCountRef, setDragCount);
239202
return;
240203
}
241204

@@ -250,11 +213,9 @@ const Draggable = ({
250213
delete fresh[i]?.btnLR;
251214
}
252215
}
216+
253217
return fresh;
254218
});
255-
256-
//? DEV
257-
devChangeStatus(setDevDragsStatus, card, 'backToDeck', dragCountRef);
258219
}
259220

260221
setXy((prev) => {
@@ -268,13 +229,16 @@ const Draggable = ({
268229
if (comeBackFlag.current && !card?.comeBack) {
269230
//? DEV
270231
devChangeStatus(setDevDragsStatus, card, 'backToDeck', dragCountRef);
232+
233+
outFlag.current = false;
271234
comeBackFlag.current = false;
272235
}
273236
}
274237
} else {
275238
//* Fling
276239
if (isCardOut) {
277-
flingHndlr();
240+
if (outFlag.current) return;
241+
flingHndlr('fling');
278242
return;
279243
}
280244

@@ -284,7 +248,10 @@ const Draggable = ({
284248
if (devSpeed.current === 'slow') devSpeedControl = 0.4;
285249
else if (devSpeed.current === 'very-slow') devSpeedControl = 0.04;
286250

287-
return { x: prev.x + speed.x * 8 * devSpeedControl, y: prev.y + speed.y * 6 * devSpeedControl };
251+
return {
252+
x: prev.x + speed.x * 8 * devSpeedControl,
253+
y: prev.y + speed.y * 6 * devSpeedControl,
254+
};
288255
});
289256
xyPrev.current = { ...xyRef.current };
290257

@@ -311,7 +278,6 @@ const Draggable = ({
311278

312279
const hndlrStart = (e: PointerEvent) => {
313280
e.preventDefault();
314-
315281
if (isDraggingRef.current) return;
316282
//TODO //TODO //TODO //TODO //TODO //TODO //TODO //TODO
317283
const cardIndex = deckRef.current.findIndex((cardItem) => cardItem.id === card.id);
@@ -341,10 +307,9 @@ const Draggable = ({
341307
pointerIdRef.current = e.pointerId;
342308

343309
draggedId.current.add(card.id);
344-
345310
dragHistory.current = [{ pos: { x: e.clientX, y: e.clientY }, time: performance.now() }];
346311

347-
dragCountUpdate(draggedId, dragCountLimit, dragCountRef, dragCount, setDragCount);
312+
dragCountUpdate(draggedId, dragCountLimit, dragCountRef, setDragCount);
348313
// console.log('🍏start');
349314

350315
// dev
@@ -372,9 +337,7 @@ const Draggable = ({
372337
const hndlrEnd = (e: PointerEvent) => {
373338
e.preventDefault();
374339
if (e.pointerId !== pointerIdRef.current) return;
375-
376340
if (!isDraggingRef.current) return;
377-
378341
if (xyRef.current.x === 0 && xyRef.current.x === 0) draggedId.current.delete(card.id);
379342

380343
isDraggingRef.current = false;
@@ -393,7 +356,7 @@ const Draggable = ({
393356
comeBackFlag.current = true;
394357
flingFlag.current = true;
395358

396-
dragCountUpdate(draggedId, dragCountLimit, dragCountRef, dragCount, setDragCount);
359+
dragCountUpdate(draggedId, dragCountLimit, dragCountRef, setDragCount);
397360
};
398361

399362
cardRef.current.addEventListener('pointerdown', hndlrStart);
@@ -408,23 +371,27 @@ const Draggable = ({
408371
window.removeEventListener('pointerleave', hndlrEnd);
409372
window.removeEventListener('pointercancel', hndlrEnd);
410373
};
411-
}, []); // слушатель создаётся ОДИН раз
374+
}, []);
412375

413376
return (
414-
<div
415-
ref={cardRef}
416-
className={DraggableCss.pos}
417-
draggable={false}
418-
onContextMenu={(e) => e.preventDefault()}
419-
style={{
420-
transform: `translate(${xy.x}px, ${xy.y}px) rotate(${rotateRand}deg)`,
421-
zIndex: isDragging ? 1 : 0,
422-
}}
423-
>
424-
<div className={DraggableCss.scale} style={{ scale: `${isDragging ? 1.2 : 1}` }}>
425-
{children}
377+
<>
378+
<div
379+
ref={cardRef}
380+
className={DraggableCss.pos}
381+
draggable={false}
382+
onContextMenu={(e) => e.preventDefault()}
383+
style={{
384+
transform: `translate(${xy.x}px, ${xy.y}px) rotate(${rotateRand}deg)`,
385+
zIndex: isDragging ? 1 : 0,
386+
}}
387+
>
388+
<div className={DraggableCss.scale} style={{ scale: `${isDragging ? 1.2 : 1}` }}>
389+
{children}
390+
</div>
426391
</div>
427-
</div>
392+
{/* needs put it on deck's level */}
393+
{/* <SideGlow xyRef={xyRef} /> */}
394+
</>
428395
);
429396
};
430397

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
.wrong,
2+
.right {
3+
position: fixed;
4+
height: 30%;
5+
top: 50%;
6+
transform: translate(0, -50%);
7+
width: 20%;
8+
9+
filter: blur(100px);
10+
pointer-events: none;
11+
user-select: none;
12+
touch-action: none;
13+
}
14+
15+
.wrong {
16+
background-color: rgb(251, 152, 220);
17+
left: -14%;
18+
}
19+
.right {
20+
background-color: palegreen;
21+
right: -14%;
22+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React, { useEffect, useRef, useState } from 'react';
2+
import type {
3+
XYType,
4+
CardType,
5+
CardHistoryType,
6+
BtnType,
7+
DragsStatusType,
8+
DevSpeedControlType,
9+
} from '../../../types/types';
10+
11+
import SideGlowCss from './SideGlow.module.css';
12+
13+
type Props = {
14+
devSpeed: React.RefObject<XYType>;
15+
};
16+
17+
const SideGlow = ({ xyRef }: Props) => {
18+
const halfScreen = window.innerWidth * 0.5;
19+
const fit = (halfScreen - xyRef.current.x) / halfScreen;
20+
21+
const center0Offset = (val: number, offset: number): number => {
22+
return Math.max(0, Math.min((val - offset) * (1 / (1 - offset)), 1));
23+
};
24+
25+
const left = center0Offset(fit - 1, 0.15);
26+
const right = center0Offset(1 - fit, 0.15);
27+
28+
// TODO сейчас с исчезновением карты резко пропадает glow
29+
30+
// TODO все такие нужно полумать как вынести этот элемент на уровень Deck
31+
return (
32+
<>
33+
<div className={SideGlowCss.wrong} style={{ opacity: left }}></div>
34+
<div className={SideGlowCss.right} style={{ opacity: right }}></div>
35+
</>
36+
);
37+
};
38+
39+
export default SideGlow;

0 commit comments

Comments
 (0)