Add shortcut for disabling grid snapping

This commit is contained in:
Mitchell McCaffrey 2021-08-04 08:32:27 +10:00
parent 9e5eb9d258
commit 6eb1f71bc2
6 changed files with 100 additions and 17 deletions

View File

@ -3,7 +3,10 @@ import { Transform } from "konva/lib/Util";
import { useEffect, useMemo, useRef } from "react";
import { Transformer as KonvaTransformer } from "react-konva";
import { useGridCellPixelSize } from "../../contexts/GridContext";
import {
useGridCellPixelSize,
useGridSnappingSensitivity,
} from "../../contexts/GridContext";
import { useSetPreventMapInteraction } from "../../contexts/MapInteractionContext";
import { roundTo } from "../../helpers/shared";
import Vector2 from "../../helpers/Vector2";
@ -56,6 +59,10 @@ function Transformer({
}, [active, nodeRef, gridCellPixelSize]);
const scale = parseGridScale(gridScale);
const snappingSensitivity = useGridSnappingSensitivity();
// Clamp snapping to 0 to accound for -1 snapping override
const gridSnappingSensitivity = Math.max(snappingSensitivity, 0);
const anchorScale = useMemo(() => getAnchorImage(192, scaleDark), []);
const anchorRotate = useMemo(() => getAnchorImage(192, rotateDark), []);
@ -192,8 +199,10 @@ function Transformer({
);
const distanceToSnap = Math.abs(snapBox.width - nearestCellWidth);
let snapping = false;
if (distanceToSnap < gridCellAbsoluteSize.x * 0.1) {
// TODO: use global grid snapping value
if (
distanceToSnap <
gridCellAbsoluteSize.x * gridSnappingSensitivity
) {
snapBox.width = nearestCellWidth;
snapping = true;
}

View File

@ -20,6 +20,7 @@ import {
useGridStrokeWidth,
useGridCellPixelOffset,
useGridOffset,
useGridSnappingSensitivity,
} from "../../contexts/GridContext";
import { useKeyboard } from "../../contexts/KeyboardContext";
@ -93,9 +94,10 @@ function FogTool({
const gridCellPixelOffset = useGridCellPixelOffset();
const gridOffset = useGridOffset();
const [gridSnappingSensitivity] = useSetting<number>(
"map.gridSnappingSensitivity"
);
const snappingSensitivity = useGridSnappingSensitivity();
// Clamp snapping to 0 to accound for -1 snapping override
const gridSnappingSensitivity = Math.max(snappingSensitivity, 0);
const [showFogGuides] = useSetting<boolean>("fog.showGuides");
const [editOpacity] = useSetting<number>("fog.editOpacity");
const mapStageRef = useMapStage();

View File

@ -3,8 +3,15 @@ import React, { useContext, useState, useEffect } from "react";
import Vector2 from "../helpers/Vector2";
import Size from "../helpers/Size";
import { getGridPixelSize, getCellPixelSize } from "../helpers/grid";
import { Grid } from "../types/Grid";
import useSetting from "../hooks/useSetting";
import shortcuts from "../shortcuts";
import { useBlur, useKeyboard } from "./KeyboardContext";
/**
* @typedef GridContextValue
* @property {Grid} grid Base grid value
@ -23,6 +30,7 @@ type GridContextValue = {
gridOffset: Vector2;
gridStrokeWidth: number;
gridCellPixelOffset: Vector2;
gridSnappingSensitivity: number;
};
/**
@ -44,6 +52,7 @@ const defaultValue: GridContextValue = {
gridOffset: new Vector2(0, 0),
gridStrokeWidth: 0,
gridCellPixelOffset: new Vector2(0, 0),
gridSnappingSensitivity: 0,
};
export const GridContext = React.createContext(defaultValue.grid);
@ -63,6 +72,9 @@ export const GridStrokeWidthContext = React.createContext(
export const GridCellPixelOffsetContext = React.createContext(
defaultValue.gridCellPixelOffset
);
export const GridSnappingSensitivityContext = React.createContext(
defaultValue.gridSnappingSensitivity
);
const defaultStrokeWidth = 1 / 10;
@ -138,6 +150,40 @@ export function GridProvider({
setGridCellPixelOffset(_gridCellPixelOffset);
}, [grid, width, height]);
const [gridSnappingSensitivity, setGridSnappingSensitivity] = useState(
defaultValue.gridSnappingSensitivity
);
const [defaultSnappingSensitivity] = useSetting<number>(
"map.gridSnappingSensitivity"
);
useEffect(() => {
if (
gridSnappingSensitivity !== defaultSnappingSensitivity &&
gridSnappingSensitivity !== -1 // Snapping not disabled
) {
setGridSnappingSensitivity(defaultSnappingSensitivity);
}
}, [defaultSnappingSensitivity, gridSnappingSensitivity]);
function handleKeyDown(event: KeyboardEvent) {
if (shortcuts.disableSnapping(event)) {
setGridSnappingSensitivity(-1);
}
}
function handleKeyUp(event: KeyboardEvent) {
if (shortcuts.disableSnapping(event)) {
setGridSnappingSensitivity(defaultSnappingSensitivity);
}
}
function handleBlur() {
setGridSnappingSensitivity(defaultSnappingSensitivity);
}
useKeyboard(handleKeyDown, handleKeyUp);
useBlur(handleBlur);
return (
<GridContext.Provider value={grid}>
<GridPixelSizeContext.Provider value={gridPixelSize}>
@ -149,8 +195,12 @@ export function GridProvider({
<GridStrokeWidthContext.Provider value={gridStrokeWidth}>
<GridCellPixelOffsetContext.Provider
value={gridCellPixelOffset}
>
<GridSnappingSensitivityContext.Provider
value={gridSnappingSensitivity}
>
{children}
</GridSnappingSensitivityContext.Provider>
</GridCellPixelOffsetContext.Provider>
</GridStrokeWidthContext.Provider>
</GridOffsetContext.Provider>
@ -220,3 +270,13 @@ export function useGridCellPixelOffset() {
}
return context;
}
export function useGridSnappingSensitivity() {
const context = useContext(GridSnappingSensitivityContext);
if (context === undefined) {
throw new Error(
"useGridSnappingSensitivity must be used within a GridProvider"
);
}
return context;
}

View File

@ -35,6 +35,7 @@ import {
useGridCellPixelOffset,
useGridOffset,
useGridPixelSize,
useGridSnappingSensitivity,
GridContext,
GridPixelSizeContext,
GridCellPixelSizeContext,
@ -42,6 +43,7 @@ import {
GridOffsetContext,
GridStrokeWidthContext,
GridCellPixelOffsetContext,
GridSnappingSensitivityContext,
} from "../contexts/GridContext";
import DatabaseContext, { useDatabase } from "../contexts/DatabaseContext";
@ -83,6 +85,7 @@ function KonvaBridge({
const gridStrokeWidth = useGridStrokeWidth();
const gridCellPixelOffset = useGridCellPixelOffset();
const gridOffset = useGridOffset();
const gridSnappingSensitivity = useGridSnappingSensitivity();
const database = useDatabase();
@ -127,8 +130,14 @@ function KonvaBridge({
>
<GridCellPixelOffsetContext.Provider
value={gridCellPixelOffset}
>
<GridSnappingSensitivityContext.Provider
value={
gridSnappingSensitivity
}
>
{children}
</GridSnappingSensitivityContext.Provider>
</GridCellPixelOffsetContext.Provider>
</GridStrokeWidthContext.Provider>
</GridOffsetContext.Provider>

View File

@ -5,13 +5,12 @@ import {
getCellCorners,
} from "../helpers/grid";
import useSetting from "./useSetting";
import {
useGrid,
useGridOffset,
useGridCellPixelSize,
useGridCellPixelOffset,
useGridSnappingSensitivity,
} from "../contexts/GridContext";
/**
@ -23,13 +22,16 @@ function useGridSnapping(
snappingSensitivity: number | undefined = undefined,
useCorners: boolean = true
) {
const [defaultSnappingSensitivity] = useSetting<number>(
"map.gridSnappingSensitivity"
);
let gridSnappingSensitivity =
snappingSensitivity === undefined
? defaultSnappingSensitivity
: snappingSensitivity;
const defaultSnappingSensitivity = useGridSnappingSensitivity();
let gridSnappingSensitivity: number;
if (defaultSnappingSensitivity === -1) {
// Snapping disabled via shortcut
gridSnappingSensitivity = 0;
} else if (snappingSensitivity === undefined) {
gridSnappingSensitivity = defaultSnappingSensitivity;
} else {
gridSnappingSensitivity = snappingSensitivity;
}
const grid = useGrid();
const gridOffset = useGridOffset();

View File

@ -102,6 +102,7 @@ const shortcuts: Record<string, Shortcut> = {
copy,
paste,
delete: ({ key }) => key === "Backspace" || key === "Delete",
disableSnapping: ({ key }) => key === "Control" || key === "Meta",
};
export default shortcuts;