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"; import AddMapButton from "../components/AddMapButton"; const mapTokenClassName = "map-token"; const zoomSpeed = -0.005; const minZoom = 0.1; const maxZoom = 5; function Map({ mapSource, mapData, tokens, onMapTokenMove, onMapTokenRemove, onMapChanged, }) { function handleProxyDragEnd(isOnMap, token) { if (isOnMap && onMapTokenMove) { onMapTokenMove(token); } if (!isOnMap && onMapTokenRemove) { onMapTokenRemove(token); } } const [mapTranslate, setMapTranslate] = useState({ x: 0, y: 0 }); const [mapScale, setMapScale] = useState(1); useEffect(() => { interact(".map") .gesturable({ listeners: { move: (event) => { setMapScale((previousMapScale) => Math.max(Math.min(previousMapScale + event.ds, maxZoom), minZoom) ); setMapTranslate((previousMapTranslate) => ({ x: previousMapTranslate.x + event.dx, y: previousMapTranslate.y + event.dy, })); }, }, }) .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) { const deltaY = event.deltaY * zoomSpeed; setMapScale((previousMapScale) => Math.max(Math.min(previousMapScale + deltaY, maxZoom), minZoom) ); } // Reset map transform when map changes useEffect(() => { setMapTranslate({ x: 0, y: 0 }); setMapScale(1); }, [mapSource]); const mapRef = useRef(null); const rows = mapData && mapData.rows; const tokenSizePercent = (1 / rows) * 100; const aspectRatio = (mapData && mapData.width / mapData.height) || 1; return ( <> {Object.values(tokens).map((token) => ( ))} ); } export default Map;