瀏覽代碼

include arrowheads in bounds

Ryan Di 1 年之前
父節點
當前提交
795511ee6b
共有 2 個文件被更改,包括 51 次插入19 次删除
  1. 39 8
      packages/excalidraw/element/bounds.ts
  2. 12 11
      packages/excalidraw/element/linearElementEditor.ts

+ 39 - 8
packages/excalidraw/element/bounds.ts

@@ -701,14 +701,45 @@ const getLinearElementRotatedBounds = (
     return coords;
     return coords;
   }
   }
 
 
-  // first element is always the curve
-  const cachedShape = ShapeCache.get(element)?.[0];
-  const shape = cachedShape ?? generateLinearElementShape(element);
-  const ops = getCurvePathOps(shape);
-  const transformXY = (x: number, y: number) =>
-    rotate(element.x + x, element.y + y, cx, cy, element.angle);
-  const res = getMinMaxXYFromCurvePathOps(ops, transformXY);
-  let coords: Bounds = [res[0], res[1], res[2], res[3]];
+  const cachedShape =
+    ShapeCache.get(element) ?? ShapeCache.generateElementShape(element, null);
+
+  const [arrowCurve, ...arrowhead] = cachedShape;
+
+  let coords = getMinMaxXYFromCurvePathOps(
+    getCurvePathOps(arrowCurve),
+    (x: number, y: number) =>
+      rotate(element.x + x, element.y + y, cx, cy, element.angle),
+  );
+
+  for (const shape of arrowhead) {
+    let [minX, minY, maxX, maxY] = getMinMaxXYFromCurvePathOps(
+      getCurvePathOps(shape),
+    );
+
+    [minX, minY] = rotate(
+      minX + element.x,
+      minY + element.y,
+      cx,
+      cy,
+      element.angle,
+    );
+    [maxX, maxY] = rotate(
+      maxX + element.x,
+      maxY + element.y,
+      cx,
+      cy,
+      element.angle,
+    );
+
+    coords = [
+      Math.min(minX, coords[0]),
+      Math.min(minY, coords[1]),
+      Math.max(maxX, coords[2]),
+      Math.max(maxY, coords[3]),
+    ];
+  }
+
   const boundTextElement = getBoundTextElement(element);
   const boundTextElement = getBoundTextElement(element);
   if (boundTextElement) {
   if (boundTextElement) {
     const coordsWithBoundText = LinearElementEditor.getMinMaxXYWithBoundText(
     const coordsWithBoundText = LinearElementEditor.getMinMaxXYWithBoundText(

+ 12 - 11
packages/excalidraw/element/linearElementEditor.ts

@@ -1421,10 +1421,10 @@ export class LinearElementEditor {
     includeBoundText: boolean = false,
     includeBoundText: boolean = false,
   ): [number, number, number, number, number, number] => {
   ): [number, number, number, number, number, number] => {
     let coords: [number, number, number, number, number, number];
     let coords: [number, number, number, number, number, number];
-    let x1;
-    let y1;
-    let x2;
-    let y2;
+    let x1 = Infinity;
+    let y1 = Infinity;
+    let x2 = -Infinity;
+    let y2 = -Infinity;
     if (element.points.length < 2 || !ShapeCache.get(element)) {
     if (element.points.length < 2 || !ShapeCache.get(element)) {
       // XXX this is just a poor estimate and not very useful
       // XXX this is just a poor estimate and not very useful
       const { minX, minY, maxX, maxY } = element.points.reduce(
       const { minX, minY, maxX, maxY } = element.points.reduce(
@@ -1446,14 +1446,15 @@ export class LinearElementEditor {
     } else {
     } else {
       const shape = ShapeCache.generateElementShape(element, null);
       const shape = ShapeCache.generateElementShape(element, null);
 
 
-      // first element is always the curve
-      const ops = getCurvePathOps(shape[0]);
+      for (const s of shape) {
+        const ops = getCurvePathOps(s);
 
 
-      const [minX, minY, maxX, maxY] = getMinMaxXYFromCurvePathOps(ops);
-      x1 = minX + element.x;
-      y1 = minY + element.y;
-      x2 = maxX + element.x;
-      y2 = maxY + element.y;
+        const [minX, minY, maxX, maxY] = getMinMaxXYFromCurvePathOps(ops);
+        x1 = Math.min(minX + element.x, x1);
+        y1 = Math.min(minY + element.y, y1);
+        x2 = Math.max(maxX + element.x, x2);
+        y2 = Math.max(maxY + element.y, y2);
+      }
     }
     }
     const cx = (x1 + x2) / 2;
     const cx = (x1 + x2) / 2;
     const cy = (y1 + y2) / 2;
     const cy = (y1 + y2) / 2;