Added notes tool setup

This commit is contained in:
Mitchell McCaffrey
2020-11-03 16:21:39 +11:00
parent 9c1960ba71
commit 9fbd0d2a9d
9 changed files with 228 additions and 1 deletions

View File

@@ -10,6 +10,7 @@ import MapGrid from "./MapGrid";
import MapMeasure from "./MapMeasure";
import MapLoadingOverlay from "./MapLoadingOverlay";
import NetworkedMapPointer from "../../network/NetworkedMapPointer";
import MapNotes from "./MapNotes";
import TokenDataContext from "../../contexts/TokenDataContext";
import SettingsContext from "../../contexts/SettingsContext";
@@ -133,6 +134,7 @@ function Map({
disabledControls.push("pan");
disabledControls.push("measure");
disabledControls.push("pointer");
disabledControls.push("note");
}
if (!allowFogDrawing) {
disabledControls.push("fog");
@@ -350,6 +352,15 @@ function Map({
/>
);
const mapNotes = (
<MapNotes
map={map}
active={selectedToolId === "note"}
gridSize={gridSizeNormalized}
selectedToolSettings={settings[selectedToolId]}
/>
);
return (
<MapInteraction
map={map}
@@ -366,6 +377,7 @@ function Map({
disabledControls={disabledControls}
>
{mapGrid}
{mapNotes}
{mapDrawing}
{mapTokens}
{mapFog}

View File

@@ -9,6 +9,7 @@ import SelectMapButton from "./SelectMapButton";
import FogToolSettings from "./controls/FogToolSettings";
import DrawingToolSettings from "./controls/DrawingToolSettings";
import MeasureToolSettings from "./controls/MeasureToolSettings";
import NoteToolSettings from "./controls/NoteToolSettings";
import PanToolIcon from "../../icons/PanToolIcon";
import FogToolIcon from "../../icons/FogToolIcon";
@@ -18,6 +19,7 @@ import ExpandMoreIcon from "../../icons/ExpandMoreIcon";
import PointerToolIcon from "../../icons/PointerToolIcon";
import FullScreenIcon from "../../icons/FullScreenIcon";
import FullScreenExitIcon from "../../icons/FullScreenExitIcon";
import NoteToolIcon from "../../icons/NoteToolIcon";
import useSetting from "../../helpers/useSetting";
@@ -66,8 +68,14 @@ function MapContols({
icon: <PointerToolIcon />,
title: "Pointer Tool (Q)",
},
note: {
id: "note",
icon: <NoteToolIcon />,
title: "Note Tool (N)",
SettingsComponent: NoteToolSettings,
},
};
const tools = ["pan", "fog", "drawing", "measure", "pointer"];
const tools = ["pan", "fog", "drawing", "measure", "pointer", "note"];
const sections = [
{

View File

@@ -135,6 +135,9 @@ function MapInteraction({
if (event.key === "q" && !disabledControls.includes("pointer")) {
onSelectedToolChange("pointer");
}
if (event.key === "n" && !disabledControls.includes("note")) {
onSelectedToolChange("note");
}
}
function handleKeyUp(event) {
@@ -153,6 +156,10 @@ function MapInteraction({
return "move";
case "fog":
case "drawing":
case "note":
return settings.settings[tool].type === "move"
? "pointer"
: "crosshair";
case "measure":
case "pointer":
return "crosshair";

View File

@@ -0,0 +1,87 @@
import React, { useContext, useState, useEffect } from "react";
import { Group, Rect } from "react-konva";
import MapInteractionContext from "../../contexts/MapInteractionContext";
import MapStageContext from "../../contexts/MapStageContext";
import { getBrushPositionForTool } from "../../helpers/drawing";
import { getRelativePointerPositionNormalized } from "../../helpers/konva";
const defaultNoteSize = 2;
function MapNotes({ map, selectedToolSettings, active, gridSize }) {
const { mapWidth, mapHeight, interactionEmitter } = useContext(
MapInteractionContext
);
const mapStageRef = useContext(MapStageContext);
const [isBrushDown, setIsBrushDown] = useState(false);
const [brushPosition, setBrushPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
if (!active) {
return;
}
const mapStage = mapStageRef.current;
function getBrushPosition() {
const mapImage = mapStage.findOne("#mapImage");
return getBrushPositionForTool(
map,
getRelativePointerPositionNormalized(mapImage),
map.snapToGrid,
false,
gridSize,
[]
);
}
function handleBrushDown() {
setBrushPosition(getBrushPosition());
setIsBrushDown(true);
}
function handleBrushMove() {
setBrushPosition(getBrushPosition());
setIsBrushDown(true);
}
function handleBrushUp() {
setBrushPosition({ x: 0, y: 0 });
setIsBrushDown(false);
}
interactionEmitter.on("dragStart", handleBrushDown);
interactionEmitter.on("drag", handleBrushMove);
interactionEmitter.on("dragEnd", handleBrushUp);
return () => {
interactionEmitter.off("dragStart", handleBrushDown);
interactionEmitter.off("drag", handleBrushMove);
interactionEmitter.off("dragEnd", handleBrushUp);
};
});
const noteWidth = map && (mapWidth / map.grid.size.x) * defaultNoteSize;
const noteHeight = map && (mapHeight / map.grid.size.y) * defaultNoteSize;
return (
<Group>
{isBrushDown && (
<Rect
x={brushPosition.x * mapWidth}
y={brushPosition.y * mapHeight}
width={noteWidth}
height={noteHeight}
offsetX={noteWidth / 2}
offsetY={noteHeight / 2}
fill="white"
shadowColor="rgba(0, 0, 0, 0.16)"
shadowOffset={{ x: 0, y: 3 }}
shadowBlur={6}
/>
)}
</Group>
);
}
export default MapNotes;

View File

@@ -0,0 +1,47 @@
import React from "react";
import { Flex } from "theme-ui";
import ToolSection from "./ToolSection";
import NoteAddIcon from "../../../icons/NoteAddIcon";
import MoveIcon from "../../../icons/MoveIcon";
import useKeyboard from "../../../helpers/useKeyboard";
function NoteToolSettings({ settings, onSettingChange }) {
// Keyboard shortcuts
function handleKeyDown({ key }) {
if (key === "a") {
onSettingChange({ type: "add" });
} else if (key === "v") {
onSettingChange({ type: "move" });
}
}
useKeyboard(handleKeyDown);
const tools = [
{
id: "add",
title: "Add Note (A)",
isSelected: settings.type === "add",
icon: <NoteAddIcon />,
},
{
id: "move",
title: "Move Note (V)",
isSelected: settings.type === "move",
icon: <MoveIcon />,
},
];
return (
<Flex sx={{ alignItems: "center" }}>
<ToolSection
tools={tools}
onToolClick={(tool) => onSettingChange({ type: tool.id })}
/>
</Flex>
);
}
export default NoteToolSettings;