Added multiple map layout and basic data flow

This commit is contained in:
Mitchell McCaffrey
2020-04-23 11:54:29 +10:00
parent f2a92f2ccd
commit 22c5b5cf75
13 changed files with 213 additions and 140 deletions
+3 -50
View File
@@ -1,11 +1,9 @@
import React, { useRef, useState, useEffect } from "react";
import React, { useState } from "react";
import { IconButton } from "theme-ui";
import AddMapModal from "../../modals/AddMapModal";
import AddMapIcon from "../../icons/AddMapIcon";
const defaultMapSize = 22;
function AddMapButton({ onMapChange }) {
const [isAddModalOpen, setIsAddModalOpen] = useState(false);
function openModal() {
@@ -15,49 +13,11 @@ function AddMapButton({ onMapChange }) {
setIsAddModalOpen(false);
}
const [imageLoaded, setImageLoaded] = useState(false);
const mapDataRef = useRef(null);
const [mapSource, setMapSource] = useState(null);
function handleImageUpload(file, fileGridX, fileGridY) {
const url = URL.createObjectURL(file);
let image = new Image();
image.onload = function () {
mapDataRef.current = {
file,
gridX: fileGridX || gridX,
gridY: fileGridY || gridY,
width: image.width,
height: image.height,
};
setImageLoaded(true);
};
image.src = url;
setMapSource(url);
if (fileGridX) {
setGridX(fileGridX);
}
if (fileGridY) {
setGridY(fileGridY);
}
}
function handleDone() {
if (mapDataRef.current && mapSource) {
onMapChange(mapDataRef.current, mapSource);
}
function handleDone(map) {
onMapChange(map);
closeModal();
}
const [gridX, setGridX] = useState(defaultMapSize);
const [gridY, setGridY] = useState(defaultMapSize);
useEffect(() => {
if (mapDataRef.current) {
mapDataRef.current.gridX = gridX;
mapDataRef.current.gridY = gridY;
}
}, [gridX, gridY]);
return (
<>
<IconButton aria-label="Add Map" title="Add Map" onClick={openModal}>
@@ -67,13 +27,6 @@ function AddMapButton({ onMapChange }) {
isOpen={isAddModalOpen}
onRequestClose={closeModal}
onDone={handleDone}
onImageUpload={handleImageUpload}
gridX={gridX}
onGridXChange={setGridX}
gridY={gridY}
onGridYChange={setGridY}
imageLoaded={imageLoaded}
mapSource={mapSource}
/>
</>
);
+11 -12
View File
@@ -17,8 +17,7 @@ const minZoom = 0.1;
const maxZoom = 5;
function Map({
mapSource,
mapData,
map,
tokens,
onMapTokenChange,
onMapTokenRemove,
@@ -80,7 +79,7 @@ function Map({
}, [drawActions, drawActionIndex]);
const disabledTools = [];
if (!mapData) {
if (!map) {
disabledTools.push("pan");
disabledTools.push("brush");
}
@@ -134,7 +133,7 @@ function Map({
move: (e) => handleMove(e, false),
},
cursorChecker: () => {
return selectedTool === "pan" && mapData ? "move" : "default";
return selectedTool === "pan" && map ? "move" : "default";
},
})
.on("doubletap", (event) => {
@@ -147,12 +146,12 @@ function Map({
return () => {
mapInteract.unset();
};
}, [selectedTool, mapData]);
}, [selectedTool, map]);
// Reset map transform when map changes
useEffect(() => {
setTranslateAndScale({ x: 0, y: 0 }, 1);
}, [mapSource]);
}, [map]);
// Bind the wheel event of the map via a ref
// in order to support non-passive event listening
@@ -194,11 +193,11 @@ function Map({
const mapRef = useRef(null);
const mapContainerRef = useRef();
const gridX = mapData && mapData.gridX;
const gridY = mapData && mapData.gridY;
const gridX = map && map.gridX;
const gridY = map && map.gridY;
const gridSizeNormalized = { x: 1 / gridX || 0, y: 1 / gridY || 0 };
const tokenSizePercent = gridSizeNormalized.x * 100;
const aspectRatio = (mapData && mapData.width / mapData.height) || 1;
const aspectRatio = (map && map.width / map.height) || 1;
const mapImage = (
<Box
@@ -218,7 +217,7 @@ function Map({
userSelect: "none",
touchAction: "none",
}}
src={mapSource}
src={map && map.source}
/>
</Box>
);
@@ -278,8 +277,8 @@ function Map({
/>
{mapImage}
<MapDrawing
width={mapData ? mapData.width : 0}
height={mapData ? mapData.height : 0}
width={map ? map.width : 0}
height={map ? map.height : 0}
selectedTool={selectedTool}
shapes={drawnShapes}
onShapeAdd={handleShapeAdd}
+55
View File
@@ -0,0 +1,55 @@
import React from "react";
import { Flex, Image as UIImage } from "theme-ui";
import AddIcon from "../../icons/AddIcon";
function MapSelect({ maps, onMapAdd }) {
const tileProps = {
m: 2,
sx: {
width: "150px",
height: "150px",
borderRadius: "4px",
justifyContent: "center",
alignItems: "center",
},
bg: "muted",
};
function tile(map) {
return (
<Flex // TODO: use DB key
key={map.source}
{...tileProps}
>
<UIImage
sx={{ width: "100%", objectFit: "contain" }}
src={map.source}
/>
</Flex>
);
}
return (
<Flex
my={2}
bg="muted"
sx={{
flexWrap: "wrap",
width: "500px",
maxHeight: "300px",
borderRadius: "4px",
// TODO: move to simple scroll
overflowY: "scroll",
flexGrow: 1,
}}
>
{maps.map(tile)}
<Flex onClick={onMapAdd} {...tileProps}>
<AddIcon />
</Flex>
</Flex>
);
}
export default MapSelect;