From 91c7c9f9ada2cf24b9fa2f2da2a1f852f24d926f Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Fri, 20 Mar 2020 21:46:52 +1100 Subject: [PATCH] Added pan and zoom to map --- src/components/Map.js | 132 +++++++++++++++++++++++++++------------- src/components/Token.js | 9 ++- 2 files changed, 99 insertions(+), 42 deletions(-) diff --git a/src/components/Map.js b/src/components/Map.js index a78376b..30add5f 100644 --- a/src/components/Map.js +++ b/src/components/Map.js @@ -1,5 +1,6 @@ -import React, { useRef } from "react"; +import React, { useRef, useEffect, useState } from "react"; import { Box, Image } from "theme-ui"; +import interact from "interactjs"; import Token from "../components/Token"; import ProxyToken from "../components/ProxyToken"; @@ -7,6 +8,9 @@ import AddMapButton from "../components/AddMapButton"; const mapTokenClassName = "map-token"; const defaultTokenSize = 48; +const zoomSpeed = -0.005; +const minZoom = 0.1; +const maxZoom = 5; function Map({ mapSource, @@ -26,6 +30,36 @@ function Map({ } } + const [mapTranslate, setMapTranslate] = useState({ x: 0, y: 0 }); + const [mapScale, setMapScale] = useState(1); + + useEffect(() => { + interact(".map").draggable({ + inertia: true, + listeners: { + move: event => { + setMapTranslate(previousMapTranslate => ({ + x: previousMapTranslate.x + event.dx, + y: previousMapTranslate.y + event.dy + })); + } + } + }); + interact(".map").on("doubletap", event => { + event.preventDefault(); + setMapTranslate({ x: 0, y: 0 }); + setMapScale(1); + }); + }, []); + + function handleZoom(event) { + event.preventDefault(); + const deltaY = event.deltaY * zoomSpeed; + setMapScale(mapScale => + Math.max(Math.min(mapScale + deltaY, maxZoom), minZoom) + ); + } + const mapRef = useRef(null); const rows = mapData && mapData.rows; const tokenSizePercent = (1 / rows) * 100; @@ -42,58 +76,74 @@ function Map({ backgroundColor: "rgba(0, 0, 0, 0.1)" }} bg="background" + onWheel={handleZoom} > - - - - - - {Object.values(tokens).map(token => ( - - - - ))} + + + + + + {Object.values(tokens).map(token => ( + + + + ))} + ; + return ( + + ); } export default Token;