mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-11-15 10:15:03 +01:00
feat: drag, resize, and rotate after selecting in lasso
This commit is contained in:
@@ -6013,6 +6013,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
if (
|
if (
|
||||||
hasDeselectedButton ||
|
hasDeselectedButton ||
|
||||||
(this.state.activeTool.type !== "selection" &&
|
(this.state.activeTool.type !== "selection" &&
|
||||||
|
this.state.activeTool.type !== "lasso" &&
|
||||||
this.state.activeTool.type !== "text" &&
|
this.state.activeTool.type !== "text" &&
|
||||||
this.state.activeTool.type !== "eraser")
|
this.state.activeTool.type !== "eraser")
|
||||||
) {
|
) {
|
||||||
@@ -6183,8 +6184,13 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
// Ebow arrows can only be moved when unconnected
|
// Ebow arrows can only be moved when unconnected
|
||||||
!isElbowArrow(hitElement) ||
|
!isElbowArrow(hitElement) ||
|
||||||
!(hitElement.startBinding || hitElement.endBinding)
|
!(hitElement.startBinding || hitElement.endBinding)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
this.state.activeTool.type !== "lasso" ||
|
||||||
|
selectedElements.length > 0
|
||||||
) {
|
) {
|
||||||
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
||||||
|
}
|
||||||
if (this.state.activeEmbeddable?.state === "hover") {
|
if (this.state.activeEmbeddable?.state === "hover") {
|
||||||
this.setState({ activeEmbeddable: null });
|
this.setState({ activeEmbeddable: null });
|
||||||
}
|
}
|
||||||
@@ -6292,19 +6298,29 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
// Ebow arrows can only be moved when unconnected
|
// Ebow arrows can only be moved when unconnected
|
||||||
!isElbowArrow(element) ||
|
!isElbowArrow(element) ||
|
||||||
!(element.startBinding || element.endBinding)
|
!(element.startBinding || element.endBinding)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
this.state.activeTool.type !== "lasso" ||
|
||||||
|
Object.keys(this.state.selectedElementIds).length > 0
|
||||||
) {
|
) {
|
||||||
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (this.hitElement(scenePointerX, scenePointerY, element)) {
|
} else if (this.hitElement(scenePointerX, scenePointerY, element)) {
|
||||||
if (
|
if (
|
||||||
// Ebow arrows can only be moved when unconnected
|
// Ebow arrows can only be moved when unconnected
|
||||||
!isElbowArrow(element) ||
|
!isElbowArrow(element) ||
|
||||||
!(element.startBinding || element.endBinding)
|
!(element.startBinding || element.endBinding)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
this.state.activeTool.type !== "lasso" ||
|
||||||
|
Object.keys(this.state.selectedElementIds).length > 0
|
||||||
) {
|
) {
|
||||||
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.state.selectedLinearElement.hoverPointIndex !== hoverPointIndex
|
this.state.selectedLinearElement.hoverPointIndex !== hoverPointIndex
|
||||||
@@ -6564,11 +6580,25 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.state.activeTool.type === "lasso") {
|
if (this.state.activeTool.type === "lasso") {
|
||||||
|
const hitSelectedElement =
|
||||||
|
pointerDownState.hit.element &&
|
||||||
|
this.isASelectedElement(pointerDownState.hit.element);
|
||||||
|
|
||||||
|
// Start a new lasso ONLY if we're not interacting with an existing
|
||||||
|
// selection (move/resize/rotate).
|
||||||
|
if (
|
||||||
|
!pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements &&
|
||||||
|
!pointerDownState.resize.handleType &&
|
||||||
|
!hitSelectedElement
|
||||||
|
) {
|
||||||
this.lassoTrail.startPath(
|
this.lassoTrail.startPath(
|
||||||
pointerDownState.origin.x,
|
pointerDownState.origin.x,
|
||||||
pointerDownState.origin.y,
|
pointerDownState.origin.y,
|
||||||
event.shiftKey,
|
event.shiftKey,
|
||||||
);
|
);
|
||||||
|
// Block drag until next pointerdown if a lasso selection is made
|
||||||
|
pointerDownState.drag.blockDragAfterLasso = true;
|
||||||
|
}
|
||||||
} else if (this.state.activeTool.type === "text") {
|
} else if (this.state.activeTool.type === "text") {
|
||||||
this.handleTextOnPointerDown(event, pointerDownState);
|
this.handleTextOnPointerDown(event, pointerDownState);
|
||||||
} else if (
|
} else if (
|
||||||
@@ -6948,6 +6978,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
hasOccurred: false,
|
hasOccurred: false,
|
||||||
offset: null,
|
offset: null,
|
||||||
origin: { ...origin },
|
origin: { ...origin },
|
||||||
|
blockDragAfterLasso: false,
|
||||||
},
|
},
|
||||||
eventListeners: {
|
eventListeners: {
|
||||||
onMove: null,
|
onMove: null,
|
||||||
@@ -7023,7 +7054,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
event: React.PointerEvent<HTMLElement>,
|
event: React.PointerEvent<HTMLElement>,
|
||||||
pointerDownState: PointerDownState,
|
pointerDownState: PointerDownState,
|
||||||
): boolean => {
|
): boolean => {
|
||||||
if (this.state.activeTool.type === "selection") {
|
if (
|
||||||
|
this.state.activeTool.type === "selection" ||
|
||||||
|
this.state.activeTool.type === "lasso"
|
||||||
|
) {
|
||||||
const elements = this.scene.getNonDeletedElements();
|
const elements = this.scene.getNonDeletedElements();
|
||||||
const elementsMap = this.scene.getNonDeletedElementsMap();
|
const elementsMap = this.scene.getNonDeletedElementsMap();
|
||||||
const selectedElements = this.scene.getSelectedElements(this.state);
|
const selectedElements = this.scene.getSelectedElements(this.state);
|
||||||
@@ -8257,7 +8291,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
(hasHitASelectedElement ||
|
(hasHitASelectedElement ||
|
||||||
pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) &&
|
pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements) &&
|
||||||
!isSelectingPointsInLineEditor &&
|
!isSelectingPointsInLineEditor &&
|
||||||
this.state.activeTool.type !== "lasso"
|
(this.state.activeTool.type !== "lasso" ||
|
||||||
|
pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements ||
|
||||||
|
hasHitASelectedElement) &&
|
||||||
|
!pointerDownState.drag.blockDragAfterLasso
|
||||||
) {
|
) {
|
||||||
const selectedElements = this.scene.getSelectedElements(this.state);
|
const selectedElements = this.scene.getSelectedElements(this.state);
|
||||||
|
|
||||||
@@ -8878,6 +8915,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
): (event: PointerEvent) => void {
|
): (event: PointerEvent) => void {
|
||||||
return withBatchedUpdates((childEvent: PointerEvent) => {
|
return withBatchedUpdates((childEvent: PointerEvent) => {
|
||||||
this.removePointer(childEvent);
|
this.removePointer(childEvent);
|
||||||
|
pointerDownState.drag.blockDragAfterLasso = false;
|
||||||
if (pointerDownState.eventListeners.onMove) {
|
if (pointerDownState.eventListeners.onMove) {
|
||||||
pointerDownState.eventListeners.onMove.flush();
|
pointerDownState.eventListeners.onMove.flush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -782,6 +782,8 @@ export type PointerDownState = Readonly<{
|
|||||||
// by default same as PointerDownState.origin. On alt-duplication, reset
|
// by default same as PointerDownState.origin. On alt-duplication, reset
|
||||||
// to current pointer position at time of duplication.
|
// to current pointer position at time of duplication.
|
||||||
origin: { x: number; y: number };
|
origin: { x: number; y: number };
|
||||||
|
// used to block drag after lasso selection until next pointerdown
|
||||||
|
blockDragAfterLasso: boolean;
|
||||||
};
|
};
|
||||||
// We need to have these in the state so that we can unsubscribe them
|
// We need to have these in the state so that we can unsubscribe them
|
||||||
eventListeners: {
|
eventListeners: {
|
||||||
|
|||||||
Reference in New Issue
Block a user