diff --git a/src/components/map/Map.js b/src/components/map/Map.js
index 3ef9c89..7233d05 100644
--- a/src/components/map/Map.js
+++ b/src/components/map/Map.js
@@ -50,7 +50,12 @@ function Map({
const [selectedToolId, setSelectedToolId] = useState("pan");
const [toolSettings, setToolSettings] = useState({
- fog: { type: "polygon", useEdgeSnapping: false, useFogCut: false },
+ fog: {
+ type: "polygon",
+ useEdgeSnapping: false,
+ useFogCut: false,
+ preview: false,
+ },
drawing: {
color: "red",
type: "brush",
@@ -278,8 +283,9 @@ function Map({
shapes={mapShapes}
onShapeAdd={handleMapShapeAdd}
onShapesRemove={handleMapShapesRemove}
- selectedToolId={selectedToolId}
- selectedToolSettings={toolSettings[selectedToolId]}
+ active={selectedToolId === "drawing"}
+ toolId="drawing"
+ toolSettings={toolSettings.drawing}
gridSize={gridSizeNormalized}
/>
);
@@ -291,9 +297,11 @@ function Map({
onShapeSubtract={handleFogShapeSubtract}
onShapesRemove={handleFogShapesRemove}
onShapesEdit={handleFogShapesEdit}
- selectedToolId={selectedToolId}
- selectedToolSettings={toolSettings[selectedToolId]}
+ active={selectedToolId === "fog"}
+ toolId="fog"
+ toolSettings={toolSettings.fog}
gridSize={gridSizeNormalized}
+ transparent={allowFogDrawing && !toolSettings.fog.preview}
/>
);
diff --git a/src/components/map/MapDrawing.js b/src/components/map/MapDrawing.js
index 370baee..b63ec70 100644
--- a/src/components/map/MapDrawing.js
+++ b/src/components/map/MapDrawing.js
@@ -21,8 +21,9 @@ function MapDrawing({
shapes,
onShapeAdd,
onShapesRemove,
- selectedToolId,
- selectedToolSettings,
+ active,
+ toolId,
+ toolSettings,
gridSize,
}) {
const { stageScale, mapWidth, mapHeight, interactionEmitter } = useContext(
@@ -33,22 +34,17 @@ function MapDrawing({
const [isBrushDown, setIsBrushDown] = useState(false);
const [erasingShapes, setErasingShapes] = useState([]);
- const shouldHover =
- selectedToolSettings && selectedToolSettings.type === "erase";
- const isEditing = selectedToolId === "drawing";
+ const shouldHover = toolSettings.type === "erase";
const isBrush =
- selectedToolSettings &&
- (selectedToolSettings.type === "brush" ||
- selectedToolSettings.type === "paint");
+ toolSettings.type === "brush" || toolSettings.type === "paint";
const isShape =
- selectedToolSettings &&
- (selectedToolSettings.type === "line" ||
- selectedToolSettings.type === "rectangle" ||
- selectedToolSettings.type === "circle" ||
- selectedToolSettings.type === "triangle");
+ toolSettings.type === "line" ||
+ toolSettings.type === "rectangle" ||
+ toolSettings.type === "circle" ||
+ toolSettings.type === "triangle";
useEffect(() => {
- if (!isEditing) {
+ if (!active) {
return;
}
const mapStage = mapStageRef.current;
@@ -57,8 +53,8 @@ function MapDrawing({
const mapImage = mapStage.findOne("#mapImage");
return getBrushPositionForTool(
getRelativePointerPositionNormalized(mapImage),
- selectedToolId,
- selectedToolSettings,
+ toolId,
+ toolSettings,
gridSize,
shapes
);
@@ -67,24 +63,24 @@ function MapDrawing({
function handleBrushDown() {
const brushPosition = getBrushPosition();
const commonShapeData = {
- color: selectedToolSettings && selectedToolSettings.color,
- blend: selectedToolSettings && selectedToolSettings.useBlending,
+ color: toolSettings.color,
+ blend: toolSettings.useBlending,
id: shortid.generate(),
};
if (isBrush) {
setDrawingShape({
type: "path",
- pathType: selectedToolSettings.type === "brush" ? "stroke" : "fill",
+ pathType: toolSettings.type === "brush" ? "stroke" : "fill",
data: { points: [brushPosition] },
- strokeWidth: selectedToolSettings.type === "brush" ? 1 : 0,
+ strokeWidth: toolSettings.type === "brush" ? 1 : 0,
...commonShapeData,
});
} else if (isShape) {
setDrawingShape({
type: "shape",
- shapeType: selectedToolSettings.type,
- data: getDefaultShapeData(selectedToolSettings.type, brushPosition),
- strokeWidth: selectedToolSettings.type === "line" ? 1 : 0,
+ shapeType: toolSettings.type,
+ data: getDefaultShapeData(toolSettings.type, brushPosition),
+ strokeWidth: toolSettings.type === "line" ? 1 : 0,
...commonShapeData,
});
}
@@ -163,13 +159,13 @@ function MapDrawing({
gridSize,
isBrush,
isBrushDown,
- isEditing,
+ active,
+ toolId,
isShape,
mapStageRef,
onShapeAdd,
onShapesRemove,
- selectedToolId,
- selectedToolSettings,
+ toolSettings,
shapes,
stageScale,
interactionEmitter,
diff --git a/src/components/map/MapFog.js b/src/components/map/MapFog.js
index 7a03c81..c660017 100644
--- a/src/components/map/MapFog.js
+++ b/src/components/map/MapFog.js
@@ -27,9 +27,11 @@ function MapFog({
onShapeSubtract,
onShapesRemove,
onShapesEdit,
- selectedToolId,
- selectedToolSettings,
+ active,
+ toolId,
+ toolSettings,
gridSize,
+ transparent,
}) {
const { stageScale, mapWidth, mapHeight, interactionEmitter } = useContext(
MapInteractionContext
@@ -39,16 +41,14 @@ function MapFog({
const [isBrushDown, setIsBrushDown] = useState(false);
const [editingShapes, setEditingShapes] = useState([]);
- const isEditing = selectedToolId === "fog";
const shouldHover =
- isEditing &&
- (selectedToolSettings.type === "toggle" ||
- selectedToolSettings.type === "remove");
+ active &&
+ (toolSettings.type === "toggle" || toolSettings.type === "remove");
const [patternImage] = useImage(diagonalPattern);
useEffect(() => {
- if (!isEditing) {
+ if (!active) {
return;
}
@@ -58,8 +58,8 @@ function MapFog({
const mapImage = mapStage.findOne("#mapImage");
return getBrushPositionForTool(
getRelativePointerPositionNormalized(mapImage),
- selectedToolId,
- selectedToolSettings,
+ toolId,
+ toolSettings,
gridSize,
shapes
);
@@ -67,7 +67,7 @@ function MapFog({
function handleBrushDown() {
const brushPosition = getBrushPosition();
- if (selectedToolSettings.type === "brush") {
+ if (toolSettings.type === "brush") {
setDrawingShape({
type: "fog",
data: {
@@ -75,7 +75,7 @@ function MapFog({
holes: [],
},
strokeWidth: 0.5,
- color: selectedToolSettings.useFogSubtract ? "red" : "black",
+ color: toolSettings.useFogSubtract ? "red" : "black",
blend: false,
id: shortid.generate(),
visible: true,
@@ -85,11 +85,7 @@ function MapFog({
}
function handleBrushMove() {
- if (
- selectedToolSettings.type === "brush" &&
- isBrushDown &&
- drawingShape
- ) {
+ if (toolSettings.type === "brush" && isBrushDown && drawingShape) {
const brushPosition = getBrushPosition();
setDrawingShape((prevShape) => {
const prevPoints = prevShape.data.points;
@@ -114,8 +110,8 @@ function MapFog({
}
function handleBrushUp() {
- if (selectedToolSettings.type === "brush" && drawingShape) {
- const subtract = selectedToolSettings.useFogSubtract;
+ if (toolSettings.type === "brush" && drawingShape) {
+ const subtract = toolSettings.useFogSubtract;
if (drawingShape.data.points.length > 1) {
let shapeData = {};
@@ -147,9 +143,9 @@ function MapFog({
// Erase
if (editingShapes.length > 0) {
- if (selectedToolSettings.type === "remove") {
+ if (toolSettings.type === "remove") {
onShapesRemove(editingShapes.map((shape) => shape.id));
- } else if (selectedToolSettings.type === "toggle") {
+ } else if (toolSettings.type === "toggle") {
onShapesEdit(
editingShapes.map((shape) => ({
...shape,
@@ -164,7 +160,7 @@ function MapFog({
}
function handlePolygonClick() {
- if (selectedToolSettings.type === "polygon") {
+ if (toolSettings.type === "polygon") {
const brushPosition = getBrushPosition();
setDrawingShape((prevDrawingShape) => {
if (prevDrawingShape) {
@@ -183,7 +179,7 @@ function MapFog({
holes: [],
},
strokeWidth: 0.5,
- color: selectedToolSettings.useFogSubtract ? "red" : "black",
+ color: toolSettings.useFogSubtract ? "red" : "black",
blend: false,
id: shortid.generate(),
visible: true,
@@ -194,7 +190,7 @@ function MapFog({
}
function handlePolygonMove() {
- if (selectedToolSettings.type === "polygon" && drawingShape) {
+ if (toolSettings.type === "polygon" && drawingShape) {
const brushPosition = getBrushPosition();
setDrawingShape((prevShape) => {
if (!prevShape) {
@@ -229,7 +225,7 @@ function MapFog({
};
}, [
mapStageRef,
- isEditing,
+ active,
drawingShape,
editingShapes,
gridSize,
@@ -238,15 +234,15 @@ function MapFog({
onShapeSubtract,
onShapesEdit,
onShapesRemove,
- selectedToolId,
- selectedToolSettings,
+ toolId,
+ toolSettings,
shapes,
stageScale,
interactionEmitter,
]);
const finishDrawingPolygon = useCallback(() => {
- const subtract = selectedToolSettings.useFogSubtract;
+ const subtract = toolSettings.useFogSubtract;
const data = {
...drawingShape.data,
// Remove the last point as it hasn't been placed yet
@@ -263,16 +259,12 @@ function MapFog({
}
setDrawingShape(null);
- }, [selectedToolSettings, drawingShape, onShapeSubtract, onShapeAdd]);
+ }, [toolSettings, drawingShape, onShapeSubtract, onShapeAdd]);
// Add keyboard shortcuts
useEffect(() => {
function handleKeyDown({ key }) {
- if (
- key === "Enter" &&
- selectedToolSettings.type === "polygon" &&
- drawingShape
- ) {
+ if (key === "Enter" && toolSettings.type === "polygon" && drawingShape) {
finishDrawingPolygon();
}
if (key === "Escape" && drawingShape) {
@@ -296,7 +288,7 @@ function MapFog({
}
return {
...prevShape,
- color: selectedToolSettings.useFogSubtract ? "black" : "red",
+ color: toolSettings.useFogSubtract ? "black" : "red",
};
});
}
@@ -307,12 +299,7 @@ function MapFog({
interactionEmitter.off("keyDown", handleKeyDown);
interactionEmitter.off("keyUp", handleKeyUp);
};
- }, [
- finishDrawingPolygon,
- interactionEmitter,
- drawingShape,
- selectedToolSettings,
- ]);
+ }, [finishDrawingPolygon, interactionEmitter, drawingShape, toolSettings]);
function handleShapeOver(shape, isDown) {
if (shouldHover && isDown) {
@@ -349,11 +336,14 @@ function MapFog({
mapWidth,
mapHeight
)}
- visible={isEditing || shape.visible}
- opacity={isEditing ? 0.5 : 1}
+ visible={(active && !toolSettings.preview) || shape.visible}
+ opacity={transparent ? 0.5 : 1}
fillPatternImage={patternImage}
- fillPriority={isEditing && !shape.visible ? "pattern" : "color"}
+ fillPriority={active && !shape.visible ? "pattern" : "color"}
holes={holes}
+ // Disable collision if the fog is transparent and we're not editing it
+ // This allows tokens to be moved under the fog
+ hitFunc={transparent && !active ? () => {} : undefined}
/>
);
}
@@ -394,8 +384,8 @@ function MapFog({
{shapes.map(renderShape)}
{drawingShape && renderShape(drawingShape)}
{drawingShape &&
- selectedToolSettings &&
- selectedToolSettings.type === "polygon" &&
+ toolSettings &&
+ toolSettings.type === "polygon" &&
renderPolygonAcceptTick(drawingShape)}
{editingShapes.length > 0 && editingShapes.map(renderEditingShape)}
diff --git a/src/components/map/controls/FogPreviewToggle.js b/src/components/map/controls/FogPreviewToggle.js
new file mode 100644
index 0000000..1e3f58a
--- /dev/null
+++ b/src/components/map/controls/FogPreviewToggle.js
@@ -0,0 +1,19 @@
+import React from "react";
+import { IconButton } from "theme-ui";
+
+import PreviewOnIcon from "../../../icons/FogPreviewOnIcon";
+import PreviewOffIcon from "../../../icons/FogPreviewOffIcon";
+
+function FogPreviewToggle({ useFogPreview, onFogPreviewChange }) {
+ return (
+ onFogPreviewChange(!useFogPreview)}
+ >
+ {useFogPreview ? : }
+
+ );
+}
+
+export default FogPreviewToggle;
diff --git a/src/components/map/controls/FogToolSettings.js b/src/components/map/controls/FogToolSettings.js
index f94b386..17c0304 100644
--- a/src/components/map/controls/FogToolSettings.js
+++ b/src/components/map/controls/FogToolSettings.js
@@ -1,9 +1,10 @@
import React, { useContext, useEffect } from "react";
-import { Flex } from "theme-ui";
+import { Flex, Label, Checkbox } from "theme-ui";
import { useMedia } from "react-media";
import EdgeSnappingToggle from "./EdgeSnappingToggle";
import RadioIconButton from "./RadioIconButton";
+import FogPreviewToggle from "./FogPreviewToggle";
import FogBrushIcon from "../../../icons/FogBrushIcon";
import FogPolygonIcon from "../../../icons/FogPolygonIcon";
@@ -142,6 +143,10 @@ function BrushToolSettings({
onSettingChange({ useEdgeSnapping })
}
/>
+ onSettingChange({ preview })}
+ />
onToolAction("fogUndo")}
diff --git a/src/icons/FogPreviewOffIcon.js b/src/icons/FogPreviewOffIcon.js
new file mode 100644
index 0000000..458c9d6
--- /dev/null
+++ b/src/icons/FogPreviewOffIcon.js
@@ -0,0 +1,18 @@
+import React from "react";
+
+function FogPreviewOffIcon() {
+ return (
+
+ );
+}
+
+export default FogPreviewOffIcon;
diff --git a/src/icons/FogPreviewOnIcon.js b/src/icons/FogPreviewOnIcon.js
new file mode 100644
index 0000000..baacee1
--- /dev/null
+++ b/src/icons/FogPreviewOnIcon.js
@@ -0,0 +1,18 @@
+import React from "react";
+
+function FogPreviewOnIcon() {
+ return (
+
+ );
+}
+
+export default FogPreviewOnIcon;