Added notes tool setup
This commit is contained in:
parent
9c1960ba71
commit
9fbd0d2a9d
@ -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}
|
||||
|
@ -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 = [
|
||||
{
|
||||
|
@ -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";
|
||||
|
87
src/components/map/MapNotes.js
Normal file
87
src/components/map/MapNotes.js
Normal 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;
|
47
src/components/map/controls/NoteToolSettings.js
Normal file
47
src/components/map/controls/NoteToolSettings.js
Normal 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;
|
19
src/icons/MoveIcon.js
Normal file
19
src/icons/MoveIcon.js
Normal file
@ -0,0 +1,19 @@
|
||||
import React from "react";
|
||||
|
||||
function MoveIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
fill="currentcolor"
|
||||
transform="scale(-1 1)"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M8.79,9.24V5.5c0-1.38,1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5v3.74c1.21-0.81,2-2.18,2-3.74c0-2.49-2.01-4.5-4.5-4.5 s-4.5,2.01-4.5,4.5C6.79,7.06,7.58,8.43,8.79,9.24z M14.29,11.71c-0.28-0.14-0.58-0.21-0.89-0.21h-0.61v-6 c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5v10.74l-3.44-0.72c-0.37-0.08-0.76,0.04-1.03,0.31c-0.43,0.44-0.43,1.14,0,1.58 l4.01,4.01C9.71,21.79,10.22,22,10.75,22h6.1c1,0,1.84-0.73,1.98-1.72l0.63-4.47c0.12-0.85-0.32-1.69-1.09-2.07L14.29,11.71z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default MoveIcon;
|
23
src/icons/NoteAddIcon.js
Normal file
23
src/icons/NoteAddIcon.js
Normal file
@ -0,0 +1,23 @@
|
||||
import React from "react";
|
||||
|
||||
function NoteAddIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
fill="currentcolor"
|
||||
transform="scale(-1 1)"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M18,12c-0.55,0-1,0.45-1,1v5.22c0,0.55-0.45,1-1,1H6c-0.55,0-1-0.45-1-1V8c0-0.55,0.45-1,1-1h5c0.55,0,1-0.45,1-1 c0-0.55-0.45-1-1-1H5C3.9,5,3,5.9,3,7v12c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-6C19,12.45,18.55,12,18,12z" />
|
||||
<path d="M21.02,5H19V2.98C19,2.44,18.56,2,18.02,2h-0.03C17.44,2,17,2.44,17,2.98V5h-2.01C14.45,5,14.01,5.44,14,5.98 c0,0.01,0,0.02,0,0.03C14,6.56,14.44,7,14.99,7H17v2.01c0,0.54,0.44,0.99,0.99,0.98c0.01,0,0.02,0,0.03,0 c0.54,0,0.98-0.44,0.98-0.98V7h2.02C21.56,7,22,6.56,22,6.02V5.98C22,5.44,21.56,5,21.02,5z" />
|
||||
<path d="M14,9H8c-0.55,0-1,0.45-1,1c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1C15,9.45,14.55,9,14,9z" />
|
||||
<path d="M14,12H8c-0.55,0-1,0.45-1,1c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1C15,12.45,14.55,12,14,12z" />
|
||||
<path d="M14,15H8c-0.55,0-1,0.45-1,1c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1C15,15.45,14.55,15,14,15z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default NoteAddIcon;
|
19
src/icons/NoteToolIcon.js
Normal file
19
src/icons/NoteToolIcon.js
Normal file
@ -0,0 +1,19 @@
|
||||
import React from "react";
|
||||
|
||||
function NoteToolIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
fill="currentcolor"
|
||||
transform="scale(-1 1)"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M19,3H4.99C3.89,3,3,3.9,3,5l0.01,14c0,1.1,0.89,2,1.99,2h10l6-6V5C21,3.9,20.1,3,19,3z M8,8h8c0.55,0,1,0.45,1,1v0 c0,0.55-0.45,1-1,1H8c-0.55,0-1-0.45-1-1v0C7,8.45,7.45,8,8,8z M11,14H8c-0.55,0-1-0.45-1-1v0c0-0.55,0.45-1,1-1h3 c0.55,0,1,0.45,1,1v0C12,13.55,11.55,14,11,14z M14,19.5V15c0-0.55,0.45-1,1-1h4.5L14,19.5z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default NoteToolIcon;
|
@ -32,6 +32,11 @@ function loadVersions(settings) {
|
||||
...prev,
|
||||
map: { fullScreen: false, labelSize: 1 },
|
||||
}));
|
||||
// v1.7.0 - Added note tool
|
||||
settings.version(3, (prev) => ({
|
||||
...prev,
|
||||
note: { type: "add" },
|
||||
}));
|
||||
}
|
||||
|
||||
export function getSettings() {
|
||||
|
Loading…
Reference in New Issue
Block a user