diff --git a/src/components/Map.js b/src/components/Map.js
index d434c06..2434476 100644
--- a/src/components/Map.js
+++ b/src/components/Map.js
@@ -34,6 +34,8 @@ function Map({
const [mapTranslate, setMapTranslate] = useState({ x: 0, y: 0 });
const [mapScale, setMapScale] = useState(1);
+ const [selectedTool, setSelectedTool] = useState("pan");
+
useEffect(() => {
interact(".map")
.gesturable({
@@ -42,10 +44,12 @@ function Map({
setMapScale((previousMapScale) =>
Math.max(Math.min(previousMapScale + event.ds, maxZoom), minZoom)
);
- setMapTranslate((previousMapTranslate) => ({
- x: previousMapTranslate.x + event.dx,
- y: previousMapTranslate.y + event.dy,
- }));
+ if (selectedTool === "pan") {
+ setMapTranslate((previousMapTranslate) => ({
+ x: previousMapTranslate.x + event.dx,
+ y: previousMapTranslate.y + event.dy,
+ }));
+ }
},
},
})
@@ -53,10 +57,12 @@ function Map({
inertia: true,
listeners: {
move: (event) => {
- // setMapTranslate((previousMapTranslate) => ({
- // x: previousMapTranslate.x + event.dx,
- // y: previousMapTranslate.y + event.dy,
- // }));
+ if (selectedTool === "pan") {
+ setMapTranslate((previousMapTranslate) => ({
+ x: previousMapTranslate.x + event.dx,
+ y: previousMapTranslate.y + event.dy,
+ }));
+ }
},
},
});
@@ -65,7 +71,7 @@ function Map({
setMapTranslate({ x: 0, y: 0 });
setMapScale(1);
});
- }, []);
+ }, [selectedTool]);
// Reset map transform when map changes
useEffect(() => {
@@ -194,10 +200,15 @@ function Map({
-
+
{divider}
-
+ onToolChange("pan")}
+ sx={{ color: selectedTool === "pan" ? "primary" : "text" }}
+ >
-
+ onToolChange("brush")}
+ sx={{ color: selectedTool === "brush" ? "primary" : "text" }}
+ >
-
+ onToolChange("erase")}
+ sx={{ color: selectedTool === "erase" ? "primary" : "text" }}
+ >
{divider}
diff --git a/src/components/MapDrawing.js b/src/components/MapDrawing.js
index 190d16e..451d9d6 100644
--- a/src/components/MapDrawing.js
+++ b/src/components/MapDrawing.js
@@ -1,7 +1,7 @@
import React, { useRef, useEffect, useState } from "react";
import simplify from "simplify-js";
-function MapDrawing({ width, height }) {
+function MapDrawing({ width, height, selectedTool }) {
const canvasRef = useRef();
const containerRef = useRef();
@@ -20,13 +20,20 @@ function MapDrawing({ width, height }) {
const [isMouseDown, setIsMouseDown] = useState(false);
function handleMouseDown(event) {
setIsMouseDown(true);
- const position = getMousePosition(event);
- setShapes((prevShapes) => [...prevShapes, { points: [position] }]);
+ if (selectedTool === "brush") {
+ const position = getMousePosition(event);
+ setShapes((prevShapes) => [...prevShapes, { points: [position] }]);
+ }
}
+ const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
function handleMouseMove(event) {
- if (isMouseDown) {
- const position = getMousePosition(event);
+ const position = getMousePosition(event);
+ if (selectedTool === "erase") {
+ setMousePosition(position);
+ }
+ if (isMouseDown && selectedTool === "brush") {
+ setMousePosition(position);
setShapes((prevShapes) => {
const currentShape = prevShapes.slice(-1)[0];
const otherShapes = prevShapes.slice(0, -1);
@@ -37,12 +44,14 @@ function MapDrawing({ width, height }) {
function handleMouseUp(event) {
setIsMouseDown(false);
- setShapes((prevShapes) => {
- const currentShape = prevShapes.slice(-1)[0];
- const otherShapes = prevShapes.slice(0, -1);
- const simplified = simplify(currentShape.points, 0.001);
- return [...otherShapes, { points: simplified }];
- });
+ if (selectedTool === "brush") {
+ setShapes((prevShapes) => {
+ const currentShape = prevShapes.slice(-1)[0];
+ const otherShapes = prevShapes.slice(0, -1);
+ const simplified = simplify(currentShape.points, 0.001);
+ return [...otherShapes, { points: simplified }];
+ });
+ }
}
useEffect(() => {
@@ -51,18 +60,43 @@ function MapDrawing({ width, height }) {
const context = canvas.getContext("2d");
context.clearRect(0, 0, width, height);
- for (let shape of shapes) {
- context.beginPath();
- context.moveTo(shape.points[0].x * width, shape.points[0].y * height);
+ let erasedShapes = [];
+ for (let [index, shape] of shapes.entries()) {
+ const path = new Path2D();
+ path.moveTo(shape.points[0].x * width, shape.points[0].y * height);
for (let point of shape.points.slice(1)) {
- context.lineTo(point.x * width, point.y * height);
+ path.lineTo(point.x * width, point.y * height);
}
- context.closePath();
- context.stroke();
- context.fill();
+ path.closePath();
+ let color = "#000000";
+ if (selectedTool === "erase") {
+ if (
+ context.isPointInPath(
+ path,
+ mousePosition.x * width,
+ mousePosition.y * height
+ )
+ ) {
+ color = "#BB99FF";
+ if (isMouseDown) {
+ erasedShapes.push(index);
+ continue;
+ }
+ }
+ }
+ context.fillStyle = color;
+ context.strokeStyle = color;
+ context.stroke(path);
+ context.fill(path);
+ }
+
+ if (erasedShapes.length > 0) {
+ setShapes((prevShapes) =>
+ prevShapes.filter((_, i) => !erasedShapes.includes(i))
+ );
}
}
- }, [shapes, width, height]);
+ }, [shapes, width, height, mousePosition, isMouseDown, selectedTool]);
return (