From 46f42ef8d79a09976a99dc138878b0f409ba40a9 Mon Sep 17 00:00:00 2001
From: David Luzar <5153846+dwelle@users.noreply.github.com>
Date: Tue, 14 Jan 2025 19:36:47 +0100
Subject: [PATCH] fix: arrow binding behaving unexpectedly on pointerup (#9010)

* fix: arrow binding behaving unexpectedly on pointerup

* update snaps
---
 .../data/__snapshots__/transform.test.ts.snap |  56 ++++----
 packages/excalidraw/element/binding.ts        |   6 -
 .../tests/__snapshots__/history.test.tsx.snap | 128 ++++++++----------
 .../tests/__snapshots__/move.test.tsx.snap    |   6 +-
 4 files changed, 89 insertions(+), 107 deletions(-)

diff --git a/packages/excalidraw/data/__snapshots__/transform.test.ts.snap b/packages/excalidraw/data/__snapshots__/transform.test.ts.snap
index 2b56d9b272..0f86b84eb7 100644
--- a/packages/excalidraw/data/__snapshots__/transform.test.ts.snap
+++ b/packages/excalidraw/data/__snapshots__/transform.test.ts.snap
@@ -95,7 +95,7 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing s
   "fillStyle": "solid",
   "frameId": null,
   "groupIds": [],
-  "height": 33.519031369643244,
+  "height": 35,
   "id": Any<String>,
   "index": "a2",
   "isDeleted": false,
@@ -109,8 +109,8 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing s
       0.5,
     ],
     [
-      382.47606040672997,
-      34.019031369643244,
+      394.5,
+      34.5,
     ],
   ],
   "roughness": 1,
@@ -128,9 +128,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing s
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 7,
+  "version": 4,
   "versionNonce": Any<Number>,
-  "width": 381.97606040672997,
+  "width": 395,
   "x": 247,
   "y": 420,
 }
@@ -167,7 +167,7 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing s
       0,
     ],
     [
-      389.5,
+      399.5,
       0,
     ],
   ],
@@ -186,10 +186,10 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing s
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 6,
+  "version": 4,
   "versionNonce": Any<Number>,
-  "width": 390,
-  "x": 237,
+  "width": 400,
+  "x": 227,
   "y": 450,
 }
 `;
@@ -319,7 +319,7 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing t
   "verticalAlign": "top",
   "width": 100,
   "x": 560,
-  "y": 236.95454545454544,
+  "y": 226.5,
 }
 `;
 
@@ -339,13 +339,13 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing t
   "endBinding": {
     "elementId": "text-2",
     "fixedPoint": null,
-    "focus": 1.625925925925924,
+    "focus": 0,
     "gap": 14,
   },
   "fillStyle": "solid",
   "frameId": null,
   "groupIds": [],
-  "height": 18.278619528619487,
+  "height": 0,
   "id": Any<String>,
   "index": "a2",
   "isDeleted": false,
@@ -356,11 +356,11 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing t
   "points": [
     [
       0.5,
-      -0.5,
+      0,
     ],
     [
-      357.2037037037038,
-      -17.778619528619487,
+      99.5,
+      0,
     ],
   ],
   "roughness": 1,
@@ -378,11 +378,11 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing t
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 6,
+  "version": 4,
   "versionNonce": Any<Number>,
-  "width": 357.7037037037038,
-  "x": 171,
-  "y": 249.45454545454544,
+  "width": 100,
+  "x": 255,
+  "y": 239,
 }
 `;
 
@@ -482,7 +482,7 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to shapes whe
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 6,
+  "version": 4,
   "versionNonce": Any<Number>,
   "width": 100,
   "x": 255,
@@ -660,7 +660,7 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to text when
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 6,
+  "version": 4,
   "versionNonce": Any<Number>,
   "width": 100,
   "x": 255,
@@ -1505,7 +1505,7 @@ exports[`Test Transform > should transform the elements correctly when linear el
       0,
     ],
     [
-      270.98528125,
+      272.485,
       0,
     ],
   ],
@@ -1526,10 +1526,10 @@ exports[`Test Transform > should transform the elements correctly when linear el
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 7,
+  "version": 4,
   "versionNonce": Any<Number>,
-  "width": 270.48528125,
-  "x": 112.76171875,
+  "width": 272.985,
+  "x": 111.262,
   "y": 57,
 }
 `;
@@ -1587,11 +1587,11 @@ exports[`Test Transform > should transform the elements correctly when linear el
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 6,
+  "version": 4,
   "versionNonce": Any<Number>,
   "width": 0,
-  "x": 83.015625,
-  "y": 81.5,
+  "x": 77.017,
+  "y": 79,
 }
 `;
 
diff --git a/packages/excalidraw/element/binding.ts b/packages/excalidraw/element/binding.ts
index 9c1b2447c8..897641bfc7 100644
--- a/packages/excalidraw/element/binding.ts
+++ b/packages/excalidraw/element/binding.ts
@@ -504,12 +504,6 @@ export const bindLinearElement = (
       }),
     });
   }
-
-  // update bound elements to make sure the binding tips are in sync with
-  // the normalized gap from above
-  if (!isElbowArrow(linearElement)) {
-    updateBoundElements(hoveredElement, elementsMap);
-  }
 };
 
 // Don't bind both ends of a simple segment
diff --git a/packages/excalidraw/tests/__snapshots__/history.test.tsx.snap b/packages/excalidraw/tests/__snapshots__/history.test.tsx.snap
index 3a701fc5f5..1d14665473 100644
--- a/packages/excalidraw/tests/__snapshots__/history.test.tsx.snap
+++ b/packages/excalidraw/tests/__snapshots__/history.test.tsx.snap
@@ -197,7 +197,7 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
   "fillStyle": "solid",
   "frameId": null,
   "groupIds": [],
-  "height": 125,
+  "height": 99,
   "id": "id166",
   "index": "a2",
   "isDeleted": false,
@@ -211,8 +211,8 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
       0,
     ],
     [
-      125,
-      125,
+      "98.20800",
+      99,
     ],
   ],
   "roughness": 1,
@@ -226,9 +226,9 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 47,
-  "width": 125,
-  "x": 0,
+  "version": 40,
+  "width": "98.20800",
+  "x": 1,
   "y": 0,
 }
 `;
@@ -298,7 +298,7 @@ History {
                 "focus": "0.00990",
                 "gap": 1,
               },
-              "height": "0.98000",
+              "height": "0.98017",
               "points": [
                 [
                   0,
@@ -306,7 +306,7 @@ History {
                 ],
                 [
                   98,
-                  "-0.98000",
+                  "-0.98017",
                 ],
               ],
               "startBinding": {
@@ -320,10 +320,10 @@ History {
               "endBinding": {
                 "elementId": "id165",
                 "fixedPoint": null,
-                "focus": "-0.02040",
+                "focus": "-0.02000",
                 "gap": 1,
               },
-              "height": "0.02000",
+              "height": "0.00169",
               "points": [
                 [
                   0,
@@ -331,13 +331,13 @@ History {
                 ],
                 [
                   98,
-                  "0.02000",
+                  "0.00169",
                 ],
               ],
               "startBinding": {
                 "elementId": "id164",
                 "fixedPoint": null,
-                "focus": "0.01959",
+                "focus": "0.02000",
                 "gap": 1,
               },
             },
@@ -393,20 +393,18 @@ History {
                 "focus": 0,
                 "gap": 1,
               },
-              "height": 125,
+              "height": 99,
               "points": [
                 [
                   0,
                   0,
                 ],
                 [
-                  125,
-                  125,
+                  "98.20800",
+                  99,
                 ],
               ],
               "startBinding": null,
-              "width": 125,
-              "x": 0,
               "y": 0,
             },
             "inserted": {
@@ -416,7 +414,7 @@ History {
                 "focus": "0.00990",
                 "gap": 1,
               },
-              "height": "0.98000",
+              "height": "0.98161",
               "points": [
                 [
                   0,
@@ -424,7 +422,7 @@ History {
                 ],
                 [
                   98,
-                  "-0.98000",
+                  "-0.98161",
                 ],
               ],
               "startBinding": {
@@ -433,9 +431,7 @@ History {
                 "focus": "0.02970",
                 "gap": 1,
               },
-              "width": 98,
-              "x": 1,
-              "y": "0.99000",
+              "y": "0.99245",
             },
           },
           "id169" => Delta {
@@ -827,9 +823,9 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 37,
-  "width": 100,
-  "x": 150,
+  "version": 30,
+  "width": 0,
+  "x": 200,
   "y": 0,
 }
 `;
@@ -866,8 +862,6 @@ History {
                   0,
                 ],
               ],
-              "width": 0,
-              "x": 149,
             },
             "inserted": {
               "points": [
@@ -876,12 +870,10 @@ History {
                   0,
                 ],
                 [
-                  "98.00000",
+                  100,
                   0,
                 ],
               ],
-              "width": "98.00000",
-              "x": "1.00000",
             },
           },
         },
@@ -938,8 +930,6 @@ History {
                 ],
               ],
               "startBinding": null,
-              "width": 100,
-              "x": 150,
             },
             "inserted": {
               "endBinding": {
@@ -964,8 +954,6 @@ History {
                 "focus": 0,
                 "gap": 1,
               },
-              "width": 0,
-              "x": 149,
             },
           },
         },
@@ -2375,9 +2363,9 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 12,
+  "version": 10,
   "width": 498,
-  "x": "1.00000",
+  "x": 1,
   "y": 0,
 }
 `;
@@ -2516,7 +2504,7 @@ History {
                   0,
                 ],
                 [
-                  "98.00000",
+                  100,
                   0,
                 ],
               ],
@@ -2535,8 +2523,8 @@ History {
               "strokeStyle": "solid",
               "strokeWidth": 2,
               "type": "arrow",
-              "width": "98.00000",
-              "x": 1,
+              "width": 100,
+              "x": 0,
               "y": 0,
             },
             "inserted": {
@@ -15179,9 +15167,9 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 12,
+  "version": 10,
   "width": "98.00000",
-  "x": "1.00000",
+  "x": 1,
   "y": 0,
 }
 `;
@@ -15220,7 +15208,7 @@ History {
                   0,
                 ],
                 [
-                  "98.00000",
+                  100,
                   0,
                 ],
               ],
@@ -15233,7 +15221,7 @@ History {
                   0,
                 ],
                 [
-                  "98.00000",
+                  100,
                   0,
                 ],
               ],
@@ -15529,7 +15517,7 @@ History {
                   0,
                 ],
                 [
-                  "98.00000",
+                  100,
                   0,
                 ],
               ],
@@ -15548,8 +15536,8 @@ History {
               "strokeStyle": "solid",
               "strokeWidth": 2,
               "type": "arrow",
-              "width": "98.00000",
-              "x": 1,
+              "width": 100,
+              "x": 0,
               "y": 0,
             },
             "inserted": {
@@ -15878,9 +15866,9 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 12,
+  "version": 10,
   "width": "98.00000",
-  "x": "1.00000",
+  "x": 1,
   "y": 0,
 }
 `;
@@ -16152,7 +16140,7 @@ History {
                   0,
                 ],
                 [
-                  "98.00000",
+                  100,
                   0,
                 ],
               ],
@@ -16171,8 +16159,8 @@ History {
               "strokeStyle": "solid",
               "strokeWidth": 2,
               "type": "arrow",
-              "width": "98.00000",
-              "x": 1,
+              "width": 100,
+              "x": 0,
               "y": 0,
             },
             "inserted": {
@@ -16501,9 +16489,9 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 12,
+  "version": 10,
   "width": "98.00000",
-  "x": "1.00000",
+  "x": 1,
   "y": 0,
 }
 `;
@@ -16775,7 +16763,7 @@ History {
                   0,
                 ],
                 [
-                  "98.00000",
+                  100,
                   0,
                 ],
               ],
@@ -16794,8 +16782,8 @@ History {
               "strokeStyle": "solid",
               "strokeWidth": 2,
               "type": "arrow",
-              "width": "98.00000",
-              "x": 1,
+              "width": 100,
+              "x": 0,
               "y": 0,
             },
             "inserted": {
@@ -17122,9 +17110,9 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 12,
+  "version": 10,
   "width": "98.00000",
-  "x": "1.00000",
+  "x": 1,
   "y": 0,
 }
 `;
@@ -17180,7 +17168,7 @@ History {
                   0,
                 ],
                 [
-                  "98.00000",
+                  100,
                   0,
                 ],
               ],
@@ -17198,7 +17186,7 @@ History {
                   0,
                 ],
                 [
-                  "98.00000",
+                  100,
                   0,
                 ],
               ],
@@ -17467,7 +17455,7 @@ History {
                   0,
                 ],
                 [
-                  "98.00000",
+                  100,
                   0,
                 ],
               ],
@@ -17486,8 +17474,8 @@ History {
               "strokeStyle": "solid",
               "strokeWidth": 2,
               "type": "arrow",
-              "width": "98.00000",
-              "x": 1,
+              "width": 100,
+              "x": 0,
               "y": 0,
             },
             "inserted": {
@@ -17840,9 +17828,9 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 13,
+  "version": 11,
   "width": "98.00000",
-  "x": "1.00000",
+  "x": 1,
   "y": 0,
 }
 `;
@@ -17913,7 +17901,7 @@ History {
                   0,
                 ],
                 [
-                  "98.00000",
+                  100,
                   0,
                 ],
               ],
@@ -17932,7 +17920,7 @@ History {
                   0,
                 ],
                 [
-                  "98.00000",
+                  100,
                   0,
                 ],
               ],
@@ -18201,7 +18189,7 @@ History {
                   0,
                 ],
                 [
-                  "98.00000",
+                  100,
                   0,
                 ],
               ],
@@ -18220,8 +18208,8 @@ History {
               "strokeStyle": "solid",
               "strokeWidth": 2,
               "type": "arrow",
-              "width": "98.00000",
-              "x": 1,
+              "width": 100,
+              "x": 0,
               "y": 0,
             },
             "inserted": {
diff --git a/packages/excalidraw/tests/__snapshots__/move.test.tsx.snap b/packages/excalidraw/tests/__snapshots__/move.test.tsx.snap
index fdd294a30b..654eccfea4 100644
--- a/packages/excalidraw/tests/__snapshots__/move.test.tsx.snap
+++ b/packages/excalidraw/tests/__snapshots__/move.test.tsx.snap
@@ -173,7 +173,7 @@ exports[`move element > rectangles with binding arrow 6`] = `
   "type": "rectangle",
   "updated": 1,
   "version": 7,
-  "versionNonce": 2066753033,
+  "versionNonce": 745419401,
   "width": 300,
   "x": 201,
   "y": 2,
@@ -232,8 +232,8 @@ exports[`move element > rectangles with binding arrow 7`] = `
   "strokeWidth": 2,
   "type": "arrow",
   "updated": 1,
-  "version": 15,
-  "versionNonce": 271613161,
+  "version": 11,
+  "versionNonce": 1996028265,
   "width": 81,
   "x": 110,
   "y": 50,