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;