diff --git a/src/components/map/MapEditor.js b/src/components/map/MapEditor.js index b4d7a06..5744a78 100644 --- a/src/components/map/MapEditor.js +++ b/src/components/map/MapEditor.js @@ -9,7 +9,7 @@ import useStageInteraction from "../../hooks/useStageInteraction"; import useImageCenter from "../../hooks/useImageCenter"; import useResponsiveLayout from "../../hooks/useResponsiveLayout"; -import { getMapDefaultInset, getGridMaxZoom } from "../../helpers/grid"; +import { getGridDefaultInset, getGridMaxZoom } from "../../helpers/grid"; import { MapInteractionProvider } from "../../contexts/MapInteractionContext"; import KeyboardContext from "../../contexts/KeyboardContext"; @@ -28,12 +28,7 @@ function MapEditor({ map, onSettingsChange }) { const [stageHeight, setStageHeight] = useState(1); const [stageScale, setStageScale] = useState(1); - const defaultInset = getMapDefaultInset( - map.width, - map.height, - map.grid.size.x, - map.grid.size.y - ); + const defaultInset = getGridDefaultInset(map.grid, map.width, map.height); const stageTranslateRef = useRef({ x: 0, y: 0 }); const mapStageRef = useRef(); diff --git a/src/database.js b/src/database.js index 3ff837c..0757bbc 100644 --- a/src/database.js +++ b/src/database.js @@ -1,7 +1,7 @@ import Dexie from "dexie"; import blobToBuffer from "./helpers/blobToBuffer"; -import { getMapDefaultInset } from "./helpers/grid"; +import { getGridDefaultInset } from "./helpers/grid"; import { convertOldActionsToShapes } from "./actions"; function loadVersions(db) { @@ -219,11 +219,10 @@ function loadVersions(db) { map.group = ""; map.grid = { size: { x: map.gridX, y: map.gridY }, - inset: getMapDefaultInset( + inset: getGridDefaultInset( + { size: { x: map.gridX, y: map.gridY }, type: "square" }, map.width, - map.height, - map.gridX, - map.gridY + map.height ), type: "square", }; diff --git a/src/helpers/grid.js b/src/helpers/grid.js index 151fa20..b290b36 100644 --- a/src/helpers/grid.js +++ b/src/helpers/grid.js @@ -4,6 +4,7 @@ import Vector2 from "./Vector2"; import { logError } from "./logging"; const SQRT3 = 1.73205; +const GRID_TYPE_NOT_IMPLEMENTED = new Error("Grid type not implemented"); /** * @typedef GridInset @@ -28,22 +29,33 @@ const SQRT3 = 1.73205; /** * Gets the cell size for a grid taking into account inset and grid type * @param {Grid} grid - * @param {number} insetWidth - * @param {number} insetHeight + * @param {number} gridWidth + * @param {number} gridHeight * @returns {CellSize} */ -export function getCellSize(grid, insetWidth, insetHeight) { - if (grid.type === "square") { - return { - width: insetWidth / grid.size.x, - height: insetHeight / grid.size.y, - }; - } else if (grid.type === "hexVertical") { - const radius = insetWidth / grid.size.x / SQRT3; - return { width: radius * SQRT3, height: radius + radius / 2, radius }; - } else if (grid.type === "hexHorizontal") { - const radius = insetHeight / grid.size.y / SQRT3; - return { width: radius + radius / 2, height: radius * SQRT3, radius }; +export function getCellSize(grid, gridWidth, gridHeight) { + switch (grid.type) { + case "square": + return { + width: gridWidth / grid.size.x, + height: gridHeight / grid.size.y, + }; + case "hexVertical": + const radiusVert = gridWidth / grid.size.x / SQRT3; + return { + width: radiusVert * SQRT3, + height: radiusVert * 2, + radius: radiusVert, + }; + case "hexHorizontal": + const radiusHorz = gridHeight / grid.size.y / SQRT3; + return { + width: radiusHorz * 2, + height: radiusHorz * SQRT3, + radius: radiusHorz, + }; + default: + throw GRID_TYPE_NOT_IMPLEMENTED; } } @@ -56,18 +68,21 @@ export function getCellSize(grid, insetWidth, insetHeight) { * @returns {Vector2} */ export function getCellLocation(grid, x, y, cellSize) { - if (grid.type === "square") { - return { x: x * cellSize.width, y: y * cellSize.height }; - } else if (grid.type === "hexVertical") { - return { - x: x * cellSize.width + (cellSize.width * (1 + (y % 2))) / 2, - y: y * cellSize.height + cellSize.radius, - }; - } else if (grid.type === "hexHorizontal") { - return { - x: x * cellSize.width + cellSize.radius, - y: y * cellSize.height + (cellSize.height * (1 + (x % 2))) / 2, - }; + switch (grid.type) { + case "square": + return { x: x * cellSize.width, y: y * cellSize.height }; + case "hexVertical": + return { + x: x * cellSize.width + (cellSize.width * (1 + (y % 2))) / 2, + y: y * cellSize.height * (3 / 4) + cellSize.radius, + }; + case "hexHorizontal": + return { + x: x * cellSize.width * (3 / 4) + cellSize.radius, + y: y * cellSize.height + (cellSize.height * (1 + (x % 2))) / 2, + }; + default: + throw GRID_TYPE_NOT_IMPLEMENTED; } } @@ -79,27 +94,44 @@ export function getCellLocation(grid, x, y, cellSize) { * @returns {boolean} */ export function shouldClampCell(grid, x, y) { - if (grid.type === "hexVertical") { - return x === grid.size.x - 1 && y % 2 !== 0; - } else if (grid.type === "hexHorizontal") { - return y === grid.size.y - 1 && x % 2 !== 0; + switch (grid.type) { + case "square": + return false; + case "hexVertical": + return x === grid.size.x - 1 && y % 2 !== 0; + case "hexHorizontal": + return y === grid.size.y - 1 && x % 2 !== 0; + default: + throw GRID_TYPE_NOT_IMPLEMENTED; } - return false; } /** * Get the default inset for a map - * @param {number} width Hidth of the map - * @param {number} height Height of the map - * @param {number} gridX Number of grid cells in the horizontal direction - * @param {number} gridY Number of grid cells in the vertical direction + * @param {Grid} grid + * @param {number} gridWidth + * @param {number} gridHeight * @returns {GridInset} */ -export function getMapDefaultInset(width, height, gridX, gridY) { - // Max the width - const gridScale = width / gridX; - const y = gridY * gridScale; - const yNorm = y / height; +export function getGridDefaultInset(grid, gridWidth, gridHeight) { + // Max the width of the inset and figure out the resulting height value + let y; + switch (grid.type) { + case "square": + y = grid.size.y * (gridWidth / grid.size.x); + break; + case "hexVertical": + const cellHeightVert = (gridWidth / grid.size.x / SQRT3) * 2; + y = grid.size.y * cellHeightVert * (3 / 4) + cellHeightVert * (1 / 4); + break; + case "hexHorizontal": + const cellHeightHroz = gridWidth / ((grid.size.x - 1) * (3 / 4) + 1); + y = grid.size.y * cellHeightHroz * (SQRT3 / 2); + break; + default: + throw GRID_TYPE_NOT_IMPLEMENTED; + } + const yNorm = y / gridHeight; return { topLeft: { x: 0, y: 0 }, bottomRight: { x: 1, y: yNorm } }; } diff --git a/src/modals/EditMapModal.js b/src/modals/EditMapModal.js index e6e06bb..e44513a 100644 --- a/src/modals/EditMapModal.js +++ b/src/modals/EditMapModal.js @@ -8,7 +8,7 @@ import MapEditor from "../components/map/MapEditor"; import MapDataContext from "../contexts/MapDataContext"; import { isEmpty } from "../helpers/shared"; -import { getMapDefaultInset } from "../helpers/grid"; +import { getGridDefaultInset } from "../helpers/grid"; import useResponsiveLayout from "../hooks/useResponsiveLayout"; @@ -65,18 +65,16 @@ function EditMapModal({ isOpen, onDone, map, mapState }) { inset.topLeft.y > inset.bottomRight.y ) { if ("size" in verifiedChanges.grid) { - verifiedChanges.grid.inset = getMapDefaultInset( + verifiedChanges.grid.inset = getGridDefaultInset( + verifiedChanges.grid, map.width, - map.height, - verifiedChanges.grid.size.x, - verifiedChanges.grid.size.y + map.height ); } else { - verifiedChanges.grid.inset = getMapDefaultInset( + verifiedChanges.grid.inset = getGridDefaultInset( + map.grid, map.width, - map.height, - map.grid.size.x, - map.grid.size.y + map.height ); } } diff --git a/src/modals/SelectMapModal.js b/src/modals/SelectMapModal.js index 6b252ed..9882426 100644 --- a/src/modals/SelectMapModal.js +++ b/src/modals/SelectMapModal.js @@ -16,7 +16,7 @@ import blobToBuffer from "../helpers/blobToBuffer"; import { resizeImage } from "../helpers/image"; import { useSearch, useGroup, handleItemSelect } from "../helpers/select"; import { - getMapDefaultInset, + getGridDefaultInset, getGridSize, gridSizeVaild, } from "../helpers/grid"; @@ -206,7 +206,7 @@ function SelectMapModal({ type: "file", grid: { size: gridSize, - inset: getMapDefaultInset( + inset: getGridDefaultInset( image.width, image.height, gridSize.x,