Add shortcut for disabling grid snapping
This commit is contained in:
parent
9e5eb9d258
commit
6eb1f71bc2
@ -3,7 +3,10 @@ import { Transform } from "konva/lib/Util";
|
|||||||
import { useEffect, useMemo, useRef } from "react";
|
import { useEffect, useMemo, useRef } from "react";
|
||||||
import { Transformer as KonvaTransformer } from "react-konva";
|
import { Transformer as KonvaTransformer } from "react-konva";
|
||||||
|
|
||||||
import { useGridCellPixelSize } from "../../contexts/GridContext";
|
import {
|
||||||
|
useGridCellPixelSize,
|
||||||
|
useGridSnappingSensitivity,
|
||||||
|
} from "../../contexts/GridContext";
|
||||||
import { useSetPreventMapInteraction } from "../../contexts/MapInteractionContext";
|
import { useSetPreventMapInteraction } from "../../contexts/MapInteractionContext";
|
||||||
import { roundTo } from "../../helpers/shared";
|
import { roundTo } from "../../helpers/shared";
|
||||||
import Vector2 from "../../helpers/Vector2";
|
import Vector2 from "../../helpers/Vector2";
|
||||||
@ -56,6 +59,10 @@ function Transformer({
|
|||||||
}, [active, nodeRef, gridCellPixelSize]);
|
}, [active, nodeRef, gridCellPixelSize]);
|
||||||
const scale = parseGridScale(gridScale);
|
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 anchorScale = useMemo(() => getAnchorImage(192, scaleDark), []);
|
||||||
const anchorRotate = useMemo(() => getAnchorImage(192, rotateDark), []);
|
const anchorRotate = useMemo(() => getAnchorImage(192, rotateDark), []);
|
||||||
|
|
||||||
@ -192,8 +199,10 @@ function Transformer({
|
|||||||
);
|
);
|
||||||
const distanceToSnap = Math.abs(snapBox.width - nearestCellWidth);
|
const distanceToSnap = Math.abs(snapBox.width - nearestCellWidth);
|
||||||
let snapping = false;
|
let snapping = false;
|
||||||
if (distanceToSnap < gridCellAbsoluteSize.x * 0.1) {
|
if (
|
||||||
// TODO: use global grid snapping value
|
distanceToSnap <
|
||||||
|
gridCellAbsoluteSize.x * gridSnappingSensitivity
|
||||||
|
) {
|
||||||
snapBox.width = nearestCellWidth;
|
snapBox.width = nearestCellWidth;
|
||||||
snapping = true;
|
snapping = true;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import {
|
|||||||
useGridStrokeWidth,
|
useGridStrokeWidth,
|
||||||
useGridCellPixelOffset,
|
useGridCellPixelOffset,
|
||||||
useGridOffset,
|
useGridOffset,
|
||||||
|
useGridSnappingSensitivity,
|
||||||
} from "../../contexts/GridContext";
|
} from "../../contexts/GridContext";
|
||||||
import { useKeyboard } from "../../contexts/KeyboardContext";
|
import { useKeyboard } from "../../contexts/KeyboardContext";
|
||||||
|
|
||||||
@ -93,9 +94,10 @@ function FogTool({
|
|||||||
const gridCellPixelOffset = useGridCellPixelOffset();
|
const gridCellPixelOffset = useGridCellPixelOffset();
|
||||||
const gridOffset = useGridOffset();
|
const gridOffset = useGridOffset();
|
||||||
|
|
||||||
const [gridSnappingSensitivity] = useSetting<number>(
|
const snappingSensitivity = useGridSnappingSensitivity();
|
||||||
"map.gridSnappingSensitivity"
|
// Clamp snapping to 0 to accound for -1 snapping override
|
||||||
);
|
const gridSnappingSensitivity = Math.max(snappingSensitivity, 0);
|
||||||
|
|
||||||
const [showFogGuides] = useSetting<boolean>("fog.showGuides");
|
const [showFogGuides] = useSetting<boolean>("fog.showGuides");
|
||||||
const [editOpacity] = useSetting<number>("fog.editOpacity");
|
const [editOpacity] = useSetting<number>("fog.editOpacity");
|
||||||
const mapStageRef = useMapStage();
|
const mapStageRef = useMapStage();
|
||||||
|
@ -3,8 +3,15 @@ import React, { useContext, useState, useEffect } from "react";
|
|||||||
import Vector2 from "../helpers/Vector2";
|
import Vector2 from "../helpers/Vector2";
|
||||||
import Size from "../helpers/Size";
|
import Size from "../helpers/Size";
|
||||||
import { getGridPixelSize, getCellPixelSize } from "../helpers/grid";
|
import { getGridPixelSize, getCellPixelSize } from "../helpers/grid";
|
||||||
|
|
||||||
import { Grid } from "../types/Grid";
|
import { Grid } from "../types/Grid";
|
||||||
|
|
||||||
|
import useSetting from "../hooks/useSetting";
|
||||||
|
|
||||||
|
import shortcuts from "../shortcuts";
|
||||||
|
|
||||||
|
import { useBlur, useKeyboard } from "./KeyboardContext";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef GridContextValue
|
* @typedef GridContextValue
|
||||||
* @property {Grid} grid Base grid value
|
* @property {Grid} grid Base grid value
|
||||||
@ -23,6 +30,7 @@ type GridContextValue = {
|
|||||||
gridOffset: Vector2;
|
gridOffset: Vector2;
|
||||||
gridStrokeWidth: number;
|
gridStrokeWidth: number;
|
||||||
gridCellPixelOffset: Vector2;
|
gridCellPixelOffset: Vector2;
|
||||||
|
gridSnappingSensitivity: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,6 +52,7 @@ const defaultValue: GridContextValue = {
|
|||||||
gridOffset: new Vector2(0, 0),
|
gridOffset: new Vector2(0, 0),
|
||||||
gridStrokeWidth: 0,
|
gridStrokeWidth: 0,
|
||||||
gridCellPixelOffset: new Vector2(0, 0),
|
gridCellPixelOffset: new Vector2(0, 0),
|
||||||
|
gridSnappingSensitivity: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const GridContext = React.createContext(defaultValue.grid);
|
export const GridContext = React.createContext(defaultValue.grid);
|
||||||
@ -63,6 +72,9 @@ export const GridStrokeWidthContext = React.createContext(
|
|||||||
export const GridCellPixelOffsetContext = React.createContext(
|
export const GridCellPixelOffsetContext = React.createContext(
|
||||||
defaultValue.gridCellPixelOffset
|
defaultValue.gridCellPixelOffset
|
||||||
);
|
);
|
||||||
|
export const GridSnappingSensitivityContext = React.createContext(
|
||||||
|
defaultValue.gridSnappingSensitivity
|
||||||
|
);
|
||||||
|
|
||||||
const defaultStrokeWidth = 1 / 10;
|
const defaultStrokeWidth = 1 / 10;
|
||||||
|
|
||||||
@ -138,6 +150,40 @@ export function GridProvider({
|
|||||||
setGridCellPixelOffset(_gridCellPixelOffset);
|
setGridCellPixelOffset(_gridCellPixelOffset);
|
||||||
}, [grid, width, height]);
|
}, [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 (
|
return (
|
||||||
<GridContext.Provider value={grid}>
|
<GridContext.Provider value={grid}>
|
||||||
<GridPixelSizeContext.Provider value={gridPixelSize}>
|
<GridPixelSizeContext.Provider value={gridPixelSize}>
|
||||||
@ -149,8 +195,12 @@ export function GridProvider({
|
|||||||
<GridStrokeWidthContext.Provider value={gridStrokeWidth}>
|
<GridStrokeWidthContext.Provider value={gridStrokeWidth}>
|
||||||
<GridCellPixelOffsetContext.Provider
|
<GridCellPixelOffsetContext.Provider
|
||||||
value={gridCellPixelOffset}
|
value={gridCellPixelOffset}
|
||||||
|
>
|
||||||
|
<GridSnappingSensitivityContext.Provider
|
||||||
|
value={gridSnappingSensitivity}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
</GridSnappingSensitivityContext.Provider>
|
||||||
</GridCellPixelOffsetContext.Provider>
|
</GridCellPixelOffsetContext.Provider>
|
||||||
</GridStrokeWidthContext.Provider>
|
</GridStrokeWidthContext.Provider>
|
||||||
</GridOffsetContext.Provider>
|
</GridOffsetContext.Provider>
|
||||||
@ -220,3 +270,13 @@ export function useGridCellPixelOffset() {
|
|||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useGridSnappingSensitivity() {
|
||||||
|
const context = useContext(GridSnappingSensitivityContext);
|
||||||
|
if (context === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
"useGridSnappingSensitivity must be used within a GridProvider"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
@ -35,6 +35,7 @@ import {
|
|||||||
useGridCellPixelOffset,
|
useGridCellPixelOffset,
|
||||||
useGridOffset,
|
useGridOffset,
|
||||||
useGridPixelSize,
|
useGridPixelSize,
|
||||||
|
useGridSnappingSensitivity,
|
||||||
GridContext,
|
GridContext,
|
||||||
GridPixelSizeContext,
|
GridPixelSizeContext,
|
||||||
GridCellPixelSizeContext,
|
GridCellPixelSizeContext,
|
||||||
@ -42,6 +43,7 @@ import {
|
|||||||
GridOffsetContext,
|
GridOffsetContext,
|
||||||
GridStrokeWidthContext,
|
GridStrokeWidthContext,
|
||||||
GridCellPixelOffsetContext,
|
GridCellPixelOffsetContext,
|
||||||
|
GridSnappingSensitivityContext,
|
||||||
} from "../contexts/GridContext";
|
} from "../contexts/GridContext";
|
||||||
import DatabaseContext, { useDatabase } from "../contexts/DatabaseContext";
|
import DatabaseContext, { useDatabase } from "../contexts/DatabaseContext";
|
||||||
|
|
||||||
@ -83,6 +85,7 @@ function KonvaBridge({
|
|||||||
const gridStrokeWidth = useGridStrokeWidth();
|
const gridStrokeWidth = useGridStrokeWidth();
|
||||||
const gridCellPixelOffset = useGridCellPixelOffset();
|
const gridCellPixelOffset = useGridCellPixelOffset();
|
||||||
const gridOffset = useGridOffset();
|
const gridOffset = useGridOffset();
|
||||||
|
const gridSnappingSensitivity = useGridSnappingSensitivity();
|
||||||
|
|
||||||
const database = useDatabase();
|
const database = useDatabase();
|
||||||
|
|
||||||
@ -127,8 +130,14 @@ function KonvaBridge({
|
|||||||
>
|
>
|
||||||
<GridCellPixelOffsetContext.Provider
|
<GridCellPixelOffsetContext.Provider
|
||||||
value={gridCellPixelOffset}
|
value={gridCellPixelOffset}
|
||||||
|
>
|
||||||
|
<GridSnappingSensitivityContext.Provider
|
||||||
|
value={
|
||||||
|
gridSnappingSensitivity
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
</GridSnappingSensitivityContext.Provider>
|
||||||
</GridCellPixelOffsetContext.Provider>
|
</GridCellPixelOffsetContext.Provider>
|
||||||
</GridStrokeWidthContext.Provider>
|
</GridStrokeWidthContext.Provider>
|
||||||
</GridOffsetContext.Provider>
|
</GridOffsetContext.Provider>
|
||||||
|
@ -5,13 +5,12 @@ import {
|
|||||||
getCellCorners,
|
getCellCorners,
|
||||||
} from "../helpers/grid";
|
} from "../helpers/grid";
|
||||||
|
|
||||||
import useSetting from "./useSetting";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
useGrid,
|
useGrid,
|
||||||
useGridOffset,
|
useGridOffset,
|
||||||
useGridCellPixelSize,
|
useGridCellPixelSize,
|
||||||
useGridCellPixelOffset,
|
useGridCellPixelOffset,
|
||||||
|
useGridSnappingSensitivity,
|
||||||
} from "../contexts/GridContext";
|
} from "../contexts/GridContext";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,13 +22,16 @@ function useGridSnapping(
|
|||||||
snappingSensitivity: number | undefined = undefined,
|
snappingSensitivity: number | undefined = undefined,
|
||||||
useCorners: boolean = true
|
useCorners: boolean = true
|
||||||
) {
|
) {
|
||||||
const [defaultSnappingSensitivity] = useSetting<number>(
|
const defaultSnappingSensitivity = useGridSnappingSensitivity();
|
||||||
"map.gridSnappingSensitivity"
|
let gridSnappingSensitivity: number;
|
||||||
);
|
if (defaultSnappingSensitivity === -1) {
|
||||||
let gridSnappingSensitivity =
|
// Snapping disabled via shortcut
|
||||||
snappingSensitivity === undefined
|
gridSnappingSensitivity = 0;
|
||||||
? defaultSnappingSensitivity
|
} else if (snappingSensitivity === undefined) {
|
||||||
: snappingSensitivity;
|
gridSnappingSensitivity = defaultSnappingSensitivity;
|
||||||
|
} else {
|
||||||
|
gridSnappingSensitivity = snappingSensitivity;
|
||||||
|
}
|
||||||
|
|
||||||
const grid = useGrid();
|
const grid = useGrid();
|
||||||
const gridOffset = useGridOffset();
|
const gridOffset = useGridOffset();
|
||||||
|
@ -102,6 +102,7 @@ const shortcuts: Record<string, Shortcut> = {
|
|||||||
copy,
|
copy,
|
||||||
paste,
|
paste,
|
||||||
delete: ({ key }) => key === "Backspace" || key === "Delete",
|
delete: ({ key }) => key === "Backspace" || key === "Delete",
|
||||||
|
disableSnapping: ({ key }) => key === "Control" || key === "Meta",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default shortcuts;
|
export default shortcuts;
|
||||||
|
Loading…
Reference in New Issue
Block a user