Added undo and redo and map control validation

This commit is contained in:
Mitchell McCaffrey
2020-04-19 13:33:31 +10:00
parent 1f20959940
commit 24de41fee7
4 changed files with 213 additions and 75 deletions
+82 -2
View File
@@ -8,6 +8,8 @@ import MapToken from "./MapToken";
import MapDrawing from "./MapDrawing";
import MapControls from "./MapControls";
import { omit } from "../helpers/shared";
const mapTokenClassName = "map-token";
const zoomSpeed = -0.005;
const minZoom = 0.1;
@@ -31,11 +33,77 @@ function Map({
}
}
const [mapTranslate, setMapTranslate] = useState({ x: 0, y: 0 });
const [mapScale, setMapScale] = useState(1);
/**
* Map drawing
*/
const [selectedTool, setSelectedTool] = useState("pan");
const [drawnShapes, setDrawnShapes] = useState([]);
const [drawActions, setDrawActions] = useState([]);
const [drawActionIndex, setDrawActionIndex] = useState(-1);
function handleShapeAdd(shape) {
setDrawActions((prevActions) => {
const newActions = [
...prevActions.slice(0, drawActionIndex + 1),
{ type: "add", shape },
];
setDrawActionIndex(newActions.length - 1);
return newActions;
});
}
function handleShapeRemove(shapeId) {
setDrawActions((prevActions) => {
const newActions = [
...prevActions.slice(0, drawActionIndex + 1),
{ type: "remove", shapeId },
];
setDrawActionIndex(newActions.length - 1);
return newActions;
});
}
useEffect(() => {
let shapesById = {};
for (let i = 0; i <= drawActionIndex; i++) {
const action = drawActions[i];
if (action.type === "add") {
shapesById[action.shape.id] = action.shape;
}
if (action.type === "remove") {
shapesById = omit(shapesById, [action.shapeId]);
}
}
setDrawnShapes(Object.values(shapesById));
}, [drawActions, drawActionIndex]);
function handleDrawActionUndo() {
setDrawActionIndex((prevIndex) => Math.max(prevIndex - 1, -1));
}
function handleDrawActionRedo() {
setDrawActionIndex((prevIndex) =>
Math.min(prevIndex + 1, drawActions.length - 1)
);
}
const disabledTools = [];
if (!mapData) {
disabledTools.push("pan");
disabledTools.push("brush");
}
if (drawnShapes.length === 0) {
disabledTools.push("erase");
}
/**
* Map movement
*/
const [mapTranslate, setMapTranslate] = useState({ x: 0, y: 0 });
const [mapScale, setMapScale] = useState(1);
useEffect(() => {
interact(".map")
.gesturable({
@@ -110,6 +178,10 @@ function Map({
};
}, []);
/**
* Member setup
*/
const mapRef = useRef(null);
const mapContainerRef = useRef();
const rows = mapData && mapData.rows;
@@ -201,6 +273,9 @@ function Map({
width={mapData ? mapData.width : 0}
height={mapData ? mapData.height : 0}
selectedTool={selectedTool}
shapes={drawnShapes}
onShapeAdd={handleShapeAdd}
onShapeRemove={handleShapeRemove}
/>
</Box>
</Box>
@@ -208,6 +283,11 @@ function Map({
onMapChange={onMapChange}
onToolChange={setSelectedTool}
selectedTool={selectedTool}
disabledTools={disabledTools}
onUndo={handleDrawActionUndo}
onRedo={handleDrawActionRedo}
undoDisabled={drawActionIndex < 0}
redoDisabled={drawActionIndex === drawActions.length - 1}
/>
</Box>
<ProxyToken