From 5357b79e70d0fcdb482df87c6d69043b402c02f3 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Wed, 29 Apr 2020 20:40:34 +1000 Subject: [PATCH] Added fog toggle --- src/components/map/Map.js | 7 ++- src/components/map/MapDrawing.js | 14 +++--- src/components/map/MapFog.js | 83 +++++++++++++++++++++---------- src/images/DiagonalPattern.png | Bin 0 -> 4794 bytes 4 files changed, 69 insertions(+), 35 deletions(-) create mode 100644 src/images/DiagonalPattern.png diff --git a/src/components/map/Map.js b/src/components/map/Map.js index 9eb2cb8..8b482a9 100644 --- a/src/components/map/Map.js +++ b/src/components/map/Map.js @@ -99,6 +99,10 @@ function Map({ onFogDraw({ type: "remove", shapeIds: [shapeId], timestamp: Date.now() }); } + function handleFogShapeEdit(shape) { + onFogDraw({ type: "edit", shapes: [shape], timestamp: Date.now() }); + } + // Replay the draw actions and convert them to shapes for the map drawing useEffect(() => { if (!mapState) { @@ -108,7 +112,7 @@ function Map({ let shapesById = {}; for (let i = 0; i <= actionIndex; i++) { const action = actions[i]; - if (action.type === "add") { + if (action.type === "add" || action.type === "edit") { for (let shape of action.shapes) { shapesById[shape.id] = shape; } @@ -233,6 +237,7 @@ function Map({ shapes={fogShapes} onShapeAdd={handleFogShapeAdd} onShapeRemove={handleFogShapeRemove} + onShapeEdit={handleFogShapeEdit} gridSize={gridSizeNormalized} /> ); diff --git a/src/components/map/MapDrawing.js b/src/components/map/MapDrawing.js index 8495a7d..fbc5416 100644 --- a/src/components/map/MapDrawing.js +++ b/src/components/map/MapDrawing.js @@ -27,7 +27,7 @@ function MapDrawing({ const canvasRef = useRef(); const containerRef = useRef(); - const [isDrawing, setIsDrawing] = useState(false); + const [isPointerDown, setIsPointerDown] = useState(false); const [drawingShape, setDrawingShape] = useState(null); const [pointerPosition, setPointerPosition] = useState({ x: -1, y: -1 }); @@ -49,14 +49,14 @@ function MapDrawing({ return; } if (event.touches && event.touches.length !== 1) { - setIsDrawing(false); + setIsPointerDown(false); setDrawingShape(null); return; } const pointer = event.touches ? event.touches[0] : event; const position = getRelativePointerPosition(pointer, containerRef.current); setPointerPosition(position); - setIsDrawing(true); + setIsPointerDown(true); const brushPosition = getBrushPositionForTool( position, selectedTool, @@ -104,7 +104,7 @@ function MapDrawing({ ); setPointerPosition(position); } - if (isDrawing) { + if (isPointerDown) { const position = getRelativePointerPosition( pointer, containerRef.current @@ -168,10 +168,10 @@ function MapDrawing({ onShapeAdd(drawingShape); } - if (selectedTool === "erase" && hoveredShapeRef.current && isDrawing) { + if (selectedTool === "erase" && hoveredShapeRef.current && isPointerDown) { onShapeRemove(hoveredShapeRef.current.id); } - setIsDrawing(false); + setIsPointerDown(false); setDrawingShape(null); } @@ -229,7 +229,7 @@ function MapDrawing({ width, height, pointerPosition, - isDrawing, + isPointerDown, selectedTool, drawingShape, gridSize, diff --git a/src/components/map/MapFog.js b/src/components/map/MapFog.js index 7b45f4d..50774e6 100644 --- a/src/components/map/MapFog.js +++ b/src/components/map/MapFog.js @@ -12,6 +12,8 @@ import { import MapInteractionContext from "../../contexts/MapInteractionContext"; +import diagonalPattern from "../../images/DiagonalPattern.png"; + function MapFog({ width, height, @@ -20,12 +22,13 @@ function MapFog({ shapes, onShapeAdd, onShapeRemove, + onShapeEdit, gridSize, }) { const canvasRef = useRef(); const containerRef = useRef(); - const [isDrawing, setIsDrawing] = useState(false); + const [isPointerDown, setIsPointerDown] = useState(false); const [drawingShape, setDrawingShape] = useState(null); const [pointerPosition, setPointerPosition] = useState({ x: -1, y: -1 }); @@ -45,14 +48,14 @@ function MapFog({ return; } if (event.touches && event.touches.length !== 1) { - setIsDrawing(false); + setIsPointerDown(false); setDrawingShape(null); return; } const pointer = event.touches ? event.touches[0] : event; const position = getRelativePointerPosition(pointer, containerRef.current); setPointerPosition(position); - setIsDrawing(true); + setIsPointerDown(true); const brushPosition = getBrushPositionForTool( position, "fog", @@ -68,6 +71,7 @@ function MapFog({ color: "black", blend: true, // Blend while drawing id: shortid.generate(), + visible: true, }); } } @@ -85,7 +89,7 @@ function MapFog({ if (shouldHover) { setPointerPosition(position); } - if (isDrawing) { + if (isPointerDown) { setPointerPosition(position); const brushPosition = getBrushPositionForTool( position, @@ -140,15 +144,18 @@ function MapFog({ } } - if ( - toolSettings.type === "remove" && - hoveredShapeRef.current && - isDrawing - ) { - onShapeRemove(hoveredShapeRef.current.id); + if (hoveredShapeRef.current && isPointerDown) { + if (toolSettings.type === "remove") { + onShapeRemove(hoveredShapeRef.current.id); + } else if (toolSettings.type === "toggle") { + onShapeEdit({ + ...hoveredShapeRef.current, + visible: !hoveredShapeRef.current.visible, + }); + } } setDrawingShape(null); - setIsDrawing(false); + setIsPointerDown(false); } // Add listeners for draw events on map to allow drawing past the bounds @@ -176,6 +183,14 @@ function MapFog({ * Rendering */ const hoveredShapeRef = useRef(null); + const diagonalPatternRef = useRef(); + + useEffect(() => { + let image = new Image(); + image.src = diagonalPattern; + diagonalPatternRef.current = image; + }, []); + useEffect(() => { const canvas = canvasRef.current; if (canvas) { @@ -183,30 +198,45 @@ function MapFog({ context.clearRect(0, 0, width, height); let hoveredShape = null; - for (let shape of shapes) { - if (shouldHover) { - if (isShapeHovered(shape, context, pointerPosition, width, height)) { - hoveredShape = shape; + if (isEditing) { + const editPattern = context.createPattern( + diagonalPatternRef.current, + "repeat" + ); + for (let shape of shapes) { + if (shouldHover) { + if ( + isShapeHovered(shape, context, pointerPosition, width, height) + ) { + hoveredShape = shape; + } } - } - if (isEditing) { drawShape( - { ...shape, blend: true }, + { + ...shape, + blend: true, + color: shape.visible ? "black" : editPattern, + }, context, gridSize, width, height ); - } else { + } + if (drawingShape) { + drawShape(drawingShape, context, gridSize, width, height); + } + if (hoveredShape) { + const shape = { ...hoveredShape, color: "#BB99FF", blend: true }; drawShape(shape, context, gridSize, width, height); } - } - if (drawingShape) { - drawShape(drawingShape, context, gridSize, width, height); - } - if (hoveredShape) { - const shape = { ...hoveredShape, color: "#BB99FF", blend: true }; - drawShape(shape, context, gridSize, width, height); + } else { + // Not editing + for (let shape of shapes) { + if (shape.visible) { + drawShape(shape, context, gridSize, width, height); + } + } } hoveredShapeRef.current = hoveredShape; } @@ -215,7 +245,6 @@ function MapFog({ width, height, pointerPosition, - isDrawing, isEditing, drawingShape, gridSize, diff --git a/src/images/DiagonalPattern.png b/src/images/DiagonalPattern.png new file mode 100644 index 0000000000000000000000000000000000000000..5d44de9e84afddd1fc27760a02c7c4d38719aa31 GIT binary patch literal 4794 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 literal 0 HcmV?d00001