mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Lock drag direction using Shift
(#1858)
Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
parent
d07099aadd
commit
c6736fa14e
5 changed files with 84 additions and 75 deletions
|
@ -209,7 +209,7 @@ const gesture: Gesture = {
|
|||
initialScale: null,
|
||||
};
|
||||
|
||||
type PointerDownState = Readonly<{
|
||||
export type PointerDownState = Readonly<{
|
||||
// The first position at which pointerDown happened
|
||||
origin: Readonly<{ x: number; y: number }>;
|
||||
// Same as "origin" but snapped to the grid, if grid is on
|
||||
|
@ -218,6 +218,9 @@ type PointerDownState = Readonly<{
|
|||
scrollbars: ReturnType<typeof isOverScrollBars>;
|
||||
// The previous pointer position
|
||||
lastCoords: { x: number; y: number };
|
||||
// map of original elements data
|
||||
// (for now only a subset of props for perf reasons)
|
||||
originalElements: Map<string, Pick<ExcalidrawElement, "x" | "y" | "angle">>;
|
||||
resize: {
|
||||
// Handle when resizing, might change during the pointer interaction
|
||||
handleType: MaybeTransformHandleType;
|
||||
|
@ -229,8 +232,6 @@ type PointerDownState = Readonly<{
|
|||
arrowDirection: "origin" | "end";
|
||||
// This is a center point of selected elements determined on the initial pointer down event (for rotation only)
|
||||
center: { x: number; y: number };
|
||||
// This is a list of selected elements determined on the initial pointer down event (for rotation only)
|
||||
originalElements: readonly NonDeleted<ExcalidrawElement>[];
|
||||
};
|
||||
hit: {
|
||||
// The element the pointer is "hitting", is determined on the initial
|
||||
|
@ -2435,13 +2436,20 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
),
|
||||
// we need to duplicate because we'll be updating this state
|
||||
lastCoords: { ...origin },
|
||||
originalElements: this.scene.getElements().reduce((acc, element) => {
|
||||
acc.set(element.id, {
|
||||
x: element.x,
|
||||
y: element.y,
|
||||
angle: element.angle,
|
||||
});
|
||||
return acc;
|
||||
}, new Map() as PointerDownState["originalElements"]),
|
||||
resize: {
|
||||
handleType: false,
|
||||
isResizing: false,
|
||||
offset: { x: 0, y: 0 },
|
||||
arrowDirection: "origin",
|
||||
center: { x: (maxX + minX) / 2, y: (maxY + minY) / 2 },
|
||||
originalElements: selectedElements.map((element) => ({ ...element })),
|
||||
},
|
||||
hit: {
|
||||
element: null,
|
||||
|
@ -2941,6 +2949,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
);
|
||||
if (
|
||||
transformElements(
|
||||
pointerDownState,
|
||||
transformHandleType,
|
||||
(newTransformHandle) => {
|
||||
pointerDownState.resize.handleType = newTransformHandle;
|
||||
|
@ -2954,7 +2963,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
resizeY,
|
||||
pointerDownState.resize.center.x,
|
||||
pointerDownState.resize.center.y,
|
||||
pointerDownState.resize.originalElements,
|
||||
)
|
||||
) {
|
||||
this.maybeSuggestBindingForAll(selectedElements);
|
||||
|
@ -3004,7 +3012,25 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
pointerCoords.y - pointerDownState.drag.offset.y,
|
||||
this.state.gridSize,
|
||||
);
|
||||
dragSelectedElements(selectedElements, dragX, dragY, this.scene);
|
||||
|
||||
const [dragDistanceX, dragDistanceY] = [
|
||||
Math.abs(pointerCoords.x - pointerDownState.origin.x),
|
||||
Math.abs(pointerCoords.y - pointerDownState.origin.y),
|
||||
];
|
||||
|
||||
// We only drag in one direction if shift is pressed
|
||||
const lockDirection = event.shiftKey;
|
||||
|
||||
dragSelectedElements(
|
||||
pointerDownState,
|
||||
selectedElements,
|
||||
dragX,
|
||||
dragY,
|
||||
this.scene,
|
||||
lockDirection,
|
||||
dragDistanceX,
|
||||
dragDistanceY,
|
||||
);
|
||||
this.maybeSuggestBindingForAll(selectedElements);
|
||||
|
||||
// We duplicate the selected element if alt is pressed on pointer move
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue