Lock drag direction using Shift (#1858)

Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
Robert van Hoesel 2020-09-11 17:22:40 +02:00 committed by GitHub
parent d07099aadd
commit c6736fa14e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 84 additions and 75 deletions

View file

@ -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