diff --git a/src/components/map/Map.js b/src/components/map/Map.js
index 927cff3..9eb2cb8 100644
--- a/src/components/map/Map.js
+++ b/src/components/map/Map.js
@@ -5,6 +5,7 @@ import ProxyToken from "../token/ProxyToken";
import TokenMenu from "../token/TokenMenu";
import MapToken from "./MapToken";
import MapDrawing from "./MapDrawing";
+import MapFog from "./MapFog";
import MapControls from "./MapControls";
import { omit } from "../../helpers/shared";
@@ -25,8 +26,9 @@ function Map({
onMapChange,
onMapStateChange,
onMapDraw,
- onMapDrawUndo,
- onMapDrawRedo,
+ onFogDraw,
+ onMapUndo,
+ onMapRedo,
allowDrawing,
allowTokenChange,
allowMapChange,
@@ -71,17 +73,30 @@ function Map({
}));
}
- const [drawnShapes, setDrawnShapes] = useState([]);
- function handleShapeAdd(shape) {
- onMapDraw({ type: "add", shapes: [shape] });
+ const [mapShapes, setMapShapes] = useState([]);
+ function handleMapShapeAdd(shape) {
+ onMapDraw({ type: "add", shapes: [shape], timestamp: Date.now() });
}
- function handleShapeRemove(shapeId) {
- onMapDraw({ type: "remove", shapeIds: [shapeId] });
+ function handleMapShapeRemove(shapeId) {
+ onMapDraw({ type: "remove", shapeIds: [shapeId], timestamp: Date.now() });
}
function handleShapeRemoveAll() {
- onMapDraw({ type: "remove", shapeIds: drawnShapes.map((s) => s.id) });
+ onMapDraw({
+ type: "remove",
+ shapeIds: mapShapes.map((s) => s.id),
+ timestamp: Date.now(),
+ });
+ }
+
+ const [fogShapes, setFogShapes] = useState([]);
+ function handleFogShapeAdd(shape) {
+ onFogDraw({ type: "add", shapes: [shape], timestamp: Date.now() });
+ }
+
+ function handleFogShapeRemove(shapeId) {
+ onFogDraw({ type: "remove", shapeIds: [shapeId], timestamp: Date.now() });
}
// Replay the draw actions and convert them to shapes for the map drawing
@@ -89,19 +104,28 @@ function Map({
if (!mapState) {
return;
}
- let shapesById = {};
- for (let i = 0; i <= mapState.drawActionIndex; i++) {
- const action = mapState.drawActions[i];
- if (action.type === "add") {
- for (let shape of action.shapes) {
- shapesById[shape.id] = shape;
+ function actionsToShapes(actions, actionIndex) {
+ let shapesById = {};
+ for (let i = 0; i <= actionIndex; i++) {
+ const action = actions[i];
+ if (action.type === "add") {
+ for (let shape of action.shapes) {
+ shapesById[shape.id] = shape;
+ }
+ }
+ if (action.type === "remove") {
+ shapesById = omit(shapesById, action.shapeIds);
}
}
- if (action.type === "remove") {
- shapesById = omit(shapesById, action.shapeIds);
- }
+ return Object.values(shapesById);
}
- setDrawnShapes(Object.values(shapesById));
+
+ setMapShapes(
+ actionsToShapes(mapState.mapDrawActions, mapState.mapDrawActionIndex)
+ );
+ setFogShapes(
+ actionsToShapes(mapState.fogDrawActions, mapState.fogDrawActionIndex)
+ );
}, [mapState]);
const disabledControls = [];
@@ -115,15 +139,15 @@ function Map({
disabledControls.push("pan");
disabledControls.push("brush");
}
- if (drawnShapes.length === 0) {
+ if (mapShapes.length === 0) {
disabledControls.push("erase");
}
- if (!mapState || mapState.drawActionIndex < 0) {
+ if (!mapState || mapState.mapDrawActionIndex < 0) {
disabledControls.push("undo");
}
if (
!mapState ||
- mapState.drawActionIndex === mapState.drawActions.length - 1
+ mapState.mapDrawActionIndex === mapState.mapDrawActions.length - 1
) {
disabledControls.push("redo");
}
@@ -191,11 +215,24 @@ function Map({
+ );
+
+ const mapFog = (
+
);
@@ -210,8 +247,8 @@ function Map({
toolSettings={toolSettings}
onToolSettingChange={handleToolSettingChange}
disabledControls={disabledControls}
- onUndo={onMapDrawUndo}
- onRedo={onMapDrawRedo}
+ onUndo={onMapUndo}
+ onRedo={onMapRedo}
/>
);
return (
@@ -224,6 +261,7 @@ function Map({
>
{map && mapImage}
{map && mapDrawing}
+ {map && mapFog}
{map && mapTokens}
{allowTokenChange && (
diff --git a/src/components/map/MapDrawing.js b/src/components/map/MapDrawing.js
index a76a29c..29c1203 100644
--- a/src/components/map/MapDrawing.js
+++ b/src/components/map/MapDrawing.js
@@ -10,6 +10,7 @@ import {
isShapeHovered,
drawShape,
simplifyPoints,
+ getRelativePointerPosition,
} from "../../helpers/drawing";
function MapDrawing({
@@ -29,34 +30,28 @@ function MapDrawing({
const [drawingShape, setDrawingShape] = useState(null);
const [pointerPosition, setPointerPosition] = useState({ x: -1, y: -1 });
- const shouldHover =
- selectedTool === "erase" ||
- (selectedTool === "fog" &&
- (toolSettings.type === "toggle" || toolSettings.type === "remove"));
+ const shouldHover = selectedTool === "erase";
+ const isEditing =
+ selectedTool === "brush" ||
+ selectedTool === "shape" ||
+ selectedTool === "erase";
// Reset pointer position when tool changes
useEffect(() => {
setPointerPosition({ x: -1, y: -1 });
}, [selectedTool]);
- function getRelativePointerPosition(event) {
- const container = containerRef.current;
- if (container) {
- const containerRect = container.getBoundingClientRect();
- const x = (event.clientX - containerRect.x) / containerRect.width;
- const y = (event.clientY - containerRect.y) / containerRect.height;
- return { x, y };
- }
- }
-
function handleStart(event) {
+ if (!isEditing) {
+ return;
+ }
if (event.touches && event.touches.length !== 1) {
setIsDrawing(false);
setDrawingShape(null);
return;
}
const pointer = event.touches ? event.touches[0] : event;
- const position = getRelativePointerPosition(pointer);
+ const position = getRelativePointerPosition(pointer, containerRef.current);
setPointerPosition(position);
setIsDrawing(true);
const brushPosition = getBrushPositionForTool(
@@ -67,6 +62,8 @@ function MapDrawing({
shapes
);
const commonShapeData = {
+ color: toolSettings && toolSettings.color,
+ blend: toolSettings && toolSettings.useBlending,
id: shortid.generate(),
};
if (selectedTool === "brush") {
@@ -75,8 +72,6 @@ function MapDrawing({
pathType: toolSettings.type,
data: { points: [brushPosition] },
strokeWidth: toolSettings.type === "stroke" ? 1 : 0,
- color: toolSettings && toolSettings.color,
- blend: toolSettings && toolSettings.useBlending,
...commonShapeData,
});
} else if (selectedTool === "shape") {
@@ -85,33 +80,32 @@ function MapDrawing({
shapeType: toolSettings.type,
data: getDefaultShapeData(toolSettings.type, brushPosition),
strokeWidth: 0,
- color: toolSettings && toolSettings.color,
- blend: toolSettings && toolSettings.useBlending,
- ...commonShapeData,
- });
- } else if (selectedTool === "fog" && toolSettings.type === "add") {
- setDrawingShape({
- type: "fog",
- data: { points: [brushPosition] },
- strokeWidth: 0.1,
- color: "black",
- blend: true, // Blend while drawing
...commonShapeData,
});
}
}
function handleMove(event) {
+ if (!isEditing) {
+ return;
+ }
if (event.touches && event.touches.length !== 1) {
return;
}
const pointer = event.touches ? event.touches[0] : event;
- const position = getRelativePointerPosition(pointer);
// Set pointer position every frame for erase tool and fog
if (shouldHover) {
+ const position = getRelativePointerPosition(
+ pointer,
+ containerRef.current
+ );
setPointerPosition(position);
}
if (isDrawing) {
+ const position = getRelativePointerPosition(
+ pointer,
+ containerRef.current
+ );
setPointerPosition(position);
const brushPosition = getBrushPositionForTool(
position,
@@ -150,28 +144,14 @@ function MapDrawing({
brushPosition
),
}));
- } else if (selectedTool === "fog" && toolSettings.type === "add") {
- setDrawingShape((prevShape) => {
- const prevPoints = prevShape.data.points;
- if (
- comparePoints(
- prevPoints[prevPoints.length - 1],
- brushPosition,
- 0.001
- )
- ) {
- return prevShape;
- }
- return {
- ...prevShape,
- data: { points: [...prevPoints, brushPosition] },
- };
- });
}
}
}
function handleStop(event) {
+ if (!isEditing) {
+ return;
+ }
if (event.touches && event.touches.length !== 0) {
return;
}
@@ -182,15 +162,6 @@ function MapDrawing({
}
} else if (selectedTool === "shape") {
onShapeAdd(drawingShape);
- } else if (selectedTool === "fog" && toolSettings.type === "add") {
- if (drawingShape.data.points.length > 1) {
- const shape = {
- ...drawingShape,
- data: { points: simplifyPoints(drawingShape.data.points, gridSize) },
- blend: false,
- };
- onShapeAdd(shape);
- }
}
setDrawingShape(null);
@@ -237,17 +208,7 @@ function MapDrawing({
hoveredShape = shape;
}
}
- if (selectedTool === "fog") {
- drawShape(
- { ...shape, blend: true },
- context,
- gridSize,
- width,
- height
- );
- } else {
- drawShape(shape, context, gridSize, width, height);
- }
+ drawShape(shape, context, gridSize, width, height);
}
if (drawingShape) {
drawShape(drawingShape, context, gridSize, width, height);
@@ -267,11 +228,19 @@ function MapDrawing({
selectedTool,
drawingShape,
gridSize,
+ shouldHover,
]);
return (