diff --git a/src/components/map/MapFog.js b/src/components/map/MapFog.js index cace424..39e759e 100644 --- a/src/components/map/MapFog.js +++ b/src/components/map/MapFog.js @@ -1,4 +1,4 @@ -import React, { useContext, useState, useEffect } from "react"; +import React, { useContext, useState, useEffect, useCallback } from "react"; import shortid from "shortid"; import { Group } from "react-konva"; import useImage from "use-image"; @@ -18,6 +18,7 @@ import colors from "../../helpers/colors"; import { HoleyLine, getRelativePointerPositionNormalized, + Tick, } from "../../helpers/konva"; function MapFog({ @@ -191,45 +192,14 @@ function MapFog({ setIsBrushDown(false); } - function handleKeyDown(event) { - if ( - event.key === "Enter" && - selectedToolSettings.type === "polygon" && - drawingShape - ) { - const subtract = selectedToolSettings.useFogSubtract; - const data = { - ...drawingShape.data, - // Remove the last point as it hasn't been placed yet - points: drawingShape.data.points.slice(0, -1), - }; - if (subtract) { - onShapeSubtract({ - id: drawingShape.id, - type: drawingShape.type, - data: data, - }); - } else { - onShapeAdd({ ...drawingShape, data: data }); - } - - setDrawingShape(null); - } - if (event.key === "Escape" && drawingShape) { - setDrawingShape(null); - } - } - mapStage.on("mousedown", handleBrushDown); mapStage.on("mousemove", handleBrushMove); mapStage.on("mouseup", handleBrushUp); - mapStage.container().addEventListener("keydown", handleKeyDown); return () => { mapStage.off("mousedown", handleBrushDown); mapStage.off("mousemove", handleBrushMove); mapStage.off("mouseup", handleBrushUp); - mapStage.container().removeEventListener("keydown", handleKeyDown); }; }, [ mapStageRef, @@ -248,6 +218,49 @@ function MapFog({ stageScale, ]); + const finishDrawingPolygon = useCallback(() => { + const subtract = selectedToolSettings.useFogSubtract; + const data = { + ...drawingShape.data, + // Remove the last point as it hasn't been placed yet + points: drawingShape.data.points.slice(0, -1), + }; + if (subtract) { + onShapeSubtract({ + id: drawingShape.id, + type: drawingShape.type, + data: data, + }); + } else { + onShapeAdd({ ...drawingShape, data: data }); + } + + setDrawingShape(null); + }, [selectedToolSettings, drawingShape, onShapeSubtract, onShapeAdd]); + + // Add keyboard shortcuts + useEffect(() => { + const mapStage = mapStageRef.current; + + function handleKeyDown(event) { + if ( + event.key === "Enter" && + selectedToolSettings.type === "polygon" && + drawingShape + ) { + finishDrawingPolygon(); + } + if (event.key === "Escape" && drawingShape) { + setDrawingShape(null); + } + } + + mapStage.container().addEventListener("keydown", handleKeyDown); + return () => { + mapStage.container().removeEventListener("keydown", handleKeyDown); + }; + }, [finishDrawingPolygon, mapStageRef, drawingShape, selectedToolSettings]); + function handleShapeOver(shape, isDown) { if (shouldHover && isDown) { if (editingShapes.findIndex((s) => s.id === shape.id) === -1) { @@ -300,10 +313,35 @@ function MapFog({ return renderShape(editingShape); } + function renderPolygonAcceptTick(shape) { + if (shape.data.points.length === 0) { + return; + } + return ( + { + // Check that there is enough points after clicking + if (shape.data.points.length < 5) { + setDrawingShape(null); + } else { + finishDrawingPolygon(); + } + }} + /> + ); + } + return ( {shapes.map(renderShape)} {drawingShape && renderShape(drawingShape)} + {drawingShape && + selectedToolSettings.type === "polygon" && + renderPolygonAcceptTick(drawingShape)} {editingShapes.length > 0 && editingShapes.map(renderEditingShape)} ); diff --git a/src/helpers/konva.js b/src/helpers/konva.js index dd799be..b648a7f 100644 --- a/src/helpers/konva.js +++ b/src/helpers/konva.js @@ -1,5 +1,5 @@ -import React from "react"; -import { Line } from "react-konva"; +import React, { useState } from "react"; +import { Line, Group, Path, Circle } from "react-konva"; // Holes should be wound in the opposite direction as the containing points array export function HoleyLine({ holes, ...props }) { @@ -106,6 +106,40 @@ export function HoleyLine({ holes, ...props }) { return ; } +export function Tick({ x, y, scale, onClick, cross }) { + const [fill, setFill] = useState("white"); + function handleEnter() { + setFill("hsl(260, 100%, 80%)"); + } + + function handleLeave() { + setFill("white"); + } + return ( + + + + + ); +} + export function getRelativePointerPosition(node) { let transform = node.getAbsoluteTransform().copy(); transform.invert();