Skip to content

Commit

Permalink
scrolling with the board
Browse files Browse the repository at this point in the history
  • Loading branch information
berg44 committed Sep 29, 2023
1 parent 4e12638 commit a2eef24
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 19 deletions.
19 changes: 11 additions & 8 deletions soos-client/src/features/gameView/GameView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from 'soos-gamelogic';
import { Player } from '~/src/components';
import { Board, ResourceBar, TradeWindow } from './components';
import BoardScaler from './components/board/BoardScaler';

type GameViewProps = {
socket: Socket;
Expand Down Expand Up @@ -136,14 +137,16 @@ export const GameView = (props: GameViewProps) => {
// </div>

<div className="Board">
<Board
socket={socket}
game={game}
makingPremoves={makingPremoves}
playerId={playerId}
possibleBuildActions={possibleBuildActions}
queuedPremoves = {queuedPremoves}
/>
<BoardScaler>
<Board
socket={socket}
game={game}
makingPremoves={makingPremoves}
playerId={playerId}
possibleBuildActions={possibleBuildActions}
queuedPremoves = {queuedPremoves}
/>
</BoardScaler>

{/* List of players' resource count & victory points */}
<div className="PlayerList">
Expand Down
11 changes: 11 additions & 0 deletions soos-client/src/features/gameView/components/board/Board.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#gameBoardContainer {
position: relative;

// hide scrollbars
overflow: hidden;
}


#gameBoard {
position: absolute;
}
23 changes: 12 additions & 11 deletions soos-client/src/features/gameView/components/board/Board.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { memo } from 'react';
import { Socket } from 'socket.io-client';
import {
BuildAction,
Expand All @@ -19,9 +20,9 @@ type BoardProps = {
queuedPremoves: BuildAction[];
};

const premoves: BuildAction[] = [];
//const premoves: BuildAction[] = [];

export const Board = (props: BoardProps) => {
export const Board = memo((props: BoardProps) => {
const { game, socket, makingPremoves, playerId, possibleBuildActions, queuedPremoves } = props;

function sendGameStateToServer() {
Expand Down Expand Up @@ -145,14 +146,14 @@ export const Board = (props: BoardProps) => {
}
const robber = <Robber game={game}></Robber>;

const premoveItems = premoves.map((action: BuildAction) => (
<li>{action.displayString()}</li>
));
const premoveDisplay = (
<div>
<ul> Your Premoves:{premoveItems}</ul>
</div>
);
// const premoveItems = premoves.map((action: BuildAction) => (
// <li>{action.displayString()}</li>
// ));
// const premoveDisplay = (
// <div>
// <ul> Your Premoves:{premoveItems}</ul>
// </div>
// );

return (
<div className="Board__body">
Expand All @@ -168,4 +169,4 @@ export const Board = (props: BoardProps) => {
{robber}
</div>
);
};
});
158 changes: 158 additions & 0 deletions soos-client/src/features/gameView/components/board/BoardScaler.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { useEffect, useState, memo } from 'react';
import { Board } from './Board';

const hexWidth = 100;
const hexHeight = 120;
const numRows = 7;
const numCols = 7;

// how much smaller is a Unit than a Square?

function getInitialXOffset() {
const boardWidth = numCols * hexWidth;
const windowWidth = window.innerWidth;
return windowWidth / 2 - boardWidth / 2;
}

function getInitialYOffset() {
const boardHeight = numRows * hexHeight;
const windowHeight = window.innerHeight;
return windowHeight / 2 - boardHeight / 2;
}

const mouseEvents = [
'mousedown',
'mouseup',
'mousemove',
'touchstart',
'touchend',
'touchcancel',
'touchmove',
'wheel',
];

const unitKinds = [
'⚔️',
'🧙',
'🌾',
];
type BoardScalerProps = {
children: React.ReactNode;
};

function BoardScaler(props:BoardScalerProps) {
const { children } = props;
const [ vsn, setVsn ] = useState<number>(0);
const triggerRerender = () => {
setVsn(vsn + 1);
};

const [ xOffset, setXOffset ] = useState<number>(getInitialXOffset());
const [ yOffset, setYOffset ] = useState<number>(getInitialYOffset());

const [ dragging, setDragging ] = useState<boolean>(false);
const [ lastMouseX, setLastMouseX ] = useState<number>(0);
const [ lastMouseY, setLastMouseY ] = useState<number>(0);
const [ mouseDownTime, setMouseDownTime ] = useState<number>(0);
const [ scale, setScale ] = useState<number>(1);

useEffect(() => {
const container = document.getElementById('gameBoardContainer');
const handleDrag = ((evt: MouseEvent | TouchEvent | WheelEvent) => {
let evtX = 0;
let evtY = 0;
if (evt.type.startsWith('touch')) {
evt.preventDefault();

const touch = (evt as TouchEvent).changedTouches[0];
if (touch) {
evtX = touch.clientX;
evtY = touch.clientY;
}
} else if (evt.type.startsWith('mouse')) {
const mouseEvt = evt as MouseEvent;

evtX = mouseEvt.clientX;
evtY = mouseEvt.clientY;

if (mouseEvt.button === 3) {
// ignore right clicks
return;
}
}

switch (evt.type) {
case 'touchstart':
case 'mousedown':
console.log('mouse down!');
setDragging(true);
setLastMouseX(evtX);
setLastMouseY(evtY);
setMouseDownTime(new Date().getTime());
break;
case 'touchend':
case 'touchcancel':
case 'mouseup':
setDragging(false);
break;
case 'touchmove':
case 'mousemove':
const dx = evtX - lastMouseX;
const dy = evtY - lastMouseY;
const distanceSq = dx * dx + dy * dy;

if (dragging && (new Date().getTime() - mouseDownTime > 100 || distanceSq > 500)) {
console.log('Mouse move!');
setXOffset(xOffset + dx);
setYOffset(yOffset + dy);

setLastMouseX(evtX);
setLastMouseY(evtY);
}
break;
case 'wheel':
const wheelEvt = evt as WheelEvent;
const scrollAmount = 1 - (wheelEvt.deltaY * .0002);
setScale(scale * scrollAmount);
break;
}
}) as EventListener;
mouseEvents.forEach(evt => {
container?.addEventListener(evt, handleDrag);
});

function handleResize() {
triggerRerender();
// TODO pan the map?
}
window.addEventListener('resize', handleResize);

return () => {
window.removeEventListener('resize', handleResize);
mouseEvents.forEach(evt => {
container?.removeEventListener(evt, handleDrag);
});
};
});

const containerStyles = {
width: window.innerWidth,
height: window.innerHeight,
};

const boardStyle = {
top: yOffset,
left: xOffset,
transform: `scale(${scale},${scale})`,
};

return (
<div id="gameBoardContainer" style={containerStyles} >
<div id="gameBoard" style={boardStyle}>
{children}
</div>
</div>
);
}

export default BoardScaler;

0 comments on commit a2eef24

Please sign in to comment.