fix: Center point for linears

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
Mark Tolmacs
2025-11-18 12:50:11 +01:00
parent 66d021a19e
commit 534da13a60
3 changed files with 27 additions and 21 deletions

View File

@@ -4,6 +4,7 @@ import {
getFeatureFlag, getFeatureFlag,
invariant, invariant,
isTransparent, isTransparent,
randomId,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { import {
@@ -1200,16 +1201,12 @@ export const bindPointToSnapToElementOutline = (
startOrEnd: "start" | "end", startOrEnd: "start" | "end",
elementsMap: ElementsMap, elementsMap: ElementsMap,
customIntersector?: LineSegment<GlobalPoint>, customIntersector?: LineSegment<GlobalPoint>,
ignoreFrameCutouts?: boolean,
): GlobalPoint => { ): GlobalPoint => {
const aabb = aabbForElement(bindableElement, elementsMap); const aabb = aabbForElement(bindableElement, elementsMap);
const localPoint = const point = LinearElementEditor.getPointAtIndexGlobalCoordinates(
arrowElement.points[ arrowElement,
startOrEnd === "start" ? 0 : arrowElement.points.length - 1 startOrEnd === "start" ? 0 : -1,
]; elementsMap,
const point = pointFrom<GlobalPoint>(
arrowElement.x + localPoint[0],
arrowElement.y + localPoint[1],
); );
if (arrowElement.points.length < 2) { if (arrowElement.points.length < 2) {
@@ -1222,17 +1219,11 @@ export const bindPointToSnapToElementOutline = (
: point; : point;
const elbowed = isElbowArrow(arrowElement); const elbowed = isElbowArrow(arrowElement);
const center = getCenterForBounds(aabb); const center = getCenterForBounds(aabb);
const adjacentPointIdx = const adjacentPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
startOrEnd === "start" ? 1 : arrowElement.points.length - 2; arrowElement,
const adjacentPoint = pointRotateRads( startOrEnd === "start" ? 1 : -2,
pointFrom<GlobalPoint>( elementsMap,
arrowElement.x + arrowElement.points[adjacentPointIdx][0],
arrowElement.y + arrowElement.points[adjacentPointIdx][1],
),
center,
arrowElement.angle ?? 0,
); );
const bindingGap = getBindingGap(bindableElement, arrowElement); const bindingGap = getBindingGap(bindableElement, arrowElement);
let intersection: GlobalPoint | null = null; let intersection: GlobalPoint | null = null;
@@ -1624,7 +1615,6 @@ export const updateBoundPoint = (
} }
const isNested = (arrowTooShort || isOverlapping) && isLargerThanOther; const isNested = (arrowTooShort || isOverlapping) && isLargerThanOther;
const maybeOutlineGlobal = const maybeOutlineGlobal =
binding.mode === "orbit" && bindableElement binding.mode === "orbit" && bindableElement
? isNested ? isNested
@@ -1632,6 +1622,7 @@ export const updateBoundPoint = (
: bindPointToSnapToElementOutline( : bindPointToSnapToElementOutline(
{ {
...arrow, ...arrow,
id: randomId(),
x: pointIndex === 0 ? global[0] : arrow.x, x: pointIndex === 0 ? global[0] : arrow.x,
y: pointIndex === 0 ? global[1] : arrow.y, y: pointIndex === 0 ? global[1] : arrow.y,
points: points:

View File

@@ -1276,7 +1276,15 @@ export const elementCenterPoint = (
xOffset: number = 0, xOffset: number = 0,
yOffset: number = 0, yOffset: number = 0,
) => { ) => {
const [x, y] = getCenterForBounds(getElementBounds(element, elementsMap)); if (isLinearElement(element)) {
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
const [x, y] = pointFrom<GlobalPoint>((x1 + x2) / 2, (y1 + y2) / 2);
return pointFrom<GlobalPoint>(x + xOffset, y + yOffset);
}
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
const [x, y] = pointFrom<GlobalPoint>((x1 + x2) / 2, (y1 + y2) / 2);
return pointFrom<GlobalPoint>(x + xOffset, y + yOffset); return pointFrom<GlobalPoint>(x + xOffset, y + yOffset);
}; };

View File

@@ -22,6 +22,9 @@ import {
invariant, invariant,
isShallowEqual, isShallowEqual,
getFeatureFlag, getFeatureFlag,
debugDrawPoint,
debugDrawLine,
randomId,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { import {
@@ -51,6 +54,7 @@ import {
updateBoundPoint, updateBoundPoint,
} from "./binding"; } from "./binding";
import { import {
elementCenterPoint,
getElementAbsoluteCoords, getElementAbsoluteCoords,
getElementPointsCoords, getElementPointsCoords,
getMinMaxXYFromCurvePathOps, getMinMaxXYFromCurvePathOps,
@@ -2275,9 +2279,12 @@ const pointDraggingUpdates = (
element.points[element.points.length - 1][1] + deltaY, element.points[element.points.length - 1][1] + deltaY,
) )
: element.points[element.points.length - 1]; : element.points[element.points.length - 1];
debugDrawPoint(pointFrom<GlobalPoint>(element.x, element.y));
const nextArrow = { const nextArrow = {
...element, ...element,
id: randomId(),
x: 0,
y: 0,
points: [ points: [
offsetStartLocalPoint, offsetStartLocalPoint,
...element.points ...element.points