mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
[skip ci] Stats binding behavior changes and test updates
This commit is contained in:
parent
ce10087edc
commit
db9e501d35
5 changed files with 50 additions and 18 deletions
|
@ -541,7 +541,7 @@ const isLinearElementSimple = (
|
|||
linearElement: NonDeleted<ExcalidrawLinearElement>,
|
||||
): boolean => linearElement.points.length < 3;
|
||||
|
||||
const unbindLinearElement = (
|
||||
export const unbindLinearElement = (
|
||||
linearElement: NonDeleted<ExcalidrawLinearElement>,
|
||||
startOrEnd: "start" | "end",
|
||||
): ExcalidrawBindableElement["id"] | null => {
|
||||
|
|
|
@ -130,7 +130,7 @@ export const isLinearElementType = (
|
|||
export const isBindingElement = (
|
||||
element?: ExcalidrawElement | null,
|
||||
includeLocked = true,
|
||||
): element is ExcalidrawLinearElement => {
|
||||
): element is ExcalidrawArrowElement => {
|
||||
return (
|
||||
element != null &&
|
||||
(!element.locked || includeLocked === true) &&
|
||||
|
|
|
@ -12,7 +12,7 @@ import type { ExcalidrawElement } from "@excalidraw/element/types";
|
|||
import { angleIcon } from "../icons";
|
||||
|
||||
import DragInput from "./DragInput";
|
||||
import { getStepSizedValue, isPropertyEditable } from "./utils";
|
||||
import { getStepSizedValue, isPropertyEditable, updateBindings } from "./utils";
|
||||
|
||||
import type { DragInputCallbackType } from "./DragInput";
|
||||
import type Scene from "../../scene/Scene";
|
||||
|
@ -47,6 +47,7 @@ const handleDegreeChange: DragInputCallbackType<AngleProps["property"]> = ({
|
|||
mutateElement(latestElement, {
|
||||
angle: nextAngle,
|
||||
});
|
||||
updateBindings(latestElement, elementsMap);
|
||||
|
||||
const boundTextElement = getBoundTextElement(latestElement, elementsMap);
|
||||
if (boundTextElement && !isArrowElement(latestElement)) {
|
||||
|
@ -72,6 +73,7 @@ const handleDegreeChange: DragInputCallbackType<AngleProps["property"]> = ({
|
|||
mutateElement(latestElement, {
|
||||
angle: nextAngle,
|
||||
});
|
||||
updateBindings(latestElement, elementsMap);
|
||||
|
||||
const boundTextElement = getBoundTextElement(latestElement, elementsMap);
|
||||
if (boundTextElement && !isArrowElement(latestElement)) {
|
||||
|
|
|
@ -140,7 +140,9 @@ describe("binding with linear elements", () => {
|
|||
expect(linear.startBinding).not.toBe(null);
|
||||
});
|
||||
|
||||
it("should remain bound to linear element on small angle change", async () => {
|
||||
// UX RATIONALE: Since we force a fixed distance from elements angle changes
|
||||
// would result in a "jump" the moment the bound object is moved
|
||||
it("should not remain bound to linear element on any angle change", async () => {
|
||||
const linear = h.elements[1] as ExcalidrawLinearElement;
|
||||
const inputAngle = UI.queryStatsProperty("A")?.querySelector(
|
||||
".drag-input",
|
||||
|
@ -148,7 +150,7 @@ describe("binding with linear elements", () => {
|
|||
|
||||
expect(linear.startBinding).not.toBe(null);
|
||||
UI.updateInput(inputAngle, String("1"));
|
||||
expect(linear.startBinding).not.toBe(null);
|
||||
expect(linear.startBinding).toBe(null);
|
||||
});
|
||||
|
||||
it("should unbind linear element on large position change", async () => {
|
||||
|
|
|
@ -3,6 +3,8 @@ import { pointFrom, pointRotateRads } from "@excalidraw/math";
|
|||
import { mutateElement } from "@excalidraw/element/mutateElement";
|
||||
import { getBoundTextElement } from "@excalidraw/element/textElement";
|
||||
import {
|
||||
isBindableElement,
|
||||
isBindingElement,
|
||||
isFrameLikeElement,
|
||||
isTextElement,
|
||||
} from "@excalidraw/element/typeChecks";
|
||||
|
@ -13,6 +15,11 @@ import {
|
|||
isInGroup,
|
||||
} from "@excalidraw/element/groups";
|
||||
|
||||
import {
|
||||
unbindLinearElement,
|
||||
updateBoundElements,
|
||||
} from "@excalidraw/element/binding";
|
||||
|
||||
import type { Radians } from "@excalidraw/math";
|
||||
|
||||
import type {
|
||||
|
@ -152,6 +159,8 @@ export const moveElement = (
|
|||
shouldInformMutation,
|
||||
);
|
||||
|
||||
updateBindings(latestElement, elementsMap);
|
||||
|
||||
const boundTextElement = getBoundTextElement(
|
||||
originalElement,
|
||||
originalElementsMap,
|
||||
|
@ -190,3 +199,22 @@ export const getAtomicUnits = (
|
|||
});
|
||||
return _atomicUnits;
|
||||
};
|
||||
|
||||
export const updateBindings = (
|
||||
latestElement: ExcalidrawElement,
|
||||
elementsMap: NonDeletedSceneElementsMap,
|
||||
options?: {
|
||||
simultaneouslyUpdated?: readonly ExcalidrawElement[];
|
||||
},
|
||||
) => {
|
||||
if (isBindingElement(latestElement)) {
|
||||
if (latestElement.startBinding) {
|
||||
unbindLinearElement(latestElement, "start");
|
||||
}
|
||||
if (latestElement.endBinding) {
|
||||
unbindLinearElement(latestElement, "end");
|
||||
}
|
||||
} else if (isBindableElement(latestElement)) {
|
||||
updateBoundElements(latestElement, elementsMap, options);
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue