fix: Arrow conversion regression (#9241)
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
parent
21ffaf4d76
commit
30983d801a
@ -111,6 +111,8 @@ import {
|
|||||||
tupleToCoors,
|
tupleToCoors,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
|
|
||||||
|
import { updateElbowArrowPoints } from "../element/elbowArrow";
|
||||||
|
|
||||||
import { register } from "./register";
|
import { register } from "./register";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
@ -1572,7 +1574,7 @@ export const actionChangeArrowType = register({
|
|||||||
if (!isArrowElement(el)) {
|
if (!isArrowElement(el)) {
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
const newElement = newElementWith(el, {
|
let newElement = newElementWith(el, {
|
||||||
roundness:
|
roundness:
|
||||||
value === ARROW_TYPE.round
|
value === ARROW_TYPE.round
|
||||||
? {
|
? {
|
||||||
@ -1587,6 +1589,8 @@ export const actionChangeArrowType = register({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (isElbowArrow(newElement)) {
|
if (isElbowArrow(newElement)) {
|
||||||
|
newElement.fixedSegments = null;
|
||||||
|
|
||||||
const elementsMap = app.scene.getNonDeletedElementsMap();
|
const elementsMap = app.scene.getNonDeletedElementsMap();
|
||||||
|
|
||||||
app.dismissLinearEditor();
|
app.dismissLinearEditor();
|
||||||
@ -1661,14 +1665,9 @@ export const actionChangeArrowType = register({
|
|||||||
endHoveredElement &&
|
endHoveredElement &&
|
||||||
bindLinearElement(newElement, endHoveredElement, "end", elementsMap);
|
bindLinearElement(newElement, endHoveredElement, "end", elementsMap);
|
||||||
|
|
||||||
mutateElement(newElement, {
|
const startBinding =
|
||||||
points: [finalStartPoint, finalEndPoint].map(
|
startElement && newElement.startBinding
|
||||||
(p): LocalPoint =>
|
|
||||||
pointFrom(p[0] - newElement.x, p[1] - newElement.y),
|
|
||||||
),
|
|
||||||
...(startElement && newElement.startBinding
|
|
||||||
? {
|
? {
|
||||||
startBinding: {
|
|
||||||
// @ts-ignore TS cannot discern check above
|
// @ts-ignore TS cannot discern check above
|
||||||
...newElement.startBinding!,
|
...newElement.startBinding!,
|
||||||
...calculateFixedPointForElbowArrowBinding(
|
...calculateFixedPointForElbowArrowBinding(
|
||||||
@ -1677,12 +1676,11 @@ export const actionChangeArrowType = register({
|
|||||||
"start",
|
"start",
|
||||||
elementsMap,
|
elementsMap,
|
||||||
),
|
),
|
||||||
},
|
|
||||||
}
|
}
|
||||||
: {}),
|
: null;
|
||||||
...(endElement && newElement.endBinding
|
const endBinding =
|
||||||
|
endElement && newElement.endBinding
|
||||||
? {
|
? {
|
||||||
endBinding: {
|
|
||||||
// @ts-ignore TS cannot discern check above
|
// @ts-ignore TS cannot discern check above
|
||||||
...newElement.endBinding,
|
...newElement.endBinding,
|
||||||
...calculateFixedPointForElbowArrowBinding(
|
...calculateFixedPointForElbowArrowBinding(
|
||||||
@ -1691,16 +1689,47 @@ export const actionChangeArrowType = register({
|
|||||||
"end",
|
"end",
|
||||||
elementsMap,
|
elementsMap,
|
||||||
),
|
),
|
||||||
},
|
|
||||||
}
|
}
|
||||||
: {}),
|
: null;
|
||||||
});
|
|
||||||
|
newElement = {
|
||||||
|
...newElement,
|
||||||
|
startBinding,
|
||||||
|
endBinding,
|
||||||
|
...updateElbowArrowPoints(newElement, elementsMap, {
|
||||||
|
points: [finalStartPoint, finalEndPoint].map(
|
||||||
|
(p): LocalPoint =>
|
||||||
|
pointFrom(p[0] - newElement.x, p[1] - newElement.y),
|
||||||
|
),
|
||||||
|
startBinding,
|
||||||
|
endBinding,
|
||||||
|
fixedSegments: null,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
LinearElementEditor.updateEditorMidPointsCache(
|
LinearElementEditor.updateEditorMidPointsCache(
|
||||||
newElement,
|
newElement,
|
||||||
elementsMap,
|
elementsMap,
|
||||||
app.state,
|
app.state,
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
const elementsMap = app.scene.getNonDeletedElementsMap();
|
||||||
|
if (newElement.startBinding) {
|
||||||
|
const startElement = elementsMap.get(
|
||||||
|
newElement.startBinding.elementId,
|
||||||
|
) as ExcalidrawBindableElement;
|
||||||
|
if (startElement) {
|
||||||
|
bindLinearElement(newElement, startElement, "start", elementsMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newElement.endBinding) {
|
||||||
|
const endElement = elementsMap.get(
|
||||||
|
newElement.endBinding.elementId,
|
||||||
|
) as ExcalidrawBindableElement;
|
||||||
|
if (endElement) {
|
||||||
|
bindLinearElement(newElement, endElement, "end", elementsMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newElement;
|
return newElement;
|
||||||
|
@ -487,20 +487,8 @@ export const bindLinearElement = (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const binding: PointBinding | FixedPointBinding = {
|
let binding: PointBinding | FixedPointBinding = {
|
||||||
elementId: hoveredElement.id,
|
elementId: hoveredElement.id,
|
||||||
...(isElbowArrow(linearElement)
|
|
||||||
? {
|
|
||||||
...calculateFixedPointForElbowArrowBinding(
|
|
||||||
linearElement,
|
|
||||||
hoveredElement,
|
|
||||||
startOrEnd,
|
|
||||||
elementsMap,
|
|
||||||
),
|
|
||||||
focus: 0,
|
|
||||||
gap: 0,
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
...normalizePointBinding(
|
...normalizePointBinding(
|
||||||
calculateFocusAndGap(
|
calculateFocusAndGap(
|
||||||
linearElement,
|
linearElement,
|
||||||
@ -510,9 +498,20 @@ export const bindLinearElement = (
|
|||||||
),
|
),
|
||||||
hoveredElement,
|
hoveredElement,
|
||||||
),
|
),
|
||||||
}),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (isElbowArrow(linearElement)) {
|
||||||
|
binding = {
|
||||||
|
...binding,
|
||||||
|
...calculateFixedPointForElbowArrowBinding(
|
||||||
|
linearElement,
|
||||||
|
hoveredElement,
|
||||||
|
startOrEnd,
|
||||||
|
elementsMap,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
mutateElement(linearElement, {
|
mutateElement(linearElement, {
|
||||||
[startOrEnd === "start" ? "startBinding" : "endBinding"]: binding,
|
[startOrEnd === "start" ? "startBinding" : "endBinding"]: binding,
|
||||||
});
|
});
|
||||||
@ -1272,13 +1271,16 @@ const updateBoundPoint = (
|
|||||||
pointDistance(adjacentPoint, edgePointAbsolute) +
|
pointDistance(adjacentPoint, edgePointAbsolute) +
|
||||||
pointDistance(adjacentPoint, center) +
|
pointDistance(adjacentPoint, center) +
|
||||||
Math.max(bindableElement.width, bindableElement.height) * 2;
|
Math.max(bindableElement.width, bindableElement.height) * 2;
|
||||||
const intersections = intersectElementWithLineSegment(
|
const intersections = [
|
||||||
|
...intersectElementWithLineSegment(
|
||||||
bindableElement,
|
bindableElement,
|
||||||
lineSegment<GlobalPoint>(
|
lineSegment<GlobalPoint>(
|
||||||
adjacentPoint,
|
adjacentPoint,
|
||||||
pointFromVector(
|
pointFromVector(
|
||||||
vectorScale(
|
vectorScale(
|
||||||
vectorNormalize(vectorFromPoint(focusPointAbsolute, adjacentPoint)),
|
vectorNormalize(
|
||||||
|
vectorFromPoint(focusPointAbsolute, adjacentPoint),
|
||||||
|
),
|
||||||
interceptorLength,
|
interceptorLength,
|
||||||
),
|
),
|
||||||
adjacentPoint,
|
adjacentPoint,
|
||||||
@ -1288,23 +1290,16 @@ const updateBoundPoint = (
|
|||||||
).sort(
|
).sort(
|
||||||
(g, h) =>
|
(g, h) =>
|
||||||
pointDistanceSq(g, adjacentPoint) - pointDistanceSq(h, adjacentPoint),
|
pointDistanceSq(g, adjacentPoint) - pointDistanceSq(h, adjacentPoint),
|
||||||
);
|
),
|
||||||
|
// Fallback when arrow doesn't point to the shape
|
||||||
// debugClear();
|
pointFromVector(
|
||||||
// debugDrawPoint(intersections[0], { color: "red", permanent: true });
|
vectorScale(
|
||||||
// debugDrawLine(
|
vectorNormalize(vectorFromPoint(focusPointAbsolute, adjacentPoint)),
|
||||||
// lineSegment<GlobalPoint>(
|
pointDistance(adjacentPoint, edgePointAbsolute),
|
||||||
// adjacentPoint,
|
),
|
||||||
// pointFromVector(
|
adjacentPoint,
|
||||||
// vectorScale(
|
),
|
||||||
// vectorNormalize(vectorFromPoint(focusPointAbsolute, adjacentPoint)),
|
];
|
||||||
// interceptorLength,
|
|
||||||
// ),
|
|
||||||
// adjacentPoint,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// { permanent: true, color: "green" },
|
|
||||||
// );
|
|
||||||
|
|
||||||
if (intersections.length > 1) {
|
if (intersections.length > 1) {
|
||||||
// The adjacent point is outside the shape (+ gap)
|
// The adjacent point is outside the shape (+ gap)
|
||||||
@ -1727,21 +1722,6 @@ const determineFocusDistance = (
|
|||||||
)
|
)
|
||||||
.sort((g, h) => Math.abs(g) - Math.abs(h));
|
.sort((g, h) => Math.abs(g) - Math.abs(h));
|
||||||
|
|
||||||
// debugClear();
|
|
||||||
// [
|
|
||||||
// lineSegmentIntersectionPoints(rotatedInterceptor, interceptees[0]),
|
|
||||||
// lineSegmentIntersectionPoints(rotatedInterceptor, interceptees[1]),
|
|
||||||
// ]
|
|
||||||
// .filter((p): p is GlobalPoint => p !== null)
|
|
||||||
// .forEach((p) => debugDrawPoint(p, { color: "black", permanent: true }));
|
|
||||||
// debugDrawPoint(determineFocusPoint(element, ordered[0] ?? 0, rotatedA), {
|
|
||||||
// color: "red",
|
|
||||||
// permanent: true,
|
|
||||||
// });
|
|
||||||
// debugDrawLine(rotatedInterceptor, { color: "green", permanent: true });
|
|
||||||
// debugDrawLine(interceptees[0], { color: "red", permanent: true });
|
|
||||||
// debugDrawLine(interceptees[1], { color: "red", permanent: true });
|
|
||||||
|
|
||||||
const signedDistanceRatio = ordered[0] ?? 0;
|
const signedDistanceRatio = ordered[0] ?? 0;
|
||||||
|
|
||||||
return signedDistanceRatio;
|
return signedDistanceRatio;
|
||||||
|
@ -998,23 +998,32 @@ export const updateElbowArrowPoints = (
|
|||||||
// 0. During all element replacement in the scene, we just need to renormalize
|
// 0. During all element replacement in the scene, we just need to renormalize
|
||||||
// the arrow
|
// the arrow
|
||||||
// TODO (dwelle,mtolmacs): Remove this once Scene.getScene() is removed
|
// TODO (dwelle,mtolmacs): Remove this once Scene.getScene() is removed
|
||||||
|
const {
|
||||||
|
startBinding: updatedStartBinding,
|
||||||
|
endBinding: updatedEndBinding,
|
||||||
|
...restOfTheUpdates
|
||||||
|
} = updates;
|
||||||
const startBinding =
|
const startBinding =
|
||||||
typeof updates.startBinding !== "undefined"
|
typeof updatedStartBinding !== "undefined"
|
||||||
? updates.startBinding
|
? updatedStartBinding
|
||||||
: arrow.startBinding;
|
: arrow.startBinding;
|
||||||
const endBinding =
|
const endBinding =
|
||||||
typeof updates.endBinding !== "undefined"
|
typeof updatedEndBinding !== "undefined"
|
||||||
? updates.endBinding
|
? updatedEndBinding
|
||||||
: arrow.endBinding;
|
: arrow.endBinding;
|
||||||
const startElement =
|
const startElement =
|
||||||
startBinding &&
|
startBinding &&
|
||||||
getBindableElementForId(startBinding.elementId, elementsMap);
|
getBindableElementForId(startBinding.elementId, elementsMap);
|
||||||
const endElement =
|
const endElement =
|
||||||
endBinding && getBindableElementForId(endBinding.elementId, elementsMap);
|
endBinding && getBindableElementForId(endBinding.elementId, elementsMap);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
(startBinding && !startElement) ||
|
||||||
|
(endBinding && !endElement) ||
|
||||||
(elementsMap.size === 0 && validateElbowPoints(updatedPoints)) ||
|
(elementsMap.size === 0 && validateElbowPoints(updatedPoints)) ||
|
||||||
startElement?.id !== startBinding?.elementId ||
|
(Object.keys(restOfTheUpdates).length === 0 &&
|
||||||
endElement?.id !== endBinding?.elementId
|
(startElement?.id !== startBinding?.elementId ||
|
||||||
|
endElement?.id !== endBinding?.elementId))
|
||||||
) {
|
) {
|
||||||
return normalizeArrowElementUpdate(
|
return normalizeArrowElementUpdate(
|
||||||
updatedPoints.map((p) =>
|
updatedPoints.map((p) =>
|
||||||
@ -1074,7 +1083,8 @@ export const updateElbowArrowPoints = (
|
|||||||
p,
|
p,
|
||||||
arrow.points[i] ?? pointFrom<LocalPoint>(Infinity, Infinity),
|
arrow.points[i] ?? pointFrom<LocalPoint>(Infinity, Infinity),
|
||||||
),
|
),
|
||||||
)
|
) &&
|
||||||
|
validateElbowPoints(updatedPoints)
|
||||||
) {
|
) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -818,8 +818,8 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
|||||||
"type": "arrow",
|
"type": "arrow",
|
||||||
"updated": 1,
|
"updated": 1,
|
||||||
"version": 30,
|
"version": 30,
|
||||||
"width": 50,
|
"width": 0,
|
||||||
"x": 200,
|
"x": "149.29289",
|
||||||
"y": 0,
|
"y": 0,
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@ -852,7 +852,7 @@ History {
|
|||||||
0,
|
0,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
50,
|
0,
|
||||||
0,
|
0,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -937,7 +937,7 @@ History {
|
|||||||
0,
|
0,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
50,
|
0,
|
||||||
0,
|
0,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user