diff --git a/package.json b/package.json index 0d3973d..a036325 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "owlbear-rodeo", - "version": "1.6.0", + "version": "1.6.1", "private": true, "dependencies": { "@babylonjs/core": "^4.1.0", diff --git a/src/components/map/MapEditor.js b/src/components/map/MapEditor.js index fb649d8..d1e046a 100644 --- a/src/components/map/MapEditor.js +++ b/src/components/map/MapEditor.js @@ -1,4 +1,4 @@ -import React, { useState, useRef, useEffect, useContext } from "react"; +import React, { useState, useRef, useContext } from "react"; import { Box, IconButton } from "theme-ui"; import { Stage, Layer, Image } from "react-konva"; import ReactResizeDetector from "react-resize-detector"; @@ -6,7 +6,8 @@ import ReactResizeDetector from "react-resize-detector"; import useMapImage from "../../helpers/useMapImage"; import usePreventOverscroll from "../../helpers/usePreventOverscroll"; import useStageInteraction from "../../helpers/useStageInteraction"; -import { getMapDefaultInset } from "../../helpers/map"; +import useImageCenter from "../../helpers/useImageCenter"; +import { getMapDefaultInset, getMapMaxZoom } from "../../helpers/map"; import { MapInteractionProvider } from "../../contexts/MapInteractionContext"; import KeyboardContext from "../../contexts/KeyboardContext"; @@ -25,19 +26,6 @@ function MapEditor({ map, onSettingsChange }) { const [stageHeight, setStageHeight] = useState(1); const [stageScale, setStageScale] = useState(1); - const stageRatio = stageWidth / stageHeight; - const mapRatio = map ? map.width / map.height : 1; - - let mapWidth; - let mapHeight; - if (stageRatio > mapRatio) { - mapWidth = map ? stageHeight / (map.height / map.width) : stageWidth; - mapHeight = stageHeight; - } else { - mapWidth = stageWidth; - mapHeight = map ? stageWidth * (map.height / map.width) : stageHeight; - } - const defaultInset = getMapDefaultInset( map.width, map.height, @@ -46,6 +34,7 @@ function MapEditor({ map, onSettingsChange }) { ); const stageTranslateRef = useRef({ x: 0, y: 0 }); + const mapStageRef = useRef(); const mapLayerRef = useRef(); const [preventMapInteraction, setPreventMapInteraction] = useState(false); @@ -54,45 +43,32 @@ function MapEditor({ map, onSettingsChange }) { setStageHeight(height); } - // Reset map translate and scale - useEffect(() => { - const layer = mapLayerRef.current; - const containerRect = containerRef.current.getBoundingClientRect(); - if (layer) { - let newTranslate; - if (stageRatio > mapRatio) { - newTranslate = { - x: -(mapWidth - containerRect.width) / 2, - y: 0, - }; - } else { - newTranslate = { - x: 0, - y: -(mapHeight - containerRect.height) / 2, - }; - } + const containerRef = useRef(); + usePreventOverscroll(containerRef); - layer.x(newTranslate.x); - layer.y(newTranslate.y); - layer.draw(); - stageTranslateRef.current = newTranslate; - - setStageScale(1); - } - }, [map.id, mapWidth, mapHeight, stageRatio, mapRatio]); + const [mapWidth, mapHeight] = useImageCenter( + map, + mapStageRef, + stageWidth, + stageHeight, + stageTranslateRef, + setStageScale, + mapLayerRef, + containerRef, + true + ); const bind = useStageInteraction( - mapLayerRef.current, + mapStageRef.current, stageScale, setStageScale, stageTranslateRef, + mapLayerRef.current, + getMapMaxZoom(map), "pan", preventMapInteraction ); - const containerRef = useRef(); - usePreventOverscroll(containerRef); - function handleGridChange(inset) { onSettingsChange("grid", { ...map.grid, @@ -128,7 +104,6 @@ function MapEditor({ map, onSettingsChange }) { map.grid.inset.topLeft.y !== defaultInset.topLeft.y || map.grid.inset.bottomRight.x !== defaultInset.bottomRight.x || map.grid.inset.bottomRight.y !== defaultInset.bottomRight.y; - return ( {showGridControls && canEditGrid && ( - - )} - {showGridControls && canEditGrid && ( - + <> + + + )} diff --git a/src/components/map/MapInteraction.js b/src/components/map/MapInteraction.js index e70e447..b750f6d 100644 --- a/src/components/map/MapInteraction.js +++ b/src/components/map/MapInteraction.js @@ -8,6 +8,8 @@ import useMapImage from "../../helpers/useMapImage"; import usePreventOverscroll from "../../helpers/usePreventOverscroll"; import useKeyboard from "../../helpers/useKeyboard"; import useStageInteraction from "../../helpers/useStageInteraction"; +import useImageCenter from "../../helpers/useImageCenter"; +import { getMapMaxZoom } from "../../helpers/map"; import { MapInteractionProvider } from "../../contexts/MapInteractionContext"; import MapStageContext, { @@ -42,52 +44,42 @@ function MapInteraction({ const [stageScale, setStageScale] = useState(1); const [preventMapInteraction, setPreventMapInteraction] = useState(false); - const stageWidthRef = useRef(stageWidth); - const stageHeightRef = useRef(stageHeight); // Avoid state udpates when panning the map by using a ref and updating the konva element directly const stageTranslateRef = useRef({ x: 0, y: 0 }); - - // Reset transform when map changes - const previousMapIdRef = useRef(); - useEffect(() => { - const layer = mapLayerRef.current; - const previousMapId = previousMapIdRef.current; - if (map && layer && previousMapId !== map.id) { - const mapHeight = stageWidthRef.current * (map.height / map.width); - const newTranslate = { - x: 0, - y: -(mapHeight - stageHeightRef.current) / 2, - }; - layer.x(newTranslate.x); - layer.y(newTranslate.y); - layer.draw(); - stageTranslateRef.current = newTranslate; - - setStageScale(1); - } - previousMapIdRef.current = map && map.id; - }, [map]); + const mapStageRef = useContext(MapStageContext); + const mapLayerRef = useRef(); + const mapImageRef = useRef(); function handleResize(width, height) { setStageWidth(width); setStageHeight(height); - stageWidthRef.current = width; - stageHeightRef.current = height; } - const mapStageRef = useContext(MapStageContext); - const mapLayerRef = useRef(); - const mapImageRef = useRef(); + const containerRef = useRef(); + usePreventOverscroll(containerRef); + + const [mapWidth, mapHeight] = useImageCenter( + map, + mapStageRef, + stageWidth, + stageHeight, + stageTranslateRef, + setStageScale, + mapLayerRef, + containerRef + ); const previousSelectedToolRef = useRef(selectedToolId); const [interactionEmitter] = useState(new EventEmitter()); const bind = useStageInteraction( - mapLayerRef.current, + mapStageRef.current, stageScale, setStageScale, stageTranslateRef, + mapLayerRef.current, + getMapMaxZoom(map), selectedToolId, preventMapInteraction, { @@ -169,12 +161,6 @@ function MapInteraction({ } } - const containerRef = useRef(); - usePreventOverscroll(containerRef); - - const mapWidth = stageWidth; - const mapHeight = map ? stageWidth * (map.height / map.width) : stageHeight; - const auth = useContext(AuthContext); const settings = useContext(SettingsContext); @@ -206,9 +192,6 @@ function MapInteraction({ width={stageWidth} height={stageHeight} scale={{ x: stageScale, y: stageScale }} - x={stageWidth / 2} - y={stageHeight / 2} - offset={{ x: stageWidth / 2, y: stageHeight / 2 }} ref={mapStageRef} > diff --git a/src/components/map/MapSettings.js b/src/components/map/MapSettings.js index 78090aa..3c6181b 100644 --- a/src/components/map/MapSettings.js +++ b/src/components/map/MapSettings.js @@ -160,7 +160,7 @@ function MapSettings({ onSettingsChange("showGrid", e.target.checked) } /> - Show Grid + Draw Grid