feat: grid mode for line editing (#1984)

This commit is contained in:
Daishi Kato 2020-07-31 00:09:51 +09:00 committed by GitHub
parent c171fb4c7f
commit 818821c293
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 27 deletions

View File

@ -1883,6 +1883,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
scenePointerX,
scenePointerY,
this.state.editingLinearElement,
this.state.gridSize,
);
if (editingLinearElement !== this.state.editingLinearElement) {
this.setState({ editingLinearElement });
@ -2778,8 +2779,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
(appState) => this.setState(appState),
x,
y,
pointerDownState.lastCoords.x,
pointerDownState.lastCoords.y,
);
if (didDrag) {

View File

@ -3,7 +3,7 @@ import {
ExcalidrawLinearElement,
ExcalidrawElement,
} from "./types";
import { distance2d, rotate, isPathALoop } from "../math";
import { distance2d, rotate, isPathALoop, getGridPoint } from "../math";
import { getElementAbsoluteCoords } from ".";
import { getElementPointsCoords } from "./bounds";
import { Point, AppState } from "../types";
@ -20,6 +20,7 @@ export class LinearElementEditor {
/** whether you're dragging a point */
public isDragging: boolean;
public lastUncommittedPoint: Point | null;
public pointerOffset: { x: number; y: number };
constructor(element: NonDeleted<ExcalidrawLinearElement>, scene: Scene) {
this.elementId = element.id as string & {
@ -31,6 +32,7 @@ export class LinearElementEditor {
this.activePointIndex = null;
this.lastUncommittedPoint = null;
this.isDragging = false;
this.pointerOffset = { x: 0, y: 0 };
}
// ---------------------------------------------------------------------------
@ -57,8 +59,6 @@ export class LinearElementEditor {
setState: React.Component<any, AppState>["setState"],
scenePointerX: number,
scenePointerY: number,
lastX: number,
lastY: number,
): boolean {
if (!appState.editingLinearElement) {
return false;
@ -80,18 +80,14 @@ export class LinearElementEditor {
},
});
}
const [deltaX, deltaY] = rotate(
scenePointerX - lastX,
scenePointerY - lastY,
0,
0,
-element.angle,
const newPoint = LinearElementEditor.createPointAt(
element,
scenePointerX - editingLinearElement.pointerOffset.x,
scenePointerY - editingLinearElement.pointerOffset.y,
appState.gridSize,
);
const targetPoint = element.points[activePointIndex];
LinearElementEditor.movePoint(element, activePointIndex, [
targetPoint[0] + deltaX,
targetPoint[1] + deltaY,
]);
LinearElementEditor.movePoint(element, activePointIndex, newPoint);
return true;
}
return false;
@ -120,13 +116,11 @@ export class LinearElementEditor {
: element.points[0],
);
}
if (isDragging) {
return {
...editingLinearElement,
isDragging: false,
};
}
return editingLinearElement;
return {
...editingLinearElement,
isDragging: false,
pointerOffset: { x: 0, y: 0 },
};
}
static handlePointerDown(
@ -165,6 +159,7 @@ export class LinearElementEditor {
element,
scenePointerX,
scenePointerY,
appState.gridSize,
),
],
});
@ -194,10 +189,29 @@ export class LinearElementEditor {
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({
editingLinearElement: {
...appState.editingLinearElement,
activePointIndex: clickedPointIndex > -1 ? clickedPointIndex : null,
pointerOffset: targetPoint
? {
x: scenePointerX - targetPoint[0],
y: scenePointerY - targetPoint[1],
}
: { x: 0, y: 0 },
},
});
return ret;
@ -208,6 +222,7 @@ export class LinearElementEditor {
scenePointerX: number,
scenePointerY: number,
editingLinearElement: LinearElementEditor,
gridSize: number | null,
): LinearElementEditor {
const { elementId, lastUncommittedPoint } = editingLinearElement;
const element = LinearElementEditor.getElement(elementId);
@ -227,8 +242,9 @@ export class LinearElementEditor {
const newPoint = LinearElementEditor.createPointAt(
element,
scenePointerX,
scenePointerY,
scenePointerX - editingLinearElement.pointerOffset.x,
scenePointerY - editingLinearElement.pointerOffset.y,
gridSize,
);
if (lastPoint === lastUncommittedPoint) {
@ -288,13 +304,15 @@ export class LinearElementEditor {
element: NonDeleted<ExcalidrawLinearElement>,
scenePointerX: number,
scenePointerY: number,
gridSize: number | null,
): Point {
const pointerOnGrid = getGridPoint(scenePointerX, scenePointerY, gridSize);
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
const cx = (x1 + x2) / 2;
const cy = (y1 + y2) / 2;
const [rotatedX, rotatedY] = rotate(
scenePointerX,
scenePointerY,
pointerOnGrid[0],
pointerOnGrid[1],
cx,
cy,
-element.angle,