Skip to content

Commit 49f1276

Browse files
authored
fix: Undo for elbow arrows create incorrect routing (#9046)
1 parent 8f20b29 commit 49f1276

File tree

3 files changed

+121
-122
lines changed

3 files changed

+121
-122
lines changed

packages/excalidraw/element/elbowArrow.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,20 @@ export const updateElbowArrowPoints = (
909909
);
910910
}
911911

912+
// 0. During all element replacement in the scene, we just need to renormalize
913+
// the arrow
914+
// TODO (dwelle,mtolmacs): Remove this once Scene.getScene() is removed
915+
if (elementsMap.size === 0 && updates.points) {
916+
return normalizeArrowElementUpdate(
917+
updates.points.map((p) =>
918+
pointFrom<GlobalPoint>(arrow.x + p[0], arrow.y + p[1]),
919+
),
920+
arrow.fixedSegments,
921+
arrow.startIsSpecial,
922+
arrow.endIsSpecial,
923+
);
924+
}
925+
912926
const updatedPoints: readonly LocalPoint[] = updates.points
913927
? updates.points && updates.points.length === 2
914928
? arrow.points.map((p, idx) =>

packages/excalidraw/tests/__snapshots__/history.test.tsx.snap

Lines changed: 103 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -10896,20 +10896,15 @@ exports[`history > multiplayer undo/redo > should redraw arrows on undo > [end o
1089610896
{
1089710897
"angle": 0,
1089810898
"backgroundColor": "transparent",
10899-
"boundElements": [
10900-
{
10901-
"id": "6Rm4g567UQM4WjLwej2Vc",
10902-
"type": "arrow",
10903-
},
10904-
],
10899+
"boundElements": [],
1090510900
"customData": undefined,
1090610901
"fillStyle": "solid",
1090710902
"frameId": null,
1090810903
"groupIds": [],
1090910904
"height": 126,
1091010905
"id": "KPrBI4g_v9qUB1XxYLgSz",
1091110906
"index": "a0",
10912-
"isDeleted": false,
10907+
"isDeleted": true,
1091310908
"link": null,
1091410909
"locked": false,
1091510910
"opacity": 100,
@@ -10922,7 +10917,7 @@ exports[`history > multiplayer undo/redo > should redraw arrows on undo > [end o
1092210917
"strokeWidth": 2,
1092310918
"type": "rectangle",
1092410919
"updated": 1,
10925-
"version": 6,
10920+
"version": 4,
1092610921
"width": 157,
1092710922
"x": 600,
1092810923
"y": 0,
@@ -10933,20 +10928,15 @@ exports[`history > multiplayer undo/redo > should redraw arrows on undo > [end o
1093310928
{
1093410929
"angle": 0,
1093510930
"backgroundColor": "transparent",
10936-
"boundElements": [
10937-
{
10938-
"id": "6Rm4g567UQM4WjLwej2Vc",
10939-
"type": "arrow",
10940-
},
10941-
],
10931+
"boundElements": [],
1094210932
"customData": undefined,
1094310933
"fillStyle": "solid",
1094410934
"frameId": null,
1094510935
"groupIds": [],
1094610936
"height": 129,
1094710937
"id": "u2JGnnmoJ0VATV4vCNJE5",
1094810938
"index": "a1",
10949-
"isDeleted": false,
10939+
"isDeleted": true,
1095010940
"link": null,
1095110941
"locked": false,
1095210942
"opacity": 100,
@@ -10959,7 +10949,7 @@ exports[`history > multiplayer undo/redo > should redraw arrows on undo > [end o
1095910949
"strokeWidth": 2,
1096010950
"type": "diamond",
1096110951
"updated": 1,
10962-
"version": 6,
10952+
"version": 4,
1096310953
"width": 124,
1096410954
"x": 1152,
1096510955
"y": 516,
@@ -10983,15 +10973,15 @@ exports[`history > multiplayer undo/redo > should redraw arrows on undo > [end o
1098310973
"focus": "-0.00161",
1098410974
"gap": "3.53708",
1098510975
},
10986-
"endIsSpecial": null,
10976+
"endIsSpecial": false,
1098710977
"fillStyle": "solid",
10988-
"fixedSegments": null,
10978+
"fixedSegments": [],
1098910979
"frameId": null,
1099010980
"groupIds": [],
10991-
"height": "448.10100",
10981+
"height": "236.10000",
1099210982
"id": "6Rm4g567UQM4WjLwej2Vc",
1099310983
"index": "a2",
10994-
"isDeleted": false,
10984+
"isDeleted": true,
1099510985
"lastCommittedPoint": null,
1099610986
"link": null,
1099710987
"locked": false,
@@ -11002,16 +10992,12 @@ exports[`history > multiplayer undo/redo > should redraw arrows on undo > [end o
1100210992
0,
1100310993
],
1100410994
[
11005-
"225.95000",
10995+
"178.90000",
1100610996
0,
1100710997
],
1100810998
[
11009-
"225.95000",
11010-
"448.10100",
11011-
],
11012-
[
11013-
"451.90000",
11014-
"448.10100",
10999+
"178.90000",
11000+
"236.10000",
1101511001
],
1101611002
],
1101711003
"roughness": 1,
@@ -11028,16 +11014,16 @@ exports[`history > multiplayer undo/redo > should redraw arrows on undo > [end o
1102811014
"focus": "-0.00159",
1102911015
"gap": 5,
1103011016
},
11031-
"startIsSpecial": null,
11017+
"startIsSpecial": false,
1103211018
"strokeColor": "#1e1e1e",
1103311019
"strokeStyle": "solid",
1103411020
"strokeWidth": 2,
1103511021
"type": "arrow",
1103611022
"updated": 1,
11037-
"version": 6,
11038-
"width": "451.90000",
11039-
"x": 762,
11040-
"y": "62.90000",
11023+
"version": 3,
11024+
"width": "178.90000",
11025+
"x": 1035,
11026+
"y": "274.90000",
1104111027
}
1104211028
`;
1104311029

@@ -11049,8 +11035,7 @@ History {
1104911035
[Function],
1105011036
],
1105111037
},
11052-
"redoStack": [],
11053-
"undoStack": [
11038+
"redoStack": [
1105411039
HistoryEntry {
1105511040
"appStateChange": AppStateChange {
1105611041
"delta": Delta {
@@ -11059,86 +11044,12 @@ History {
1105911044
},
1106011045
},
1106111046
"elementsChange": ElementsChange {
11062-
"added": Map {},
11063-
"removed": Map {
11064-
"KPrBI4g_v9qUB1XxYLgSz" => Delta {
11047+
"added": Map {
11048+
"6Rm4g567UQM4WjLwej2Vc" => Delta {
1106511049
"deleted": {
11066-
"angle": 0,
11067-
"backgroundColor": "transparent",
11068-
"boundElements": null,
11069-
"customData": undefined,
11070-
"fillStyle": "solid",
11071-
"frameId": null,
11072-
"groupIds": [],
11073-
"height": 126,
11074-
"index": "a0",
11075-
"isDeleted": false,
11076-
"link": null,
11077-
"locked": false,
11078-
"opacity": 100,
11079-
"roughness": 1,
11080-
"roundness": {
11081-
"type": 3,
11082-
},
11083-
"strokeColor": "#1e1e1e",
11084-
"strokeStyle": "solid",
11085-
"strokeWidth": 2,
11086-
"type": "rectangle",
11087-
"width": 157,
11088-
"x": 873,
11089-
"y": 212,
11090-
},
11091-
"inserted": {
1109211050
"isDeleted": true,
1109311051
},
11094-
},
11095-
"u2JGnnmoJ0VATV4vCNJE5" => Delta {
11096-
"deleted": {
11097-
"angle": 0,
11098-
"backgroundColor": "transparent",
11099-
"boundElements": null,
11100-
"customData": undefined,
11101-
"fillStyle": "solid",
11102-
"frameId": null,
11103-
"groupIds": [],
11104-
"height": 129,
11105-
"index": "a1",
11106-
"isDeleted": false,
11107-
"link": null,
11108-
"locked": false,
11109-
"opacity": 100,
11110-
"roughness": 1,
11111-
"roundness": {
11112-
"type": 3,
11113-
},
11114-
"strokeColor": "#1e1e1e",
11115-
"strokeStyle": "solid",
11116-
"strokeWidth": 2,
11117-
"type": "diamond",
11118-
"width": 124,
11119-
"x": 1152,
11120-
"y": 516,
11121-
},
1112211052
"inserted": {
11123-
"isDeleted": true,
11124-
},
11125-
},
11126-
},
11127-
"updated": Map {},
11128-
},
11129-
},
11130-
HistoryEntry {
11131-
"appStateChange": AppStateChange {
11132-
"delta": Delta {
11133-
"deleted": {},
11134-
"inserted": {},
11135-
},
11136-
},
11137-
"elementsChange": ElementsChange {
11138-
"added": Map {},
11139-
"removed": Map {
11140-
"6Rm4g567UQM4WjLwej2Vc" => Delta {
11141-
"deleted": {
1114211053
"angle": 0,
1114311054
"backgroundColor": "transparent",
1114411055
"boundElements": null,
@@ -11203,42 +11114,117 @@ History {
1120311114
"x": 1035,
1120411115
"y": "274.90000",
1120511116
},
11206-
"inserted": {
11207-
"isDeleted": true,
11208-
},
1120911117
},
1121011118
},
11119+
"removed": Map {},
1121111120
"updated": Map {
1121211121
"KPrBI4g_v9qUB1XxYLgSz" => Delta {
1121311122
"deleted": {
11123+
"boundElements": [],
11124+
},
11125+
"inserted": {
1121411126
"boundElements": [
1121511127
{
1121611128
"id": "6Rm4g567UQM4WjLwej2Vc",
1121711129
"type": "arrow",
1121811130
},
1121911131
],
1122011132
},
11221-
"inserted": {
11222-
"boundElements": [],
11223-
},
1122411133
},
1122511134
"u2JGnnmoJ0VATV4vCNJE5" => Delta {
1122611135
"deleted": {
11136+
"boundElements": [],
11137+
},
11138+
"inserted": {
1122711139
"boundElements": [
1122811140
{
1122911141
"id": "6Rm4g567UQM4WjLwej2Vc",
1123011142
"type": "arrow",
1123111143
},
1123211144
],
1123311145
},
11146+
},
11147+
},
11148+
},
11149+
},
11150+
HistoryEntry {
11151+
"appStateChange": AppStateChange {
11152+
"delta": Delta {
11153+
"deleted": {},
11154+
"inserted": {},
11155+
},
11156+
},
11157+
"elementsChange": ElementsChange {
11158+
"added": Map {
11159+
"KPrBI4g_v9qUB1XxYLgSz" => Delta {
11160+
"deleted": {
11161+
"isDeleted": true,
11162+
},
1123411163
"inserted": {
11235-
"boundElements": [],
11164+
"angle": 0,
11165+
"backgroundColor": "transparent",
11166+
"boundElements": null,
11167+
"customData": undefined,
11168+
"fillStyle": "solid",
11169+
"frameId": null,
11170+
"groupIds": [],
11171+
"height": 126,
11172+
"index": "a0",
11173+
"isDeleted": false,
11174+
"link": null,
11175+
"locked": false,
11176+
"opacity": 100,
11177+
"roughness": 1,
11178+
"roundness": {
11179+
"type": 3,
11180+
},
11181+
"strokeColor": "#1e1e1e",
11182+
"strokeStyle": "solid",
11183+
"strokeWidth": 2,
11184+
"type": "rectangle",
11185+
"width": 157,
11186+
"x": 600,
11187+
"y": 0,
11188+
},
11189+
},
11190+
"u2JGnnmoJ0VATV4vCNJE5" => Delta {
11191+
"deleted": {
11192+
"isDeleted": true,
11193+
},
11194+
"inserted": {
11195+
"angle": 0,
11196+
"backgroundColor": "transparent",
11197+
"boundElements": null,
11198+
"customData": undefined,
11199+
"fillStyle": "solid",
11200+
"frameId": null,
11201+
"groupIds": [],
11202+
"height": 129,
11203+
"index": "a1",
11204+
"isDeleted": false,
11205+
"link": null,
11206+
"locked": false,
11207+
"opacity": 100,
11208+
"roughness": 1,
11209+
"roundness": {
11210+
"type": 3,
11211+
},
11212+
"strokeColor": "#1e1e1e",
11213+
"strokeStyle": "solid",
11214+
"strokeWidth": 2,
11215+
"type": "diamond",
11216+
"width": 124,
11217+
"x": 1152,
11218+
"y": 516,
1123611219
},
1123711220
},
1123811221
},
11222+
"removed": Map {},
11223+
"updated": Map {},
1123911224
},
1124011225
},
1124111226
],
11227+
"undoStack": [],
1124211228
}
1124311229
`;
1124411230

packages/excalidraw/tests/history.test.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,16 +2077,15 @@ describe("history", () => {
20772077
storeAction: StoreAction.UPDATE,
20782078
});
20792079

2080-
Keyboard.redo();
2080+
Keyboard.undo();
20812081

20822082
const modifiedArrow = h.elements.filter(
20832083
(el) => el.type === "arrow",
20842084
)[0] as ExcalidrawElbowArrowElement;
2085-
expect(modifiedArrow.points).toEqual([
2085+
expect(modifiedArrow.points).toCloselyEqualPoints([
20862086
[0, 0],
2087-
[225.95000000000005, 0],
2088-
[225.95000000000005, 448.10100010002003],
2089-
[451.9000000000001, 448.10100010002003],
2087+
[178.9, 0],
2088+
[178.9, 236.1],
20902089
]);
20912090
});
20922091

0 commit comments

Comments
 (0)