Added keyboard shortcuts to drawing and remaining fog tools

This commit is contained in:
Mitchell McCaffrey 2020-06-24 18:05:33 +10:00
parent 96a100c02a
commit 80b711296b
4 changed files with 158 additions and 21 deletions

View File

@ -122,7 +122,7 @@ function MapFog({
if (subtract) {
shapeData = { id: drawingShape.id, type: drawingShape.type };
} else {
shapeData = drawingShape;
shapeData = { ...drawingShape, color: "black" };
}
const shape = {
...shapeData,
@ -259,7 +259,7 @@ function MapFog({
data: data,
});
} else {
onShapeAdd({ ...drawingShape, data: data });
onShapeAdd({ ...drawingShape, data: data, color: "black" });
}
setDrawingShape(null);
@ -267,26 +267,52 @@ function MapFog({
// Add keyboard shortcuts
useEffect(() => {
const mapStage = mapStageRef.current;
function handleKeyDown(event) {
function handleKeyDown({ key }) {
if (
event.key === "Enter" &&
key === "Enter" &&
selectedToolSettings.type === "polygon" &&
drawingShape
) {
finishDrawingPolygon();
}
if (event.key === "Escape" && drawingShape) {
if (key === "Escape" && drawingShape) {
setDrawingShape(null);
}
if (key === "Alt" && drawingShape) {
updateShapeColor();
}
}
mapStage.container().addEventListener("keydown", handleKeyDown);
function handleKeyUp({ key }) {
if (key === "Alt" && drawingShape) {
updateShapeColor();
}
}
function updateShapeColor() {
setDrawingShape((prevShape) => {
if (!prevShape) {
return;
}
return {
...prevShape,
color: selectedToolSettings.useFogSubtract ? "black" : "red",
};
});
}
interactionEmitter.on("keyDown", handleKeyDown);
interactionEmitter.on("keyUp", handleKeyUp);
return () => {
mapStage.container().removeEventListener("keydown", handleKeyDown);
interactionEmitter.off("keyDown", handleKeyDown);
interactionEmitter.off("keyUp", handleKeyUp);
};
}, [finishDrawingPolygon, mapStageRef, drawingShape, selectedToolSettings]);
}, [
finishDrawingPolygon,
interactionEmitter,
drawingShape,
selectedToolSettings,
]);
function handleShapeOver(shape, isDown) {
if (shouldHover && isDown) {

View File

@ -127,7 +127,7 @@ function MapInteraction({
isInteractingWithCanvas.current =
event.target === mapLayerRef.current.getCanvas()._canvas;
},
onDrag: ({ delta, xy, first, last, pinching }) => {
onDrag: ({ delta, first, last, pinching }) => {
if (
preventMapInteraction ||
pinching ||
@ -166,6 +166,27 @@ function MapInteraction({
stageHeightRef.current = height;
}
function handleKeyDown(event) {
// Change to pan tool when pressing space
if (event.key === " " && selectedToolId === "pan") {
// Stop active state on pan icon from being selected
event.preventDefault();
}
if (event.key === " " && selectedToolId !== "pan") {
event.preventDefault();
previousSelectedToolRef.current = selectedToolId;
onSelectedToolChange("pan");
}
interactionEmitter.emit("keyDown", event);
}
function handleKeyUp(event) {
if (event.key === " " && selectedToolId === "pan") {
onSelectedToolChange(previousSelectedToolRef.current);
}
interactionEmitter.emit("keyUp", event);
}
function getCursorForTool(tool) {
switch (tool) {
case "pan":
@ -200,14 +221,6 @@ function MapInteraction({
interactionEmitter,
};
// Enable keyboard interaction for map stage container
useEffect(() => {
const container = mapStageRef.current.container();
container.tabIndex = 1;
container.style.outline = "none";
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<Box
sx={{
@ -215,10 +228,14 @@ function MapInteraction({
position: "relative",
cursor: getCursorForTool(selectedToolId),
touchAction: "none",
outline: "none",
}}
ref={containerRef}
{...bind()}
className="map"
tabIndex={1}
onKeyDown={handleKeyDown}
onKeyUp={handleKeyUp}
>
<ReactResizeDetector handleWidth handleHeight onResize={handleResize}>
<Stage

View File

@ -1,4 +1,4 @@
import React, { useEffect } from "react";
import React, { useEffect, useContext } from "react";
import { Flex, IconButton } from "theme-ui";
import ColorControl from "./ColorControl";
@ -18,12 +18,56 @@ import RedoButton from "./RedoButton";
import Divider from "../../Divider";
import MapInteractionContext from "../../../contexts/MapInteractionContext";
function DrawingToolSettings({
settings,
onSettingChange,
onToolAction,
disabledActions,
}) {
const { interactionEmitter } = useContext(MapInteractionContext);
// Keyboard shotcuts
useEffect(() => {
function handleKeyDown({ key, ctrlKey, metaKey, shiftKey }) {
if (key === "b") {
onSettingChange({ type: "brush" });
} else if (key === "p") {
onSettingChange({ type: "paint" });
} else if (key === "r") {
onSettingChange({ type: "rectangle" });
} else if (key === "c") {
onSettingChange({ type: "circle" });
} else if (key === "t") {
onSettingChange({ type: "triangle" });
} else if (key === "e") {
onSettingChange({ type: "erase" });
} else if (key === "o") {
onSettingChange({ useBlending: !settings.useBlending });
} else if (
key === "z" &&
(ctrlKey || metaKey) &&
shiftKey &&
!disabledActions.includes("redo")
) {
onToolAction("mapRedo");
} else if (
key === "z" &&
(ctrlKey || metaKey) &&
!shiftKey &&
!disabledActions.includes("undo")
) {
onToolAction("mapUndo");
}
}
interactionEmitter.on("keyDown", handleKeyDown);
return () => {
interactionEmitter.off("keyDown", handleKeyDown);
};
});
// Change to brush if on erase and it gets disabled
useEffect(() => {
if (settings.type === "erase" && disabledActions.includes("erase")) {

View File

@ -1,4 +1,4 @@
import React from "react";
import React, { useContext, useEffect } from "react";
import { Flex } from "theme-ui";
import EdgeSnappingToggle from "./EdgeSnappingToggle";
@ -16,12 +16,62 @@ import RedoButton from "./RedoButton";
import Divider from "../../Divider";
import MapInteractionContext from "../../../contexts/MapInteractionContext";
function BrushToolSettings({
settings,
onSettingChange,
onToolAction,
disabledActions,
}) {
const { interactionEmitter } = useContext(MapInteractionContext);
// Keyboard shortcuts
useEffect(() => {
function handleKeyDown({ key, ctrlKey, metaKey, shiftKey }) {
if (key === "Alt") {
onSettingChange({ useFogSubtract: !settings.useFogSubtract });
} else if (key === "p") {
onSettingChange({ type: "polygon" });
} else if (key === "b") {
onSettingChange({ type: "brush" });
} else if (key === "t") {
onSettingChange({ type: "toggle" });
} else if (key === "r") {
onSettingChange({ type: "remove" });
} else if (key === "s") {
onSettingChange({ useEdgeSnapping: !settings.useEdgeSnapping });
} else if (
key === "z" &&
(ctrlKey || metaKey) &&
shiftKey &&
!disabledActions.includes("redo")
) {
onToolAction("fogRedo");
} else if (
key === "z" &&
(ctrlKey || metaKey) &&
!shiftKey &&
!disabledActions.includes("undo")
) {
onToolAction("fogUndo");
}
}
function handleKeyUp({ key }) {
if (key === "Alt") {
onSettingChange({ useFogSubtract: !settings.useFogSubtract });
}
}
interactionEmitter.on("keyDown", handleKeyDown);
interactionEmitter.on("keyUp", handleKeyUp);
return () => {
interactionEmitter.off("keyDown", handleKeyDown);
interactionEmitter.off("keyUp", handleKeyUp);
};
});
return (
<Flex sx={{ alignItems: "center" }}>
<RadioIconButton