瀏覽代碼

fix: Re-route elbow arrows when pasted (#8448)

Re-route elbow arrows when pasted
Márk Tolmács 11 月之前
父節點
當前提交
e0a22edfbd
共有 2 個文件被更改,包括 55 次插入13 次删除
  1. 18 2
      packages/excalidraw/components/App.tsx
  2. 37 11
      packages/excalidraw/element/routing.ts

+ 18 - 2
packages/excalidraw/components/App.tsx

@@ -435,7 +435,7 @@ import { actionTextAutoResize } from "../actions/actionTextAutoResize";
 import { getVisibleSceneBounds } from "../element/bounds";
 import { isMaybeMermaidDefinition } from "../mermaid";
 import NewElementCanvas from "./canvases/NewElementCanvas";
-import { mutateElbowArrow } from "../element/routing";
+import { mutateElbowArrow, updateElbowArrow } from "../element/routing";
 import {
   FlowChartCreator,
   FlowChartNavigator,
@@ -3109,7 +3109,23 @@ class App extends React.Component<AppProps, AppState> {
     retainSeed?: boolean;
     fitToContent?: boolean;
   }) => {
-    const elements = restoreElements(opts.elements, null, undefined);
+    let elements = opts.elements.map((el) =>
+      isElbowArrow(el)
+        ? {
+            ...el,
+            ...updateElbowArrow(
+              {
+                ...el,
+                startBinding: null,
+                endBinding: null,
+              },
+              this.scene.getNonDeletedElementsMap(),
+              [el.points[0], el.points[el.points.length - 1]],
+            ),
+          }
+        : el,
+    );
+    elements = restoreElements(elements, null, undefined);
     const [minX, minY, maxX, maxY] = getCommonBounds(elements);
 
     const elementsCenterX = distance(minX, maxX) / 2;

+ 37 - 11
packages/excalidraw/element/routing.ts

@@ -36,6 +36,7 @@ import {
   HEADING_UP,
   vectorToHeading,
 } from "./heading";
+import type { ElementUpdate } from "./mutateElement";
 import { mutateElement } from "./mutateElement";
 import { isBindableElement, isRectanguloidElement } from "./typeChecks";
 import type {
@@ -82,6 +83,39 @@ export const mutateElbowArrow = (
     informMutation?: boolean;
   },
 ) => {
+  const update = updateElbowArrow(
+    arrow,
+    elementsMap,
+    nextPoints,
+    offset,
+    options,
+  );
+  if (update) {
+    mutateElement(
+      arrow,
+      {
+        ...otherUpdates,
+        ...update,
+        angle: 0 as Radians,
+      },
+      options?.informMutation,
+    );
+  } else {
+    console.error("Elbow arrow cannot find a route");
+  }
+};
+
+export const updateElbowArrow = (
+  arrow: ExcalidrawElbowArrowElement,
+  elementsMap: NonDeletedSceneElementsMap | SceneElementsMap,
+  nextPoints: readonly LocalPoint[],
+  offset?: Vector,
+  options?: {
+    isDragging?: boolean;
+    disableBinding?: boolean;
+    informMutation?: boolean;
+  },
+): ElementUpdate<ExcalidrawElbowArrowElement> | null => {
   const origStartGlobalPoint: GlobalPoint = pointTranslate(
     pointTranslate<LocalPoint, GlobalPoint>(
       nextPoints[0],
@@ -297,18 +331,10 @@ export const mutateElbowArrow = (
     startDongle && points.unshift(startGlobalPoint);
     endDongle && points.push(endGlobalPoint);
 
-    mutateElement(
-      arrow,
-      {
-        ...otherUpdates,
-        ...normalizedArrowElementUpdate(simplifyElbowArrowPoints(points), 0, 0),
-        angle: 0 as Radians,
-      },
-      options?.informMutation,
-    );
-  } else {
-    console.error("Elbow arrow cannot find a route");
+    return normalizedArrowElementUpdate(simplifyElbowArrowPoints(points), 0, 0);
   }
+
+  return null;
 };
 
 const offsetFromHeading = (