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 MapFog from "./MapFog";
|
||||
import MapDice from "./MapDice";
|
||||
import MapGrid from "./MapGrid";
|
||||
|
||||
import TokenDataContext from "../../contexts/TokenDataContext";
|
||||
import MapLoadingContext from "../../contexts/MapLoadingContext";
|
||||
@ -294,6 +295,10 @@ function Map({
|
||||
/>
|
||||
);
|
||||
|
||||
const mapGrid = map && map.showGrid && (
|
||||
<MapGrid map={map} gridSize={gridSizeNormalized} />
|
||||
);
|
||||
|
||||
return (
|
||||
<MapInteraction
|
||||
map={map}
|
||||
@ -308,6 +313,7 @@ function Map({
|
||||
}
|
||||
selectedToolId={selectedToolId}
|
||||
>
|
||||
{mapGrid}
|
||||
{mapDrawing}
|
||||
{mapTokens}
|
||||
{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 Divider from "../Divider";
|
||||
|
||||
function MapSettings({
|
||||
map,
|
||||
mapState,
|
||||
@ -57,6 +59,27 @@ function MapSettings({
|
||||
{showMore && (
|
||||
<>
|
||||
<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>
|
||||
<Flex my={1}>
|
||||
<Label>
|
||||
@ -85,16 +108,6 @@ function MapSettings({
|
||||
</Label>
|
||||
</Flex>
|
||||
</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
|
||||
|
@ -43,6 +43,7 @@ export function MapDataProvider({ children }) {
|
||||
created: Date.now() + i,
|
||||
lastModified: Date.now() + i,
|
||||
gridType: "grid",
|
||||
showGrid: false,
|
||||
});
|
||||
// Add a state for the map if there isn't one already
|
||||
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
|
||||
|
@ -17,6 +17,7 @@ const defaultMapProps = {
|
||||
// Grid type
|
||||
// TODO: add support for hex horizontal and hex vertical
|
||||
gridType: "grid",
|
||||
showGrid: false,
|
||||
};
|
||||
|
||||
function SelectMapModal({
|
||||
|
Loading…
Reference in New Issue
Block a user