feat: Arrow binding is a preference (#10839)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import {
|
||||
KEYS,
|
||||
arrayToMap,
|
||||
getFeatureFlag,
|
||||
invariant,
|
||||
@@ -137,12 +136,6 @@ export const maxBindingDistance_simple = (zoom?: AppState["zoom"]): number => {
|
||||
);
|
||||
};
|
||||
|
||||
export const shouldEnableBindingForPointerEvent = (
|
||||
event: React.PointerEvent<HTMLElement>,
|
||||
) => {
|
||||
return !event[KEYS.CTRL_OR_CMD];
|
||||
};
|
||||
|
||||
export const isBindingEnabled = (appState: {
|
||||
isBindingEnabled: AppState["isBindingEnabled"];
|
||||
}): boolean => {
|
||||
@@ -177,8 +170,20 @@ export const bindOrUnbindBindingElement = (
|
||||
},
|
||||
);
|
||||
|
||||
bindOrUnbindBindingElementEdge(arrow, start, "start", scene);
|
||||
bindOrUnbindBindingElementEdge(arrow, end, "end", scene);
|
||||
bindOrUnbindBindingElementEdge(
|
||||
arrow,
|
||||
start,
|
||||
"start",
|
||||
scene,
|
||||
appState.isBindingEnabled,
|
||||
);
|
||||
bindOrUnbindBindingElementEdge(
|
||||
arrow,
|
||||
end,
|
||||
"end",
|
||||
scene,
|
||||
appState.isBindingEnabled,
|
||||
);
|
||||
if (start.focusPoint || end.focusPoint) {
|
||||
// If the strategy dictates a focus point override, then
|
||||
// update the arrow points to point to the focus point.
|
||||
@@ -221,12 +226,21 @@ const bindOrUnbindBindingElementEdge = (
|
||||
{ mode, element, focusPoint }: BindingStrategy,
|
||||
startOrEnd: "start" | "end",
|
||||
scene: Scene,
|
||||
shouldSnapToOutline = true,
|
||||
): void => {
|
||||
if (mode === null) {
|
||||
// null means break the binding
|
||||
unbindBindingElement(arrow, startOrEnd, scene);
|
||||
} else if (mode !== undefined) {
|
||||
bindBindingElement(arrow, element, mode, startOrEnd, scene, focusPoint);
|
||||
bindBindingElement(
|
||||
arrow,
|
||||
element,
|
||||
mode,
|
||||
startOrEnd,
|
||||
scene,
|
||||
focusPoint,
|
||||
shouldSnapToOutline,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -798,6 +812,7 @@ const getBindingStrategyForDraggingBindingElementEndpoints_simple = (
|
||||
startDragged ? "start" : "end",
|
||||
elementsMap,
|
||||
appState.zoom,
|
||||
appState.isMidpointSnappingEnabled,
|
||||
) || globalPoint,
|
||||
}
|
||||
: { mode: null };
|
||||
@@ -842,6 +857,7 @@ const getBindingStrategyForDraggingBindingElementEndpoints_simple = (
|
||||
startDragged ? "end" : "start",
|
||||
elementsMap,
|
||||
appState.zoom,
|
||||
appState.isMidpointSnappingEnabled,
|
||||
) || otherEndpoint,
|
||||
}
|
||||
: { mode: undefined }
|
||||
@@ -1005,6 +1021,7 @@ export const bindBindingElement = (
|
||||
startOrEnd: "start" | "end",
|
||||
scene: Scene,
|
||||
focusPoint?: GlobalPoint,
|
||||
shouldSnapToOutline = true,
|
||||
): void => {
|
||||
const elementsMap = scene.getNonDeletedElementsMap();
|
||||
|
||||
@@ -1019,6 +1036,7 @@ export const bindBindingElement = (
|
||||
hoveredElement,
|
||||
startOrEnd,
|
||||
elementsMap,
|
||||
shouldSnapToOutline,
|
||||
),
|
||||
};
|
||||
} else {
|
||||
@@ -1352,6 +1370,7 @@ export const bindPointToSnapToElementOutline = (
|
||||
startOrEnd: "start" | "end",
|
||||
elementsMap: ElementsMap,
|
||||
customIntersector?: LineSegment<GlobalPoint>,
|
||||
isMidpointSnappingEnabled = true,
|
||||
): GlobalPoint => {
|
||||
const elbowed = isElbowArrow(arrowElement);
|
||||
const point = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
||||
@@ -1391,13 +1410,9 @@ export const bindPointToSnapToElementOutline = (
|
||||
const isHorizontal = headingIsHorizontal(
|
||||
headingForPointFromElement(bindableElement, aabb, point),
|
||||
);
|
||||
const snapPoint = snapToMid(
|
||||
bindableElement,
|
||||
elementsMap,
|
||||
edgePoint,
|
||||
0.05,
|
||||
arrowElement,
|
||||
);
|
||||
const snapPoint = isMidpointSnappingEnabled
|
||||
? snapToMid(bindableElement, elementsMap, edgePoint, 0.05, arrowElement)
|
||||
: undefined;
|
||||
const resolved = snapPoint || point;
|
||||
const otherPoint = pointFrom<GlobalPoint>(
|
||||
isHorizontal ? bindableCenter[0] : resolved[0],
|
||||
@@ -1892,6 +1907,8 @@ export const calculateFixedPointForElbowArrowBinding = (
|
||||
hoveredElement: ExcalidrawBindableElement,
|
||||
startOrEnd: "start" | "end",
|
||||
elementsMap: ElementsMap,
|
||||
shouldSnapToOutline = true,
|
||||
isMidpointSnappingEnabled = true,
|
||||
): { fixedPoint: FixedPoint } => {
|
||||
const bounds = [
|
||||
hoveredElement.x,
|
||||
@@ -1899,12 +1916,20 @@ export const calculateFixedPointForElbowArrowBinding = (
|
||||
hoveredElement.x + hoveredElement.width,
|
||||
hoveredElement.y + hoveredElement.height,
|
||||
] as Bounds;
|
||||
const snappedPoint = bindPointToSnapToElementOutline(
|
||||
linearElement,
|
||||
hoveredElement,
|
||||
startOrEnd,
|
||||
elementsMap,
|
||||
);
|
||||
const snappedPoint = shouldSnapToOutline
|
||||
? bindPointToSnapToElementOutline(
|
||||
linearElement,
|
||||
hoveredElement,
|
||||
startOrEnd,
|
||||
elementsMap,
|
||||
undefined,
|
||||
isMidpointSnappingEnabled,
|
||||
)
|
||||
: LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
||||
linearElement,
|
||||
startOrEnd === "start" ? 0 : -1,
|
||||
elementsMap,
|
||||
);
|
||||
const globalMidPoint = pointFrom(
|
||||
bounds[0] + (bounds[2] - bounds[0]) / 2,
|
||||
bounds[1] + (bounds[3] - bounds[1]) / 2,
|
||||
|
||||
Reference in New Issue
Block a user