@excalidraw/excalidraw 0.17.1-c0b80a0 → 0.17.1-c329470

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/dist/browser/dev/excalidraw-assets-dev/{chunk-JGDL4H2X.js → chunk-3DLVY5XU.js} +8272 -6864
  2. package/dist/browser/dev/excalidraw-assets-dev/chunk-3DLVY5XU.js.map +7 -0
  3. package/dist/browser/dev/excalidraw-assets-dev/{chunk-V7NFEZA6.js → chunk-NOAEU4NM.js} +9 -2
  4. package/dist/browser/dev/excalidraw-assets-dev/chunk-NOAEU4NM.js.map +7 -0
  5. package/dist/browser/dev/excalidraw-assets-dev/{en-ZSVWGT55.js → en-7IBTMWBG.js} +2 -2
  6. package/dist/browser/dev/excalidraw-assets-dev/{image-RJG3J34Y.js → image-N5AC7SEK.js} +2 -6
  7. package/dist/browser/dev/index.css +85 -50
  8. package/dist/browser/dev/index.css.map +3 -3
  9. package/dist/browser/dev/index.js +4375 -3766
  10. package/dist/browser/dev/index.js.map +4 -4
  11. package/dist/browser/prod/excalidraw-assets/{chunk-LDVEIXGO.js → chunk-7CSIPVOW.js} +2 -2
  12. package/dist/browser/prod/excalidraw-assets/chunk-TX3BU7T2.js +47 -0
  13. package/dist/browser/prod/excalidraw-assets/{en-UPNEHLDS.js → en-LOGQBETY.js} +1 -1
  14. package/dist/browser/prod/excalidraw-assets/image-3V4U7GZE.js +1 -0
  15. package/dist/browser/prod/index.css +1 -1
  16. package/dist/browser/prod/index.js +40 -40
  17. package/dist/dev/index.css +85 -50
  18. package/dist/dev/index.css.map +3 -3
  19. package/dist/dev/index.js +8688 -6706
  20. package/dist/dev/index.js.map +4 -4
  21. package/dist/{prod/locales/en-ZXYG7GCR.json → dev/locales/en-V6KXFSCK.json} +8 -1
  22. package/dist/excalidraw/actions/actionAlign.d.ts +7 -6
  23. package/dist/excalidraw/actions/actionAlign.js +14 -14
  24. package/dist/excalidraw/actions/actionClipboard.d.ts +7 -3
  25. package/dist/excalidraw/actions/actionDeleteSelected.d.ts +7 -3
  26. package/dist/excalidraw/actions/actionDeleteSelected.js +103 -34
  27. package/dist/excalidraw/actions/actionDuplicateSelection.js +105 -95
  28. package/dist/excalidraw/actions/actionFlip.js +16 -7
  29. package/dist/excalidraw/actions/actionFrame.d.ts +493 -0
  30. package/dist/excalidraw/actions/actionFrame.js +45 -2
  31. package/dist/excalidraw/actions/actionGroup.js +6 -4
  32. package/dist/excalidraw/actions/actionProperties.js +145 -116
  33. package/dist/excalidraw/actions/actionSelectAll.js +4 -3
  34. package/dist/excalidraw/actions/shortcuts.d.ts +1 -1
  35. package/dist/excalidraw/actions/shortcuts.js +1 -0
  36. package/dist/excalidraw/actions/types.d.ts +1 -1
  37. package/dist/excalidraw/align.d.ts +2 -1
  38. package/dist/excalidraw/align.js +15 -6
  39. package/dist/excalidraw/clipboard.d.ts +27 -5
  40. package/dist/excalidraw/clipboard.js +55 -28
  41. package/dist/excalidraw/components/Actions.d.ts +2 -1
  42. package/dist/excalidraw/components/Actions.js +4 -2
  43. package/dist/excalidraw/components/ActiveConfirmDialog.d.ts +1 -1
  44. package/dist/excalidraw/components/ActiveConfirmDialog.js +2 -3
  45. package/dist/excalidraw/components/App.d.ts +1 -0
  46. package/dist/excalidraw/components/App.js +216 -111
  47. package/dist/excalidraw/components/ColorPicker/ColorInput.js +2 -3
  48. package/dist/excalidraw/components/ColorPicker/ColorPicker.js +2 -3
  49. package/dist/excalidraw/components/ColorPicker/CustomColorList.js +1 -1
  50. package/dist/excalidraw/components/ColorPicker/Picker.js +1 -1
  51. package/dist/excalidraw/components/ColorPicker/PickerColorList.js +1 -1
  52. package/dist/excalidraw/components/ColorPicker/ShadeList.js +1 -1
  53. package/dist/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +1 -1
  54. package/dist/excalidraw/components/ColorPicker/colorPickerUtils.js +1 -1
  55. package/dist/excalidraw/components/CommandPalette/CommandPalette.js +3 -3
  56. package/dist/excalidraw/components/ConfirmDialog.js +17 -5
  57. package/dist/excalidraw/components/Dialog.js +2 -3
  58. package/dist/excalidraw/components/EyeDropper.d.ts +1 -1
  59. package/dist/excalidraw/components/EyeDropper.js +1 -1
  60. package/dist/excalidraw/components/IconPicker.d.ts +2 -2
  61. package/dist/excalidraw/components/IconPicker.js +56 -53
  62. package/dist/excalidraw/components/LayerUI.js +6 -6
  63. package/dist/excalidraw/components/LibraryMenu.d.ts +2 -16
  64. package/dist/excalidraw/components/LibraryMenu.js +70 -28
  65. package/dist/excalidraw/components/LibraryMenuHeaderContent.js +4 -5
  66. package/dist/excalidraw/components/MobileMenu.js +1 -1
  67. package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirm.js +2 -3
  68. package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.d.ts +1 -1
  69. package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.js +2 -3
  70. package/dist/excalidraw/components/Range.d.ts +9 -0
  71. package/dist/excalidraw/components/Range.js +24 -0
  72. package/dist/excalidraw/components/SearchMenu.d.ts +1 -1
  73. package/dist/excalidraw/components/SearchMenu.js +3 -4
  74. package/dist/excalidraw/components/Sidebar/Sidebar.d.ts +1 -1
  75. package/dist/excalidraw/components/Sidebar/Sidebar.js +2 -3
  76. package/dist/excalidraw/components/Stats/Collapsible.d.ts +2 -1
  77. package/dist/excalidraw/components/Stats/Collapsible.js +2 -2
  78. package/dist/excalidraw/components/Stats/Dimension.js +94 -8
  79. package/dist/excalidraw/components/Stats/MultiDimension.js +8 -5
  80. package/dist/excalidraw/components/Stats/Position.js +63 -3
  81. package/dist/excalidraw/components/Stats/index.js +21 -4
  82. package/dist/excalidraw/components/Stats/utils.d.ts +1 -1
  83. package/dist/excalidraw/components/Stats/utils.js +2 -55
  84. package/dist/excalidraw/components/TTDDialog/TTDDialog.js +1 -1
  85. package/dist/excalidraw/components/ToolButton.js +4 -9
  86. package/dist/excalidraw/components/hoc/withInternalFallback.js +3 -3
  87. package/dist/excalidraw/components/hyperlink/Hyperlink.js +6 -12
  88. package/dist/excalidraw/components/icons.d.ts +9 -0
  89. package/dist/excalidraw/components/icons.js +4 -4
  90. package/dist/excalidraw/components/main-menu/DefaultItems.js +2 -3
  91. package/dist/excalidraw/constants.d.ts +5 -1
  92. package/dist/excalidraw/constants.js +9 -1
  93. package/dist/excalidraw/context/tunnels.d.ts +2 -1
  94. package/dist/excalidraw/context/tunnels.js +3 -1
  95. package/dist/excalidraw/data/blob.d.ts +1 -0
  96. package/dist/excalidraw/data/blob.js +7 -3
  97. package/dist/excalidraw/data/filesystem.d.ts +2 -1
  98. package/dist/excalidraw/data/filesystem.js +1 -0
  99. package/dist/excalidraw/data/image.d.ts +0 -6
  100. package/dist/excalidraw/data/image.js +1 -43
  101. package/dist/excalidraw/data/index.js +6 -6
  102. package/dist/excalidraw/data/library.d.ts +9 -3
  103. package/dist/excalidraw/data/library.js +43 -6
  104. package/dist/excalidraw/data/restore.js +26 -8
  105. package/dist/excalidraw/data/url.d.ts +0 -1
  106. package/dist/excalidraw/data/url.js +2 -4
  107. package/dist/excalidraw/editor-jotai.d.ts +56 -0
  108. package/dist/excalidraw/editor-jotai.js +8 -0
  109. package/dist/excalidraw/element/binding.d.ts +9 -6
  110. package/dist/excalidraw/element/binding.js +124 -44
  111. package/dist/excalidraw/element/bounds.js +10 -0
  112. package/dist/excalidraw/element/cropElement.d.ts +5 -0
  113. package/dist/excalidraw/element/cropElement.js +28 -1
  114. package/dist/excalidraw/element/dragElements.js +13 -7
  115. package/dist/excalidraw/element/elbowArrow.d.ts +16 -0
  116. package/dist/excalidraw/element/elbowArrow.js +1268 -0
  117. package/dist/excalidraw/element/embeddable.js +4 -5
  118. package/dist/excalidraw/element/flowchart.d.ts +1 -1
  119. package/dist/excalidraw/element/flowchart.js +25 -9
  120. package/dist/excalidraw/element/heading.d.ts +5 -1
  121. package/dist/excalidraw/element/heading.js +5 -1
  122. package/dist/excalidraw/element/image.js +19 -5
  123. package/dist/excalidraw/element/linearElementEditor.d.ts +9 -10
  124. package/dist/excalidraw/element/linearElementEditor.js +97 -38
  125. package/dist/excalidraw/element/mutateElement.d.ts +3 -1
  126. package/dist/excalidraw/element/mutateElement.js +31 -4
  127. package/dist/excalidraw/element/newElement.d.ts +8 -12
  128. package/dist/excalidraw/element/newElement.js +36 -21
  129. package/dist/excalidraw/element/resizeElements.d.ts +20 -5
  130. package/dist/excalidraw/element/resizeElements.js +593 -361
  131. package/dist/excalidraw/element/sortElements.js +1 -4
  132. package/dist/excalidraw/element/types.d.ts +23 -1
  133. package/dist/excalidraw/fonts/Fonts.d.ts +0 -16
  134. package/dist/excalidraw/fonts/Fonts.js +6 -31
  135. package/dist/excalidraw/frame.d.ts +11 -5
  136. package/dist/excalidraw/frame.js +146 -35
  137. package/dist/excalidraw/groups.js +3 -0
  138. package/dist/excalidraw/hooks/useLibraryItemSvg.d.ts +1 -1
  139. package/dist/excalidraw/hooks/useLibraryItemSvg.js +2 -3
  140. package/dist/excalidraw/hooks/useScrollPosition.js +1 -1
  141. package/dist/excalidraw/i18n.js +3 -4
  142. package/dist/excalidraw/index.js +3 -4
  143. package/dist/excalidraw/locales/en.json +8 -1
  144. package/dist/excalidraw/renderer/interactiveScene.js +43 -32
  145. package/dist/excalidraw/renderer/staticScene.js +6 -4
  146. package/dist/excalidraw/renderer/staticSvgScene.js +1 -1
  147. package/dist/excalidraw/scene/Shape.js +40 -17
  148. package/dist/excalidraw/scene/comparisons.d.ts +0 -477
  149. package/dist/excalidraw/scene/comparisons.js +0 -37
  150. package/dist/excalidraw/scene/export.d.ts +7 -0
  151. package/dist/excalidraw/scene/export.js +107 -43
  152. package/dist/excalidraw/scene/index.d.ts +1 -1
  153. package/dist/excalidraw/scene/index.js +1 -1
  154. package/dist/excalidraw/scene/selection.js +4 -1
  155. package/dist/excalidraw/types.d.ts +15 -0
  156. package/dist/excalidraw/utility-types.d.ts +1 -0
  157. package/dist/excalidraw/utils.d.ts +8 -1
  158. package/dist/excalidraw/utils.js +9 -0
  159. package/dist/excalidraw/visualdebug.d.ts +8 -1
  160. package/dist/excalidraw/visualdebug.js +3 -0
  161. package/dist/math/line.d.ts +19 -0
  162. package/dist/math/line.js +32 -3
  163. package/dist/math/point.d.ts +10 -0
  164. package/dist/math/point.js +12 -1
  165. package/dist/prod/index.css +1 -1
  166. package/dist/prod/index.js +29 -44
  167. package/dist/{dev/locales/en-ZXYG7GCR.json → prod/locales/en-V6KXFSCK.json} +8 -1
  168. package/package.json +5 -2
  169. package/dist/browser/dev/excalidraw-assets-dev/chunk-JGDL4H2X.js.map +0 -7
  170. package/dist/browser/dev/excalidraw-assets-dev/chunk-V7NFEZA6.js.map +0 -7
  171. package/dist/browser/prod/excalidraw-assets/chunk-S2XKB3DE.js +0 -62
  172. package/dist/browser/prod/excalidraw-assets/image-OFI2YYMP.js +0 -1
  173. package/dist/excalidraw/element/routing.d.ts +0 -12
  174. package/dist/excalidraw/element/routing.js +0 -642
  175. package/dist/excalidraw/jotai.d.ts +0 -34
  176. package/dist/excalidraw/jotai.js +0 -18
  177. /package/dist/browser/dev/excalidraw-assets-dev/{en-ZSVWGT55.js.map → en-7IBTMWBG.js.map} +0 -0
  178. /package/dist/browser/dev/excalidraw-assets-dev/{image-RJG3J34Y.js.map → image-N5AC7SEK.js.map} +0 -0
@@ -5,15 +5,25 @@ import { renderSelectionElement } from "../renderer/renderElement";
5
5
  import { getClientColor, renderRemoteCursors } from "../clients";
6
6
  import { isSelectedViaGroup, getSelectedGroupIds, getElementsInGroup, selectGroupsFromGivenElements, } from "../groups";
7
7
  import { getOmitSidesForDevice, shouldShowBoundingBox, } from "../element/transformHandles";
8
- import { arrayToMap, throttleRAF } from "../utils";
8
+ import { arrayToMap, invariant, throttleRAF } from "../utils";
9
9
  import { DEFAULT_TRANSFORM_HANDLE_SPACING, FRAME_STYLE, THEME, } from "../constants";
10
10
  import { renderSnaps } from "../renderer/renderSnaps";
11
- import { maxBindingGap } from "../element/binding";
11
+ import { BINDING_HIGHLIGHT_OFFSET, BINDING_HIGHLIGHT_THICKNESS, maxBindingGap, } from "../element/binding";
12
12
  import { LinearElementEditor } from "../element/linearElementEditor";
13
13
  import { bootstrapCanvas, fillCircle, getNormalizedCanvasDimensions, } from "./helpers";
14
14
  import oc from "open-color";
15
15
  import { isElbowArrow, isFrameLikeElement, isImageElement, isLinearElement, isTextElement, } from "../element/typeChecks";
16
+ import { pointFrom, } from "../../math";
16
17
  import { getCornerRadius } from "../shapes";
18
+ const renderElbowArrowMidPointHighlight = (context, appState) => {
19
+ invariant(appState.selectedLinearElement, "selectedLinearElement is null");
20
+ const { segmentMidPointHoveredCoords } = appState.selectedLinearElement;
21
+ invariant(segmentMidPointHoveredCoords, "midPointCoords is null");
22
+ context.save();
23
+ context.translate(appState.scrollX, appState.scrollY);
24
+ highlightPoint(segmentMidPointHoveredCoords, context, appState);
25
+ context.restore();
26
+ };
17
27
  const renderLinearElementPointHighlight = (context, appState, elementsMap) => {
18
28
  const { elementId, hoverPointIndex } = appState.selectedLinearElement;
19
29
  if (appState.editingLinearElement?.selectedPointsIndices?.includes(hoverPointIndex)) {
@@ -83,16 +93,16 @@ const strokeEllipseWithRotation = (context, width, height, cx, cy, angle) => {
83
93
  context.ellipse(cx, cy, width / 2, height / 2, angle, 0, Math.PI * 2);
84
94
  context.stroke();
85
95
  };
86
- const renderBindingHighlightForBindableElement = (context, element, elementsMap) => {
96
+ const renderBindingHighlightForBindableElement = (context, element, elementsMap, zoom) => {
87
97
  const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
88
98
  const width = x2 - x1;
89
99
  const height = y2 - y1;
90
- const thickness = 10;
91
- // So that we don't overlap the element itself
92
- const strokeOffset = 4;
93
100
  context.strokeStyle = "rgba(0,0,0,.05)";
94
- context.lineWidth = thickness - strokeOffset;
95
- const padding = strokeOffset / 2 + thickness / 2;
101
+ // When zooming out, make line width greater for visibility
102
+ const zoomValue = zoom.value < 1 ? zoom.value : 1;
103
+ context.lineWidth = BINDING_HIGHLIGHT_THICKNESS / zoomValue;
104
+ // To ensure the binding highlight doesn't overlap the element itself
105
+ const padding = context.lineWidth / 2 + BINDING_HIGHLIGHT_OFFSET;
96
106
  const radius = getCornerRadius(Math.min(element.width, element.height), element);
97
107
  switch (element.type) {
98
108
  case "rectangle":
@@ -115,9 +125,9 @@ const renderBindingHighlightForBindableElement = (context, element, elementsMap)
115
125
  break;
116
126
  }
117
127
  };
118
- const renderBindingHighlightForSuggestedPointBinding = (context, suggestedBinding, elementsMap) => {
128
+ const renderBindingHighlightForSuggestedPointBinding = (context, suggestedBinding, elementsMap, zoom) => {
119
129
  const [element, startOrEnd, bindableElement] = suggestedBinding;
120
- const threshold = maxBindingGap(bindableElement, bindableElement.width, bindableElement.height);
130
+ const threshold = maxBindingGap(bindableElement, bindableElement.width, bindableElement.height, zoom);
121
131
  context.strokeStyle = "rgba(0,0,0,0)";
122
132
  context.fillStyle = "rgba(0,0,0,.05)";
123
133
  const pointIndices = startOrEnd === "both" ? [0, -1] : startOrEnd === "start" ? [0] : [-1];
@@ -157,7 +167,7 @@ const renderBindingHighlight = (context, appState, suggestedBinding, elementsMap
157
167
  : renderBindingHighlightForBindableElement;
158
168
  context.save();
159
169
  context.translate(appState.scrollX, appState.scrollY);
160
- renderHighlight(context, suggestedBinding, elementsMap);
170
+ renderHighlight(context, suggestedBinding, elementsMap, appState.zoom);
161
171
  context.restore();
162
172
  };
163
173
  const renderFrameHighlight = (context, appState, frame, elementsMap) => {
@@ -219,28 +229,24 @@ const renderLinearPointHandles = (context, appState, element, elementsMap) => {
219
229
  const isSelected = !!appState.editingLinearElement?.selectedPointsIndices?.includes(idx);
220
230
  renderSingleLinearPoint(context, appState, point, radius, isSelected);
221
231
  });
222
- //Rendering segment mid points
223
- const midPoints = LinearElementEditor.getEditorMidPoints(element, elementsMap, appState).filter((midPoint) => midPoint !== null);
224
- midPoints.forEach((segmentMidPoint) => {
225
- if (appState?.selectedLinearElement?.segmentMidPointHoveredCoords &&
226
- LinearElementEditor.arePointsEqual(segmentMidPoint, appState.selectedLinearElement.segmentMidPointHoveredCoords)) {
227
- // The order of renderingSingleLinearPoint and highLight points is different
228
- // inside vs outside editor as hover states are different,
229
- // in editor when hovered the original point is not visible as hover state fully covers it whereas outside the
230
- // editor original point is visible and hover state is just an outer circle.
231
- if (appState.editingLinearElement) {
232
- renderSingleLinearPoint(context, appState, segmentMidPoint, radius, false);
233
- highlightPoint(segmentMidPoint, context, appState);
232
+ // Rendering segment mid points
233
+ if (isElbowArrow(element)) {
234
+ const fixedSegments = element.fixedSegments?.map((segment) => segment.index) || [];
235
+ points.slice(0, -1).forEach((p, idx) => {
236
+ if (!LinearElementEditor.isSegmentTooShort(element, points[idx + 1], points[idx], idx, appState.zoom)) {
237
+ renderSingleLinearPoint(context, appState, pointFrom((p[0] + points[idx + 1][0]) / 2, (p[1] + points[idx + 1][1]) / 2), POINT_HANDLE_SIZE / 2, false, !fixedSegments.includes(idx + 1));
234
238
  }
235
- else {
236
- highlightPoint(segmentMidPoint, context, appState);
237
- renderSingleLinearPoint(context, appState, segmentMidPoint, radius, false);
239
+ });
240
+ }
241
+ else {
242
+ const midPoints = LinearElementEditor.getEditorMidPoints(element, elementsMap, appState).filter((midPoint, idx, midPoints) => midPoint !== null &&
243
+ !(isElbowArrow(element) && (idx === 0 || idx === midPoints.length - 1)));
244
+ midPoints.forEach((segmentMidPoint) => {
245
+ if (appState.editingLinearElement || points.length === 2) {
246
+ renderSingleLinearPoint(context, appState, segmentMidPoint, POINT_HANDLE_SIZE / 2, false, true);
238
247
  }
239
- }
240
- else if (appState.editingLinearElement || points.length === 2) {
241
- renderSingleLinearPoint(context, appState, segmentMidPoint, POINT_HANDLE_SIZE / 2, false, true);
242
- }
243
- });
248
+ });
249
+ }
244
250
  context.restore();
245
251
  };
246
252
  const renderTransformHandles = (context, renderConfig, appState, transformHandles, angle) => {
@@ -421,7 +427,12 @@ const _renderInteractiveScene = ({ canvas, elementsMap, visibleElements, selecte
421
427
  appState.editingLinearElement?.elementId === selectedElements[0].id) {
422
428
  renderLinearPointHandles(context, appState, selectedElements[0], elementsMap);
423
429
  }
424
- if (appState.selectedLinearElement &&
430
+ if (isElbowArrow(selectedElements[0]) &&
431
+ appState.selectedLinearElement &&
432
+ appState.selectedLinearElement.segmentMidPointHoveredCoords) {
433
+ renderElbowArrowMidPointHighlight(context, appState);
434
+ }
435
+ else if (appState.selectedLinearElement &&
425
436
  appState.selectedLinearElement.hoverPointIndex >= 0 &&
426
437
  !(isElbowArrow(selectedElements[0]) &&
427
438
  appState.selectedLinearElement.hoverPointIndex > 0 &&
@@ -1,6 +1,6 @@
1
1
  import { FRAME_STYLE } from "../constants";
2
2
  import { getElementAbsoluteCoords } from "../element";
3
- import { elementOverlapsWithFrame, getTargetFrame, isElementInFrame, } from "../frame";
3
+ import { elementOverlapsWithFrame, getTargetFrame, shouldApplyFrameClip, } from "../frame";
4
4
  import { isEmbeddableElement, isIframeLikeElement, isTextElement, } from "../element/typeChecks";
5
5
  import { renderElement } from "../renderer/renderElement";
6
6
  import { createPlaceholderEmbeddableLabel } from "../element/embeddable";
@@ -148,6 +148,7 @@ const _renderStaticScene = ({ canvas, rc, elementsMap, allElementsMap, visibleEl
148
148
  element.groupIds.forEach((groupId) => groupsToBeAddedToFrame.add(groupId));
149
149
  }
150
150
  });
151
+ const inFrameGroupsMap = new Map();
151
152
  // Paint visible elements
152
153
  visibleElements
153
154
  .filter((el) => !isIframeLikeElement(el))
@@ -165,8 +166,8 @@ const _renderStaticScene = ({ canvas, rc, elementsMap, allElementsMap, visibleEl
165
166
  appState.frameRendering.enabled &&
166
167
  appState.frameRendering.clip) {
167
168
  const frame = getTargetFrame(element, elementsMap, appState);
168
- // TODO do we need to check isElementInFrame here?
169
- if (frame && isElementInFrame(element, elementsMap, appState)) {
169
+ if (frame &&
170
+ shouldApplyFrameClip(element, frame, appState, elementsMap, inFrameGroupsMap)) {
170
171
  frameClip(frame, context, renderConfig, appState);
171
172
  }
172
173
  renderElement(element, elementsMap, allElementsMap, rc, context, renderConfig, appState);
@@ -217,7 +218,8 @@ const _renderStaticScene = ({ canvas, rc, elementsMap, allElementsMap, visibleEl
217
218
  appState.frameRendering.clip) {
218
219
  context.save();
219
220
  const frame = getTargetFrame(element, elementsMap, appState);
220
- if (frame && isElementInFrame(element, elementsMap, appState)) {
221
+ if (frame &&
222
+ shouldApplyFrameClip(element, frame, appState, elementsMap, inFrameGroupsMap)) {
221
223
  frameClip(frame, context, renderConfig, appState);
222
224
  }
223
225
  render();
@@ -263,7 +263,7 @@ const renderElementToSvg = (element, elementsMap, rsvg, svgRoot, files, offsetX,
263
263
  image.setAttribute("height", "100%");
264
264
  }
265
265
  symbol.appendChild(image);
266
- root.prepend(symbol);
266
+ (root.querySelector("defs") || root).prepend(symbol);
267
267
  }
268
268
  const use = svgRoot.ownerDocument.createElementNS(SVG_NS, "use");
269
269
  use.setAttribute("href", `#${symbolId}`);
@@ -5,8 +5,9 @@ import { simplify } from "points-on-curve";
5
5
  import { ROUGHNESS } from "../constants";
6
6
  import { isElbowArrow, isEmbeddableElement, isIframeElement, isIframeLikeElement, isLinearElement, } from "../element/typeChecks";
7
7
  import { canChangeRoundness } from "./comparisons";
8
- import { pointFrom, pointDistance, } from "../../math";
8
+ import { pointFrom, pointDistance } from "../../math";
9
9
  import { getCornerRadius, isPathALoop } from "../shapes";
10
+ import { headingForPointIsHorizontal } from "../element/heading";
10
11
  const getDashArrayDashed = (strokeWidth) => [8, 8 + strokeWidth];
11
12
  const getDashArrayDotted = (strokeWidth) => [1.5, 6 + strokeWidth];
12
13
  function adjustRoughness(element) {
@@ -117,6 +118,13 @@ const getArrowheadShapes = (element, shape, position, arrowhead, generator, opti
117
118
  if (arrowheadPoints === null) {
118
119
  return [];
119
120
  }
121
+ const generateCrowfootOne = (arrowheadPoints, options) => {
122
+ if (arrowheadPoints === null) {
123
+ return [];
124
+ }
125
+ const [, , x3, y3, x4, y4] = arrowheadPoints;
126
+ return [generator.line(x3, y3, x4, y4, options)];
127
+ };
120
128
  switch (arrowhead) {
121
129
  case "dot":
122
130
  case "circle":
@@ -179,8 +187,12 @@ const getArrowheadShapes = (element, shape, position, arrowhead, generator, opti
179
187
  }),
180
188
  ];
181
189
  }
190
+ case "crowfoot_one":
191
+ return generateCrowfootOne(arrowheadPoints, options);
182
192
  case "bar":
183
193
  case "arrow":
194
+ case "crowfoot_many":
195
+ case "crowfoot_one_or_many":
184
196
  default: {
185
197
  const [x2, y2, x3, y3, x4, y4] = arrowheadPoints;
186
198
  if (element.strokeStyle === "dotted") {
@@ -196,6 +208,9 @@ const getArrowheadShapes = (element, shape, position, arrowhead, generator, opti
196
208
  return [
197
209
  generator.line(x3, y3, x2, y2, options),
198
210
  generator.line(x4, y4, x2, y2, options),
211
+ ...(arrowhead === "crowfoot_one_or_many"
212
+ ? generateCrowfootOne(getArrowheadPoints(element, shape, position, "crowfoot_one"), options)
213
+ : []),
199
214
  ];
200
215
  }
201
216
  }
@@ -339,36 +354,44 @@ const generateElbowArrowShape = (points, radius) => {
339
354
  for (let i = 1; i < points.length - 1; i += 1) {
340
355
  const prev = points[i - 1];
341
356
  const next = points[i + 1];
357
+ const point = points[i];
358
+ const prevIsHorizontal = headingForPointIsHorizontal(point, prev);
359
+ const nextIsHorizontal = headingForPointIsHorizontal(next, point);
342
360
  const corner = Math.min(radius, pointDistance(points[i], next) / 2, pointDistance(points[i], prev) / 2);
343
- if (prev[0] < points[i][0] && prev[1] === points[i][1]) {
344
- // LEFT
345
- subpoints.push([points[i][0] - corner, points[i][1]]);
361
+ if (prevIsHorizontal) {
362
+ if (prev[0] < point[0]) {
363
+ // LEFT
364
+ subpoints.push([points[i][0] - corner, points[i][1]]);
365
+ }
366
+ else {
367
+ // RIGHT
368
+ subpoints.push([points[i][0] + corner, points[i][1]]);
369
+ }
346
370
  }
347
- else if (prev[0] === points[i][0] && prev[1] < points[i][1]) {
371
+ else if (prev[1] < point[1]) {
348
372
  // UP
349
373
  subpoints.push([points[i][0], points[i][1] - corner]);
350
374
  }
351
- else if (prev[0] > points[i][0] && prev[1] === points[i][1]) {
352
- // RIGHT
353
- subpoints.push([points[i][0] + corner, points[i][1]]);
354
- }
355
375
  else {
356
376
  subpoints.push([points[i][0], points[i][1] + corner]);
357
377
  }
358
378
  subpoints.push(points[i]);
359
- if (next[0] < points[i][0] && next[1] === points[i][1]) {
360
- // LEFT
361
- subpoints.push([points[i][0] - corner, points[i][1]]);
379
+ if (nextIsHorizontal) {
380
+ if (next[0] < point[0]) {
381
+ // LEFT
382
+ subpoints.push([points[i][0] - corner, points[i][1]]);
383
+ }
384
+ else {
385
+ // RIGHT
386
+ subpoints.push([points[i][0] + corner, points[i][1]]);
387
+ }
362
388
  }
363
- else if (next[0] === points[i][0] && next[1] < points[i][1]) {
389
+ else if (next[1] < point[1]) {
364
390
  // UP
365
391
  subpoints.push([points[i][0], points[i][1] - corner]);
366
392
  }
367
- else if (next[0] > points[i][0] && next[1] === points[i][1]) {
368
- // RIGHT
369
- subpoints.push([points[i][0] + corner, points[i][1]]);
370
- }
371
393
  else {
394
+ // DOWN
372
395
  subpoints.push([points[i][0], points[i][1] + corner]);
373
396
  }
374
397
  }