feat: adjust line-confirm-threshold based on zoom (#2884)
Co-authored-by: Lipis <lipiridis@gmail.com>
This commit is contained in:
parent
ba9b65b051
commit
e6cd97c4f2
@ -83,7 +83,7 @@ export const actionFinalize = register({
|
|||||||
// If the multi point line closes the loop,
|
// If the multi point line closes the loop,
|
||||||
// set the last point to first point.
|
// set the last point to first point.
|
||||||
// This ensures that loop remains closed at different scales.
|
// This ensures that loop remains closed at different scales.
|
||||||
const isLoop = isPathALoop(multiPointElement.points);
|
const isLoop = isPathALoop(multiPointElement.points, appState.zoom.value);
|
||||||
if (
|
if (
|
||||||
multiPointElement.type === "line" ||
|
multiPointElement.type === "line" ||
|
||||||
multiPointElement.type === "draw"
|
multiPointElement.type === "draw"
|
||||||
|
@ -1963,7 +1963,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
points: points.slice(0, -1),
|
points: points.slice(0, -1),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (isPathALoop(points)) {
|
if (isPathALoop(points, this.state.zoom.value)) {
|
||||||
document.documentElement.style.cursor = CURSOR_TYPE.POINTER;
|
document.documentElement.style.cursor = CURSOR_TYPE.POINTER;
|
||||||
}
|
}
|
||||||
// update last uncommitted point
|
// update last uncommitted point
|
||||||
@ -2635,7 +2635,10 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
const { multiElement } = this.state;
|
const { multiElement } = this.state;
|
||||||
|
|
||||||
// finalize if completing a loop
|
// finalize if completing a loop
|
||||||
if (multiElement.type === "line" && isPathALoop(multiElement.points)) {
|
if (
|
||||||
|
multiElement.type === "line" &&
|
||||||
|
isPathALoop(multiElement.points, this.state.zoom.value)
|
||||||
|
) {
|
||||||
mutateElement(multiElement, {
|
mutateElement(multiElement, {
|
||||||
lastCommittedPoint:
|
lastCommittedPoint:
|
||||||
multiElement.points[multiElement.points.length - 1],
|
multiElement.points[multiElement.points.length - 1],
|
||||||
|
@ -2,8 +2,8 @@ import { FontFamily } from "./element/types";
|
|||||||
|
|
||||||
export const APP_NAME = "Excalidraw";
|
export const APP_NAME = "Excalidraw";
|
||||||
|
|
||||||
export const DRAGGING_THRESHOLD = 10; // 10px
|
export const DRAGGING_THRESHOLD = 10; // px
|
||||||
export const LINE_CONFIRM_THRESHOLD = 10; // 10px
|
export const LINE_CONFIRM_THRESHOLD = 8; // px
|
||||||
export const ELEMENT_SHIFT_TRANSLATE_AMOUNT = 5;
|
export const ELEMENT_SHIFT_TRANSLATE_AMOUNT = 5;
|
||||||
export const ELEMENT_TRANSLATE_AMOUNT = 1;
|
export const ELEMENT_TRANSLATE_AMOUNT = 1;
|
||||||
export const TEXT_TO_CENTER_SNAP_THRESHOLD = 30;
|
export const TEXT_TO_CENTER_SNAP_THRESHOLD = 30;
|
||||||
|
@ -129,7 +129,7 @@ export class LinearElementEditor {
|
|||||||
isDragging &&
|
isDragging &&
|
||||||
(activePointIndex === 0 || activePointIndex === element.points.length - 1)
|
(activePointIndex === 0 || activePointIndex === element.points.length - 1)
|
||||||
) {
|
) {
|
||||||
if (isPathALoop(element.points)) {
|
if (isPathALoop(element.points, appState.zoom.value)) {
|
||||||
LinearElementEditor.movePoint(
|
LinearElementEditor.movePoint(
|
||||||
element,
|
element,
|
||||||
activePointIndex,
|
activePointIndex,
|
||||||
|
15
src/math.ts
15
src/math.ts
@ -1,4 +1,4 @@
|
|||||||
import { Point } from "./types";
|
import { NormalizedZoomValue, Point, Zoom } from "./types";
|
||||||
import { LINE_CONFIRM_THRESHOLD } from "./constants";
|
import { LINE_CONFIRM_THRESHOLD } from "./constants";
|
||||||
import { ExcalidrawLinearElement } from "./element/types";
|
import { ExcalidrawLinearElement } from "./element/types";
|
||||||
|
|
||||||
@ -147,13 +147,16 @@ export const centerPoint = (a: Point, b: Point): Point => {
|
|||||||
// to be considered a loop
|
// to be considered a loop
|
||||||
export const isPathALoop = (
|
export const isPathALoop = (
|
||||||
points: ExcalidrawLinearElement["points"],
|
points: ExcalidrawLinearElement["points"],
|
||||||
|
/** supply if you want the loop detection to account for current zoom */
|
||||||
|
zoomValue: Zoom["value"] = 1 as NormalizedZoomValue,
|
||||||
): boolean => {
|
): boolean => {
|
||||||
if (points.length >= 3) {
|
if (points.length >= 3) {
|
||||||
const [firstPoint, lastPoint] = [points[0], points[points.length - 1]];
|
const [first, last] = [points[0], points[points.length - 1]];
|
||||||
return (
|
const distance = distance2d(first[0], first[1], last[0], last[1]);
|
||||||
distance2d(firstPoint[0], firstPoint[1], lastPoint[0], lastPoint[1]) <=
|
|
||||||
LINE_CONFIRM_THRESHOLD
|
// Adjusting LINE_CONFIRM_THRESHOLD to current zoom so that when zoomed in
|
||||||
);
|
// really close we make the threshold smaller, and vice versa.
|
||||||
|
return distance <= LINE_CONFIRM_THRESHOLD / zoomValue;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user