Преглед на файлове

Apply outline tracking to simple arrows as well

Signed-off-by: Mark Tolmacs <[email protected]>
Mark Tolmacs преди 5 месеца
родител
ревизия
154855916b
променени са 3 файла, в които са добавени 68 реда и са изтрити 9 реда
  1. 26 1
      packages/element/src/binding.ts
  2. 42 7
      packages/element/src/linearElementEditor.ts
  3. 0 1
      packages/excalidraw/components/App.tsx

+ 26 - 1
packages/element/src/binding.ts

@@ -965,6 +965,7 @@ export const bindPointToSnapToElementOutline = (
           ),
           otherPoint,
         ),
+        adjacentPoint,
       ),
     ).sort(
       (g, h) =>
@@ -1016,7 +1017,31 @@ export const bindPointToSnapToElementOutline = (
     );
   }
 
-  return edgePoint;
+  const currentDistance = pointDistance(edgePoint, center);
+  const fullDistance = Math.max(
+    pointDistance(intersection ?? edgePoint, center),
+    1e-5, // Avoid division by zero
+  );
+  const ratio = round(currentDistance / fullDistance);
+
+  switch (true) {
+    case ratio > 0.5:
+      return pointFromVector(
+        vectorScale(
+          vectorNormalize(
+            vectorFromPoint(intersection ?? center, adjacentPoint),
+          ),
+          -FIXED_BINDING_DISTANCE,
+        ),
+        intersection ?? edgePoint,
+      );
+    default:
+      if (elbowed) {
+        return headingToMidBindPoint(edgePoint, bindableElement, aabb);
+      }
+
+      return edgePoint;
+  }
 };
 
 export const avoidRectangularCorner = (

+ 42 - 7
packages/element/src/linearElementEditor.ts

@@ -257,7 +257,7 @@ export class LinearElementEditor {
       return null;
     }
     const { elementId } = linearElementEditor;
-    const elementsMap = scene.getNonDeletedElementsMap();
+    const elementsMap = app.scene.getNonDeletedElementsMap();
     const element = LinearElementEditor.getElement(elementId, elementsMap);
     if (!element) {
       return null;
@@ -333,19 +333,54 @@ export class LinearElementEditor {
         LinearElementEditor.movePoints(
           element,
           selectedPointsIndices.map((pointIndex) => {
+            let p = pointFrom<GlobalPoint>(
+              element.x + element.points[pointIndex][0] + deltaX,
+              element.y + element.points[pointIndex][1] + deltaY,
+            );
+            if (
+              pointIndex === lastClickedPoint &&
+              (pointIndex === 0 || pointIndex === element.points.length - 1)
+            ) {
+              const hoveredElement = getHoveredElementForBinding(
+                {
+                  x: scenePointerX,
+                  y: scenePointerY,
+                },
+                app.scene.getNonDeletedElements(),
+                app.scene.getNonDeletedElementsMap(),
+                app.state.zoom,
+                isElbowArrow(element),
+                isElbowArrow(element),
+              );
+              if (hoveredElement) {
+                const newPoints = Array.from(element.points);
+                newPoints[pointIndex] = pointFrom(
+                  element.points[pointIndex][0] + deltaX,
+                  element.points[pointIndex][1] + deltaY,
+                );
+                p = bindPointToSnapToElementOutline(
+                  {
+                    ...element,
+                    points: newPoints,
+                  },
+                  hoveredElement,
+                  pointIndex === 0 ? "start" : "end",
+                );
+              }
+            }
+
             const newPointPosition: LocalPoint =
               pointIndex === lastClickedPoint
                 ? LinearElementEditor.createPointAt(
                     element,
                     elementsMap,
-                    scenePointerX - linearElementEditor.pointerOffset.x,
-                    scenePointerY - linearElementEditor.pointerOffset.y,
+                    p[0],
+                    p[1],
+                    // p[0] - linearElementEditor.pointerOffset.x,
+                    // p[1] - linearElementEditor.pointerOffset.y,
                     event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),
                   )
-                : pointFrom(
-                    element.points[pointIndex][0] + deltaX,
-                    element.points[pointIndex][1] + deltaY,
-                  );
+                : pointFrom(p[0] - element.x, p[1] - element.y);
             return {
               index: pointIndex,
               point: newPointPosition,

+ 0 - 1
packages/excalidraw/components/App.tsx

@@ -8237,7 +8237,6 @@ class App extends React.Component<AppProps, AppState> {
             );
           },
           linearElementEditor,
-          this.scene,
         );
         if (newLinearElementEditor) {
           pointerDownState.lastCoords.x = pointerCoords.x;