Skip to content

Commit

Permalink
fix(app-board): make drag aware of panel mode
Browse files Browse the repository at this point in the history
  • Loading branch information
rams23 committed Jan 19, 2021
1 parent 8270e61 commit 22d892d
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import React, { RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { DndContext, DragEndEvent, DragMoveEvent, DragOverlay, DragStartEvent, Modifiers } from '@dnd-kit/core';
import { RectEntry, ViewRect } from '@dnd-kit/core/dist/types';
import { createPortal } from 'react-dom';
import { Transform } from '@dnd-kit/utilities';
import { GameEvent, GameEventType } from '../../types/gameEvents';
import { GameUIState } from '../../types/gameUIState';
import ConnectedCard from '../ConnectedCard';
import { PanelMode } from '../DeckPanel/DeckPanel';
import { DEFAULT_CARD_SIZE, PANEL_CARD_SCALE, PANEL_CARD_SIZE } from '../../../dimensions';

const DEBUG_ENABLED = false;
const DEBUG_ENABLED = true;

const debugPrint = (...data: any[]) => DEBUG_ENABLED && console.debug('[CardsGameListeners]', ...data);

Expand All @@ -26,6 +28,10 @@ type Props = {
* Current game board scale (used for target coordinates calculation).
*/
boardScale: number;
/**
* Current panel mode
*/
panelModeRef: RefObject<PanelMode>;
/**
* Current game board panning amount (used for target coordinates calculation).
*/
Expand All @@ -49,9 +55,6 @@ type AbsoluteWindowPositions = {
};
};

const CARD_WIDTH = 280;
const CARD_HEIGHT = 200;

let collisionTime = 0;
let moveTime = 0;
let modifiersTime = 0;
Expand All @@ -66,7 +69,14 @@ let movementStart = 0;
*
* Wrap panel and game with this
*/
const CardsGameListeners: React.FC<Props> = ({ onEvent, children, currentGameState, boardScale, panAmount }) => {
const CardsGameListeners: React.FC<Props> = ({
onEvent,
children,
currentGameState,
boardScale,
panAmount,
panelModeRef,
}) => {
const gameStateRef = useRef<GameUIState>(currentGameState);
const translationDeltaRef = useRef<TranslationDeltas>({});
const absoluteItemPositionWithResectToWindowRef = useRef<AbsoluteWindowPositions>({});
Expand Down Expand Up @@ -158,10 +168,21 @@ const CardsGameListeners: React.FC<Props> = ({ onEvent, children, currentGameSta
y: currentPosition.y + delta.y / panScaleRef.current,
};
} else {
const centerAdjustmentX = (CARD_WIDTH - CARD_WIDTH * panScaleRef.current) / 2;
const centerAdjustmentY = (CARD_HEIGHT - CARD_HEIGHT * panScaleRef.current) / 2;

const absoluteWindowPosition = absoluteItemPositionWithResectToWindowRef.current[cardId];
const centerAdjustmentX = (PANEL_CARD_SIZE.width - DEFAULT_CARD_SIZE.width * panScaleRef.current) / 2;
const centerAdjustmentY = (PANEL_CARD_SIZE.height - DEFAULT_CARD_SIZE.height * panScaleRef.current) / 2;

let absoluteWindowPosition = absoluteItemPositionWithResectToWindowRef.current[cardId];

/*
* dnd kit does not consider translation on calculating absolute position so we need to subtract the
* translation given by the card animation on hover
*/
if (panelModeRef.current === 'stacked') {
absoluteWindowPosition = {
...absoluteWindowPosition,
y: absoluteWindowPosition.y - 100,
};
}

// rescale window position considering panning and scale
newPosition = {
Expand All @@ -187,7 +208,7 @@ const CardsGameListeners: React.FC<Props> = ({ onEvent, children, currentGameSta
position: newPosition,
});
},
[onEvent],
[onEvent, panelModeRef],
);

const modifiers = useMemo(
Expand Down Expand Up @@ -228,19 +249,27 @@ const CardsGameListeners: React.FC<Props> = ({ onEvent, children, currentGameSta
panPositionRef.current.y,
};
} else {
let y = args.transform.y;
/*
* dnd kit does not consider translation on calculating absolute position so we need to subtract the
* translation given by the card animation on hover
*/
if (panelModeRef.current === 'stacked') {
y = y - 100;
}
newTransform = {
scaleY: 1,
scaleX: 1,
x: args.transform.x,
y: args.transform.y,
y: y,
};
}
const end = performance.now();
modifiersTime += end - start;
return newTransform;
},
] as Modifiers,
[draggingCardId],
[draggingCardId, panelModeRef],
);

const customCollisionDetectionStrategy = useCallback(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import DraggableCard from '../DraggableCard';
import styled, { css } from 'styled-components';
import { IconButton, AnimatedGrid } from '@pipeline/components';
Expand Down Expand Up @@ -42,10 +42,15 @@ const PanelButtons = styled.div`

type Props = {
cardsIds: string[];
panelModeRef: React.MutableRefObject<PanelMode>;
};

const DeckPanel: React.FC<Props> = ({ cardsIds }) => {
const [panelMode, setPanelMode] = useState<PanelMode>('tow-columns');
const DeckPanel: React.FC<Props> = ({ cardsIds, panelModeRef }) => {
const [panelMode, setPanelMode] = useState<PanelMode>('stacked');

useEffect(() => {
panelModeRef.current = panelMode;
}, [panelMode, panelModeRef]);

return (
<DroppablePanelArea mode={panelMode}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ const FixedPanel = styled.div<{ closed: boolean; mode: PanelMode }>`
${props =>
props.closed
? `transform: translate(${props.mode === 'stacked' ? 300 : 594}px);`
? `transform: translate(${
(props.mode === 'stacked' ? PANEL_ONE_COLUMNS_WIDTH : PANEL_TWO_COLUMNS_WIDTH) - 40
}px);`
: 'transform: translate(0);'} ${props =>
props.mode === 'stacked' ? `width: ${PANEL_ONE_COLUMNS_WIDTH}px;` : `width: ${PANEL_TWO_COLUMNS_WIDTH}px;`}
`;
Expand All @@ -48,6 +50,7 @@ const ToggleButton = styled.button`
background: transparent;
border: none;
border-radius: 9px;
cursor: pointer;
`;

const ToggleIndicator = styled.div`
Expand Down
15 changes: 12 additions & 3 deletions packages/game-app/src/gameView/components/GameView/GameView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useMemo } from 'react';
import React, { useCallback, useMemo, useRef } from 'react';
import CardsGameListeners from '../CardsGameListeners';
import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch';
import Board from '../Board';
Expand All @@ -11,6 +11,7 @@ import { selectors } from '../../slice';
import useCardEventHandler from '../../hooks/useCardEventHandler';
import DeckPanel from '../DeckPanel';
import BottomWidgetsRow from '../BottomWidgetsRow/BottomWidgetsRow';
import { PanelMode } from '../DeckPanel/DeckPanel';

type GameProps = {
pan: { x: number; y: number };
Expand All @@ -28,8 +29,16 @@ const Game: React.FC<GameProps> = React.memo(({ pan, scale, gameId, fitWindow, z

const { onCardEvent } = useCardEventHandler();

const panelModeRef = useRef<PanelMode>('stacked');

return (
<CardsGameListeners onEvent={onCardEvent} boardScale={scale} panAmount={pan} currentGameState={state}>
<CardsGameListeners
panelModeRef={panelModeRef}
onEvent={onCardEvent}
boardScale={scale}
panAmount={pan}
currentGameState={state}
>
<div className="board-wrapper">
<TransformComponent>
<Board>
Expand All @@ -40,7 +49,7 @@ const Game: React.FC<GameProps> = React.memo(({ pan, scale, gameId, fitWindow, z
</TransformComponent>
<BottomWidgetsRow fitWindow={fitWindow} zoomIn={zoomIn} zoomOut={zoomOut} />
</div>
<DeckPanel cardsIds={deckCardsIds} />
<DeckPanel panelModeRef={panelModeRef} cardsIds={deckCardsIds} />
</CardsGameListeners>
);
});
Expand Down

0 comments on commit 22d892d

Please sign in to comment.