feat: grid mode for line editing (#1984)
This commit is contained in:
parent
c171fb4c7f
commit
818821c293
@ -1883,6 +1883,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
scenePointerX,
|
scenePointerX,
|
||||||
scenePointerY,
|
scenePointerY,
|
||||||
this.state.editingLinearElement,
|
this.state.editingLinearElement,
|
||||||
|
this.state.gridSize,
|
||||||
);
|
);
|
||||||
if (editingLinearElement !== this.state.editingLinearElement) {
|
if (editingLinearElement !== this.state.editingLinearElement) {
|
||||||
this.setState({ editingLinearElement });
|
this.setState({ editingLinearElement });
|
||||||
@ -2778,8 +2779,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
(appState) => this.setState(appState),
|
(appState) => this.setState(appState),
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
pointerDownState.lastCoords.x,
|
|
||||||
pointerDownState.lastCoords.y,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (didDrag) {
|
if (didDrag) {
|
||||||
|
@ -3,7 +3,7 @@ import {
|
|||||||
ExcalidrawLinearElement,
|
ExcalidrawLinearElement,
|
||||||
ExcalidrawElement,
|
ExcalidrawElement,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import { distance2d, rotate, isPathALoop } from "../math";
|
import { distance2d, rotate, isPathALoop, getGridPoint } from "../math";
|
||||||
import { getElementAbsoluteCoords } from ".";
|
import { getElementAbsoluteCoords } from ".";
|
||||||
import { getElementPointsCoords } from "./bounds";
|
import { getElementPointsCoords } from "./bounds";
|
||||||
import { Point, AppState } from "../types";
|
import { Point, AppState } from "../types";
|
||||||
@ -20,6 +20,7 @@ export class LinearElementEditor {
|
|||||||
/** whether you're dragging a point */
|
/** whether you're dragging a point */
|
||||||
public isDragging: boolean;
|
public isDragging: boolean;
|
||||||
public lastUncommittedPoint: Point | null;
|
public lastUncommittedPoint: Point | null;
|
||||||
|
public pointerOffset: { x: number; y: number };
|
||||||
|
|
||||||
constructor(element: NonDeleted<ExcalidrawLinearElement>, scene: Scene) {
|
constructor(element: NonDeleted<ExcalidrawLinearElement>, scene: Scene) {
|
||||||
this.elementId = element.id as string & {
|
this.elementId = element.id as string & {
|
||||||
@ -31,6 +32,7 @@ export class LinearElementEditor {
|
|||||||
this.activePointIndex = null;
|
this.activePointIndex = null;
|
||||||
this.lastUncommittedPoint = null;
|
this.lastUncommittedPoint = null;
|
||||||
this.isDragging = false;
|
this.isDragging = false;
|
||||||
|
this.pointerOffset = { x: 0, y: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -57,8 +59,6 @@ export class LinearElementEditor {
|
|||||||
setState: React.Component<any, AppState>["setState"],
|
setState: React.Component<any, AppState>["setState"],
|
||||||
scenePointerX: number,
|
scenePointerX: number,
|
||||||
scenePointerY: number,
|
scenePointerY: number,
|
||||||
lastX: number,
|
|
||||||
lastY: number,
|
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!appState.editingLinearElement) {
|
if (!appState.editingLinearElement) {
|
||||||
return false;
|
return false;
|
||||||
@ -80,18 +80,14 @@ export class LinearElementEditor {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const [deltaX, deltaY] = rotate(
|
|
||||||
scenePointerX - lastX,
|
const newPoint = LinearElementEditor.createPointAt(
|
||||||
scenePointerY - lastY,
|
element,
|
||||||
0,
|
scenePointerX - editingLinearElement.pointerOffset.x,
|
||||||
0,
|
scenePointerY - editingLinearElement.pointerOffset.y,
|
||||||
-element.angle,
|
appState.gridSize,
|
||||||
);
|
);
|
||||||
const targetPoint = element.points[activePointIndex];
|
LinearElementEditor.movePoint(element, activePointIndex, newPoint);
|
||||||
LinearElementEditor.movePoint(element, activePointIndex, [
|
|
||||||
targetPoint[0] + deltaX,
|
|
||||||
targetPoint[1] + deltaY,
|
|
||||||
]);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -120,13 +116,11 @@ export class LinearElementEditor {
|
|||||||
: element.points[0],
|
: element.points[0],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (isDragging) {
|
return {
|
||||||
return {
|
...editingLinearElement,
|
||||||
...editingLinearElement,
|
isDragging: false,
|
||||||
isDragging: false,
|
pointerOffset: { x: 0, y: 0 },
|
||||||
};
|
};
|
||||||
}
|
|
||||||
return editingLinearElement;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static handlePointerDown(
|
static handlePointerDown(
|
||||||
@ -165,6 +159,7 @@ export class LinearElementEditor {
|
|||||||
element,
|
element,
|
||||||
scenePointerX,
|
scenePointerX,
|
||||||
scenePointerY,
|
scenePointerY,
|
||||||
|
appState.gridSize,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -194,10 +189,29 @@ export class LinearElementEditor {
|
|||||||
ret.hitElement = element;
|
ret.hitElement = element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
|
||||||
|
const cx = (x1 + x2) / 2;
|
||||||
|
const cy = (y1 + y2) / 2;
|
||||||
|
const targetPoint =
|
||||||
|
clickedPointIndex > -1 &&
|
||||||
|
rotate(
|
||||||
|
element.x + element.points[clickedPointIndex][0],
|
||||||
|
element.y + element.points[clickedPointIndex][1],
|
||||||
|
cx,
|
||||||
|
cy,
|
||||||
|
element.angle,
|
||||||
|
);
|
||||||
|
|
||||||
setState({
|
setState({
|
||||||
editingLinearElement: {
|
editingLinearElement: {
|
||||||
...appState.editingLinearElement,
|
...appState.editingLinearElement,
|
||||||
activePointIndex: clickedPointIndex > -1 ? clickedPointIndex : null,
|
activePointIndex: clickedPointIndex > -1 ? clickedPointIndex : null,
|
||||||
|
pointerOffset: targetPoint
|
||||||
|
? {
|
||||||
|
x: scenePointerX - targetPoint[0],
|
||||||
|
y: scenePointerY - targetPoint[1],
|
||||||
|
}
|
||||||
|
: { x: 0, y: 0 },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return ret;
|
return ret;
|
||||||
@ -208,6 +222,7 @@ export class LinearElementEditor {
|
|||||||
scenePointerX: number,
|
scenePointerX: number,
|
||||||
scenePointerY: number,
|
scenePointerY: number,
|
||||||
editingLinearElement: LinearElementEditor,
|
editingLinearElement: LinearElementEditor,
|
||||||
|
gridSize: number | null,
|
||||||
): LinearElementEditor {
|
): LinearElementEditor {
|
||||||
const { elementId, lastUncommittedPoint } = editingLinearElement;
|
const { elementId, lastUncommittedPoint } = editingLinearElement;
|
||||||
const element = LinearElementEditor.getElement(elementId);
|
const element = LinearElementEditor.getElement(elementId);
|
||||||
@ -227,8 +242,9 @@ export class LinearElementEditor {
|
|||||||
|
|
||||||
const newPoint = LinearElementEditor.createPointAt(
|
const newPoint = LinearElementEditor.createPointAt(
|
||||||
element,
|
element,
|
||||||
scenePointerX,
|
scenePointerX - editingLinearElement.pointerOffset.x,
|
||||||
scenePointerY,
|
scenePointerY - editingLinearElement.pointerOffset.y,
|
||||||
|
gridSize,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (lastPoint === lastUncommittedPoint) {
|
if (lastPoint === lastUncommittedPoint) {
|
||||||
@ -288,13 +304,15 @@ export class LinearElementEditor {
|
|||||||
element: NonDeleted<ExcalidrawLinearElement>,
|
element: NonDeleted<ExcalidrawLinearElement>,
|
||||||
scenePointerX: number,
|
scenePointerX: number,
|
||||||
scenePointerY: number,
|
scenePointerY: number,
|
||||||
|
gridSize: number | null,
|
||||||
): Point {
|
): Point {
|
||||||
|
const pointerOnGrid = getGridPoint(scenePointerX, scenePointerY, gridSize);
|
||||||
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
|
||||||
const cx = (x1 + x2) / 2;
|
const cx = (x1 + x2) / 2;
|
||||||
const cy = (y1 + y2) / 2;
|
const cy = (y1 + y2) / 2;
|
||||||
const [rotatedX, rotatedY] = rotate(
|
const [rotatedX, rotatedY] = rotate(
|
||||||
scenePointerX,
|
pointerOnGrid[0],
|
||||||
scenePointerY,
|
pointerOnGrid[1],
|
||||||
cx,
|
cx,
|
||||||
cy,
|
cy,
|
||||||
-element.angle,
|
-element.angle,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user