Ver Fonte

rebind arrow on rotation (#2096)

David Luzar há 4 anos atrás
pai
commit
26ef235019

+ 5 - 7
src/components/App.tsx

@@ -143,7 +143,6 @@ import {
   isLinearElementType,
   isBindingElement,
   isBindingElementType,
-  isBindableElement,
 } from "../element/typeChecks";
 import { actionFinalize, actionDeleteSelected } from "../actions";
 import { loadLibrary } from "../data/localStorage";
@@ -168,7 +167,6 @@ import {
   bindOrUnbindSelectedElements,
   unbindLinearElements,
   fixBindingsAfterDuplication,
-  maybeBindBindableElement,
   getElligibleElementForBindingElementAtCoors,
   fixBindingsAfterDeletion,
   isLinearElementSimpleAndAlreadyBound,
@@ -2946,6 +2944,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
           )
         ) {
           this.maybeSuggestBindingForAll(selectedElements);
+          bindOrUnbindSelectedElements(selectedElements);
           return;
         }
       }
@@ -3339,11 +3338,10 @@ class App extends React.Component<ExcalidrawProps, AppState> {
           getNormalizedDimensions(draggingElement),
         );
 
-        if (
-          isBindingEnabled(this.state) &&
-          isBindableElement(draggingElement)
-        ) {
-          maybeBindBindableElement(draggingElement);
+        if (isBindingEnabled(this.state)) {
+          bindOrUnbindSelectedElements(
+            getSelectedElements(this.scene.getElements(), this.state),
+          );
         }
       }
 

+ 28 - 28
src/tests/__snapshots__/regressionTests.test.tsx.snap

@@ -997,7 +997,7 @@ Object {
   "versionNonce": 915032327,
   "width": 10,
   "x": 30,
-  "y": 30,
+  "y": 0,
 }
 `;
 
@@ -1025,7 +1025,7 @@ Object {
   "versionNonce": 81784553,
   "width": 10,
   "x": 60,
-  "y": 60,
+  "y": 0,
 }
 `;
 
@@ -1125,7 +1125,7 @@ Object {
           "versionNonce": 453191,
           "width": 10,
           "x": 30,
-          "y": 30,
+          "y": 0,
         },
       ],
     },
@@ -1191,7 +1191,7 @@ Object {
           "versionNonce": 1116226695,
           "width": 10,
           "x": 30,
-          "y": 30,
+          "y": 0,
         },
       ],
     },
@@ -1255,7 +1255,7 @@ Object {
           "versionNonce": 1116226695,
           "width": 10,
           "x": 30,
-          "y": 30,
+          "y": 0,
         },
       ],
     },
@@ -1318,7 +1318,7 @@ Object {
           "versionNonce": 1116226695,
           "width": 10,
           "x": 30,
-          "y": 30,
+          "y": 0,
         },
         Object {
           "angle": 0,
@@ -1341,7 +1341,7 @@ Object {
           "versionNonce": 1604849351,
           "width": 10,
           "x": 60,
-          "y": 60,
+          "y": 0,
         },
       ],
     },
@@ -1410,7 +1410,7 @@ Object {
           "versionNonce": 915032327,
           "width": 10,
           "x": 30,
-          "y": 30,
+          "y": 0,
         },
         Object {
           "angle": 0,
@@ -1435,7 +1435,7 @@ Object {
           "versionNonce": 81784553,
           "width": 10,
           "x": 60,
-          "y": 60,
+          "y": 0,
         },
       ],
     },
@@ -1501,7 +1501,7 @@ Object {
           "versionNonce": 915032327,
           "width": 10,
           "x": 30,
-          "y": 30,
+          "y": 0,
         },
         Object {
           "angle": 0,
@@ -1526,7 +1526,7 @@ Object {
           "versionNonce": 81784553,
           "width": 10,
           "x": 60,
-          "y": 60,
+          "y": 0,
         },
       ],
     },
@@ -1592,7 +1592,7 @@ Object {
           "versionNonce": 915032327,
           "width": 10,
           "x": 30,
-          "y": 30,
+          "y": 0,
         },
         Object {
           "angle": 0,
@@ -1617,7 +1617,7 @@ Object {
           "versionNonce": 81784553,
           "width": 10,
           "x": 60,
-          "y": 60,
+          "y": 0,
         },
       ],
     },
@@ -25348,7 +25348,7 @@ Object {
   "versionNonce": 81784553,
   "width": 10,
   "x": 10,
-  "y": 10,
+  "y": 0,
 }
 `;
 
@@ -25377,7 +25377,7 @@ Object {
   "versionNonce": 747212839,
   "width": 10,
   "x": 50,
-  "y": 50,
+  "y": 0,
 }
 `;
 
@@ -25476,7 +25476,7 @@ Object {
           "versionNonce": 1278240551,
           "width": 10,
           "x": 10,
-          "y": 10,
+          "y": 0,
         },
       ],
     },
@@ -25512,7 +25512,7 @@ Object {
           "versionNonce": 1278240551,
           "width": 10,
           "x": 10,
-          "y": 10,
+          "y": 0,
         },
         Object {
           "angle": 0,
@@ -25535,7 +25535,7 @@ Object {
           "versionNonce": 453191,
           "width": 10,
           "x": 50,
-          "y": 50,
+          "y": 0,
         },
       ],
     },
@@ -25576,7 +25576,7 @@ Object {
           "versionNonce": 1150084233,
           "width": 10,
           "x": 10,
-          "y": 10,
+          "y": 0,
         },
         Object {
           "angle": 0,
@@ -25601,7 +25601,7 @@ Object {
           "versionNonce": 1116226695,
           "width": 10,
           "x": 50,
-          "y": 50,
+          "y": 0,
         },
       ],
     },
@@ -25639,7 +25639,7 @@ Object {
           "versionNonce": 1150084233,
           "width": 10,
           "x": 10,
-          "y": 10,
+          "y": 0,
         },
         Object {
           "angle": 0,
@@ -25664,7 +25664,7 @@ Object {
           "versionNonce": 1116226695,
           "width": 10,
           "x": 50,
-          "y": 50,
+          "y": 0,
         },
         Object {
           "angle": 0,
@@ -25725,7 +25725,7 @@ Object {
           "versionNonce": 1150084233,
           "width": 10,
           "x": 10,
-          "y": 10,
+          "y": 0,
         },
         Object {
           "angle": 0,
@@ -25750,7 +25750,7 @@ Object {
           "versionNonce": 1116226695,
           "width": 10,
           "x": 50,
-          "y": 50,
+          "y": 0,
         },
         Object {
           "angle": 0,
@@ -25837,7 +25837,7 @@ Object {
           "versionNonce": 1150084233,
           "width": 10,
           "x": 10,
-          "y": 10,
+          "y": 0,
         },
         Object {
           "angle": 0,
@@ -25862,7 +25862,7 @@ Object {
           "versionNonce": 1116226695,
           "width": 10,
           "x": 50,
-          "y": 50,
+          "y": 0,
         },
         Object {
           "angle": 0,
@@ -25954,7 +25954,7 @@ Object {
           "versionNonce": 81784553,
           "width": 10,
           "x": 10,
-          "y": 10,
+          "y": 0,
         },
         Object {
           "angle": 0,
@@ -25980,7 +25980,7 @@ Object {
           "versionNonce": 747212839,
           "width": 10,
           "x": 50,
-          "y": 50,
+          "y": 0,
         },
         Object {
           "angle": 0,

+ 49 - 0
src/tests/binding.test.tsx

@@ -0,0 +1,49 @@
+import React from "react";
+import { render } from "./test-utils";
+import App from "../components/App";
+import { UI, Pointer } from "./helpers/ui";
+import { getTransformHandles } from "../element/transformHandles";
+
+const { h } = window;
+
+const mouse = new Pointer("mouse");
+
+describe("element binding", () => {
+  beforeEach(() => {
+    render(<App />);
+  });
+
+  // NOTE if this tests fails, skip it -- it was really flaky at one point
+  it("rotation of arrow should rebind both ends", () => {
+    const rect1 = UI.createElement("rectangle", {
+      x: 0,
+      width: 100,
+      height: 1000,
+    });
+    const rect2 = UI.createElement("rectangle", {
+      x: 200,
+      width: 100,
+      height: 1000,
+    });
+    const arrow = UI.createElement("arrow", {
+      x: 110,
+      y: 50,
+      width: 80,
+      height: 1,
+    });
+    expect(arrow.startBinding?.elementId).toBe(rect1.id);
+    expect(arrow.endBinding?.elementId).toBe(rect2.id);
+
+    const { rotation } = getTransformHandles(arrow, h.state.zoom, "mouse");
+    if (rotation) {
+      const rotationHandleX = rotation[0] + rotation[2] / 2;
+      const rotationHandleY = rotation[1] + rotation[3] / 2;
+      mouse.down(rotationHandleX, rotationHandleY);
+      mouse.move(0, 1000);
+      mouse.up();
+    }
+    expect(arrow.angle).toBeGreaterThan(3);
+    expect(arrow.startBinding?.elementId).toBe(rect2.id);
+    expect(arrow.endBinding?.elementId).toBe(rect1.id);
+  });
+});

+ 19 - 7
src/tests/helpers/ui.ts

@@ -1,7 +1,11 @@
 import { ToolName } from "../queries/toolQueries";
 import { fireEvent, GlobalTestState } from "../test-utils";
 import { KEYS, Key } from "../../keys";
-import { ExcalidrawElement } from "../../element/types";
+import {
+  ExcalidrawElement,
+  ExcalidrawLinearElement,
+  ExcalidrawTextElement,
+} from "../../element/types";
 import { API } from "./api";
 
 const { h } = window;
@@ -174,24 +178,32 @@ export class UI {
     fireEvent.click(GlobalTestState.renderResult.getByToolName(toolName));
   };
 
-  static createElement(
-    type: ToolName,
+  static createElement<T extends ToolName>(
+    type: T,
     {
       x = 0,
-      y = x,
+      y = 0,
       size = 10,
+      width = size,
+      height = width,
     }: {
       x?: number;
       y?: number;
       size?: number;
+      width?: number;
+      height?: number;
     },
-  ) {
+  ): T extends "arrow" | "line" | "draw"
+    ? ExcalidrawLinearElement
+    : T extends "text"
+    ? ExcalidrawTextElement
+    : ExcalidrawElement {
     UI.clickTool(type);
     mouse.reset();
     mouse.down(x, y);
     mouse.reset();
-    mouse.up(x + size, y + size);
-    return h.elements[h.elements.length - 1];
+    mouse.up(x + (width ?? height ?? size), y + (height ?? size));
+    return h.elements[h.elements.length - 1] as any;
   }
 
   static group(elements: ExcalidrawElement[]) {