Made grid snapping have a threshold and removed the option to toggle it on and off
This commit is contained in:
parent
734b966a53
commit
b3bf3c3598
@ -49,18 +49,16 @@ function Map({
|
|||||||
|
|
||||||
const [selectedToolId, setSelectedToolId] = useState("pan");
|
const [selectedToolId, setSelectedToolId] = useState("pan");
|
||||||
const [toolSettings, setToolSettings] = useState({
|
const [toolSettings, setToolSettings] = useState({
|
||||||
fog: { type: "add", useGridSnapping: false, useEdgeSnapping: true },
|
fog: { type: "add", useEdgeSnapping: true },
|
||||||
brush: {
|
brush: {
|
||||||
color: "darkGray",
|
color: "darkGray",
|
||||||
type: "stroke",
|
type: "stroke",
|
||||||
useBlending: false,
|
useBlending: false,
|
||||||
useGridSnapping: false,
|
|
||||||
},
|
},
|
||||||
shape: {
|
shape: {
|
||||||
color: "red",
|
color: "red",
|
||||||
type: "rectangle",
|
type: "rectangle",
|
||||||
useBlending: true,
|
useBlending: true,
|
||||||
useGridSnapping: false,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
function handleToolSettingChange(tool, change) {
|
function handleToolSettingChange(tool, change) {
|
||||||
|
@ -56,7 +56,7 @@ function MapDrawing({
|
|||||||
setIsDrawing(true);
|
setIsDrawing(true);
|
||||||
const brushPosition = getBrushPositionForTool(
|
const brushPosition = getBrushPositionForTool(
|
||||||
position,
|
position,
|
||||||
toolSettings,
|
selectedTool,
|
||||||
gridSize,
|
gridSize,
|
||||||
shapes
|
shapes
|
||||||
);
|
);
|
||||||
@ -97,7 +97,7 @@ function MapDrawing({
|
|||||||
setPointerPosition(position);
|
setPointerPosition(position);
|
||||||
const brushPosition = getBrushPositionForTool(
|
const brushPosition = getBrushPositionForTool(
|
||||||
position,
|
position,
|
||||||
toolSettings,
|
selectedTool,
|
||||||
gridSize,
|
gridSize,
|
||||||
shapes
|
shapes
|
||||||
);
|
);
|
||||||
|
@ -3,7 +3,6 @@ import { Flex } from "theme-ui";
|
|||||||
|
|
||||||
import ColorControl from "./ColorControl";
|
import ColorControl from "./ColorControl";
|
||||||
import AlphaBlendToggle from "./AlphaBlendToggle";
|
import AlphaBlendToggle from "./AlphaBlendToggle";
|
||||||
import GridSnappingToggle from "./GridSnappingToggle";
|
|
||||||
import RadioIconButton from "./RadioIconButton";
|
import RadioIconButton from "./RadioIconButton";
|
||||||
|
|
||||||
import BrushStrokeIcon from "../../../icons/BrushStrokeIcon";
|
import BrushStrokeIcon from "../../../icons/BrushStrokeIcon";
|
||||||
@ -38,12 +37,6 @@ function BrushToolSettings({ settings, onSettingChange }) {
|
|||||||
useBlending={settings.useBlending}
|
useBlending={settings.useBlending}
|
||||||
onBlendingChange={(useBlending) => onSettingChange({ useBlending })}
|
onBlendingChange={(useBlending) => onSettingChange({ useBlending })}
|
||||||
/>
|
/>
|
||||||
<GridSnappingToggle
|
|
||||||
useGridSnapping={settings.useGridSnapping}
|
|
||||||
onGridSnappingChange={(useGridSnapping) =>
|
|
||||||
onSettingChange({ useGridSnapping })
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Flex } from "theme-ui";
|
import { Flex } from "theme-ui";
|
||||||
|
|
||||||
import GridSnappingToggle from "./GridSnappingToggle";
|
|
||||||
import EdgeSnappingToggle from "./EdgeSnappingToggle";
|
import EdgeSnappingToggle from "./EdgeSnappingToggle";
|
||||||
import RadioIconButton from "./RadioIconButton";
|
import RadioIconButton from "./RadioIconButton";
|
||||||
|
|
||||||
@ -36,12 +35,6 @@ function BrushToolSettings({ settings, onSettingChange }) {
|
|||||||
<FogToggleIcon />
|
<FogToggleIcon />
|
||||||
</RadioIconButton>
|
</RadioIconButton>
|
||||||
<Divider vertical />
|
<Divider vertical />
|
||||||
<GridSnappingToggle
|
|
||||||
useGridSnapping={settings.useGridSnapping}
|
|
||||||
onGridSnappingChange={(useGridSnapping) =>
|
|
||||||
onSettingChange({ useGridSnapping })
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<EdgeSnappingToggle
|
<EdgeSnappingToggle
|
||||||
useEdgeSnapping={settings.useEdgeSnapping}
|
useEdgeSnapping={settings.useEdgeSnapping}
|
||||||
onEdgeSnappingChange={(useEdgeSnapping) =>
|
onEdgeSnappingChange={(useEdgeSnapping) =>
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import { IconButton } from "theme-ui";
|
|
||||||
|
|
||||||
import GridOnIcon from "../../../icons/GridOnIcon";
|
|
||||||
import GridOffIcon from "../../../icons/GridOffIcon";
|
|
||||||
|
|
||||||
function GridSnappingToggle({ useGridSnapping, onGridSnappingChange }) {
|
|
||||||
return (
|
|
||||||
<IconButton
|
|
||||||
aria-label={
|
|
||||||
useGridSnapping ? "Disable Grid Snapping" : "Enable Grid Snapping"
|
|
||||||
}
|
|
||||||
title={useGridSnapping ? "Disable Grid Snapping" : "Enable Grid Snapping"}
|
|
||||||
onClick={() => onGridSnappingChange(!useGridSnapping)}
|
|
||||||
>
|
|
||||||
{useGridSnapping ? <GridOnIcon /> : <GridOffIcon />}
|
|
||||||
</IconButton>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default GridSnappingToggle;
|
|
@ -3,7 +3,6 @@ import { Flex } from "theme-ui";
|
|||||||
|
|
||||||
import ColorControl from "./ColorControl";
|
import ColorControl from "./ColorControl";
|
||||||
import AlphaBlendToggle from "./AlphaBlendToggle";
|
import AlphaBlendToggle from "./AlphaBlendToggle";
|
||||||
import GridSnappingToggle from "./GridSnappingToggle";
|
|
||||||
import RadioIconButton from "./RadioIconButton";
|
import RadioIconButton from "./RadioIconButton";
|
||||||
|
|
||||||
import ShapeRectangleIcon from "../../../icons/ShapeRectangleIcon";
|
import ShapeRectangleIcon from "../../../icons/ShapeRectangleIcon";
|
||||||
@ -46,12 +45,6 @@ function ShapeToolSettings({ settings, onSettingChange }) {
|
|||||||
useBlending={settings.useBlending}
|
useBlending={settings.useBlending}
|
||||||
onBlendingChange={(useBlending) => onSettingChange({ useBlending })}
|
onBlendingChange={(useBlending) => onSettingChange({ useBlending })}
|
||||||
/>
|
/>
|
||||||
<GridSnappingToggle
|
|
||||||
useGridSnapping={settings.useGridSnapping}
|
|
||||||
onGridSnappingChange={(useGridSnapping) =>
|
|
||||||
onSettingChange({ useGridSnapping })
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
import { snapPositionToGrid } from "./shared";
|
|
||||||
import * as Vector2 from "./vector2";
|
import * as Vector2 from "./vector2";
|
||||||
import { toDegrees } from "./shared";
|
import { toDegrees } from "./shared";
|
||||||
import colors from "./colors";
|
import colors from "./colors";
|
||||||
|
|
||||||
export function getBrushPositionForTool(
|
const snappingThreshold = 1 / 5;
|
||||||
brushPosition,
|
export function getBrushPositionForTool(brushPosition, tool, gridSize, shapes) {
|
||||||
settings,
|
|
||||||
gridSize,
|
|
||||||
shapes
|
|
||||||
) {
|
|
||||||
let position = brushPosition;
|
let position = brushPosition;
|
||||||
if (settings && settings.useGridSnapping) {
|
if (tool === "shape") {
|
||||||
position = snapPositionToGrid(position, gridSize);
|
const snapped = Vector2.roundTo(position, gridSize);
|
||||||
|
const minGrid = Vector2.min(gridSize);
|
||||||
|
const distance = Vector2.length(Vector2.subtract(snapped, position));
|
||||||
|
if (distance < minGrid * snappingThreshold) {
|
||||||
|
position = snapped;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return position;
|
return position;
|
||||||
@ -187,7 +187,7 @@ export function shapeToPath(shape, canvasWidth, canvasHeight) {
|
|||||||
canvasWidth,
|
canvasWidth,
|
||||||
canvasHeight
|
canvasHeight
|
||||||
);
|
);
|
||||||
} else if ((shape.shapeType === "rectangle", canvasWidth, canvasHeight)) {
|
} else if (shape.shapeType === "rectangle") {
|
||||||
return rectangleToPath(
|
return rectangleToPath(
|
||||||
data.x,
|
data.x,
|
||||||
data.y,
|
data.y,
|
||||||
|
@ -28,13 +28,6 @@ export function roundTo(x, to) {
|
|||||||
return Math.round(x / to) * to;
|
return Math.round(x / to) * to;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function snapPositionToGrid(position, gridSize) {
|
|
||||||
return {
|
|
||||||
x: roundTo(position.x, gridSize.x),
|
|
||||||
y: roundTo(position.y, gridSize.y),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toRadians(angle) {
|
export function toRadians(angle) {
|
||||||
return angle * (Math.PI / 180);
|
return angle * (Math.PI / 180);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { toRadians } from "./shared";
|
import { toRadians, roundTo as roundToNumber } from "./shared";
|
||||||
|
|
||||||
export function lengthSquared(p) {
|
export function lengthSquared(p) {
|
||||||
return p.x * p.x + p.y * p.y;
|
return p.x * p.x + p.y * p.y;
|
||||||
@ -70,3 +70,10 @@ export function min(a) {
|
|||||||
export function max(a) {
|
export function max(a) {
|
||||||
return a.x > a.y ? a.x : a.y;
|
return a.x > a.y ? a.x : a.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function roundTo(p, to) {
|
||||||
|
return {
|
||||||
|
x: roundToNumber(p.x, to.x),
|
||||||
|
y: roundToNumber(p.y, to.y),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
|
|
||||||
function GridOffIcon() {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
width="24"
|
|
||||||
fill="currentcolor"
|
|
||||||
// Fixes bug with not firing click event when used in a button
|
|
||||||
style={{ pointerEvents: "none" }}
|
|
||||||
>
|
|
||||||
<path d="M0 0h24v24H0V0z" fill="none" />
|
|
||||||
<path d="M8 4v.89l2 2V4h4v4h-2.89l2 2H14v.89l2 2V10h4v4h-2.89l2 2H20v.89l2 2V4c0-1.1-.9-2-2-2H5.11l2 2H8zm8 0h3c.55 0 1 .45 1 1v3h-4V4zm6.16 17.88L2.12 1.84c-.39-.39-1.02-.39-1.41 0-.39.39-.39 1.02 0 1.41L2 4.55V20c0 1.1.9 2 2 2h15.45l1.3 1.3c.39.39 1.02.39 1.41 0 .39-.39.39-1.03 0-1.42zM10 12.55L11.45 14H10v-1.45zm-6-6L5.45 8H4V6.55zM8 20H5c-.55 0-1-.45-1-1v-3h4v4zm0-6H4v-4h3.45l.55.55V14zm6 6h-4v-4h3.45l.55.55V20zm2 0v-1.45L17.45 20H16z" />
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default GridOffIcon;
|
|
@ -1,20 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
|
|
||||||
function GridOnIcon() {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
width="24"
|
|
||||||
fill="currentcolor"
|
|
||||||
// Fixes bug with not firing click event when used in a button
|
|
||||||
style={{ pointerEvents: "none" }}
|
|
||||||
>
|
|
||||||
<path d="M0 0h24v24H0V0z" fill="none" />
|
|
||||||
<path d="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM8 20H5c-.55 0-1-.45-1-1v-3h4v4zm0-6H4v-4h4v4zm0-6H4V5c0-.55.45-1 1-1h3v4zm6 12h-4v-4h4v4zm0-6h-4v-4h4v4zm0-6h-4V4h4v4zm5 12h-3v-4h4v3c0 .55-.45 1-1 1zm1-6h-4v-4h4v4zm0-6h-4V4h3c.55 0 1 .45 1 1v3z" />
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default GridOnIcon;
|
|
Loading…
Reference in New Issue
Block a user