mirror of
https://github.com/excalidraw/excalidraw
synced 2025-07-25 13:58:22 +08:00
Restore drag
This commit is contained in:
@ -13,7 +13,7 @@ import type {
|
||||
|
||||
import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types";
|
||||
|
||||
import { updateBoundElements } from "./binding";
|
||||
import { bindOrUnbindLinearElement, updateBoundElements } from "./binding";
|
||||
import { getCommonBounds } from "./bounds";
|
||||
import { getPerfectElementSize } from "./sizeHelpers";
|
||||
import { getBoundTextElement } from "./textElement";
|
||||
@ -44,7 +44,7 @@ export const dragSelectedElements = (
|
||||
) => {
|
||||
if (
|
||||
_selectedElements.length === 1 &&
|
||||
isArrowElement(_selectedElements[0]) &&
|
||||
isElbowArrow(_selectedElements[0]) &&
|
||||
(_selectedElements[0].startBinding || _selectedElements[0].endBinding)
|
||||
) {
|
||||
return;
|
||||
@ -102,9 +102,26 @@ export const dragSelectedElements = (
|
||||
gridSize,
|
||||
);
|
||||
|
||||
const elementsToUpdateIds = new Set(
|
||||
Array.from(elementsToUpdate, (el) => el.id),
|
||||
);
|
||||
|
||||
elementsToUpdate.forEach((element) => {
|
||||
updateElementCoords(pointerDownState, element, scene, adjustedOffset);
|
||||
const isArrow = !isArrowElement(element);
|
||||
const isStartBoundElementSelected =
|
||||
isArrow ||
|
||||
(element.startBinding
|
||||
? elementsToUpdateIds.has(element.startBinding.elementId)
|
||||
: false);
|
||||
const isEndBoundElementSelected =
|
||||
isArrow ||
|
||||
(element.endBinding
|
||||
? elementsToUpdateIds.has(element.endBinding.elementId)
|
||||
: false);
|
||||
|
||||
if (!isArrowElement(element)) {
|
||||
updateElementCoords(pointerDownState, element, scene, adjustedOffset);
|
||||
|
||||
// skip arrow labels since we calculate its position during render
|
||||
const textElement = getBoundTextElement(
|
||||
element,
|
||||
@ -121,6 +138,28 @@ export const dragSelectedElements = (
|
||||
updateBoundElements(element, scene, {
|
||||
simultaneouslyUpdated: Array.from(elementsToUpdate),
|
||||
});
|
||||
} else if (
|
||||
// NOTE: Add a little initial drag to the arrow dragging to avoid
|
||||
// accidentally unbinding the arrow when the user just wants to select it.
|
||||
Math.max(Math.abs(adjustedOffset.x), Math.abs(adjustedOffset.y)) > 1
|
||||
) {
|
||||
updateElementCoords(pointerDownState, element, scene, adjustedOffset);
|
||||
|
||||
const shouldUnbindStart =
|
||||
element.startBinding && !isStartBoundElementSelected;
|
||||
const shouldUnbindEnd = element.endBinding && !isEndBoundElementSelected;
|
||||
if (shouldUnbindStart || shouldUnbindEnd) {
|
||||
// NOTE: Moving the bound arrow should unbind it, otherwise we would
|
||||
// have weird situations, like 0 lenght arrow when the user moves
|
||||
// the arrow outside a filled shape suddenly forcing the arrow start
|
||||
// and end point to jump "outside" the shape.
|
||||
bindOrUnbindLinearElement(
|
||||
element,
|
||||
shouldUnbindStart ? null : "keep",
|
||||
shouldUnbindEnd ? null : "keep",
|
||||
scene,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -4365,7 +4365,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
const arrowIdsToRemove = new Set<string>();
|
||||
|
||||
selectedElements
|
||||
.filter(isArrowElement)
|
||||
.filter(isElbowArrow)
|
||||
.filter((arrow) => {
|
||||
const startElementNotInSelection =
|
||||
arrow.startBinding &&
|
||||
@ -6398,8 +6398,8 @@ class App extends React.Component<AppProps, AppState> {
|
||||
});
|
||||
} else if (
|
||||
!hitElement ||
|
||||
// Arrows can only be moved when unconnected
|
||||
!isArrowElement(hitElement) ||
|
||||
// Elbow arrows can only be moved when unconnected
|
||||
!isElbowArrow(hitElement) ||
|
||||
!(hitElement.startBinding || hitElement.endBinding)
|
||||
) {
|
||||
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
||||
@ -6515,8 +6515,8 @@ class App extends React.Component<AppProps, AppState> {
|
||||
setCursor(this.interactiveCanvas, CURSOR_TYPE.POINTER);
|
||||
} else if (this.hitElement(scenePointerX, scenePointerY, element)) {
|
||||
if (
|
||||
// Arrows can only be moved when unconnected
|
||||
!isArrowElement(element) ||
|
||||
// Elbow arrows can only be moved when unconnected
|
||||
!isElbowArrow(element) ||
|
||||
!(element.startBinding || element.endBinding)
|
||||
) {
|
||||
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
||||
@ -6524,8 +6524,8 @@ class App extends React.Component<AppProps, AppState> {
|
||||
}
|
||||
} else if (this.hitElement(scenePointerX, scenePointerY, element)) {
|
||||
if (
|
||||
// Arrows can only be moved when unconnected
|
||||
!isArrowElement(element) ||
|
||||
// Elbow arrow can only be moved when unconnected
|
||||
!isElbowArrow(element) ||
|
||||
!(element.startBinding || element.endBinding)
|
||||
) {
|
||||
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
||||
|
Reference in New Issue
Block a user