Răsfoiți Sursa

Position revert

Mark Tolmacs 5 luni în urmă
părinte
comite
5cc5c626df

+ 8 - 29
packages/excalidraw/components/Stats/Angle.tsx

@@ -18,10 +18,7 @@ import type { AppState } from "@excalidraw/excalidraw/types";
 
 import type { Degrees, Radians } from "@excalidraw/math";
 
-import type {
-  ExcalidrawElement,
-  NonDeletedExcalidrawElement,
-} from "@excalidraw/element/types";
+import type { ExcalidrawElement } from "@excalidraw/element/types";
 
 import { angleIcon } from "../icons";
 
@@ -75,14 +72,6 @@ const handleDegreeChange: DragInputCallbackType<AngleProps["property"]> = ({
         mutateElement(boundTextElement, { angle: nextAngle });
       }
 
-      setAppState({
-        suggestedBindings: getSuggestedBindingsForArrows(
-          [latestElement] as NonDeletedExcalidrawElement[],
-          elementsMap,
-          originalAppState.zoom,
-        ),
-      });
-
       return;
     }
 
@@ -114,7 +103,7 @@ const handleDegreeChange: DragInputCallbackType<AngleProps["property"]> = ({
 
     setAppState({
       suggestedBindings: getSuggestedBindingsForArrows(
-        [latestElement] as NonDeletedExcalidrawElement[],
+        [latestElement],
         elementsMap,
         originalAppState.zoom,
       ),
@@ -122,7 +111,7 @@ const handleDegreeChange: DragInputCallbackType<AngleProps["property"]> = ({
   }
 };
 
-const handleFinished: DragFinishedCallbackType = ({
+const handleFinished: DragFinishedCallbackType<AngleProps["property"]> = ({
   originalElements,
   originalAppState,
   scene,
@@ -137,25 +126,15 @@ const handleFinished: DragFinishedCallbackType = ({
 
     if (latestElement) {
       updateBindings(latestElement, elementsMap, originalAppState.zoom, () => {
-        const revertAngle = (latestElement.angle -
-          degreesToRadians(accumulatedChange as Degrees)) as Radians;
+        const change = degreesToRadians(accumulatedChange as Degrees);
 
         mutateElement(latestElement, {
-          angle: revertAngle,
+          angle: (latestElement.angle - change) as Radians,
         });
+      });
 
-        const boundTextElement = getBoundTextElement(
-          latestElement,
-          elementsMap,
-        );
-
-        if (boundTextElement && !isArrowElement(latestElement)) {
-          mutateElement(boundTextElement, { angle: revertAngle });
-        }
-
-        setAppState({
-          suggestedBindings: [],
-        });
+      setAppState({
+        suggestedBindings: [],
       });
     }
   }

+ 17 - 2
packages/excalidraw/components/Stats/DragInput.tsx

@@ -37,10 +37,14 @@ export type DragInputCallbackType<
   setAppState: React.Component<any, AppState>["setState"];
 }) => void;
 
-export type DragFinishedCallbackType<E = ExcalidrawElement> = (props: {
+export type DragFinishedCallbackType<
+  P extends StatsInputProperty,
+  E = ExcalidrawElement,
+> = (props: {
   originalElements: readonly E[];
   originalElementsMap: ElementsMap;
   scene: Scene;
+  property: P;
   originalAppState: AppState;
   accumulatedChange: number;
   setAppState: React.Component<any, AppState>["setState"];
@@ -57,7 +61,7 @@ interface StatsDragInputProps<
   editable?: boolean;
   shouldKeepAspectRatio?: boolean;
   dragInputCallback: DragInputCallbackType<T, E>;
-  dragFinishedCallback?: DragFinishedCallbackType<E>;
+  dragFinishedCallback?: DragFinishedCallbackType<T, E>;
   property: T;
   scene: Scene;
   appState: AppState;
@@ -136,6 +140,7 @@ const StatsDragInput = <
     // reason: idempotent to avoid unnecessary
     if (isNaN(original) || Math.abs(rounded - original) >= SMALLEST_DELTA) {
       stateRef.current.lastUpdatedValue = updatedValue;
+      const originalElementsMap = app.scene.getNonDeletedElementsMap();
       dragInputCallback({
         accumulatedChange: 0,
         instantChange: 0,
@@ -150,6 +155,15 @@ const StatsDragInput = <
         setInputValue: (value) => setInputValue(String(value)),
         setAppState,
       });
+      dragFinishedCallback?.({
+        originalElements: elements,
+        originalElementsMap,
+        scene,
+        originalAppState: appState,
+        accumulatedChange: rounded,
+        property,
+        setAppState,
+      });
       app.syncActionResult({
         captureUpdate: CaptureUpdateAction.IMMEDIATELY,
       });
@@ -303,6 +317,7 @@ const StatsDragInput = <
                   originalElementsMap,
                   scene,
                   originalAppState,
+                  property,
                   accumulatedChange,
                   setAppState,
                 });

+ 60 - 8
packages/excalidraw/components/Stats/Position.tsx

@@ -7,12 +7,17 @@ import {
 import { mutateElement } from "@excalidraw/element/mutateElement";
 import { isImageElement } from "@excalidraw/element/typeChecks";
 
+import { getSuggestedBindingsForArrows } from "@excalidraw/element/binding";
+
 import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types";
 
 import StatsDragInput from "./DragInput";
-import { getStepSizedValue, moveElement } from "./utils";
+import { getStepSizedValue, moveElement, updateBindings } from "./utils";
 
-import type { DragInputCallbackType } from "./DragInput";
+import type {
+  DragFinishedCallbackType,
+  DragInputCallbackType,
+} from "./DragInput";
 import type Scene from "../../scene/Scene";
 import type { AppState } from "../../types";
 
@@ -36,6 +41,7 @@ const handlePositionChange: DragInputCallbackType<"x" | "y"> = ({
   property,
   scene,
   originalAppState,
+  setAppState,
 }) => {
   const elementsMap = scene.getNonDeletedElementsMap();
   const origElement = originalElements[0];
@@ -122,6 +128,14 @@ const handlePositionChange: DragInputCallbackType<"x" | "y"> = ({
       crop: nextCrop,
     });
 
+    setAppState({
+      suggestedBindings: getSuggestedBindingsForArrows(
+        [origElement],
+        elementsMap,
+        originalAppState.zoom,
+      ),
+    });
+
     return;
   }
 
@@ -135,6 +149,7 @@ const handlePositionChange: DragInputCallbackType<"x" | "y"> = ({
       elementsMap,
       originalElementsMap,
     );
+
     return;
   }
 
@@ -166,15 +181,51 @@ const handlePositionChange: DragInputCallbackType<"x" | "y"> = ({
     elementsMap,
     originalElementsMap,
   );
+
+  if (origElement) {
+    const latestElement = elementsMap.get(origElement.id);
+
+    if (latestElement) {
+      setAppState({
+        suggestedBindings: getSuggestedBindingsForArrows(
+          [latestElement],
+          elementsMap,
+          originalAppState.zoom,
+        ),
+      });
+    }
+  }
 };
 
-const Position = ({
-  property,
-  element,
-  elementsMap,
+const handleFinished: DragFinishedCallbackType<"x" | "y"> = ({
+  originalElements,
+  originalAppState,
   scene,
-  appState,
-}: PositionProps) => {
+  accumulatedChange,
+  property,
+  setAppState,
+}) => {
+  const elementsMap = scene.getNonDeletedElementsMap();
+  const origElement = originalElements[0];
+
+  if (origElement) {
+    const latestElement = elementsMap.get(origElement.id);
+
+    if (latestElement) {
+      updateBindings(latestElement, elementsMap, originalAppState.zoom, () => {
+        mutateElement(latestElement, {
+          [property]: latestElement[property] - accumulatedChange,
+        });
+      });
+
+      setAppState({
+        suggestedBindings: [],
+      });
+    }
+  }
+};
+
+const Position = ({ property, element, scene, appState }: PositionProps) => {
   const [topLeftX, topLeftY] = pointRotateRads(
     pointFrom(element.x, element.y),
     pointFrom(element.x + element.width / 2, element.y + element.height / 2),
@@ -202,6 +253,7 @@ const Position = ({
       label={property === "x" ? "X" : "Y"}
       elements={[element]}
       dragInputCallback={handlePositionChange}
+      dragFinishedCallback={handleFinished}
       scene={scene}
       value={value}
       property={property}

+ 2 - 6
packages/excalidraw/components/Stats/utils.ts

@@ -204,7 +204,7 @@ export const updateBindings = (
   latestElement: ExcalidrawElement,
   elementsMap: NonDeletedSceneElementsMap,
   zoom?: AppState["zoom"],
-  remainedBound?: () => void,
+  bindingElementKeptOriginalBinding?: () => void,
 ) => {
   if (isBindingElement(latestElement)) {
     const [start, end] = getOriginalBindingsIfStillCloseToArrowEnds(
@@ -217,7 +217,7 @@ export const updateBindings = (
       (latestElement.startBinding && start) ||
       (latestElement.endBinding && end)
     ) {
-      remainedBound?.();
+      bindingElementKeptOriginalBinding?.();
     } else {
       if (latestElement.startBinding && !start) {
         unbindLinearElement(latestElement, "start");
@@ -227,9 +227,5 @@ export const updateBindings = (
         unbindLinearElement(latestElement, "end");
       }
     }
-
-    // else if (end) {
-    //   updateBoundElements(end, elementsMap);
-    // }
   }
 };