From 548ec5f09a71b7615a57a52c8995c7594de72ade Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Fri, 7 Aug 2020 12:55:16 +1000 Subject: [PATCH] Added grid snapping to map tokens --- src/components/map/Map.js | 1 + src/components/map/MapToken.js | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/components/map/Map.js b/src/components/map/Map.js index 2e7d854..fa0c28a 100644 --- a/src/components/map/Map.js +++ b/src/components/map/Map.js @@ -252,6 +252,7 @@ function Map({ } mapState={mapState} fadeOnHover={selectedToolId === "drawing"} + map={map} /> ))} diff --git a/src/components/map/MapToken.js b/src/components/map/MapToken.js index 54bd867..2156ba7 100644 --- a/src/components/map/MapToken.js +++ b/src/components/map/MapToken.js @@ -6,6 +6,7 @@ import useImage from "use-image"; import useDataSource from "../../helpers/useDataSource"; import useDebounce from "../../helpers/useDebounce"; import usePrevious from "../../helpers/usePrevious"; +import * as Vector2 from "../../helpers/vector2"; import AuthContext from "../../contexts/AuthContext"; import MapInteractionContext from "../../contexts/MapInteractionContext"; @@ -15,6 +16,8 @@ import TokenLabel from "../token/TokenLabel"; import { tokenSources, unknownSource } from "../../tokens"; +const snappingThreshold = 1 / 5; + function MapToken({ token, tokenState, @@ -26,6 +29,7 @@ function MapToken({ draggable, mapState, fadeOnHover, + map, }) { const { userId } = useContext(AuthContext); const { @@ -74,6 +78,25 @@ function MapToken({ onTokenDragStart(event); } + function handleDragMove(event) { + const tokenGroup = event.target; + // Snap to corners of grid + if (map.snapToGrid) { + const position = { + x: tokenGroup.x() + tokenGroup.width() / 2, + y: tokenGroup.y() + tokenGroup.height() / 2, + }; + const gridSize = { x: mapWidth / map.gridX, y: mapHeight / map.gridY }; + const gridSnap = Vector2.roundTo(position, gridSize); + const gridDistance = Vector2.length(Vector2.subtract(gridSnap, position)); + const minGrid = Vector2.min(gridSize); + if (gridDistance < minGrid * snappingThreshold) { + tokenGroup.x(gridSnap.x - tokenGroup.width() / 2); + tokenGroup.y(gridSnap.y - tokenGroup.height() / 2); + } + } + } + function handleDragEnd(event) { const tokenGroup = event.target; @@ -192,6 +215,7 @@ function MapToken({ onTap={handleClick} onDragEnd={handleDragEnd} onDragStart={handleDragStart} + onDragMove={handleDragMove} opacity={tokenOpacity} name={token && token.isVehicle ? "vehicle" : "token"} id={tokenState.id}