feat: Orthogonal (elbow) arrows for diagramming (#8299)

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
Márk Tolmács 2024-08-01 18:39:03 +02:00 committed by GitHub
parent a133a70e87
commit 15e019706d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
69 changed files with 5415 additions and 1144 deletions

View file

@ -796,6 +796,7 @@ exports[`contextMenu element > right-clicking on a group should select whole gro
},
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -998,6 +999,7 @@ exports[`contextMenu element > selecting 'Add to library' in context menu adds e
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -1210,6 +1212,7 @@ exports[`contextMenu element > selecting 'Bring forward' in context menu brings
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -1537,6 +1540,7 @@ exports[`contextMenu element > selecting 'Bring to front' in context menu brings
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -1864,6 +1868,7 @@ exports[`contextMenu element > selecting 'Copy styles' in context menu copies st
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -2076,6 +2081,7 @@ exports[`contextMenu element > selecting 'Delete' in context menu deletes elemen
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -2312,6 +2318,7 @@ exports[`contextMenu element > selecting 'Duplicate' in context menu duplicates
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -2609,6 +2616,7 @@ exports[`contextMenu element > selecting 'Group selection' in context menu group
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -2974,6 +2982,7 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "#a5d8ff",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "cross-hatch",
@ -3445,6 +3454,7 @@ exports[`contextMenu element > selecting 'Send backward' in context menu sends e
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -3764,6 +3774,7 @@ exports[`contextMenu element > selecting 'Send to back' in context menu sends el
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -4083,6 +4094,7 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -5265,6 +5277,7 @@ exports[`contextMenu element > shows 'Group selection' in context menu for multi
},
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -6388,6 +6401,7 @@ exports[`contextMenu element > shows 'Ungroup selection' in context menu for gro
},
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -7319,6 +7333,7 @@ exports[`contextMenu element > shows context menu for canvas > [end of test] app
},
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -8227,6 +8242,7 @@ exports[`contextMenu element > shows context menu for element > [end of test] ap
},
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -9117,6 +9133,7 @@ exports[`contextMenu element > shows context menu for element > [end of test] ap
},
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",

View file

@ -8,6 +8,7 @@ exports[`Test dragCreate > add element to the scene when pointer dragging long e
"backgroundColor": "transparent",
"boundElements": null,
"customData": undefined,
"elbowed": false,
"endArrowhead": "arrow",
"endBinding": null,
"fillStyle": "solid",

File diff suppressed because it is too large Load diff

View file

@ -173,7 +173,7 @@ exports[`move element > rectangles with binding arrow 6`] = `
"type": "rectangle",
"updated": 1,
"version": 7,
"versionNonce": 1984422985,
"versionNonce": 745419401,
"width": 300,
"x": 201,
"y": 2,
@ -186,16 +186,18 @@ exports[`move element > rectangles with binding arrow 7`] = `
"backgroundColor": "transparent",
"boundElements": null,
"customData": undefined,
"elbowed": false,
"endArrowhead": "arrow",
"endBinding": {
"elementId": "id1",
"fixedPoint": null,
"focus": "-0.46667",
"gap": 10,
},
"fillStyle": "solid",
"frameId": null,
"groupIds": [],
"height": "81.48231",
"height": "81.47368",
"id": "id2",
"index": "a2",
"isDeleted": false,
@ -210,7 +212,7 @@ exports[`move element > rectangles with binding arrow 7`] = `
],
[
81,
"81.48231",
"81.47368",
],
],
"roughness": 1,
@ -221,6 +223,7 @@ exports[`move element > rectangles with binding arrow 7`] = `
"startArrowhead": null,
"startBinding": {
"elementId": "id0",
"fixedPoint": null,
"focus": "-0.60000",
"gap": 10,
},
@ -229,10 +232,10 @@ exports[`move element > rectangles with binding arrow 7`] = `
"strokeWidth": 2,
"type": "arrow",
"updated": 1,
"version": 14,
"versionNonce": 2066753033,
"version": 11,
"versionNonce": 1996028265,
"width": 81,
"x": 110,
"y": "49.98179",
"y": 50,
}
`;

View file

@ -6,6 +6,7 @@ exports[`multi point mode in linear elements > arrow 3`] = `
"backgroundColor": "transparent",
"boundElements": null,
"customData": undefined,
"elbowed": false,
"endArrowhead": "arrow",
"endBinding": null,
"fillStyle": "solid",

View file

@ -13,6 +13,7 @@ exports[`given element A and group of elements B and given both are selected whe
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -421,6 +422,7 @@ exports[`given element A and group of elements B and given both are selected whe
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -820,6 +822,7 @@ exports[`regression tests > Cmd/Ctrl-click exclusively select element under poin
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -1358,6 +1361,7 @@ exports[`regression tests > Drags selected element when hitting only bounding bo
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -1555,6 +1559,7 @@ exports[`regression tests > adjusts z order when grouping > [end of test] appSta
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -1923,6 +1928,7 @@ exports[`regression tests > alt-drag duplicates an element > [end of test] appSt
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -2156,6 +2162,7 @@ exports[`regression tests > arrow keys > [end of test] appState 1`] = `
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -2329,6 +2336,7 @@ exports[`regression tests > can drag element that covers another element, while
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -2642,6 +2650,7 @@ exports[`regression tests > change the properties of a shape > [end of test] app
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "#ffc9c9",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -2881,6 +2890,7 @@ exports[`regression tests > click on an element and drag it > [dragged] appState
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -3117,6 +3127,7 @@ exports[`regression tests > click on an element and drag it > [end of test] appS
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -3340,6 +3351,7 @@ exports[`regression tests > click to select a shape > [end of test] appState 1`]
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -3589,6 +3601,7 @@ exports[`regression tests > click-drag to select a group > [end of test] appStat
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -3893,6 +3906,7 @@ exports[`regression tests > deleting last but one element in editing group shoul
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -4300,6 +4314,7 @@ exports[`regression tests > deselects group of selected elements on pointer down
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -4606,6 +4621,7 @@ exports[`regression tests > deselects group of selected elements on pointer up w
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -4882,6 +4898,7 @@ exports[`regression tests > deselects selected element on pointer down when poin
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -5115,6 +5132,7 @@ exports[`regression tests > deselects selected element, on pointer up, when clic
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -5307,6 +5325,7 @@ exports[`regression tests > double click to edit a group > [end of test] appStat
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -5682,6 +5701,7 @@ exports[`regression tests > drags selected elements from point inside common bou
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -5965,6 +5985,7 @@ exports[`regression tests > draw every type of shape > [end of test] appState 1`
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -6247,6 +6268,7 @@ History {
"backgroundColor": "transparent",
"boundElements": null,
"customData": undefined,
"elbowed": false,
"endArrowhead": "arrow",
"endBinding": null,
"fillStyle": "solid",
@ -6387,6 +6409,7 @@ History {
"backgroundColor": "transparent",
"boundElements": null,
"customData": undefined,
"elbowed": false,
"endArrowhead": "arrow",
"endBinding": null,
"fillStyle": "solid",
@ -6764,6 +6787,7 @@ exports[`regression tests > given a group of selected elements with an element t
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -7087,6 +7111,7 @@ exports[`regression tests > given a selected element A and a not selected elemen
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "#ffc9c9",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -7356,6 +7381,7 @@ exports[`regression tests > given selected element A with lower z-index than uns
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -7583,6 +7609,7 @@ exports[`regression tests > given selected element A with lower z-index than uns
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -7813,6 +7840,7 @@ exports[`regression tests > key 2 selects rectangle tool > [end of test] appStat
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -7986,6 +8014,7 @@ exports[`regression tests > key 3 selects diamond tool > [end of test] appState
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -8159,6 +8188,7 @@ exports[`regression tests > key 4 selects ellipse tool > [end of test] appState
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -8332,6 +8362,7 @@ exports[`regression tests > key 5 selects arrow tool > [end of test] appState 1`
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -8408,6 +8439,7 @@ exports[`regression tests > key 5 selects arrow tool > [end of test] appState 1`
"isDragging": false,
"lastUncommittedPoint": null,
"pointerDownState": {
"lastClickedIsEndPoint": false,
"lastClickedPoint": -1,
"origin": null,
"prevSelectedPointsIndices": null,
@ -8480,6 +8512,7 @@ History {
"backgroundColor": "transparent",
"boundElements": null,
"customData": undefined,
"elbowed": false,
"endArrowhead": "arrow",
"endBinding": null,
"fillStyle": "solid",
@ -8545,6 +8578,7 @@ exports[`regression tests > key 6 selects line tool > [end of test] appState 1`]
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -8621,6 +8655,7 @@ exports[`regression tests > key 6 selects line tool > [end of test] appState 1`]
"isDragging": false,
"lastUncommittedPoint": null,
"pointerDownState": {
"lastClickedIsEndPoint": false,
"lastClickedPoint": -1,
"origin": null,
"prevSelectedPointsIndices": null,
@ -8758,6 +8793,7 @@ exports[`regression tests > key 7 selects freedraw tool > [end of test] appState
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -8945,6 +8981,7 @@ exports[`regression tests > key a selects arrow tool > [end of test] appState 1`
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -9021,6 +9058,7 @@ exports[`regression tests > key a selects arrow tool > [end of test] appState 1`
"isDragging": false,
"lastUncommittedPoint": null,
"pointerDownState": {
"lastClickedIsEndPoint": false,
"lastClickedPoint": -1,
"origin": null,
"prevSelectedPointsIndices": null,
@ -9093,6 +9131,7 @@ History {
"backgroundColor": "transparent",
"boundElements": null,
"customData": undefined,
"elbowed": false,
"endArrowhead": "arrow",
"endBinding": null,
"fillStyle": "solid",
@ -9158,6 +9197,7 @@ exports[`regression tests > key d selects diamond tool > [end of test] appState
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -9331,6 +9371,7 @@ exports[`regression tests > key l selects line tool > [end of test] appState 1`]
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -9407,6 +9448,7 @@ exports[`regression tests > key l selects line tool > [end of test] appState 1`]
"isDragging": false,
"lastUncommittedPoint": null,
"pointerDownState": {
"lastClickedIsEndPoint": false,
"lastClickedPoint": -1,
"origin": null,
"prevSelectedPointsIndices": null,
@ -9544,6 +9586,7 @@ exports[`regression tests > key o selects ellipse tool > [end of test] appState
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -9717,6 +9760,7 @@ exports[`regression tests > key p selects freedraw tool > [end of test] appState
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -9904,6 +9948,7 @@ exports[`regression tests > key r selects rectangle tool > [end of test] appStat
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -10077,6 +10122,7 @@ exports[`regression tests > make a group and duplicate it > [end of test] appSta
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -10584,6 +10630,7 @@ exports[`regression tests > noop interaction after undo shouldn't create history
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -10854,6 +10901,7 @@ exports[`regression tests > pinch-to-zoom works > [end of test] appState 1`] = `
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -10973,6 +11021,7 @@ exports[`regression tests > shift click on selected element should deselect it o
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -11165,6 +11214,7 @@ exports[`regression tests > shift-click to multiselect, then drag > [end of test
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -11469,6 +11519,7 @@ exports[`regression tests > should group elements and ungroup them > [end of tes
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -11874,6 +11925,7 @@ exports[`regression tests > single-clicking on a subgroup of a selected group sh
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -12480,6 +12532,7 @@ exports[`regression tests > spacebar + drag scrolls the canvas > [end of test] a
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -12602,6 +12655,7 @@ exports[`regression tests > supports nested groups > [end of test] appState 1`]
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -13179,6 +13233,7 @@ exports[`regression tests > switches from group of selected elements to another
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -13540,6 +13595,7 @@ exports[`regression tests > switches selected element on pointer down > [end of
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -13828,6 +13884,7 @@ exports[`regression tests > two-finger scroll works > [end of test] appState 1`]
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -13947,6 +14004,7 @@ exports[`regression tests > undo/redo drawing an element > [end of test] appStat
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -14146,6 +14204,7 @@ History {
"backgroundColor": "transparent",
"boundElements": null,
"customData": undefined,
"elbowed": false,
"endArrowhead": "arrow",
"endBinding": null,
"fillStyle": "solid",
@ -14318,6 +14377,7 @@ exports[`regression tests > updates fontSize & fontFamily appState > [end of tes
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",
@ -14437,6 +14497,7 @@ exports[`regression tests > zoom hotkeys > [end of test] appState 1`] = `
"contextMenu": null,
"currentChartType": "bar",
"currentHoveredFontFamily": null,
"currentItemArrowType": "round",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "solid",

View file

@ -6,6 +6,7 @@ exports[`select single element on the scene > arrow 1`] = `
"backgroundColor": "transparent",
"boundElements": null,
"customData": undefined,
"elbowed": false,
"endArrowhead": "arrow",
"endBinding": null,
"fillStyle": "solid",

View file

@ -62,6 +62,7 @@ describe("element binding", () => {
expect(arrow.startBinding).toEqual({
elementId: rect.id,
fixedPoint: null,
focus: expect.toBeNonNaNNumber(),
gap: expect.toBeNonNaNNumber(),
});
@ -74,11 +75,13 @@ describe("element binding", () => {
// Both the start and the end points should be bound
expect(arrow.startBinding).toEqual({
elementId: rect.id,
fixedPoint: null,
focus: expect.toBeNonNaNNumber(),
gap: expect.toBeNonNaNNumber(),
});
expect(arrow.endBinding).toEqual({
elementId: rect.id,
fixedPoint: null,
focus: expect.toBeNonNaNNumber(),
gap: expect.toBeNonNaNNumber(),
});
@ -318,11 +321,13 @@ describe("element binding", () => {
elementId: "rectangle1",
focus: 0.2,
gap: 7,
fixedPoint: [0.5, 1],
},
endBinding: {
elementId: "text1",
focus: 0.2,
gap: 7,
fixedPoint: [1, 0.5],
},
});
@ -337,11 +342,13 @@ describe("element binding", () => {
elementId: "text1",
focus: 0.2,
gap: 7,
fixedPoint: [0.5, 1],
},
endBinding: {
elementId: "rectangle1",
focus: 0.2,
gap: 7,
fixedPoint: [1, 0.5],
},
});

View file

@ -6,6 +6,7 @@ exports[`restoreElements > should restore arrow element correctly 1`] = `
"backgroundColor": "transparent",
"boundElements": [],
"customData": undefined,
"elbowed": false,
"endArrowhead": null,
"endBinding": null,
"fillStyle": "solid",

View file

@ -149,8 +149,6 @@ const createLinearElementWithCurveInsideMinMaxPoints = (
[-922.4761962890625, 300.3277587890625],
[828.0126953125, 410.51605224609375],
],
startArrowhead: null,
endArrowhead: null,
});
};
@ -183,8 +181,6 @@ const createLinearElementsWithCurveOutsideMinMaxPoints = (
[-591.2804897585779, 36.09360810181511],
[-148.56510566829502, 53.96308359105342],
],
startArrowhead: null,
endArrowhead: null,
...extraProps,
});
};

View file

@ -19,6 +19,7 @@ import util from "util";
import path from "path";
import { getMimeType } from "../../data/blob";
import {
newArrowElement,
newEmbeddableElement,
newFrameElement,
newFreeDrawElement,
@ -146,6 +147,7 @@ export class API {
endBinding?: T extends "arrow"
? ExcalidrawLinearElement["endBinding"]
: never;
elbowed?: boolean;
}): T extends "arrow" | "line"
? ExcalidrawLinearElement
: T extends "freedraw"
@ -250,14 +252,24 @@ export class API {
});
break;
case "arrow":
element = newArrowElement({
...base,
width,
height,
type,
points: rest.points ?? [
[0, 0],
[100, 100],
],
elbowed: rest.elbowed ?? false,
});
break;
case "line":
element = newLinearElement({
...base,
width,
height,
type,
startArrowhead: null,
endArrowhead: null,
points: rest.points ?? [
[0, 0],
[100, 100],

File diff suppressed because it is too large Load diff

View file

@ -95,7 +95,12 @@ describe("library", () => {
const arrow = API.createElement({
id: "arrow1",
type: "arrow",
endBinding: { elementId: "rectangle1", focus: -1, gap: 0 },
endBinding: {
elementId: "rectangle1",
focus: -1,
gap: 0,
fixedPoint: [0.5, 1],
},
});
await API.drop(

View file

@ -5,7 +5,7 @@ import type {
ExcalidrawTextElementWithContainer,
FontString,
} from "../element/types";
import { Excalidraw } from "../index";
import { Excalidraw, mutateElement } from "../index";
import { centerPoint } from "../math";
import { reseed } from "../random";
import * as StaticScene from "../renderer/staticScene";
@ -107,6 +107,7 @@ describe("Test Linear Elements", () => {
],
roundness,
});
mutateElement(line, { points: line.points });
h.elements = [line];
mouse.clickAt(p1[0], p1[1]);
return line;
@ -307,7 +308,7 @@ describe("Test Linear Elements", () => {
expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot(
`9`,
);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`7`);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`6`);
const midPointsWithRoundEdge = LinearElementEditor.getEditorMidPoints(
h.elements[0] as ExcalidrawLinearElement,
@ -365,7 +366,7 @@ describe("Test Linear Elements", () => {
expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot(
`12`,
);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`8`);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`7`);
expect([line.x, line.y]).toEqual([
points[0][0] + deltaX,
@ -427,7 +428,7 @@ describe("Test Linear Elements", () => {
expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot(
`16`,
);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`8`);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`7`);
expect(line.points.length).toEqual(5);
@ -478,7 +479,7 @@ describe("Test Linear Elements", () => {
expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot(
`12`,
);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`7`);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`6`);
const newPoints = LinearElementEditor.getPointsGlobalCoordinates(
line,
@ -519,7 +520,7 @@ describe("Test Linear Elements", () => {
expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot(
`12`,
);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`7`);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`6`);
const newPoints = LinearElementEditor.getPointsGlobalCoordinates(
line,
@ -567,7 +568,7 @@ describe("Test Linear Elements", () => {
expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot(
`18`,
);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`8`);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`7`);
const newMidPoints = LinearElementEditor.getEditorMidPoints(
line,
@ -617,7 +618,7 @@ describe("Test Linear Elements", () => {
expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot(
`16`,
);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`8`);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`7`);
expect(line.points.length).toEqual(5);
expect((h.elements[0] as ExcalidrawLinearElement).points)
@ -715,7 +716,7 @@ describe("Test Linear Elements", () => {
expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot(
`12`,
);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`7`);
expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`6`);
const newPoints = LinearElementEditor.getPointsGlobalCoordinates(
line,
@ -843,6 +844,7 @@ describe("Test Linear Elements", () => {
id: textElement.id,
}),
};
const elements: ExcalidrawElement[] = [];
h.elements.forEach((element) => {
if (element.id === container.id) {
@ -1235,7 +1237,7 @@ describe("Test Linear Elements", () => {
mouse.moveTo(200, 0);
mouse.upAt(200, 0);
expect(arrow.width).toBe(200);
expect(arrow.width).toBe(205);
expect(rect.x).toBe(200);
expect(rect.y).toBe(0);
expect(handleBindTextResizeSpy).toHaveBeenCalledWith(
@ -1356,16 +1358,20 @@ describe("Test Linear Elements", () => {
const line = createThreePointerLinearElement("arrow");
const [origStartX, origStartY] = [line.x, line.y];
LinearElementEditor.movePoints(line, [
{ index: 0, point: [line.points[0][0] + 10, line.points[0][1] + 10] },
{
index: line.points.length - 1,
point: [
line.points[line.points.length - 1][0] - 10,
line.points[line.points.length - 1][1] - 10,
],
},
]);
LinearElementEditor.movePoints(
line,
[
{ index: 0, point: [line.points[0][0] + 10, line.points[0][1] + 10] },
{
index: line.points.length - 1,
point: [
line.points[line.points.length - 1][0] - 10,
line.points[line.points.length - 1][1] - 10,
],
},
],
h.scene,
);
expect(line.x).toBe(origStartX + 10);
expect(line.y).toBe(origStartY + 10);

View file

@ -13,6 +13,7 @@ import type {
import { UI, Pointer, Keyboard } from "./helpers/ui";
import { KEYS } from "../keys";
import { vi } from "vitest";
import type Scene from "../scene/Scene";
// Unmount ReactDOM from root
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
@ -85,6 +86,7 @@ describe("move element", () => {
rectA.get() as ExcalidrawRectangleElement,
rectB.get() as ExcalidrawRectangleElement,
elementsMap,
{} as Scene,
);
// select the second rectangle

View file

@ -798,6 +798,7 @@ describe("multiple selection", () => {
width: 100,
height: 0,
});
const rightBoundArrow = UI.createElement("arrow", {
x: 210,
y: 50,
@ -822,11 +823,16 @@ describe("multiple selection", () => {
expect(leftBoundArrow.x).toBeCloseTo(-110);
expect(leftBoundArrow.y).toBeCloseTo(50);
expect(leftBoundArrow.width).toBeCloseTo(140, 0);
expect(leftBoundArrow.width).toBeCloseTo(137.5, 0);
expect(leftBoundArrow.height).toBeCloseTo(7, 0);
expect(leftBoundArrow.angle).toEqual(0);
expect(leftBoundArrow.startBinding).toBeNull();
expect(leftBoundArrow.endBinding).toMatchObject(leftArrowBinding);
expect(leftBoundArrow.endBinding?.gap).toBeCloseTo(12.352);
expect(leftBoundArrow.endBinding?.elementId).toBe(
leftArrowBinding.elementId,
);
expect(leftBoundArrow.endBinding?.fixedPoint).toBeNull();
expect(leftBoundArrow.endBinding?.focus).toBe(leftArrowBinding.focus);
expect(rightBoundArrow.x).toBeCloseTo(210);
expect(rightBoundArrow.y).toBeCloseTo(
@ -836,7 +842,12 @@ describe("multiple selection", () => {
expect(rightBoundArrow.height).toBeCloseTo(0);
expect(rightBoundArrow.angle).toEqual(0);
expect(rightBoundArrow.startBinding).toBeNull();
expect(rightBoundArrow.endBinding).toMatchObject(rightArrowBinding);
expect(rightBoundArrow.endBinding?.gap).toBeCloseTo(8.0952);
expect(rightBoundArrow.endBinding?.elementId).toBe(
rightArrowBinding.elementId,
);
expect(rightBoundArrow.endBinding?.fixedPoint).toBeNull();
expect(rightBoundArrow.endBinding?.focus).toBe(rightArrowBinding.focus);
});
it("resizes with labeled arrows", async () => {