Added show map grid option to maps
This commit is contained in:
parent
0720a3df2b
commit
faddf03ecf
@ -6,6 +6,7 @@ import MapToken from "./MapToken";
|
|||||||
import MapDrawing from "./MapDrawing";
|
import MapDrawing from "./MapDrawing";
|
||||||
import MapFog from "./MapFog";
|
import MapFog from "./MapFog";
|
||||||
import MapDice from "./MapDice";
|
import MapDice from "./MapDice";
|
||||||
|
import MapGrid from "./MapGrid";
|
||||||
|
|
||||||
import TokenDataContext from "../../contexts/TokenDataContext";
|
import TokenDataContext from "../../contexts/TokenDataContext";
|
||||||
import MapLoadingContext from "../../contexts/MapLoadingContext";
|
import MapLoadingContext from "../../contexts/MapLoadingContext";
|
||||||
@ -294,6 +295,10 @@ function Map({
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const mapGrid = map && map.showGrid && (
|
||||||
|
<MapGrid map={map} gridSize={gridSizeNormalized} />
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MapInteraction
|
<MapInteraction
|
||||||
map={map}
|
map={map}
|
||||||
@ -308,6 +313,7 @@ function Map({
|
|||||||
}
|
}
|
||||||
selectedToolId={selectedToolId}
|
selectedToolId={selectedToolId}
|
||||||
>
|
>
|
||||||
|
{mapGrid}
|
||||||
{mapDrawing}
|
{mapDrawing}
|
||||||
{mapTokens}
|
{mapTokens}
|
||||||
{mapFog}
|
{mapFog}
|
||||||
|
93
src/components/map/MapGrid.js
Normal file
93
src/components/map/MapGrid.js
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
|
import { Line, Group } from "react-konva";
|
||||||
|
import useImage from "use-image";
|
||||||
|
|
||||||
|
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
||||||
|
|
||||||
|
import useDataSource from "../../helpers/useDataSource";
|
||||||
|
import { mapSources as defaultMapSources } from "../../maps";
|
||||||
|
|
||||||
|
import { getStrokeWidth } from "../../helpers/drawing";
|
||||||
|
|
||||||
|
const lightnessDetectionOffset = 0.1;
|
||||||
|
|
||||||
|
function MapGrid({ map, gridSize }) {
|
||||||
|
const mapSource = useDataSource(map, defaultMapSources);
|
||||||
|
const [mapImage, mapLoadingStatus] = useImage(mapSource);
|
||||||
|
|
||||||
|
const gridX = map && map.gridX;
|
||||||
|
const gridY = map && map.gridY;
|
||||||
|
|
||||||
|
const { mapWidth, mapHeight } = useContext(MapInteractionContext);
|
||||||
|
|
||||||
|
const lineSpacingX = mapWidth / gridX;
|
||||||
|
const lineSpacingY = mapHeight / gridY;
|
||||||
|
|
||||||
|
const [isImageLight, setIsImageLight] = useState(true);
|
||||||
|
|
||||||
|
// When the map changes find the average lightness of its pixels
|
||||||
|
useEffect(() => {
|
||||||
|
if (mapLoadingStatus === "loaded") {
|
||||||
|
const imageWidth = mapImage.width;
|
||||||
|
const imageHeight = mapImage.height;
|
||||||
|
let canvas = document.createElement("canvas");
|
||||||
|
canvas.width = imageWidth;
|
||||||
|
canvas.height = imageHeight;
|
||||||
|
let context = canvas.getContext("2d");
|
||||||
|
context.drawImage(mapImage, 0, 0);
|
||||||
|
const imageData = context.getImageData(0, 0, imageWidth, imageHeight);
|
||||||
|
|
||||||
|
const data = imageData.data;
|
||||||
|
let lightPixels = 0;
|
||||||
|
let darkPixels = 0;
|
||||||
|
// Loop over every pixels rgba values
|
||||||
|
for (let i = 0; i < data.length; i += 4) {
|
||||||
|
const r = data[i];
|
||||||
|
const g = data[i + 1];
|
||||||
|
const b = data[i + 2];
|
||||||
|
|
||||||
|
const max = Math.max(Math.max(r, g), b);
|
||||||
|
if (max < 128) {
|
||||||
|
darkPixels++;
|
||||||
|
} else {
|
||||||
|
lightPixels++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const norm = (lightPixels - darkPixels) / (imageWidth * imageHeight);
|
||||||
|
if (norm + lightnessDetectionOffset < 0) {
|
||||||
|
setIsImageLight(false);
|
||||||
|
} else {
|
||||||
|
setIsImageLight(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [mapImage, mapLoadingStatus]);
|
||||||
|
|
||||||
|
const lines = [];
|
||||||
|
for (let x = 1; x < gridX; x++) {
|
||||||
|
lines.push(
|
||||||
|
<Line
|
||||||
|
key={`grid_x_${x}`}
|
||||||
|
points={[x * lineSpacingX, 0, x * lineSpacingX, mapHeight]}
|
||||||
|
stroke={isImageLight ? "black" : "white"}
|
||||||
|
strokeWidth={getStrokeWidth(0.1, gridSize, mapWidth, mapHeight)}
|
||||||
|
opacity={0.8}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for (let y = 1; y < gridY; y++) {
|
||||||
|
lines.push(
|
||||||
|
<Line
|
||||||
|
key={`grid_y_${y}`}
|
||||||
|
points={[0, y * lineSpacingY, mapWidth, y * lineSpacingY]}
|
||||||
|
stroke={isImageLight ? "black" : "white"}
|
||||||
|
strokeWidth={getStrokeWidth(0.1, gridSize, mapWidth, mapHeight)}
|
||||||
|
opacity={0.8}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Group>{lines}</Group>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MapGrid;
|
@ -3,6 +3,8 @@ import { Flex, Box, Label, Input, Checkbox, IconButton } from "theme-ui";
|
|||||||
|
|
||||||
import ExpandMoreIcon from "../../icons/ExpandMoreIcon";
|
import ExpandMoreIcon from "../../icons/ExpandMoreIcon";
|
||||||
|
|
||||||
|
import Divider from "../Divider";
|
||||||
|
|
||||||
function MapSettings({
|
function MapSettings({
|
||||||
map,
|
map,
|
||||||
mapState,
|
mapState,
|
||||||
@ -57,6 +59,27 @@ function MapSettings({
|
|||||||
{showMore && (
|
{showMore && (
|
||||||
<>
|
<>
|
||||||
<Box mt={2} sx={{ flexGrow: 1 }}>
|
<Box mt={2} sx={{ flexGrow: 1 }}>
|
||||||
|
<Label htmlFor="name">Name</Label>
|
||||||
|
<Input
|
||||||
|
name="name"
|
||||||
|
value={(map && map.name) || ""}
|
||||||
|
onChange={(e) => onSettingsChange("name", e.target.value)}
|
||||||
|
disabled={!map || map.type === "default"}
|
||||||
|
my={1}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box my={2}>
|
||||||
|
<Label>
|
||||||
|
<Checkbox
|
||||||
|
checked={map && map.showGrid}
|
||||||
|
disabled={!map || map.type === "default"}
|
||||||
|
onChange={(e) => onSettingsChange("showGrid", e.target.checked)}
|
||||||
|
/>
|
||||||
|
Show Grid
|
||||||
|
</Label>
|
||||||
|
</Box>
|
||||||
|
<Divider fill />
|
||||||
|
<Box my={2} sx={{ flexGrow: 1 }}>
|
||||||
<Label>Allow others to edit</Label>
|
<Label>Allow others to edit</Label>
|
||||||
<Flex my={1}>
|
<Flex my={1}>
|
||||||
<Label>
|
<Label>
|
||||||
@ -85,16 +108,6 @@ function MapSettings({
|
|||||||
</Label>
|
</Label>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Box>
|
</Box>
|
||||||
<Box my={2} sx={{ flexGrow: 1 }}>
|
|
||||||
<Label htmlFor="name">Name</Label>
|
|
||||||
<Input
|
|
||||||
name="name"
|
|
||||||
value={(map && map.name) || ""}
|
|
||||||
onChange={(e) => onSettingsChange("name", e.target.value)}
|
|
||||||
disabled={!map || map.type === "default"}
|
|
||||||
my={1}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<IconButton
|
<IconButton
|
||||||
|
@ -43,6 +43,7 @@ export function MapDataProvider({ children }) {
|
|||||||
created: Date.now() + i,
|
created: Date.now() + i,
|
||||||
lastModified: Date.now() + i,
|
lastModified: Date.now() + i,
|
||||||
gridType: "grid",
|
gridType: "grid",
|
||||||
|
showGrid: false,
|
||||||
});
|
});
|
||||||
// Add a state for the map if there isn't one already
|
// Add a state for the map if there isn't one already
|
||||||
const state = await database.table("states").get(id);
|
const state = await database.table("states").get(id);
|
||||||
|
@ -89,6 +89,17 @@ function loadVersions(db) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// v1.3.1 - Added show grid option
|
||||||
|
db.version(4)
|
||||||
|
.stores({})
|
||||||
|
.upgrade((tx) => {
|
||||||
|
return tx
|
||||||
|
.table("maps")
|
||||||
|
.toCollection()
|
||||||
|
.modify((map) => {
|
||||||
|
map.showGrid = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the dexie database used in DatabaseContext
|
// Get the dexie database used in DatabaseContext
|
||||||
|
@ -17,6 +17,7 @@ const defaultMapProps = {
|
|||||||
// Grid type
|
// Grid type
|
||||||
// TODO: add support for hex horizontal and hex vertical
|
// TODO: add support for hex horizontal and hex vertical
|
||||||
gridType: "grid",
|
gridType: "grid",
|
||||||
|
showGrid: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
function SelectMapModal({
|
function SelectMapModal({
|
||||||
|
Loading…
Reference in New Issue
Block a user