@excalidraw/element 0.18.0-51ad895 → 0.18.0-54a9826
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.
- package/dist/dev/index.js +2215 -742
- package/dist/dev/index.js.map +4 -4
- package/dist/prod/index.js +17 -17
- package/dist/types/common/src/bounds.d.ts +10 -0
- package/dist/types/common/src/colors.d.ts +59 -39
- package/dist/types/common/src/constants.d.ts +16 -11
- package/dist/types/common/src/editorInterface.d.ts +1 -1
- package/dist/types/common/src/font-metadata.d.ts +1 -3
- package/dist/types/common/src/index.d.ts +1 -1
- package/dist/types/common/src/keys.d.ts +1 -1
- package/dist/types/common/src/utility-types.d.ts +0 -1
- package/dist/types/common/src/utils.d.ts +43 -34
- package/dist/types/element/src/Scene.d.ts +3 -3
- package/dist/types/element/src/arrows/focus.d.ts +27 -0
- package/dist/types/element/src/arrows/helpers.d.ts +5 -0
- package/dist/types/element/src/binding.d.ts +13 -6
- package/dist/types/element/src/bounds.d.ts +2 -10
- package/dist/types/element/src/collision.d.ts +4 -3
- package/dist/types/element/src/comparisons.d.ts +7 -7
- package/dist/types/element/src/distribute.d.ts +2 -1
- package/dist/types/element/src/dragElements.d.ts +3 -3
- package/dist/types/element/src/duplicate.d.ts +3 -3
- package/dist/types/element/src/fractionalIndex.d.ts +2 -2
- package/dist/types/element/src/frame.d.ts +5 -1
- package/dist/types/element/src/heading.d.ts +2 -1
- package/dist/types/element/src/image.d.ts +1 -11
- package/dist/types/element/src/index.d.ts +3 -0
- package/dist/types/element/src/linearElementEditor.d.ts +3 -2
- package/dist/types/element/src/mutateElement.d.ts +3 -1
- package/dist/types/element/src/newElement.d.ts +6 -6
- package/dist/types/element/src/renderElement.d.ts +0 -6
- package/dist/types/element/src/resizeElements.d.ts +10 -10
- package/dist/types/element/src/resizeTest.d.ts +1 -1
- package/dist/types/element/src/selection.d.ts +3 -7
- package/dist/types/element/src/shape.d.ts +8 -7
- package/dist/types/element/src/textMeasurements.d.ts +1 -3
- package/dist/types/{excalidraw/data → element/src}/transform.d.ts +3 -3
- package/dist/types/element/src/transformHandles.d.ts +3 -23
- package/dist/types/element/src/typeChecks.d.ts +2 -4
- package/dist/types/element/src/utils.d.ts +3 -1
- package/dist/types/{common → element}/src/visualdebug.d.ts +20 -2
- package/dist/types/element/src/zindex.d.ts +1 -1
- package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +62 -126
- package/dist/types/excalidraw/actions/actionAlign.d.ts +0 -1
- package/dist/types/excalidraw/actions/actionBoundText.d.ts +44 -87
- package/dist/types/excalidraw/actions/actionCanvas.d.ts +263 -510
- package/dist/types/excalidraw/actions/actionClipboard.d.ts +44 -87
- package/dist/types/excalidraw/actions/actionCropEditor.d.ts +21 -43
- package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +76 -142
- package/dist/types/excalidraw/actions/actionDistribute.d.ts +0 -1
- package/dist/types/excalidraw/actions/actionDuplicateSelection.d.ts +0 -1
- package/dist/types/excalidraw/actions/actionElementLink.d.ts +18 -40
- package/dist/types/excalidraw/actions/actionElementLock.d.ts +45 -88
- package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +22 -44
- package/dist/types/excalidraw/actions/actionExport.d.ts +85 -170
- package/dist/types/excalidraw/actions/actionFinalize.d.ts +1 -2
- package/dist/types/excalidraw/actions/actionFlip.d.ts +0 -1
- package/dist/types/excalidraw/actions/actionFrame.d.ts +181 -302
- package/dist/types/excalidraw/actions/actionGroup.d.ts +48 -99
- package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +124 -180
- package/dist/types/excalidraw/actions/actionLink.d.ts +22 -44
- package/dist/types/excalidraw/actions/actionMenu.d.ts +17 -39
- package/dist/types/excalidraw/actions/actionNavigate.d.ts +14 -17
- package/dist/types/excalidraw/actions/actionProperties.d.ts +59 -102
- package/dist/types/excalidraw/actions/actionSelectAll.d.ts +24 -50
- package/dist/types/excalidraw/actions/actionStyles.d.ts +20 -42
- package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +22 -44
- package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +22 -44
- package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +16 -38
- package/dist/types/excalidraw/actions/actionToggleStats.d.ts +22 -44
- package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +22 -44
- package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +22 -44
- package/dist/types/excalidraw/actions/actionZindex.d.ts +0 -1
- package/dist/types/excalidraw/actions/manager.d.ts +1 -1
- package/dist/types/excalidraw/actions/register.d.ts +2 -2
- package/dist/types/excalidraw/appState.d.ts +3 -3
- package/dist/types/excalidraw/clipboard.d.ts +11 -33
- package/dist/types/excalidraw/components/Actions.d.ts +1 -1
- package/dist/types/excalidraw/components/App.d.ts +39 -41
- package/dist/types/excalidraw/components/Card.d.ts +1 -3
- package/dist/types/excalidraw/components/ColorPicker/ColorInput.d.ts +2 -4
- package/dist/types/excalidraw/components/ColorPicker/ColorPicker.d.ts +0 -1
- package/dist/types/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +0 -1
- package/dist/types/excalidraw/components/ColorPicker/keyboardNavHandlers.d.ts +0 -1
- package/dist/types/excalidraw/components/CommandPalette/types.d.ts +0 -1
- package/dist/types/excalidraw/components/ConvertElementTypePopup.d.ts +2 -2
- package/dist/types/excalidraw/components/DarkModeToggle.d.ts +1 -1
- package/dist/types/excalidraw/components/DefaultSidebar.d.ts +9 -13
- package/dist/types/excalidraw/components/ElementLinkDialog.d.ts +1 -1
- package/dist/types/excalidraw/components/Ellipsify.d.ts +1 -2
- package/dist/types/excalidraw/components/ErrorDialog.d.ts +1 -1
- package/dist/types/excalidraw/components/ExcalidrawLogo.d.ts +0 -1
- package/dist/types/excalidraw/components/EyeDropper.d.ts +0 -1
- package/dist/types/excalidraw/components/FilledButton.d.ts +1 -0
- package/dist/types/excalidraw/components/FontPicker/keyboardNavHandlers.d.ts +0 -1
- package/dist/types/excalidraw/components/HelpDialog.d.ts +1 -1
- package/dist/types/excalidraw/components/InlineIcon.d.ts +2 -2
- package/dist/types/excalidraw/components/LibraryMenuControlButtons.d.ts +1 -1
- package/dist/types/excalidraw/components/LibraryMenuHeaderContent.d.ts +1 -2
- package/dist/types/excalidraw/components/LibraryUnit.d.ts +2 -3
- package/dist/types/excalidraw/components/LoadingMessage.d.ts +0 -1
- package/dist/types/excalidraw/components/MobileToolBar.d.ts +0 -1
- package/dist/types/excalidraw/components/Modal.d.ts +0 -1
- package/dist/types/excalidraw/components/OverwriteConfirm/OverwriteConfirm.d.ts +1 -1
- package/dist/types/excalidraw/components/RadioGroup.d.ts +0 -1
- package/dist/types/excalidraw/components/RadioSelection.d.ts +4 -4
- package/dist/types/excalidraw/components/ScrollableList.d.ts +0 -1
- package/dist/types/excalidraw/components/Sidebar/Sidebar.d.ts +15 -21
- package/dist/types/excalidraw/components/Sidebar/SidebarHeader.d.ts +1 -1
- package/dist/types/excalidraw/components/Sidebar/SidebarTab.d.ts +1 -2
- package/dist/types/excalidraw/components/Sidebar/SidebarTabTrigger.d.ts +1 -2
- package/dist/types/excalidraw/components/Sidebar/SidebarTabTriggers.d.ts +1 -2
- package/dist/types/excalidraw/components/Sidebar/SidebarTabs.d.ts +1 -2
- package/dist/types/excalidraw/components/Spinner.d.ts +4 -4
- package/dist/types/excalidraw/components/Stats/CanvasGrid.d.ts +0 -1
- package/dist/types/excalidraw/components/Stats/Collapsible.d.ts +0 -1
- package/dist/types/excalidraw/components/Stats/DragInput.d.ts +0 -1
- package/dist/types/excalidraw/components/Stats/index.d.ts +7 -8
- package/dist/types/excalidraw/components/TTDDialog/Chat/ChatHistoryMenu.d.ts +15 -0
- package/dist/types/excalidraw/components/TTDDialog/Chat/ChatInterface.d.ts +23 -0
- package/dist/types/excalidraw/components/TTDDialog/Chat/ChatMessage.d.ts +14 -0
- package/dist/types/excalidraw/components/TTDDialog/Chat/TTDChatPanel.d.ts +27 -0
- package/dist/types/excalidraw/components/TTDDialog/Chat/index.d.ts +3 -0
- package/dist/types/excalidraw/components/TTDDialog/Chat/useChatAgent.d.ts +8 -0
- package/dist/types/excalidraw/components/TTDDialog/MermaidToExcalidraw.d.ts +3 -2
- package/dist/types/excalidraw/components/TTDDialog/TTDContext.d.ts +13 -0
- package/dist/types/excalidraw/components/TTDDialog/TTDDialog.d.ts +12 -29
- package/dist/types/excalidraw/components/TTDDialog/TTDDialogOutput.d.ts +2 -2
- package/dist/types/excalidraw/components/TTDDialog/TTDDialogPanel.d.ts +13 -9
- package/dist/types/excalidraw/components/TTDDialog/TTDDialogTab.d.ts +1 -2
- package/dist/types/excalidraw/components/TTDDialog/TTDDialogTabTrigger.d.ts +1 -2
- package/dist/types/excalidraw/components/TTDDialog/TTDDialogTabTriggers.d.ts +1 -2
- package/dist/types/excalidraw/components/TTDDialog/TTDDialogTrigger.d.ts +1 -1
- package/dist/types/excalidraw/components/TTDDialog/TTDPreviewPanel.d.ts +9 -0
- package/dist/types/excalidraw/components/TTDDialog/TTDWelcomeMessage.d.ts +1 -0
- package/dist/types/excalidraw/components/TTDDialog/TextToDiagram.d.ts +9 -0
- package/dist/types/excalidraw/components/TTDDialog/common.d.ts +16 -16
- package/dist/types/excalidraw/components/TTDDialog/hooks/useChatManagement.d.ts +13 -0
- package/dist/types/excalidraw/components/TTDDialog/hooks/useMermaidRenderer.d.ts +14 -0
- package/dist/types/excalidraw/components/TTDDialog/hooks/useTextGeneration.d.ts +7 -0
- package/dist/types/excalidraw/components/TTDDialog/types.d.ts +95 -0
- package/dist/types/excalidraw/components/TTDDialog/useTTDChatStorage.d.ts +22 -0
- package/dist/types/excalidraw/components/TTDDialog/utils/TTDStreamFetch.d.ts +24 -0
- package/dist/types/excalidraw/components/TTDDialog/utils/chat.d.ts +10 -0
- package/dist/types/excalidraw/components/TTDDialog/utils/mermaidValidation.d.ts +1 -0
- package/dist/types/excalidraw/components/Toast.d.ts +3 -3
- package/dist/types/excalidraw/components/Trans.d.ts +2 -2
- package/dist/types/excalidraw/components/dropdownMenu/DropdownMenu.d.ts +30 -33
- package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuContent.d.ts +5 -5
- package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuGroup.d.ts +3 -3
- package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItem.d.ts +12 -19
- package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemContent.d.ts +5 -4
- package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.d.ts +0 -1
- package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemCustom.d.ts +2 -2
- package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemLink.d.ts +6 -6
- package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuTrigger.d.ts +3 -4
- package/dist/types/excalidraw/components/dropdownMenu/common.d.ts +1 -1
- package/dist/types/excalidraw/components/hoc/withInternalFallback.d.ts +1 -1
- package/dist/types/excalidraw/components/hyperlink/helpers.d.ts +1 -1
- package/dist/types/excalidraw/components/icons.d.ts +16 -12
- package/dist/types/excalidraw/components/live-collaboration/LiveCollaborationTrigger.d.ts +2 -13
- package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +2 -2
- package/dist/types/excalidraw/components/main-menu/MainMenu.d.ts +26 -29
- package/dist/types/excalidraw/components/welcome-screen/WelcomeScreen.Center.d.ts +6 -6
- package/dist/types/excalidraw/components/welcome-screen/WelcomeScreen.d.ts +15 -16
- package/dist/types/excalidraw/data/blob.d.ts +321 -3
- package/dist/types/excalidraw/data/encode.d.ts +4 -4
- package/dist/types/excalidraw/data/encryption.d.ts +5 -5
- package/dist/types/excalidraw/data/filesystem.d.ts +2 -2
- package/dist/types/excalidraw/data/index.d.ts +3 -3
- package/dist/types/excalidraw/data/json.d.ts +159 -2
- package/dist/types/excalidraw/data/library.d.ts +24 -9
- package/dist/types/excalidraw/data/restore.d.ts +25 -10
- package/dist/types/excalidraw/editor-jotai.d.ts +11 -11
- package/dist/types/excalidraw/errors.d.ts +14 -0
- package/dist/types/excalidraw/hooks/useOutsideClick.d.ts +1 -2
- package/dist/types/excalidraw/hooks/useScrollPosition.d.ts +1 -2
- package/dist/types/excalidraw/i18n.d.ts +2 -2
- package/dist/types/excalidraw/index.d.ts +5 -4
- package/dist/types/excalidraw/renderer/helpers.d.ts +6 -4
- package/dist/types/excalidraw/renderer/interactiveScene.d.ts +8 -6
- package/dist/types/excalidraw/scene/Renderer.d.ts +5 -2
- package/dist/types/excalidraw/scene/export.d.ts +2 -2
- package/dist/types/excalidraw/scene/scroll.d.ts +1 -6
- package/dist/types/excalidraw/scene/types.d.ts +7 -2
- package/dist/types/excalidraw/snapping.d.ts +5 -5
- package/dist/types/excalidraw/subset/harfbuzz/harfbuzz-bindings.d.ts +1 -1
- package/dist/types/excalidraw/subset/harfbuzz/harfbuzz-loader.d.ts +1 -1
- package/dist/types/excalidraw/subset/harfbuzz/harfbuzz-wasm.d.ts +1 -1
- package/dist/types/excalidraw/subset/woff2/woff2-loader.d.ts +2 -2
- package/dist/types/excalidraw/subset/woff2/woff2-wasm.d.ts +1 -1
- package/dist/types/excalidraw/types.d.ts +2 -3
- package/dist/types/excalidraw/wysiwyg/textWysiwyg.d.ts +2 -2
- package/dist/types/math/src/polygon.d.ts +2 -2
- package/dist/types/math/src/range.d.ts +1 -3
- package/dist/types/math/src/segment.d.ts +3 -3
- package/dist/types/utils/src/bbox.d.ts +1 -1
- package/dist/types/utils/src/export.d.ts +5 -5
- package/dist/types/utils/src/shape.d.ts +6 -6
- package/dist/types/utils/src/withinBounds.d.ts +2 -2
- package/package.json +9 -3
package/dist/dev/index.js
CHANGED
|
@@ -199,7 +199,7 @@ import {
|
|
|
199
199
|
radiansBetweenAngles,
|
|
200
200
|
radiansDifference
|
|
201
201
|
} from "@excalidraw/math";
|
|
202
|
-
import { pointsEqual as
|
|
202
|
+
import { pointsEqual as pointsEqual7 } from "@excalidraw/math";
|
|
203
203
|
|
|
204
204
|
// src/bounds.ts
|
|
205
205
|
init_define_import_meta_env();
|
|
@@ -2447,21 +2447,6 @@ var getClosedCurveShape = (element, roughShape, startingPoint = pointFrom(0, 0),
|
|
|
2447
2447
|
|
|
2448
2448
|
// src/shape.ts
|
|
2449
2449
|
init_define_import_meta_env();
|
|
2450
|
-
import {
|
|
2451
|
-
pointFrom as pointFrom13,
|
|
2452
|
-
pointDistance as pointDistance6,
|
|
2453
|
-
pointRotateRads as pointRotateRads12
|
|
2454
|
-
} from "@excalidraw/math";
|
|
2455
|
-
import {
|
|
2456
|
-
ROUGHNESS,
|
|
2457
|
-
isTransparent as isTransparent3,
|
|
2458
|
-
assertNever as assertNever2,
|
|
2459
|
-
COLOR_PALETTE,
|
|
2460
|
-
LINE_POLYGON_POINT_MERGE_DISTANCE
|
|
2461
|
-
} from "@excalidraw/common";
|
|
2462
|
-
|
|
2463
|
-
// src/renderElement.ts
|
|
2464
|
-
init_define_import_meta_env();
|
|
2465
2450
|
|
|
2466
2451
|
// ../../node_modules/perfect-freehand/dist/esm/index.js
|
|
2467
2452
|
init_define_import_meta_env();
|
|
@@ -2626,7 +2611,24 @@ function ae(e, t = {}) {
|
|
|
2626
2611
|
return ce(me(e, t), t);
|
|
2627
2612
|
}
|
|
2628
2613
|
|
|
2614
|
+
// src/shape.ts
|
|
2615
|
+
import {
|
|
2616
|
+
pointFrom as pointFrom13,
|
|
2617
|
+
pointDistance as pointDistance6,
|
|
2618
|
+
pointRotateRads as pointRotateRads12
|
|
2619
|
+
} from "@excalidraw/math";
|
|
2620
|
+
import {
|
|
2621
|
+
ROUGHNESS,
|
|
2622
|
+
THEME as THEME2,
|
|
2623
|
+
isTransparent as isTransparent3,
|
|
2624
|
+
assertNever as assertNever2,
|
|
2625
|
+
COLOR_PALETTE,
|
|
2626
|
+
LINE_POLYGON_POINT_MERGE_DISTANCE,
|
|
2627
|
+
applyDarkModeFilter as applyDarkModeFilter2
|
|
2628
|
+
} from "@excalidraw/common";
|
|
2629
|
+
|
|
2629
2630
|
// src/renderElement.ts
|
|
2631
|
+
init_define_import_meta_env();
|
|
2630
2632
|
import {
|
|
2631
2633
|
isRightAngleRads,
|
|
2632
2634
|
lineSegment as lineSegment6,
|
|
@@ -2638,13 +2640,16 @@ import {
|
|
|
2638
2640
|
DEFAULT_REDUCED_GLOBAL_ALPHA,
|
|
2639
2641
|
ELEMENT_READY_TO_ERASE_OPACITY,
|
|
2640
2642
|
FRAME_STYLE,
|
|
2643
|
+
DARK_THEME_FILTER,
|
|
2641
2644
|
MIME_TYPES,
|
|
2642
2645
|
THEME,
|
|
2643
2646
|
distance as distance2,
|
|
2644
2647
|
getFontString as getFontString3,
|
|
2645
2648
|
isRTL,
|
|
2646
2649
|
getVerticalOffset,
|
|
2647
|
-
invariant as invariant9
|
|
2650
|
+
invariant as invariant9,
|
|
2651
|
+
applyDarkModeFilter,
|
|
2652
|
+
isSafari
|
|
2648
2653
|
} from "@excalidraw/common";
|
|
2649
2654
|
|
|
2650
2655
|
// src/cropElement.ts
|
|
@@ -3111,7 +3116,7 @@ import {
|
|
|
3111
3116
|
pointCenter as pointCenter2,
|
|
3112
3117
|
pointFrom as pointFrom9,
|
|
3113
3118
|
pointRotateRads as pointRotateRads9,
|
|
3114
|
-
pointsEqual as
|
|
3119
|
+
pointsEqual as pointsEqual6,
|
|
3115
3120
|
pointDistance as pointDistance5,
|
|
3116
3121
|
vectorFromPoint as vectorFromPoint8,
|
|
3117
3122
|
curveLength,
|
|
@@ -3129,7 +3134,6 @@ import {
|
|
|
3129
3134
|
} from "@excalidraw/common";
|
|
3130
3135
|
import {
|
|
3131
3136
|
deconstructLinearOrFreeDrawElement as deconstructLinearOrFreeDrawElement2,
|
|
3132
|
-
getHoveredElementForBinding as getHoveredElementForBinding2,
|
|
3133
3137
|
isPathALoop as isPathALoop2,
|
|
3134
3138
|
moveArrowAboveBindable,
|
|
3135
3139
|
projectFixedPointOntoDiagonal as projectFixedPointOntoDiagonal2
|
|
@@ -3153,6 +3157,7 @@ import {
|
|
|
3153
3157
|
pointFrom as pointFrom8,
|
|
3154
3158
|
pointFromVector as pointFromVector6,
|
|
3155
3159
|
pointRotateRads as pointRotateRads8,
|
|
3160
|
+
pointsEqual as pointsEqual5,
|
|
3156
3161
|
vectorFromPoint as vectorFromPoint7,
|
|
3157
3162
|
vectorNormalize as vectorNormalize4,
|
|
3158
3163
|
vectorScale as vectorScale7
|
|
@@ -3350,7 +3355,6 @@ var getDefaultRoundnessTypeForElement = (element) => {
|
|
|
3350
3355
|
}
|
|
3351
3356
|
return null;
|
|
3352
3357
|
};
|
|
3353
|
-
var isBounds = (box) => Array.isArray(box) && box.length === 4 && typeof box[0] === "number" && typeof box[1] === "number" && typeof box[2] === "number" && typeof box[3] === "number";
|
|
3354
3358
|
var getLinearElementSubType = (element) => {
|
|
3355
3359
|
if (isSharpArrow(element)) {
|
|
3356
3360
|
return "sharpArrow";
|
|
@@ -4776,6 +4780,11 @@ var shouldTestInside = (element) => {
|
|
|
4776
4780
|
}
|
|
4777
4781
|
return isDraggableFromInside || isImageElement(element);
|
|
4778
4782
|
};
|
|
4783
|
+
var cachedPoint = null;
|
|
4784
|
+
var cachedElement = null;
|
|
4785
|
+
var cachedThreshold = Infinity;
|
|
4786
|
+
var cachedHit = false;
|
|
4787
|
+
var cachedOverrideShouldTestInside = false;
|
|
4779
4788
|
var hitElementItself = ({
|
|
4780
4789
|
point,
|
|
4781
4790
|
element,
|
|
@@ -4784,6 +4793,12 @@ var hitElementItself = ({
|
|
|
4784
4793
|
frameNameBound = null,
|
|
4785
4794
|
overrideShouldTestInside = false
|
|
4786
4795
|
}) => {
|
|
4796
|
+
if (cachedPoint && pointsEqual2(point, cachedPoint) && cachedThreshold <= threshold && overrideShouldTestInside === cachedOverrideShouldTestInside) {
|
|
4797
|
+
const derefElement = cachedElement?.deref();
|
|
4798
|
+
if (derefElement && derefElement.id === element.id && derefElement.version === element.version && derefElement.versionNonce === element.versionNonce) {
|
|
4799
|
+
return cachedHit;
|
|
4800
|
+
}
|
|
4801
|
+
}
|
|
4787
4802
|
const hitFrameName = frameNameBound ? isPointWithinBounds(
|
|
4788
4803
|
pointFrom5(frameNameBound.x - threshold, frameNameBound.y - threshold),
|
|
4789
4804
|
point,
|
|
@@ -4810,7 +4825,13 @@ var hitElementItself = ({
|
|
|
4810
4825
|
// we would need `onShape` as well to include the "borders"
|
|
4811
4826
|
isPointInElement(point, element, elementsMap) || isPointOnElementOutline(point, element, elementsMap, threshold)
|
|
4812
4827
|
) : isPointOnElementOutline(point, element, elementsMap, threshold);
|
|
4813
|
-
|
|
4828
|
+
const result = hitElement || hitFrameName;
|
|
4829
|
+
cachedPoint = point;
|
|
4830
|
+
cachedElement = new WeakRef(element);
|
|
4831
|
+
cachedThreshold = threshold;
|
|
4832
|
+
cachedOverrideShouldTestInside = overrideShouldTestInside;
|
|
4833
|
+
cachedHit = result;
|
|
4834
|
+
return result;
|
|
4814
4835
|
};
|
|
4815
4836
|
var hitElementBoundingBox = (point, element, elementsMap, tolerance = 0) => {
|
|
4816
4837
|
let [x1, y1, x2, y2] = getElementBounds(element, elementsMap);
|
|
@@ -4872,7 +4893,7 @@ var bindingBorderTest = (element, [x, y], elementsMap, tolerance = 0) => {
|
|
|
4872
4893
|
const distance3 = distanceToElement(element, elementsMap, p);
|
|
4873
4894
|
return shouldTestInside2 ? intersections.length === 0 || distance3 <= tolerance : intersections.length > 0 && distance3 <= t;
|
|
4874
4895
|
};
|
|
4875
|
-
var getAllHoveredElementAtPoint = (point, elements, elementsMap,
|
|
4896
|
+
var getAllHoveredElementAtPoint = (point, elements, elementsMap, tolerance) => {
|
|
4876
4897
|
const candidateElements = [];
|
|
4877
4898
|
for (let index = elements.length - 1; index >= 0; --index) {
|
|
4878
4899
|
const element = elements[index];
|
|
@@ -4880,7 +4901,7 @@ var getAllHoveredElementAtPoint = (point, elements, elementsMap, toleranceFn) =>
|
|
|
4880
4901
|
!element.isDeleted,
|
|
4881
4902
|
"Elements in the function parameter for getAllElementsAtPositionForBinding() should not contain deleted elements"
|
|
4882
4903
|
);
|
|
4883
|
-
if (isBindableElement(element, false) && bindingBorderTest(element, point, elementsMap,
|
|
4904
|
+
if (isBindableElement(element, false) && bindingBorderTest(element, point, elementsMap, tolerance)) {
|
|
4884
4905
|
candidateElements.push(element);
|
|
4885
4906
|
if (!isTransparent(element.backgroundColor)) {
|
|
4886
4907
|
break;
|
|
@@ -4889,12 +4910,12 @@ var getAllHoveredElementAtPoint = (point, elements, elementsMap, toleranceFn) =>
|
|
|
4889
4910
|
}
|
|
4890
4911
|
return candidateElements;
|
|
4891
4912
|
};
|
|
4892
|
-
var getHoveredElementForBinding = (point, elements, elementsMap,
|
|
4913
|
+
var getHoveredElementForBinding = (point, elements, elementsMap, tolerance) => {
|
|
4893
4914
|
const candidateElements = getAllHoveredElementAtPoint(
|
|
4894
4915
|
point,
|
|
4895
4916
|
elements,
|
|
4896
4917
|
elementsMap,
|
|
4897
|
-
|
|
4918
|
+
tolerance
|
|
4898
4919
|
);
|
|
4899
4920
|
if (!candidateElements || candidateElements.length === 0) {
|
|
4900
4921
|
return null;
|
|
@@ -4906,6 +4927,32 @@ var getHoveredElementForBinding = (point, elements, elementsMap, toleranceFn) =>
|
|
|
4906
4927
|
(a2, b2) => b2.width ** 2 + b2.height ** 2 - (a2.width ** 2 + a2.height ** 2)
|
|
4907
4928
|
).pop();
|
|
4908
4929
|
};
|
|
4930
|
+
var getHoveredElementForFocusPoint = (point, arrow, elements, elementsMap, tolerance) => {
|
|
4931
|
+
const candidateElements = [];
|
|
4932
|
+
for (let index = elements.length - 1; index >= 0; --index) {
|
|
4933
|
+
const element = elements[index];
|
|
4934
|
+
invariant4(
|
|
4935
|
+
!element.isDeleted,
|
|
4936
|
+
"Elements in the function parameter for getAllElementsAtPositionForBinding() should not contain deleted elements"
|
|
4937
|
+
);
|
|
4938
|
+
if (isBindableElement(element, false) && bindingBorderTest(element, point, elementsMap, tolerance)) {
|
|
4939
|
+
candidateElements.push(element);
|
|
4940
|
+
}
|
|
4941
|
+
}
|
|
4942
|
+
if (!candidateElements || candidateElements.length === 0) {
|
|
4943
|
+
return null;
|
|
4944
|
+
}
|
|
4945
|
+
if (candidateElements.length === 1) {
|
|
4946
|
+
return candidateElements[0];
|
|
4947
|
+
}
|
|
4948
|
+
const distanceFilteredCandidateElements = candidateElements.filter(
|
|
4949
|
+
(el) => distanceToElement(el, elementsMap, point) <= getBindingGap(el, arrow) || isPointInElement(point, el, elementsMap)
|
|
4950
|
+
);
|
|
4951
|
+
if (distanceFilteredCandidateElements.length === 0) {
|
|
4952
|
+
return null;
|
|
4953
|
+
}
|
|
4954
|
+
return distanceFilteredCandidateElements[0];
|
|
4955
|
+
};
|
|
4909
4956
|
var intersectElementWithLineSegment = (element, elementsMap, line2, offset = 0, onlyFirst = false) => {
|
|
4910
4957
|
const intersectorBounds = [
|
|
4911
4958
|
Math.min(line2[0][0] - offset, line2[1][0] - offset),
|
|
@@ -5177,7 +5224,11 @@ var isBindableElementInsideOtherBindable = (innerElement, outerElement, elements
|
|
|
5177
5224
|
|
|
5178
5225
|
// src/heading.ts
|
|
5179
5226
|
init_define_import_meta_env();
|
|
5180
|
-
import {
|
|
5227
|
+
import {
|
|
5228
|
+
invariant as invariant5,
|
|
5229
|
+
isDevEnv as isDevEnv2,
|
|
5230
|
+
isTestEnv as isTestEnv3
|
|
5231
|
+
} from "@excalidraw/common";
|
|
5181
5232
|
import {
|
|
5182
5233
|
pointFrom as pointFrom6,
|
|
5183
5234
|
pointFromVector as pointFromVector5,
|
|
@@ -6822,7 +6873,7 @@ var getHoveredElement = (origPoint, elementsMap, elements, zoom) => {
|
|
|
6822
6873
|
origPoint,
|
|
6823
6874
|
elements,
|
|
6824
6875
|
elementsMap,
|
|
6825
|
-
|
|
6876
|
+
maxBindingDistance_simple(zoom)
|
|
6826
6877
|
);
|
|
6827
6878
|
};
|
|
6828
6879
|
var gridAddressesEqual = (a2, b2) => a2[0] === b2[0] && a2[1] === b2[1];
|
|
@@ -6935,6 +6986,7 @@ var bumpVersion = (element, version) => {
|
|
|
6935
6986
|
// src/binding.ts
|
|
6936
6987
|
var BASE_BINDING_GAP = 10;
|
|
6937
6988
|
var BASE_BINDING_GAP_ELBOW = 5;
|
|
6989
|
+
var FOCUS_POINT_SIZE = 10 / 1.5;
|
|
6938
6990
|
var getBindingGap = (bindTarget, opts) => {
|
|
6939
6991
|
return (opts.elbowed ? BASE_BINDING_GAP_ELBOW : BASE_BINDING_GAP) + bindTarget.strokeWidth / 2;
|
|
6940
6992
|
};
|
|
@@ -6955,10 +7007,12 @@ var shouldEnableBindingForPointerEvent = (event) => {
|
|
|
6955
7007
|
var isBindingEnabled = (appState) => {
|
|
6956
7008
|
return appState.isBindingEnabled;
|
|
6957
7009
|
};
|
|
6958
|
-
var bindOrUnbindBindingElement = (arrow, draggingPoints, scene, appState, opts) => {
|
|
7010
|
+
var bindOrUnbindBindingElement = (arrow, draggingPoints, scenePointerX, scenePointerY, scene, appState, opts) => {
|
|
6959
7011
|
const { start, end } = getBindingStrategyForDraggingBindingElementEndpoints(
|
|
6960
7012
|
arrow,
|
|
6961
7013
|
draggingPoints,
|
|
7014
|
+
scenePointerX,
|
|
7015
|
+
scenePointerY,
|
|
6962
7016
|
scene.getNonDeletedElementsMap(),
|
|
6963
7017
|
scene.getNonDeletedElements(),
|
|
6964
7018
|
appState,
|
|
@@ -7021,7 +7075,7 @@ var bindingStrategyForElbowArrowEndpointDragging = (arrow, draggingPoints, eleme
|
|
|
7021
7075
|
globalPoint,
|
|
7022
7076
|
elements,
|
|
7023
7077
|
elementsMap,
|
|
7024
|
-
|
|
7078
|
+
maxBindingDistance_simple(zoom)
|
|
7025
7079
|
);
|
|
7026
7080
|
const current = hit ? {
|
|
7027
7081
|
element: hit,
|
|
@@ -7205,7 +7259,7 @@ var bindingStrategyForSimpleArrowEndpointDragging_complex = (point, currentBindi
|
|
|
7205
7259
|
}
|
|
7206
7260
|
return { current, other: isMultiPoint ? { mode: void 0 } : other };
|
|
7207
7261
|
};
|
|
7208
|
-
var getBindingStrategyForDraggingBindingElementEndpoints = (arrow, draggingPoints, elementsMap, elements, appState, opts) => {
|
|
7262
|
+
var getBindingStrategyForDraggingBindingElementEndpoints = (arrow, draggingPoints, screenPointerX, screenPointerY, elementsMap, elements, appState, opts) => {
|
|
7209
7263
|
if (getFeatureFlag("COMPLEX_BINDINGS")) {
|
|
7210
7264
|
return getBindingStrategyForDraggingBindingElementEndpoints_complex(
|
|
7211
7265
|
arrow,
|
|
@@ -7219,13 +7273,15 @@ var getBindingStrategyForDraggingBindingElementEndpoints = (arrow, draggingPoint
|
|
|
7219
7273
|
return getBindingStrategyForDraggingBindingElementEndpoints_simple(
|
|
7220
7274
|
arrow,
|
|
7221
7275
|
draggingPoints,
|
|
7276
|
+
screenPointerX,
|
|
7277
|
+
screenPointerY,
|
|
7222
7278
|
elementsMap,
|
|
7223
7279
|
elements,
|
|
7224
7280
|
appState,
|
|
7225
7281
|
opts
|
|
7226
7282
|
);
|
|
7227
7283
|
};
|
|
7228
|
-
var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggingPoints, elementsMap, elements, appState, opts) => {
|
|
7284
|
+
var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggingPoints, scenePointerX, scenePointerY, elementsMap, elements, appState, opts) => {
|
|
7229
7285
|
const startIdx = 0;
|
|
7230
7286
|
const endIdx = arrow.points.length - 1;
|
|
7231
7287
|
const startDragged = draggingPoints.has(startIdx);
|
|
@@ -7273,9 +7329,13 @@ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggi
|
|
|
7273
7329
|
globalPoint,
|
|
7274
7330
|
elements,
|
|
7275
7331
|
elementsMap,
|
|
7276
|
-
|
|
7332
|
+
maxBindingDistance_simple(appState.zoom)
|
|
7277
7333
|
);
|
|
7278
|
-
const pointInElement = hit &&
|
|
7334
|
+
const pointInElement = hit && (opts?.angleLocked ? isPointInElement(
|
|
7335
|
+
pointFrom8(scenePointerX, scenePointerY),
|
|
7336
|
+
hit,
|
|
7337
|
+
elementsMap
|
|
7338
|
+
) : isPointInElement(globalPoint, hit, elementsMap));
|
|
7279
7339
|
const otherBindableElement = otherBinding ? elementsMap.get(
|
|
7280
7340
|
otherBinding.elementId
|
|
7281
7341
|
) : void 0;
|
|
@@ -7284,7 +7344,13 @@ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggi
|
|
|
7284
7344
|
otherBindableElement,
|
|
7285
7345
|
elementsMap
|
|
7286
7346
|
);
|
|
7287
|
-
const otherFocusPointIsInElement = otherBindableElement && otherFocusPoint &&
|
|
7347
|
+
const otherFocusPointIsInElement = otherBindableElement && otherFocusPoint && hitElementItself({
|
|
7348
|
+
point: otherFocusPoint,
|
|
7349
|
+
element: otherBindableElement,
|
|
7350
|
+
elementsMap,
|
|
7351
|
+
threshold: 0,
|
|
7352
|
+
overrideShouldTestInside: true
|
|
7353
|
+
});
|
|
7288
7354
|
if (otherBinding && otherBinding.elementId === hit?.id) {
|
|
7289
7355
|
invariant7(
|
|
7290
7356
|
!opts?.newArrow || appState.selectedLinearElement?.initialState.origin,
|
|
@@ -7345,10 +7411,25 @@ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggi
|
|
|
7345
7411
|
elementsMap
|
|
7346
7412
|
) || globalPoint
|
|
7347
7413
|
} : { mode: null };
|
|
7414
|
+
const otherEndpoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
7415
|
+
arrow,
|
|
7416
|
+
startDragged ? -1 : 0,
|
|
7417
|
+
elementsMap
|
|
7418
|
+
);
|
|
7348
7419
|
const other = otherBindableElement && !otherFocusPointIsInElement && appState.selectedLinearElement?.initialState.altFocusPoint ? {
|
|
7349
7420
|
mode: "orbit",
|
|
7350
7421
|
element: otherBindableElement,
|
|
7351
7422
|
focusPoint: appState.selectedLinearElement.initialState.altFocusPoint
|
|
7423
|
+
} : opts?.angleLocked && otherBindableElement ? {
|
|
7424
|
+
mode: "orbit",
|
|
7425
|
+
element: otherBindableElement,
|
|
7426
|
+
focusPoint: projectFixedPointOntoDiagonal(
|
|
7427
|
+
arrow,
|
|
7428
|
+
otherEndpoint,
|
|
7429
|
+
otherBindableElement,
|
|
7430
|
+
startDragged ? "end" : "start",
|
|
7431
|
+
elementsMap
|
|
7432
|
+
) || otherEndpoint
|
|
7352
7433
|
} : { mode: void 0 };
|
|
7353
7434
|
return {
|
|
7354
7435
|
start: startDragged ? current : other,
|
|
@@ -7450,6 +7531,8 @@ var bindOrUnbindBindingElements = (selectedArrows, scene, appState) => {
|
|
|
7450
7531
|
arrow,
|
|
7451
7532
|
/* @__PURE__ */ new Map(),
|
|
7452
7533
|
// No dragging points in this case
|
|
7534
|
+
Infinity,
|
|
7535
|
+
Infinity,
|
|
7453
7536
|
scene,
|
|
7454
7537
|
appState
|
|
7455
7538
|
);
|
|
@@ -7576,9 +7659,71 @@ var updateBoundElements = (changedElement, scene, options) => {
|
|
|
7576
7659
|
}
|
|
7577
7660
|
});
|
|
7578
7661
|
};
|
|
7662
|
+
var updateArrowBindings = (latestElement, startOrEnd, elementsMap, scene, appState) => {
|
|
7663
|
+
invariant7(
|
|
7664
|
+
!isElbowArrow(latestElement),
|
|
7665
|
+
"Elbow arrows not supported for indirect updates"
|
|
7666
|
+
);
|
|
7667
|
+
const binding = latestElement[startOrEnd];
|
|
7668
|
+
const bindableElement = binding && elementsMap.get(binding.elementId);
|
|
7669
|
+
const point = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
7670
|
+
latestElement,
|
|
7671
|
+
startOrEnd === "startBinding" ? 0 : -1,
|
|
7672
|
+
elementsMap
|
|
7673
|
+
);
|
|
7674
|
+
const hit = bindableElement && hitElementItself({
|
|
7675
|
+
element: bindableElement,
|
|
7676
|
+
point,
|
|
7677
|
+
elementsMap,
|
|
7678
|
+
threshold: maxBindingDistance_simple(appState.zoom)
|
|
7679
|
+
});
|
|
7680
|
+
const strategyName = startOrEnd === "startBinding" ? "start" : "end";
|
|
7681
|
+
unbindBindingElement(latestElement, strategyName, scene);
|
|
7682
|
+
if (hit) {
|
|
7683
|
+
const pointIdx = startOrEnd === "startBinding" ? 0 : latestElement.points.length - 1;
|
|
7684
|
+
const localPoint = latestElement.points[pointIdx];
|
|
7685
|
+
const strategy = getBindingStrategyForDraggingBindingElementEndpoints_simple(
|
|
7686
|
+
latestElement,
|
|
7687
|
+
/* @__PURE__ */ new Map([[pointIdx, { point: localPoint }]]),
|
|
7688
|
+
point[0],
|
|
7689
|
+
point[1],
|
|
7690
|
+
elementsMap,
|
|
7691
|
+
scene.getNonDeletedElements(),
|
|
7692
|
+
appState
|
|
7693
|
+
);
|
|
7694
|
+
if (strategy[strategyName] && strategy[strategyName].element?.id === bindableElement.id && strategy[strategyName].mode) {
|
|
7695
|
+
bindBindingElement(
|
|
7696
|
+
latestElement,
|
|
7697
|
+
bindableElement,
|
|
7698
|
+
strategy[strategyName].mode,
|
|
7699
|
+
strategyName,
|
|
7700
|
+
scene,
|
|
7701
|
+
strategy[strategyName].focusPoint
|
|
7702
|
+
);
|
|
7703
|
+
}
|
|
7704
|
+
}
|
|
7705
|
+
};
|
|
7579
7706
|
var updateBindings = (latestElement, scene, appState, options) => {
|
|
7580
7707
|
if (isArrowElement(latestElement)) {
|
|
7581
|
-
|
|
7708
|
+
const elementsMap = scene.getNonDeletedElementsMap();
|
|
7709
|
+
if (latestElement.startBinding) {
|
|
7710
|
+
updateArrowBindings(
|
|
7711
|
+
latestElement,
|
|
7712
|
+
"startBinding",
|
|
7713
|
+
elementsMap,
|
|
7714
|
+
scene,
|
|
7715
|
+
appState
|
|
7716
|
+
);
|
|
7717
|
+
}
|
|
7718
|
+
if (latestElement.endBinding) {
|
|
7719
|
+
updateArrowBindings(
|
|
7720
|
+
latestElement,
|
|
7721
|
+
"endBinding",
|
|
7722
|
+
elementsMap,
|
|
7723
|
+
scene,
|
|
7724
|
+
appState
|
|
7725
|
+
);
|
|
7726
|
+
}
|
|
7582
7727
|
} else {
|
|
7583
7728
|
updateBoundElements(latestElement, scene, {
|
|
7584
7729
|
...options,
|
|
@@ -7852,9 +7997,13 @@ var snapToMid = (arrowElement, bindTarget, elementsMap, p, tolerance = 0.05) =>
|
|
|
7852
7997
|
return p;
|
|
7853
7998
|
};
|
|
7854
7999
|
var compareElementArea = (a2, b2) => b2.width ** 2 + b2.height ** 2 - (a2.width ** 2 + a2.height ** 2);
|
|
7855
|
-
var updateBoundPoint = (arrow, startOrEnd, binding, bindableElement, elementsMap,
|
|
8000
|
+
var updateBoundPoint = (arrow, startOrEnd, binding, bindableElement, elementsMap, opts) => {
|
|
7856
8001
|
if (binding == null || // We only need to update the other end if this is a 2 point line element
|
|
7857
|
-
binding.elementId !== bindableElement.id && arrow.points.length > 2
|
|
8002
|
+
binding.elementId !== bindableElement.id && arrow.points.length > 2 || // Initial arrow created on pointer down needs to not update the points
|
|
8003
|
+
pointsEqual5(
|
|
8004
|
+
arrow.points[arrow.points.length - 1],
|
|
8005
|
+
pointFrom8(0, 0)
|
|
8006
|
+
)) {
|
|
7858
8007
|
return null;
|
|
7859
8008
|
}
|
|
7860
8009
|
const global2 = getGlobalFixedPointForBindableElement(
|
|
@@ -7904,14 +8053,14 @@ var updateBoundPoint = (arrow, startOrEnd, binding, bindableElement, elementsMap
|
|
|
7904
8053
|
}
|
|
7905
8054
|
}
|
|
7906
8055
|
const isNested = (arrowTooShort || isOverlapping) && isLargerThanOther;
|
|
7907
|
-
let _customIntersector = customIntersector;
|
|
8056
|
+
let _customIntersector = opts?.customIntersector;
|
|
7908
8057
|
if (!elbowed && !_customIntersector) {
|
|
7909
8058
|
const [x1, y1, x2, y2] = LinearElementEditor.getElementAbsoluteCoords(
|
|
7910
8059
|
arrow,
|
|
7911
8060
|
elementsMap
|
|
7912
8061
|
);
|
|
7913
8062
|
const center = pointFrom8((x1 + x2) / 2, (y1 + y2) / 2);
|
|
7914
|
-
const edgePoint =
|
|
8063
|
+
const edgePoint = global2;
|
|
7915
8064
|
const adjacentPoint = pointRotateRads8(
|
|
7916
8065
|
pointFrom8(
|
|
7917
8066
|
arrow.x + arrow.points[pointIndex === 0 ? 1 : arrow.points.length - 2][0],
|
|
@@ -7999,10 +8148,7 @@ var calculateFixedPointForNonElbowArrowBinding = (linearElement, hoveredElement,
|
|
|
7999
8148
|
startOrEnd === "start" ? 0 : -1,
|
|
8000
8149
|
elementsMap
|
|
8001
8150
|
);
|
|
8002
|
-
const elementCenter =
|
|
8003
|
-
hoveredElement.x + hoveredElement.width / 2,
|
|
8004
|
-
hoveredElement.y + hoveredElement.height / 2
|
|
8005
|
-
);
|
|
8151
|
+
const elementCenter = elementCenterPoint(hoveredElement, elementsMap);
|
|
8006
8152
|
const nonRotatedPoint = pointRotateRads8(
|
|
8007
8153
|
edgePoint,
|
|
8008
8154
|
elementCenter,
|
|
@@ -8339,6 +8485,356 @@ var normalizeFixedPoint = (fixedPoint) => {
|
|
|
8339
8485
|
}
|
|
8340
8486
|
return fixedPoint;
|
|
8341
8487
|
};
|
|
8488
|
+
var getShapeType = (element) => {
|
|
8489
|
+
if (element.type === "ellipse" || element.type === "diamond") {
|
|
8490
|
+
return element.type;
|
|
8491
|
+
}
|
|
8492
|
+
return "rectangle";
|
|
8493
|
+
};
|
|
8494
|
+
var SHAPE_CONFIGS = {
|
|
8495
|
+
// rectangle: 15° corners, 75° edges
|
|
8496
|
+
rectangle: [
|
|
8497
|
+
{ centerAngle: 0, sectorWidth: 75, side: "right" },
|
|
8498
|
+
{ centerAngle: 45, sectorWidth: 15, side: "bottom-right" },
|
|
8499
|
+
{ centerAngle: 90, sectorWidth: 75, side: "bottom" },
|
|
8500
|
+
{ centerAngle: 135, sectorWidth: 15, side: "bottom-left" },
|
|
8501
|
+
{ centerAngle: 180, sectorWidth: 75, side: "left" },
|
|
8502
|
+
{ centerAngle: 225, sectorWidth: 15, side: "top-left" },
|
|
8503
|
+
{ centerAngle: 270, sectorWidth: 75, side: "top" },
|
|
8504
|
+
{ centerAngle: 315, sectorWidth: 15, side: "top-right" }
|
|
8505
|
+
],
|
|
8506
|
+
// diamond: 15° vertices, 75° edges
|
|
8507
|
+
diamond: [
|
|
8508
|
+
{ centerAngle: 0, sectorWidth: 15, side: "right" },
|
|
8509
|
+
{ centerAngle: 45, sectorWidth: 75, side: "bottom-right" },
|
|
8510
|
+
{ centerAngle: 90, sectorWidth: 15, side: "bottom" },
|
|
8511
|
+
{ centerAngle: 135, sectorWidth: 75, side: "bottom-left" },
|
|
8512
|
+
{ centerAngle: 180, sectorWidth: 15, side: "left" },
|
|
8513
|
+
{ centerAngle: 225, sectorWidth: 75, side: "top-left" },
|
|
8514
|
+
{ centerAngle: 270, sectorWidth: 15, side: "top" },
|
|
8515
|
+
{ centerAngle: 315, sectorWidth: 75, side: "top-right" }
|
|
8516
|
+
],
|
|
8517
|
+
// ellipse: 15° cardinal points, 75° diagonals
|
|
8518
|
+
ellipse: [
|
|
8519
|
+
{ centerAngle: 0, sectorWidth: 15, side: "right" },
|
|
8520
|
+
{ centerAngle: 45, sectorWidth: 75, side: "bottom-right" },
|
|
8521
|
+
{ centerAngle: 90, sectorWidth: 15, side: "bottom" },
|
|
8522
|
+
{ centerAngle: 135, sectorWidth: 75, side: "bottom-left" },
|
|
8523
|
+
{ centerAngle: 180, sectorWidth: 15, side: "left" },
|
|
8524
|
+
{ centerAngle: 225, sectorWidth: 75, side: "top-left" },
|
|
8525
|
+
{ centerAngle: 270, sectorWidth: 15, side: "top" },
|
|
8526
|
+
{ centerAngle: 315, sectorWidth: 75, side: "top-right" }
|
|
8527
|
+
]
|
|
8528
|
+
};
|
|
8529
|
+
var getSectorBoundaries = (config) => {
|
|
8530
|
+
return config.map((sector, index) => {
|
|
8531
|
+
const halfWidth = sector.sectorWidth / 2;
|
|
8532
|
+
let start = sector.centerAngle - halfWidth;
|
|
8533
|
+
let end = sector.centerAngle + halfWidth;
|
|
8534
|
+
start = (start % 360 + 360) % 360;
|
|
8535
|
+
end = (end % 360 + 360) % 360;
|
|
8536
|
+
return { start, end, side: sector.side };
|
|
8537
|
+
});
|
|
8538
|
+
};
|
|
8539
|
+
var getShapeSideAdaptive = (fixedPoint, shapeType) => {
|
|
8540
|
+
const [x, y] = fixedPoint;
|
|
8541
|
+
const centerX = x - 0.5;
|
|
8542
|
+
const centerY = y - 0.5;
|
|
8543
|
+
let angle = Math.atan2(centerY, centerX);
|
|
8544
|
+
if (angle < 0) {
|
|
8545
|
+
angle += 2 * Math.PI;
|
|
8546
|
+
}
|
|
8547
|
+
const degrees = angle * 180 / Math.PI;
|
|
8548
|
+
const config = SHAPE_CONFIGS[shapeType];
|
|
8549
|
+
const boundaries = getSectorBoundaries(config);
|
|
8550
|
+
for (const boundary of boundaries) {
|
|
8551
|
+
if (boundary.start <= boundary.end) {
|
|
8552
|
+
if (degrees >= boundary.start && degrees <= boundary.end) {
|
|
8553
|
+
return boundary.side;
|
|
8554
|
+
}
|
|
8555
|
+
} else if (degrees >= boundary.start || degrees <= boundary.end) {
|
|
8556
|
+
return boundary.side;
|
|
8557
|
+
}
|
|
8558
|
+
}
|
|
8559
|
+
let minDiff = Infinity;
|
|
8560
|
+
let nearestSide = config[0].side;
|
|
8561
|
+
for (const sector of config) {
|
|
8562
|
+
let diff = Math.abs(degrees - sector.centerAngle);
|
|
8563
|
+
if (diff > 180) {
|
|
8564
|
+
diff = 360 - diff;
|
|
8565
|
+
}
|
|
8566
|
+
if (diff < minDiff) {
|
|
8567
|
+
minDiff = diff;
|
|
8568
|
+
nearestSide = sector.side;
|
|
8569
|
+
}
|
|
8570
|
+
}
|
|
8571
|
+
return nearestSide;
|
|
8572
|
+
};
|
|
8573
|
+
var getBindingSideMidPoint = (binding, elementsMap) => {
|
|
8574
|
+
const bindableElement = elementsMap.get(binding.elementId);
|
|
8575
|
+
if (!bindableElement || bindableElement.isDeleted || !isBindableElement(bindableElement)) {
|
|
8576
|
+
return null;
|
|
8577
|
+
}
|
|
8578
|
+
const center = elementCenterPoint(bindableElement, elementsMap);
|
|
8579
|
+
const shapeType = getShapeType(bindableElement);
|
|
8580
|
+
const side = getShapeSideAdaptive(
|
|
8581
|
+
normalizeFixedPoint(binding.fixedPoint),
|
|
8582
|
+
shapeType
|
|
8583
|
+
);
|
|
8584
|
+
const OFFSET = 0.01;
|
|
8585
|
+
if (bindableElement.type === "diamond") {
|
|
8586
|
+
const [sides, corners] = deconstructDiamondElement(bindableElement);
|
|
8587
|
+
const [bottomRight, bottomLeft, topLeft, topRight] = sides;
|
|
8588
|
+
let x;
|
|
8589
|
+
let y;
|
|
8590
|
+
switch (side) {
|
|
8591
|
+
case "left": {
|
|
8592
|
+
if (corners.length >= 3) {
|
|
8593
|
+
const leftCorner = corners[2];
|
|
8594
|
+
const midPoint = leftCorner[1];
|
|
8595
|
+
x = midPoint[0] - OFFSET;
|
|
8596
|
+
y = midPoint[1];
|
|
8597
|
+
} else {
|
|
8598
|
+
const midPoint = getMidPoint(bottomLeft[1], topLeft[0]);
|
|
8599
|
+
x = midPoint[0] - OFFSET;
|
|
8600
|
+
y = midPoint[1];
|
|
8601
|
+
}
|
|
8602
|
+
break;
|
|
8603
|
+
}
|
|
8604
|
+
case "right": {
|
|
8605
|
+
if (corners.length >= 1) {
|
|
8606
|
+
const rightCorner = corners[0];
|
|
8607
|
+
const midPoint = rightCorner[1];
|
|
8608
|
+
x = midPoint[0] + OFFSET;
|
|
8609
|
+
y = midPoint[1];
|
|
8610
|
+
} else {
|
|
8611
|
+
const midPoint = getMidPoint(topRight[1], bottomRight[0]);
|
|
8612
|
+
x = midPoint[0] + OFFSET;
|
|
8613
|
+
y = midPoint[1];
|
|
8614
|
+
}
|
|
8615
|
+
break;
|
|
8616
|
+
}
|
|
8617
|
+
case "top": {
|
|
8618
|
+
if (corners.length >= 4) {
|
|
8619
|
+
const topCorner = corners[3];
|
|
8620
|
+
const midPoint = topCorner[1];
|
|
8621
|
+
x = midPoint[0];
|
|
8622
|
+
y = midPoint[1] - OFFSET;
|
|
8623
|
+
} else {
|
|
8624
|
+
const midPoint = getMidPoint(topLeft[1], topRight[0]);
|
|
8625
|
+
x = midPoint[0];
|
|
8626
|
+
y = midPoint[1] - OFFSET;
|
|
8627
|
+
}
|
|
8628
|
+
break;
|
|
8629
|
+
}
|
|
8630
|
+
case "bottom": {
|
|
8631
|
+
if (corners.length >= 2) {
|
|
8632
|
+
const bottomCorner = corners[1];
|
|
8633
|
+
const midPoint = bottomCorner[1];
|
|
8634
|
+
x = midPoint[0];
|
|
8635
|
+
y = midPoint[1] + OFFSET;
|
|
8636
|
+
} else {
|
|
8637
|
+
const midPoint = getMidPoint(bottomRight[1], bottomLeft[0]);
|
|
8638
|
+
x = midPoint[0];
|
|
8639
|
+
y = midPoint[1] + OFFSET;
|
|
8640
|
+
}
|
|
8641
|
+
break;
|
|
8642
|
+
}
|
|
8643
|
+
case "top-right": {
|
|
8644
|
+
const midPoint = getMidPoint(topRight[0], topRight[1]);
|
|
8645
|
+
x = midPoint[0] + OFFSET * 0.707;
|
|
8646
|
+
y = midPoint[1] - OFFSET * 0.707;
|
|
8647
|
+
break;
|
|
8648
|
+
}
|
|
8649
|
+
case "bottom-right": {
|
|
8650
|
+
const midPoint = getMidPoint(bottomRight[0], bottomRight[1]);
|
|
8651
|
+
x = midPoint[0] + OFFSET * 0.707;
|
|
8652
|
+
y = midPoint[1] + OFFSET * 0.707;
|
|
8653
|
+
break;
|
|
8654
|
+
}
|
|
8655
|
+
case "bottom-left": {
|
|
8656
|
+
const midPoint = getMidPoint(bottomLeft[0], bottomLeft[1]);
|
|
8657
|
+
x = midPoint[0] - OFFSET * 0.707;
|
|
8658
|
+
y = midPoint[1] + OFFSET * 0.707;
|
|
8659
|
+
break;
|
|
8660
|
+
}
|
|
8661
|
+
case "top-left": {
|
|
8662
|
+
const midPoint = getMidPoint(topLeft[0], topLeft[1]);
|
|
8663
|
+
x = midPoint[0] - OFFSET * 0.707;
|
|
8664
|
+
y = midPoint[1] - OFFSET * 0.707;
|
|
8665
|
+
break;
|
|
8666
|
+
}
|
|
8667
|
+
default: {
|
|
8668
|
+
return null;
|
|
8669
|
+
}
|
|
8670
|
+
}
|
|
8671
|
+
return pointRotateRads8(pointFrom8(x, y), center, bindableElement.angle);
|
|
8672
|
+
}
|
|
8673
|
+
if (bindableElement.type === "ellipse") {
|
|
8674
|
+
const ellipseCenterX = bindableElement.x + bindableElement.width / 2;
|
|
8675
|
+
const ellipseCenterY = bindableElement.y + bindableElement.height / 2;
|
|
8676
|
+
const radiusX = bindableElement.width / 2;
|
|
8677
|
+
const radiusY = bindableElement.height / 2;
|
|
8678
|
+
let x;
|
|
8679
|
+
let y;
|
|
8680
|
+
switch (side) {
|
|
8681
|
+
case "top": {
|
|
8682
|
+
x = ellipseCenterX;
|
|
8683
|
+
y = ellipseCenterY - radiusY - OFFSET;
|
|
8684
|
+
break;
|
|
8685
|
+
}
|
|
8686
|
+
case "right": {
|
|
8687
|
+
x = ellipseCenterX + radiusX + OFFSET;
|
|
8688
|
+
y = ellipseCenterY;
|
|
8689
|
+
break;
|
|
8690
|
+
}
|
|
8691
|
+
case "bottom": {
|
|
8692
|
+
x = ellipseCenterX;
|
|
8693
|
+
y = ellipseCenterY + radiusY + OFFSET;
|
|
8694
|
+
break;
|
|
8695
|
+
}
|
|
8696
|
+
case "left": {
|
|
8697
|
+
x = ellipseCenterX - radiusX - OFFSET;
|
|
8698
|
+
y = ellipseCenterY;
|
|
8699
|
+
break;
|
|
8700
|
+
}
|
|
8701
|
+
case "top-right": {
|
|
8702
|
+
const angle = -Math.PI / 4;
|
|
8703
|
+
const ellipseX = radiusX * Math.cos(angle);
|
|
8704
|
+
const ellipseY = radiusY * Math.sin(angle);
|
|
8705
|
+
x = ellipseCenterX + ellipseX + OFFSET * 0.707;
|
|
8706
|
+
y = ellipseCenterY + ellipseY - OFFSET * 0.707;
|
|
8707
|
+
break;
|
|
8708
|
+
}
|
|
8709
|
+
case "bottom-right": {
|
|
8710
|
+
const angle = Math.PI / 4;
|
|
8711
|
+
const ellipseX = radiusX * Math.cos(angle);
|
|
8712
|
+
const ellipseY = radiusY * Math.sin(angle);
|
|
8713
|
+
x = ellipseCenterX + ellipseX + OFFSET * 0.707;
|
|
8714
|
+
y = ellipseCenterY + ellipseY + OFFSET * 0.707;
|
|
8715
|
+
break;
|
|
8716
|
+
}
|
|
8717
|
+
case "bottom-left": {
|
|
8718
|
+
const angle = 3 * Math.PI / 4;
|
|
8719
|
+
const ellipseX = radiusX * Math.cos(angle);
|
|
8720
|
+
const ellipseY = radiusY * Math.sin(angle);
|
|
8721
|
+
x = ellipseCenterX + ellipseX - OFFSET * 0.707;
|
|
8722
|
+
y = ellipseCenterY + ellipseY + OFFSET * 0.707;
|
|
8723
|
+
break;
|
|
8724
|
+
}
|
|
8725
|
+
case "top-left": {
|
|
8726
|
+
const angle = -3 * Math.PI / 4;
|
|
8727
|
+
const ellipseX = radiusX * Math.cos(angle);
|
|
8728
|
+
const ellipseY = radiusY * Math.sin(angle);
|
|
8729
|
+
x = ellipseCenterX + ellipseX - OFFSET * 0.707;
|
|
8730
|
+
y = ellipseCenterY + ellipseY - OFFSET * 0.707;
|
|
8731
|
+
break;
|
|
8732
|
+
}
|
|
8733
|
+
default: {
|
|
8734
|
+
return null;
|
|
8735
|
+
}
|
|
8736
|
+
}
|
|
8737
|
+
return pointRotateRads8(pointFrom8(x, y), center, bindableElement.angle);
|
|
8738
|
+
}
|
|
8739
|
+
if (isRectangularElement(bindableElement)) {
|
|
8740
|
+
const [sides, corners] = deconstructRectanguloidElement(
|
|
8741
|
+
bindableElement
|
|
8742
|
+
);
|
|
8743
|
+
const [top, right, bottom, left] = sides;
|
|
8744
|
+
let x;
|
|
8745
|
+
let y;
|
|
8746
|
+
switch (side) {
|
|
8747
|
+
case "top": {
|
|
8748
|
+
const midPoint = getMidPoint(top[0], top[1]);
|
|
8749
|
+
x = midPoint[0];
|
|
8750
|
+
y = midPoint[1] - OFFSET;
|
|
8751
|
+
break;
|
|
8752
|
+
}
|
|
8753
|
+
case "right": {
|
|
8754
|
+
const midPoint = getMidPoint(right[0], right[1]);
|
|
8755
|
+
x = midPoint[0] + OFFSET;
|
|
8756
|
+
y = midPoint[1];
|
|
8757
|
+
break;
|
|
8758
|
+
}
|
|
8759
|
+
case "bottom": {
|
|
8760
|
+
const midPoint = getMidPoint(bottom[0], bottom[1]);
|
|
8761
|
+
x = midPoint[0];
|
|
8762
|
+
y = midPoint[1] + OFFSET;
|
|
8763
|
+
break;
|
|
8764
|
+
}
|
|
8765
|
+
case "left": {
|
|
8766
|
+
const midPoint = getMidPoint(left[0], left[1]);
|
|
8767
|
+
x = midPoint[0] - OFFSET;
|
|
8768
|
+
y = midPoint[1];
|
|
8769
|
+
break;
|
|
8770
|
+
}
|
|
8771
|
+
case "top-left": {
|
|
8772
|
+
if (corners.length >= 1) {
|
|
8773
|
+
const corner = corners[0];
|
|
8774
|
+
const p1 = corner[0];
|
|
8775
|
+
const p2 = corner[3];
|
|
8776
|
+
const midPoint = getMidPoint(p1, p2);
|
|
8777
|
+
x = midPoint[0] - OFFSET * 0.707;
|
|
8778
|
+
y = midPoint[1] - OFFSET * 0.707;
|
|
8779
|
+
} else {
|
|
8780
|
+
x = bindableElement.x - OFFSET;
|
|
8781
|
+
y = bindableElement.y - OFFSET;
|
|
8782
|
+
}
|
|
8783
|
+
break;
|
|
8784
|
+
}
|
|
8785
|
+
case "top-right": {
|
|
8786
|
+
if (corners.length >= 2) {
|
|
8787
|
+
const corner = corners[1];
|
|
8788
|
+
const p1 = corner[0];
|
|
8789
|
+
const p2 = corner[3];
|
|
8790
|
+
const midPoint = getMidPoint(p1, p2);
|
|
8791
|
+
x = midPoint[0] + OFFSET * 0.707;
|
|
8792
|
+
y = midPoint[1] - OFFSET * 0.707;
|
|
8793
|
+
} else {
|
|
8794
|
+
x = bindableElement.x + bindableElement.width + OFFSET;
|
|
8795
|
+
y = bindableElement.y - OFFSET;
|
|
8796
|
+
}
|
|
8797
|
+
break;
|
|
8798
|
+
}
|
|
8799
|
+
case "bottom-right": {
|
|
8800
|
+
if (corners.length >= 3) {
|
|
8801
|
+
const corner = corners[2];
|
|
8802
|
+
const p1 = corner[0];
|
|
8803
|
+
const p2 = corner[3];
|
|
8804
|
+
const midPoint = getMidPoint(p1, p2);
|
|
8805
|
+
x = midPoint[0] + OFFSET * 0.707;
|
|
8806
|
+
y = midPoint[1] + OFFSET * 0.707;
|
|
8807
|
+
} else {
|
|
8808
|
+
x = bindableElement.x + bindableElement.width + OFFSET;
|
|
8809
|
+
y = bindableElement.y + bindableElement.height + OFFSET;
|
|
8810
|
+
}
|
|
8811
|
+
break;
|
|
8812
|
+
}
|
|
8813
|
+
case "bottom-left": {
|
|
8814
|
+
if (corners.length >= 4) {
|
|
8815
|
+
const corner = corners[3];
|
|
8816
|
+
const p1 = corner[0];
|
|
8817
|
+
const p2 = corner[3];
|
|
8818
|
+
const midPoint = getMidPoint(p1, p2);
|
|
8819
|
+
x = midPoint[0] - OFFSET * 0.707;
|
|
8820
|
+
y = midPoint[1] + OFFSET * 0.707;
|
|
8821
|
+
} else {
|
|
8822
|
+
x = bindableElement.x - OFFSET;
|
|
8823
|
+
y = bindableElement.y + bindableElement.height + OFFSET;
|
|
8824
|
+
}
|
|
8825
|
+
break;
|
|
8826
|
+
}
|
|
8827
|
+
default: {
|
|
8828
|
+
return null;
|
|
8829
|
+
}
|
|
8830
|
+
}
|
|
8831
|
+
return pointRotateRads8(pointFrom8(x, y), center, bindableElement.angle);
|
|
8832
|
+
}
|
|
8833
|
+
return null;
|
|
8834
|
+
};
|
|
8835
|
+
var getMidPoint = (p1, p2) => {
|
|
8836
|
+
return pointFrom8((p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2);
|
|
8837
|
+
};
|
|
8342
8838
|
|
|
8343
8839
|
// src/linearElementEditor.ts
|
|
8344
8840
|
var getNormalizedPoints = ({
|
|
@@ -8366,6 +8862,8 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
8366
8862
|
pointerOffset;
|
|
8367
8863
|
hoverPointIndex;
|
|
8368
8864
|
segmentMidPointHoveredCoords;
|
|
8865
|
+
hoveredFocusPointBinding;
|
|
8866
|
+
draggedFocusPointBinding;
|
|
8369
8867
|
elbowed;
|
|
8370
8868
|
customLineAngle;
|
|
8371
8869
|
isEditing;
|
|
@@ -8375,7 +8873,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
8375
8873
|
pointerDownState;
|
|
8376
8874
|
constructor(element, elementsMap, isEditing = false) {
|
|
8377
8875
|
this.elementId = element.id;
|
|
8378
|
-
if (!
|
|
8876
|
+
if (!pointsEqual6(element.points[0], pointFrom9(0, 0))) {
|
|
8379
8877
|
console.error("Linear element is not normalized", Error().stack);
|
|
8380
8878
|
mutateElement(
|
|
8381
8879
|
element,
|
|
@@ -8402,6 +8900,8 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
8402
8900
|
};
|
|
8403
8901
|
this.hoverPointIndex = -1;
|
|
8404
8902
|
this.segmentMidPointHoveredCoords = null;
|
|
8903
|
+
this.hoveredFocusPointBinding = null;
|
|
8904
|
+
this.draggedFocusPointBinding = null;
|
|
8405
8905
|
this.elbowed = isElbowArrow(element) && element.elbowed;
|
|
8406
8906
|
this.customLineAngle = null;
|
|
8407
8907
|
this.isEditing = isEditing;
|
|
@@ -8465,14 +8965,9 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
8465
8965
|
const point = element.points[idx];
|
|
8466
8966
|
const pivotPoint = element.points[idx - 1];
|
|
8467
8967
|
const customLineAngle = linearElementEditor.customLineAngle ?? determineCustomLinearAngle(pivotPoint, element.points[idx]);
|
|
8468
|
-
const hoveredElement = getHoveredElementForBinding2(
|
|
8469
|
-
pointFrom9(scenePointerX, scenePointerY),
|
|
8470
|
-
elements,
|
|
8471
|
-
elementsMap
|
|
8472
|
-
);
|
|
8473
8968
|
let deltaX = 0;
|
|
8474
8969
|
let deltaY = 0;
|
|
8475
|
-
if (shouldRotateWithDiscreteAngle(event)
|
|
8970
|
+
if (shouldRotateWithDiscreteAngle(event)) {
|
|
8476
8971
|
const [width, height] = _LinearElementEditor._getShiftLockedDelta(
|
|
8477
8972
|
element,
|
|
8478
8973
|
elementsMap,
|
|
@@ -8503,11 +8998,13 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
8503
8998
|
[idx],
|
|
8504
8999
|
deltaX,
|
|
8505
9000
|
deltaY,
|
|
9001
|
+
scenePointerX,
|
|
9002
|
+
scenePointerY,
|
|
8506
9003
|
elementsMap,
|
|
8507
9004
|
element,
|
|
8508
9005
|
elements,
|
|
8509
9006
|
app,
|
|
8510
|
-
event
|
|
9007
|
+
shouldRotateWithDiscreteAngle(event),
|
|
8511
9008
|
event.altKey
|
|
8512
9009
|
);
|
|
8513
9010
|
_LinearElementEditor.movePoints(element, app.scene, positions, {
|
|
@@ -8597,14 +9094,9 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
8597
9094
|
const endIsSelected = selectedPointsIndices.includes(
|
|
8598
9095
|
element.points.length - 1
|
|
8599
9096
|
);
|
|
8600
|
-
const hoveredElement = getHoveredElementForBinding2(
|
|
8601
|
-
pointFrom9(scenePointerX, scenePointerY),
|
|
8602
|
-
elements,
|
|
8603
|
-
elementsMap
|
|
8604
|
-
);
|
|
8605
9097
|
let deltaX = 0;
|
|
8606
9098
|
let deltaY = 0;
|
|
8607
|
-
if (shouldRotateWithDiscreteAngle(event) && singlePointDragged
|
|
9099
|
+
if (shouldRotateWithDiscreteAngle(event) && singlePointDragged) {
|
|
8608
9100
|
const [width, height] = _LinearElementEditor._getShiftLockedDelta(
|
|
8609
9101
|
element,
|
|
8610
9102
|
elementsMap,
|
|
@@ -8635,11 +9127,13 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
8635
9127
|
selectedPointsIndices,
|
|
8636
9128
|
deltaX,
|
|
8637
9129
|
deltaY,
|
|
9130
|
+
scenePointerX,
|
|
9131
|
+
scenePointerY,
|
|
8638
9132
|
elementsMap,
|
|
8639
9133
|
element,
|
|
8640
9134
|
elements,
|
|
8641
9135
|
app,
|
|
8642
|
-
event
|
|
9136
|
+
shouldRotateWithDiscreteAngle(event) && singlePointDragged,
|
|
8643
9137
|
event.altKey
|
|
8644
9138
|
);
|
|
8645
9139
|
_LinearElementEditor.movePoints(element, app.scene, positions, {
|
|
@@ -8768,7 +9262,6 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
8768
9262
|
(pointIndex) => pointIndex !== pointerDownState.lastClickedPoint
|
|
8769
9263
|
) : selectedPointsIndices : selectedPointsIndices?.includes(pointerDownState.lastClickedPoint) ? [pointerDownState.lastClickedPoint] : selectedPointsIndices,
|
|
8770
9264
|
isDragging: false,
|
|
8771
|
-
pointerOffset: { x: 0, y: 0 },
|
|
8772
9265
|
customLineAngle: null,
|
|
8773
9266
|
initialState: {
|
|
8774
9267
|
...editingLinearElement.initialState,
|
|
@@ -9060,7 +9553,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9060
9553
|
if (!point1 || !point2) {
|
|
9061
9554
|
return false;
|
|
9062
9555
|
}
|
|
9063
|
-
return
|
|
9556
|
+
return pointsEqual6(point1, point2);
|
|
9064
9557
|
}
|
|
9065
9558
|
static handlePointerMoveInEditMode(event, scenePointerX, scenePointerY, app) {
|
|
9066
9559
|
const appState = app.state;
|
|
@@ -9713,7 +10206,7 @@ var normalizeSelectedPoints = (points) => {
|
|
|
9713
10206
|
nextPoints = nextPoints.sort((a2, b2) => a2 - b2);
|
|
9714
10207
|
return nextPoints.length ? nextPoints : null;
|
|
9715
10208
|
};
|
|
9716
|
-
var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, elementsMap, element, elements, app,
|
|
10209
|
+
var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, scenePointerX, scenePointerY, elementsMap, element, elements, app, angleLocked, altKey) => {
|
|
9717
10210
|
const naiveDraggingPoints = new Map(
|
|
9718
10211
|
selectedPointsIndices.map((pointIndex) => {
|
|
9719
10212
|
return [
|
|
@@ -9740,12 +10233,14 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, elementsMap,
|
|
|
9740
10233
|
const { start, end } = getBindingStrategyForDraggingBindingElementEndpoints(
|
|
9741
10234
|
element,
|
|
9742
10235
|
naiveDraggingPoints,
|
|
10236
|
+
scenePointerX,
|
|
10237
|
+
scenePointerY,
|
|
9743
10238
|
elementsMap,
|
|
9744
10239
|
elements,
|
|
9745
10240
|
app.state,
|
|
9746
10241
|
{
|
|
9747
10242
|
newArrow: !!app.state.newElement,
|
|
9748
|
-
|
|
10243
|
+
angleLocked,
|
|
9749
10244
|
altKey
|
|
9750
10245
|
}
|
|
9751
10246
|
);
|
|
@@ -9757,6 +10252,51 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, elementsMap,
|
|
|
9757
10252
|
}
|
|
9758
10253
|
};
|
|
9759
10254
|
}
|
|
10255
|
+
if (!startIsDragged && !endIsDragged) {
|
|
10256
|
+
const nextArrow2 = {
|
|
10257
|
+
...element,
|
|
10258
|
+
points: element.points.map((p, idx) => {
|
|
10259
|
+
return naiveDraggingPoints.get(idx)?.point ?? p;
|
|
10260
|
+
})
|
|
10261
|
+
};
|
|
10262
|
+
const positions = new Map(naiveDraggingPoints);
|
|
10263
|
+
if (element.startBinding) {
|
|
10264
|
+
const startBindable2 = elementsMap.get(element.startBinding.elementId);
|
|
10265
|
+
if (startBindable2) {
|
|
10266
|
+
const startPoint = updateBoundPoint(
|
|
10267
|
+
nextArrow2,
|
|
10268
|
+
"startBinding",
|
|
10269
|
+
element.startBinding,
|
|
10270
|
+
startBindable2,
|
|
10271
|
+
elementsMap
|
|
10272
|
+
) ?? null;
|
|
10273
|
+
if (startPoint) {
|
|
10274
|
+
positions.set(0, { point: startPoint, isDragging: true });
|
|
10275
|
+
}
|
|
10276
|
+
}
|
|
10277
|
+
}
|
|
10278
|
+
if (element.endBinding) {
|
|
10279
|
+
const endBindable2 = elementsMap.get(element.endBinding.elementId);
|
|
10280
|
+
if (endBindable2) {
|
|
10281
|
+
const endPoint = updateBoundPoint(
|
|
10282
|
+
nextArrow2,
|
|
10283
|
+
"endBinding",
|
|
10284
|
+
element.endBinding,
|
|
10285
|
+
endBindable2,
|
|
10286
|
+
elementsMap
|
|
10287
|
+
) ?? null;
|
|
10288
|
+
if (endPoint) {
|
|
10289
|
+
positions.set(element.points.length - 1, {
|
|
10290
|
+
point: endPoint,
|
|
10291
|
+
isDragging: true
|
|
10292
|
+
});
|
|
10293
|
+
}
|
|
10294
|
+
}
|
|
10295
|
+
}
|
|
10296
|
+
return {
|
|
10297
|
+
positions
|
|
10298
|
+
};
|
|
10299
|
+
}
|
|
9760
10300
|
if (startIsDragged === endIsDragged) {
|
|
9761
10301
|
return {
|
|
9762
10302
|
positions: naiveDraggingPoints
|
|
@@ -9823,7 +10363,8 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, elementsMap,
|
|
|
9823
10363
|
startBinding: updates.startBinding === void 0 ? element.startBinding : updates.startBinding === null ? null : updates.startBinding,
|
|
9824
10364
|
endBinding: updates.endBinding === void 0 ? element.endBinding : updates.endBinding === null ? null : updates.endBinding
|
|
9825
10365
|
};
|
|
9826
|
-
const
|
|
10366
|
+
const startCustomIntersector = start.focusPoint && end.focusPoint ? lineSegment5(start.focusPoint, end.focusPoint) : void 0;
|
|
10367
|
+
const endCustomIntersector = start.focusPoint && end.focusPoint ? lineSegment5(end.focusPoint, start.focusPoint) : void 0;
|
|
9827
10368
|
const startIsDraggingOverEndElement = element.endBinding && nextArrow.startBinding && startIsDragged && nextArrow.startBinding.elementId === element.endBinding.elementId;
|
|
9828
10369
|
const endIsDraggingOverStartElement = element.startBinding && nextArrow.endBinding && endIsDragged && element.startBinding.elementId === nextArrow.endBinding.elementId;
|
|
9829
10370
|
const endBindable = nextArrow.endBinding ? end.element ?? elementsMap.get(
|
|
@@ -9835,24 +10376,23 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, elementsMap,
|
|
|
9835
10376
|
nextArrow.endBinding,
|
|
9836
10377
|
endBindable,
|
|
9837
10378
|
elementsMap,
|
|
9838
|
-
|
|
10379
|
+
{
|
|
10380
|
+
customIntersector: endCustomIntersector
|
|
10381
|
+
}
|
|
9839
10382
|
) || nextArrow.points[nextArrow.points.length - 1] : nextArrow.points[nextArrow.points.length - 1];
|
|
9840
10383
|
nextArrow.points[nextArrow.points.length - 1] = endLocalPoint;
|
|
9841
10384
|
const startBindable = nextArrow.startBinding ? start.element ?? elementsMap.get(
|
|
9842
10385
|
nextArrow.startBinding.elementId
|
|
9843
10386
|
) : null;
|
|
9844
|
-
const startLocalPoint = endIsDraggingOverStartElement && getFeatureFlag2("COMPLEX_BINDINGS") ? nextArrow.points[0] : startIsDraggingOverEndElement && app.state.bindMode !== "inside" && getFeatureFlag2("COMPLEX_BINDINGS") ?
|
|
10387
|
+
const startLocalPoint = endIsDraggingOverStartElement && getFeatureFlag2("COMPLEX_BINDINGS") ? nextArrow.points[0] : startIsDraggingOverEndElement && app.state.bindMode !== "inside" && getFeatureFlag2("COMPLEX_BINDINGS") ? endLocalPoint : startBindable ? updateBoundPoint(
|
|
9845
10388
|
element,
|
|
9846
10389
|
"startBinding",
|
|
9847
10390
|
nextArrow.startBinding,
|
|
9848
10391
|
startBindable,
|
|
9849
10392
|
elementsMap,
|
|
9850
|
-
customIntersector
|
|
10393
|
+
{ customIntersector: startCustomIntersector }
|
|
9851
10394
|
) || nextArrow.points[0] : nextArrow.points[0];
|
|
9852
|
-
const endChanged =
|
|
9853
|
-
endLocalPoint,
|
|
9854
|
-
nextArrow.points[nextArrow.points.length - 1]
|
|
9855
|
-
) !== 0;
|
|
10395
|
+
const endChanged = !startIsDraggingOverEndElement && !(endIsDraggingOverStartElement && app.state.bindMode !== "inside" && getFeatureFlag2("COMPLEX_BINDINGS")) && !!endBindable;
|
|
9856
10396
|
const startChanged = pointDistance5(startLocalPoint, nextArrow.points[0]) !== 0;
|
|
9857
10397
|
const indicesSet = new Set(selectedPointsIndices);
|
|
9858
10398
|
if (startBindable && startChanged) {
|
|
@@ -9863,10 +10403,7 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, elementsMap,
|
|
|
9863
10403
|
}
|
|
9864
10404
|
const indices = Array.from(indicesSet);
|
|
9865
10405
|
return {
|
|
9866
|
-
updates
|
|
9867
|
-
startBinding: updates.startBinding,
|
|
9868
|
-
suggestedBinding: updates.suggestedBinding
|
|
9869
|
-
} : void 0,
|
|
10406
|
+
updates,
|
|
9870
10407
|
positions: new Map(
|
|
9871
10408
|
indices.map((idx) => {
|
|
9872
10409
|
return [
|
|
@@ -11019,11 +11556,7 @@ var frameAndChildrenSelectedTogether = (selectedElements) => {
|
|
|
11019
11556
|
};
|
|
11020
11557
|
|
|
11021
11558
|
// src/renderElement.ts
|
|
11022
|
-
var IMAGE_INVERT_FILTER = "invert(100%) hue-rotate(180deg) saturate(1.25)";
|
|
11023
11559
|
var isPendingImageElement = (element, renderConfig) => isInitializedImageElement(element) && !renderConfig.imageCache.has(element.fileId);
|
|
11024
|
-
var shouldResetImageFilter = (element, renderConfig, appState) => {
|
|
11025
|
-
return appState.theme === THEME.DARK && isInitializedImageElement(element) && !isPendingImageElement(element, renderConfig) && renderConfig.imageCache.get(element.fileId)?.mimeType !== MIME_TYPES.svg;
|
|
11026
|
-
};
|
|
11027
11560
|
var getCanvasPadding = (element) => {
|
|
11028
11561
|
switch (element.type) {
|
|
11029
11562
|
case "freedraw":
|
|
@@ -11095,9 +11628,6 @@ var generateElementCanvas = (element, elementsMap, zoom, renderConfig, appState)
|
|
|
11095
11628
|
window.devicePixelRatio * scale
|
|
11096
11629
|
);
|
|
11097
11630
|
const rc = rough_default.canvas(canvas);
|
|
11098
|
-
if (shouldResetImageFilter(element, renderConfig, appState)) {
|
|
11099
|
-
context.filter = IMAGE_INVERT_FILTER;
|
|
11100
|
-
}
|
|
11101
11631
|
drawElementOnCanvas(element, rc, context, renderConfig);
|
|
11102
11632
|
context.restore();
|
|
11103
11633
|
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
@@ -11161,8 +11691,8 @@ var IMAGE_ERROR_PLACEHOLDER_IMG = typeof document !== "undefined" ? document.cre
|
|
|
11161
11691
|
IMAGE_ERROR_PLACEHOLDER_IMG.src = `data:${MIME_TYPES.svg},${encodeURIComponent(
|
|
11162
11692
|
`<svg viewBox="0 0 668 668" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"><path d="M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48ZM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56ZM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48Z" style="fill:#888;fill-rule:nonzero" transform="matrix(.81709 0 0 .81709 124.825 145.825)"/><path d="M256 8C119.034 8 8 119.033 8 256c0 136.967 111.034 248 248 248s248-111.034 248-248S392.967 8 256 8Zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676ZM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676Z" style="fill:#888;fill-rule:nonzero" transform="matrix(.30366 0 0 .30366 506.822 60.065)"/></svg>`
|
|
11163
11693
|
)}`;
|
|
11164
|
-
var drawImagePlaceholder = (element, context) => {
|
|
11165
|
-
context.fillStyle = "#E7E7E7";
|
|
11694
|
+
var drawImagePlaceholder = (element, context, theme) => {
|
|
11695
|
+
context.fillStyle = theme === THEME.DARK ? "#2E2E2E" : "#E7E7E7";
|
|
11166
11696
|
context.fillRect(0, 0, element.width, element.height);
|
|
11167
11697
|
const imageMinWidthOrHeight = Math.min(element.width, element.height);
|
|
11168
11698
|
const size = Math.min(
|
|
@@ -11186,33 +11716,38 @@ var drawElementOnCanvas = (element, rc, context, renderConfig) => {
|
|
|
11186
11716
|
case "ellipse": {
|
|
11187
11717
|
context.lineJoin = "round";
|
|
11188
11718
|
context.lineCap = "round";
|
|
11189
|
-
rc.draw(ShapeCache.
|
|
11719
|
+
rc.draw(ShapeCache.generateElementShape(element, renderConfig));
|
|
11190
11720
|
break;
|
|
11191
11721
|
}
|
|
11192
11722
|
case "arrow":
|
|
11193
11723
|
case "line": {
|
|
11194
11724
|
context.lineJoin = "round";
|
|
11195
11725
|
context.lineCap = "round";
|
|
11196
|
-
ShapeCache.
|
|
11197
|
-
|
|
11198
|
-
|
|
11726
|
+
ShapeCache.generateElementShape(element, renderConfig).forEach(
|
|
11727
|
+
(shape) => {
|
|
11728
|
+
rc.draw(shape);
|
|
11729
|
+
}
|
|
11730
|
+
);
|
|
11199
11731
|
break;
|
|
11200
11732
|
}
|
|
11201
11733
|
case "freedraw": {
|
|
11202
11734
|
context.save();
|
|
11203
|
-
|
|
11204
|
-
const
|
|
11205
|
-
|
|
11206
|
-
|
|
11207
|
-
|
|
11208
|
-
|
|
11209
|
-
|
|
11210
|
-
|
|
11735
|
+
const shapes = ShapeCache.generateElementShape(element, renderConfig);
|
|
11736
|
+
for (const shape of shapes) {
|
|
11737
|
+
if (typeof shape === "string") {
|
|
11738
|
+
context.fillStyle = renderConfig.theme === THEME.DARK ? applyDarkModeFilter(element.strokeColor) : element.strokeColor;
|
|
11739
|
+
context.fill(new Path2D(shape));
|
|
11740
|
+
} else {
|
|
11741
|
+
rc.draw(shape);
|
|
11742
|
+
}
|
|
11743
|
+
}
|
|
11211
11744
|
context.restore();
|
|
11212
11745
|
break;
|
|
11213
11746
|
}
|
|
11214
11747
|
case "image": {
|
|
11215
|
-
|
|
11748
|
+
context.save();
|
|
11749
|
+
const cacheEntry = element.fileId !== null ? renderConfig.imageCache.get(element.fileId) : null;
|
|
11750
|
+
const img = isInitializedImageElement(element) ? cacheEntry?.image : void 0;
|
|
11216
11751
|
if (img != null && !(img instanceof Promise)) {
|
|
11217
11752
|
if (element.roundness && context.roundRect) {
|
|
11218
11753
|
context.beginPath();
|
|
@@ -11231,33 +11766,84 @@ var drawElementOnCanvas = (element, rc, context, renderConfig) => {
|
|
|
11231
11766
|
width: img.naturalWidth,
|
|
11232
11767
|
height: img.naturalHeight
|
|
11233
11768
|
};
|
|
11234
|
-
|
|
11235
|
-
|
|
11236
|
-
|
|
11237
|
-
|
|
11238
|
-
width
|
|
11239
|
-
height
|
|
11240
|
-
|
|
11241
|
-
|
|
11242
|
-
|
|
11243
|
-
|
|
11244
|
-
|
|
11245
|
-
|
|
11246
|
-
|
|
11247
|
-
|
|
11248
|
-
|
|
11249
|
-
|
|
11250
|
-
|
|
11251
|
-
|
|
11252
|
-
|
|
11253
|
-
|
|
11254
|
-
|
|
11255
|
-
|
|
11256
|
-
|
|
11257
|
-
|
|
11258
|
-
|
|
11769
|
+
const shouldInvertImage = renderConfig.theme === THEME.DARK && cacheEntry?.mimeType === MIME_TYPES.svg;
|
|
11770
|
+
if (shouldInvertImage && isSafari) {
|
|
11771
|
+
const devicePixelRatio = window.devicePixelRatio || 1;
|
|
11772
|
+
const tempCanvas = document.createElement("canvas");
|
|
11773
|
+
tempCanvas.width = element.width * devicePixelRatio;
|
|
11774
|
+
tempCanvas.height = element.height * devicePixelRatio;
|
|
11775
|
+
const tempContext = tempCanvas.getContext("2d");
|
|
11776
|
+
if (tempContext) {
|
|
11777
|
+
tempContext.scale(devicePixelRatio, devicePixelRatio);
|
|
11778
|
+
tempContext.drawImage(
|
|
11779
|
+
img,
|
|
11780
|
+
x,
|
|
11781
|
+
y,
|
|
11782
|
+
width,
|
|
11783
|
+
height,
|
|
11784
|
+
0,
|
|
11785
|
+
0,
|
|
11786
|
+
element.width,
|
|
11787
|
+
element.height
|
|
11788
|
+
);
|
|
11789
|
+
const imageData = tempContext.getImageData(
|
|
11790
|
+
0,
|
|
11791
|
+
0,
|
|
11792
|
+
tempCanvas.width,
|
|
11793
|
+
tempCanvas.height
|
|
11794
|
+
);
|
|
11795
|
+
const data = imageData.data;
|
|
11796
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
11797
|
+
data[i] = 255 - data[i];
|
|
11798
|
+
data[i + 1] = 255 - data[i + 1];
|
|
11799
|
+
data[i + 2] = 255 - data[i + 2];
|
|
11800
|
+
}
|
|
11801
|
+
tempContext.putImageData(imageData, 0, 0);
|
|
11802
|
+
context.drawImage(
|
|
11803
|
+
tempCanvas,
|
|
11804
|
+
0,
|
|
11805
|
+
0,
|
|
11806
|
+
tempCanvas.width,
|
|
11807
|
+
tempCanvas.height,
|
|
11808
|
+
0,
|
|
11809
|
+
0,
|
|
11810
|
+
element.width,
|
|
11811
|
+
element.height
|
|
11812
|
+
);
|
|
11813
|
+
}
|
|
11814
|
+
} else {
|
|
11815
|
+
if (shouldInvertImage) {
|
|
11816
|
+
context.filter = DARK_THEME_FILTER;
|
|
11817
|
+
}
|
|
11818
|
+
context.drawImage(
|
|
11819
|
+
img,
|
|
11820
|
+
x,
|
|
11821
|
+
y,
|
|
11822
|
+
width,
|
|
11823
|
+
height,
|
|
11824
|
+
0,
|
|
11825
|
+
0,
|
|
11826
|
+
element.width,
|
|
11827
|
+
element.height
|
|
11828
|
+
);
|
|
11829
|
+
}
|
|
11830
|
+
} else {
|
|
11831
|
+
drawImagePlaceholder(element, context, renderConfig.theme);
|
|
11832
|
+
}
|
|
11833
|
+
context.restore();
|
|
11834
|
+
break;
|
|
11835
|
+
}
|
|
11836
|
+
default: {
|
|
11837
|
+
if (isTextElement(element)) {
|
|
11838
|
+
const rtl = isRTL(element.text);
|
|
11839
|
+
const shouldTemporarilyAttach = rtl && !context.canvas.isConnected;
|
|
11840
|
+
if (shouldTemporarilyAttach) {
|
|
11841
|
+
document.body.appendChild(context.canvas);
|
|
11842
|
+
}
|
|
11843
|
+
context.canvas.setAttribute("dir", rtl ? "rtl" : "ltr");
|
|
11844
|
+
context.save();
|
|
11259
11845
|
context.font = getFontString3(element);
|
|
11260
|
-
context.fillStyle = element.strokeColor;
|
|
11846
|
+
context.fillStyle = renderConfig.theme === THEME.DARK ? applyDarkModeFilter(element.strokeColor) : element.strokeColor;
|
|
11261
11847
|
context.textAlign = element.textAlign;
|
|
11262
11848
|
const lines = element.text.replace(/\r\n?/g, "\n").split("\n");
|
|
11263
11849
|
const horizontalOffset = element.textAlign === "center" ? element.width / 2 : element.textAlign === "right" ? element.width : 0;
|
|
@@ -11405,9 +11991,9 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
11405
11991
|
);
|
|
11406
11992
|
context.fillStyle = "rgba(0, 0, 200, 0.04)";
|
|
11407
11993
|
context.lineWidth = FRAME_STYLE.strokeWidth / appState.zoom.value;
|
|
11408
|
-
context.strokeStyle = FRAME_STYLE.strokeColor;
|
|
11994
|
+
context.strokeStyle = appState.theme === THEME.DARK ? applyDarkModeFilter(FRAME_STYLE.strokeColor) : FRAME_STYLE.strokeColor;
|
|
11409
11995
|
if (isMagicFrameElement(element)) {
|
|
11410
|
-
context.strokeStyle = appState.theme === THEME.LIGHT ? "#7affd7" : "#1d8264";
|
|
11996
|
+
context.strokeStyle = appState.theme === THEME.LIGHT ? "#7affd7" : applyDarkModeFilter("#1d8264");
|
|
11411
11997
|
}
|
|
11412
11998
|
if (FRAME_STYLE.radius && context.roundRect) {
|
|
11413
11999
|
context.beginPath();
|
|
@@ -11428,7 +12014,6 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
11428
12014
|
break;
|
|
11429
12015
|
}
|
|
11430
12016
|
case "freedraw": {
|
|
11431
|
-
ShapeCache.generateElementShape(element, null);
|
|
11432
12017
|
if (renderConfig.isExporting) {
|
|
11433
12018
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
|
|
11434
12019
|
const cx = (x1 + x2) / 2 + appState.scrollX;
|
|
@@ -11470,7 +12055,6 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
11470
12055
|
case "text":
|
|
11471
12056
|
case "iframe":
|
|
11472
12057
|
case "embeddable": {
|
|
11473
|
-
ShapeCache.generateElementShape(element, renderConfig);
|
|
11474
12058
|
if (renderConfig.isExporting) {
|
|
11475
12059
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
|
|
11476
12060
|
const cx = (x1 + x2) / 2 + appState.scrollX;
|
|
@@ -11491,9 +12075,6 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
11491
12075
|
}
|
|
11492
12076
|
context.save();
|
|
11493
12077
|
context.translate(cx, cy);
|
|
11494
|
-
if (shouldResetImageFilter(element, renderConfig, appState)) {
|
|
11495
|
-
context.filter = "none";
|
|
11496
|
-
}
|
|
11497
12078
|
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
11498
12079
|
if (isArrowElement(element) && boundTextElement) {
|
|
11499
12080
|
const tempCanvas = document.createElement("canvas");
|
|
@@ -11605,19 +12186,6 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
11605
12186
|
}
|
|
11606
12187
|
context.globalAlpha = 1;
|
|
11607
12188
|
};
|
|
11608
|
-
var pathsCache = /* @__PURE__ */ new WeakMap([]);
|
|
11609
|
-
function generateFreeDrawShape(element) {
|
|
11610
|
-
const svgPathData = getFreeDrawSvgPath(element);
|
|
11611
|
-
const path = new Path2D(svgPathData);
|
|
11612
|
-
pathsCache.set(element, path);
|
|
11613
|
-
return path;
|
|
11614
|
-
}
|
|
11615
|
-
function getFreeDrawPath2D(element) {
|
|
11616
|
-
return pathsCache.get(element);
|
|
11617
|
-
}
|
|
11618
|
-
function getFreeDrawSvgPath(element) {
|
|
11619
|
-
return getSvgPathFromStroke(getFreedrawOutlinePoints(element));
|
|
11620
|
-
}
|
|
11621
12189
|
function getFreedrawOutlineAsSegments(element, points, elementsMap) {
|
|
11622
12190
|
const bounds = getElementBounds(
|
|
11623
12191
|
{
|
|
@@ -11667,46 +12235,11 @@ function getFreedrawOutlineAsSegments(element, points, elementsMap) {
|
|
|
11667
12235
|
]
|
|
11668
12236
|
);
|
|
11669
12237
|
}
|
|
11670
|
-
function getFreedrawOutlinePoints(element) {
|
|
11671
|
-
const inputPoints = element.simulatePressure ? element.points : element.points.length ? element.points.map(([x, y], i) => [x, y, element.pressures[i]]) : [[0, 0, 0.5]];
|
|
11672
|
-
const options = {
|
|
11673
|
-
simulatePressure: element.simulatePressure,
|
|
11674
|
-
size: element.strokeWidth * 4.25,
|
|
11675
|
-
thinning: 0.6,
|
|
11676
|
-
smoothing: 0.5,
|
|
11677
|
-
streamline: 0.5,
|
|
11678
|
-
easing: (t) => Math.sin(t * Math.PI / 2),
|
|
11679
|
-
// https://easings.net/#easeOutSine
|
|
11680
|
-
last: true
|
|
11681
|
-
};
|
|
11682
|
-
return ae(inputPoints, options);
|
|
11683
|
-
}
|
|
11684
|
-
function med(A2, B2) {
|
|
11685
|
-
return [(A2[0] + B2[0]) / 2, (A2[1] + B2[1]) / 2];
|
|
11686
|
-
}
|
|
11687
|
-
var TO_FIXED_PRECISION = /(\s?[A-Z]?,?-?[0-9]*\.[0-9]{0,2})(([0-9]|e|-)*)/g;
|
|
11688
|
-
function getSvgPathFromStroke(points) {
|
|
11689
|
-
if (!points.length) {
|
|
11690
|
-
return "";
|
|
11691
|
-
}
|
|
11692
|
-
const max = points.length - 1;
|
|
11693
|
-
return points.reduce(
|
|
11694
|
-
(acc, point, i, arr) => {
|
|
11695
|
-
if (i === max) {
|
|
11696
|
-
acc.push(point, med(point, arr[0]), "L", arr[0], "Z");
|
|
11697
|
-
} else {
|
|
11698
|
-
acc.push(point, med(point, arr[i + 1]));
|
|
11699
|
-
}
|
|
11700
|
-
return acc;
|
|
11701
|
-
},
|
|
11702
|
-
["M", points[0], "Q"]
|
|
11703
|
-
).join(" ").replace(TO_FIXED_PRECISION, "$1");
|
|
11704
|
-
}
|
|
11705
12238
|
|
|
11706
12239
|
// src/comparisons.ts
|
|
11707
12240
|
init_define_import_meta_env();
|
|
11708
12241
|
var hasBackground = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "line" || type === "freedraw";
|
|
11709
|
-
var hasStrokeColor = (type) => type === "rectangle" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line" || type === "text";
|
|
12242
|
+
var hasStrokeColor = (type) => type === "rectangle" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line" || type === "text" || type === "embeddable";
|
|
11710
12243
|
var hasStrokeWidth = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line";
|
|
11711
12244
|
var hasStrokeStyle = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "arrow" || type === "line";
|
|
11712
12245
|
var canChangeRoundness = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "line" || type === "diamond" || type === "image";
|
|
@@ -11721,13 +12254,17 @@ var ShapeCache = class _ShapeCache {
|
|
|
11721
12254
|
* Retrieves shape from cache if available. Use this only if shape
|
|
11722
12255
|
* is optional and you have a fallback in case it's not cached.
|
|
11723
12256
|
*/
|
|
11724
|
-
static get = (element) => {
|
|
11725
|
-
|
|
11726
|
-
|
|
11727
|
-
|
|
12257
|
+
static get = (element, theme) => {
|
|
12258
|
+
const cached = _ShapeCache.cache.get(element);
|
|
12259
|
+
if (cached && (theme === null || cached.theme === theme)) {
|
|
12260
|
+
return cached.shape;
|
|
12261
|
+
}
|
|
12262
|
+
return void 0;
|
|
12263
|
+
};
|
|
12264
|
+
static delete = (element) => {
|
|
12265
|
+
_ShapeCache.cache.delete(element);
|
|
12266
|
+
elementWithCanvasCache.delete(element);
|
|
11728
12267
|
};
|
|
11729
|
-
static set = (element, shape) => _ShapeCache.cache.set(element, shape);
|
|
11730
|
-
static delete = (element) => _ShapeCache.cache.delete(element);
|
|
11731
12268
|
static destroy = () => {
|
|
11732
12269
|
_ShapeCache.cache = /* @__PURE__ */ new WeakMap();
|
|
11733
12270
|
};
|
|
@@ -11736,21 +12273,27 @@ var ShapeCache = class _ShapeCache {
|
|
|
11736
12273
|
* returns cached shape.
|
|
11737
12274
|
*/
|
|
11738
12275
|
static generateElementShape = (element, renderConfig) => {
|
|
11739
|
-
const cachedShape = renderConfig?.isExporting ? void 0 : _ShapeCache.get(element);
|
|
12276
|
+
const cachedShape = renderConfig?.isExporting ? void 0 : _ShapeCache.get(element, renderConfig ? renderConfig.theme : null);
|
|
11740
12277
|
if (cachedShape !== void 0) {
|
|
11741
12278
|
return cachedShape;
|
|
11742
12279
|
}
|
|
11743
12280
|
elementWithCanvasCache.delete(element);
|
|
11744
|
-
const shape =
|
|
12281
|
+
const shape = _generateElementShape(
|
|
11745
12282
|
element,
|
|
11746
12283
|
_ShapeCache.rg,
|
|
11747
12284
|
renderConfig || {
|
|
11748
12285
|
isExporting: false,
|
|
11749
12286
|
canvasBackgroundColor: COLOR_PALETTE.white,
|
|
11750
|
-
embedsValidationStatus: null
|
|
12287
|
+
embedsValidationStatus: null,
|
|
12288
|
+
theme: THEME2.LIGHT
|
|
11751
12289
|
}
|
|
11752
12290
|
);
|
|
11753
|
-
|
|
12291
|
+
if (!renderConfig?.isExporting) {
|
|
12292
|
+
_ShapeCache.cache.set(element, {
|
|
12293
|
+
shape,
|
|
12294
|
+
theme: renderConfig?.theme || THEME2.LIGHT
|
|
12295
|
+
});
|
|
12296
|
+
}
|
|
11754
12297
|
return shape;
|
|
11755
12298
|
};
|
|
11756
12299
|
};
|
|
@@ -11770,7 +12313,7 @@ function adjustRoughness(element) {
|
|
|
11770
12313
|
}
|
|
11771
12314
|
return Math.min(roughness / (maxSize < 10 ? 3 : 2), 2.5);
|
|
11772
12315
|
}
|
|
11773
|
-
var generateRoughOptions = (element, continuousPath = false) => {
|
|
12316
|
+
var generateRoughOptions = (element, continuousPath = false, isDarkMode = false) => {
|
|
11774
12317
|
const options = {
|
|
11775
12318
|
seed: element.seed,
|
|
11776
12319
|
strokeLineDash: element.strokeStyle === "dashed" ? getDashArrayDashed(element.strokeWidth) : element.strokeStyle === "dotted" ? getDashArrayDotted(element.strokeWidth) : void 0,
|
|
@@ -11786,7 +12329,7 @@ var generateRoughOptions = (element, continuousPath = false) => {
|
|
|
11786
12329
|
fillWeight: element.strokeWidth / 2,
|
|
11787
12330
|
hachureGap: element.strokeWidth * 4,
|
|
11788
12331
|
roughness: adjustRoughness(element),
|
|
11789
|
-
stroke: element.strokeColor,
|
|
12332
|
+
stroke: isDarkMode ? applyDarkModeFilter2(element.strokeColor) : element.strokeColor,
|
|
11790
12333
|
preserveVertices: continuousPath || element.roughness < ROUGHNESS.cartoonist
|
|
11791
12334
|
};
|
|
11792
12335
|
switch (element.type) {
|
|
@@ -11796,7 +12339,7 @@ var generateRoughOptions = (element, continuousPath = false) => {
|
|
|
11796
12339
|
case "diamond":
|
|
11797
12340
|
case "ellipse": {
|
|
11798
12341
|
options.fillStyle = element.fillStyle;
|
|
11799
|
-
options.fill = isTransparent3(element.backgroundColor) ? void 0 : element.backgroundColor;
|
|
12342
|
+
options.fill = isTransparent3(element.backgroundColor) ? void 0 : isDarkMode ? applyDarkModeFilter2(element.backgroundColor) : element.backgroundColor;
|
|
11800
12343
|
if (element.type === "ellipse") {
|
|
11801
12344
|
options.curveFitting = 1;
|
|
11802
12345
|
}
|
|
@@ -11806,7 +12349,7 @@ var generateRoughOptions = (element, continuousPath = false) => {
|
|
|
11806
12349
|
case "freedraw": {
|
|
11807
12350
|
if (isPathALoop(element.points)) {
|
|
11808
12351
|
options.fillStyle = element.fillStyle;
|
|
11809
|
-
options.fill = element.backgroundColor === "transparent" ? void 0 : element.backgroundColor;
|
|
12352
|
+
options.fill = element.backgroundColor === "transparent" ? void 0 : isDarkMode ? applyDarkModeFilter2(element.backgroundColor) : element.backgroundColor;
|
|
11810
12353
|
}
|
|
11811
12354
|
return options;
|
|
11812
12355
|
}
|
|
@@ -11834,7 +12377,7 @@ var modifyIframeLikeForRoughOptions = (element, isExporting, embedsValidationSta
|
|
|
11834
12377
|
}
|
|
11835
12378
|
return element;
|
|
11836
12379
|
};
|
|
11837
|
-
var getArrowheadShapes = (element, shape, position, arrowhead, generator, options, canvasBackgroundColor) => {
|
|
12380
|
+
var getArrowheadShapes = (element, shape, position, arrowhead, generator, options, canvasBackgroundColor, isDarkMode) => {
|
|
11838
12381
|
const arrowheadPoints = getArrowheadPoints(
|
|
11839
12382
|
element,
|
|
11840
12383
|
shape,
|
|
@@ -11851,6 +12394,7 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
|
|
|
11851
12394
|
const [, , x3, y3, x4, y4] = arrowheadPoints2;
|
|
11852
12395
|
return [generator.line(x3, y3, x4, y4, options2)];
|
|
11853
12396
|
};
|
|
12397
|
+
const strokeColor = isDarkMode ? applyDarkModeFilter2(element.strokeColor) : element.strokeColor;
|
|
11854
12398
|
switch (arrowhead) {
|
|
11855
12399
|
case "dot":
|
|
11856
12400
|
case "circle":
|
|
@@ -11860,9 +12404,9 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
|
|
|
11860
12404
|
return [
|
|
11861
12405
|
generator.circle(x, y, diameter, {
|
|
11862
12406
|
...options,
|
|
11863
|
-
fill: arrowhead === "circle_outline" ? canvasBackgroundColor :
|
|
12407
|
+
fill: arrowhead === "circle_outline" ? canvasBackgroundColor : strokeColor,
|
|
11864
12408
|
fillStyle: "solid",
|
|
11865
|
-
stroke:
|
|
12409
|
+
stroke: strokeColor,
|
|
11866
12410
|
roughness: Math.min(0.5, options.roughness || 0)
|
|
11867
12411
|
})
|
|
11868
12412
|
];
|
|
@@ -11881,7 +12425,7 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
|
|
|
11881
12425
|
],
|
|
11882
12426
|
{
|
|
11883
12427
|
...options,
|
|
11884
|
-
fill: arrowhead === "triangle_outline" ? canvasBackgroundColor :
|
|
12428
|
+
fill: arrowhead === "triangle_outline" ? canvasBackgroundColor : strokeColor,
|
|
11885
12429
|
fillStyle: "solid",
|
|
11886
12430
|
roughness: Math.min(1, options.roughness || 0)
|
|
11887
12431
|
}
|
|
@@ -11903,7 +12447,7 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
|
|
|
11903
12447
|
],
|
|
11904
12448
|
{
|
|
11905
12449
|
...options,
|
|
11906
|
-
fill: arrowhead === "diamond_outline" ? canvasBackgroundColor :
|
|
12450
|
+
fill: arrowhead === "diamond_outline" ? canvasBackgroundColor : strokeColor,
|
|
11907
12451
|
fillStyle: "solid",
|
|
11908
12452
|
roughness: Math.min(1, options.roughness || 0)
|
|
11909
12453
|
}
|
|
@@ -12084,11 +12628,13 @@ var generateLinearCollisionShape = (element) => {
|
|
|
12084
12628
|
}
|
|
12085
12629
|
}
|
|
12086
12630
|
};
|
|
12087
|
-
var
|
|
12631
|
+
var _generateElementShape = (element, generator, {
|
|
12088
12632
|
isExporting,
|
|
12089
12633
|
canvasBackgroundColor,
|
|
12090
|
-
embedsValidationStatus
|
|
12634
|
+
embedsValidationStatus,
|
|
12635
|
+
theme
|
|
12091
12636
|
}) => {
|
|
12637
|
+
const isDarkMode = theme === THEME2.DARK;
|
|
12092
12638
|
switch (element.type) {
|
|
12093
12639
|
case "rectangle":
|
|
12094
12640
|
case "iframe":
|
|
@@ -12106,7 +12652,8 @@ var generateElementShape = (element, generator, {
|
|
|
12106
12652
|
isExporting,
|
|
12107
12653
|
embedsValidationStatus
|
|
12108
12654
|
),
|
|
12109
|
-
true
|
|
12655
|
+
true,
|
|
12656
|
+
isDarkMode
|
|
12110
12657
|
)
|
|
12111
12658
|
);
|
|
12112
12659
|
} else {
|
|
@@ -12121,7 +12668,8 @@ var generateElementShape = (element, generator, {
|
|
|
12121
12668
|
isExporting,
|
|
12122
12669
|
embedsValidationStatus
|
|
12123
12670
|
),
|
|
12124
|
-
false
|
|
12671
|
+
false,
|
|
12672
|
+
isDarkMode
|
|
12125
12673
|
)
|
|
12126
12674
|
);
|
|
12127
12675
|
}
|
|
@@ -12145,7 +12693,7 @@ var generateElementShape = (element, generator, {
|
|
|
12145
12693
|
C ${leftX} ${leftY}, ${leftX} ${leftY}, ${leftX + verticalRadius} ${leftY - horizontalRadius}
|
|
12146
12694
|
L ${topX - verticalRadius} ${topY + horizontalRadius}
|
|
12147
12695
|
C ${topX} ${topY}, ${topX} ${topY}, ${topX + verticalRadius} ${topY + horizontalRadius}`,
|
|
12148
|
-
generateRoughOptions(element, true)
|
|
12696
|
+
generateRoughOptions(element, true, isDarkMode)
|
|
12149
12697
|
);
|
|
12150
12698
|
} else {
|
|
12151
12699
|
shape = generator.polygon(
|
|
@@ -12155,7 +12703,7 @@ var generateElementShape = (element, generator, {
|
|
|
12155
12703
|
[bottomX, bottomY],
|
|
12156
12704
|
[leftX, leftY]
|
|
12157
12705
|
],
|
|
12158
|
-
generateRoughOptions(element)
|
|
12706
|
+
generateRoughOptions(element, false, isDarkMode)
|
|
12159
12707
|
);
|
|
12160
12708
|
}
|
|
12161
12709
|
return shape;
|
|
@@ -12166,14 +12714,14 @@ var generateElementShape = (element, generator, {
|
|
|
12166
12714
|
element.height / 2,
|
|
12167
12715
|
element.width,
|
|
12168
12716
|
element.height,
|
|
12169
|
-
generateRoughOptions(element)
|
|
12717
|
+
generateRoughOptions(element, false, isDarkMode)
|
|
12170
12718
|
);
|
|
12171
12719
|
return shape;
|
|
12172
12720
|
}
|
|
12173
12721
|
case "line":
|
|
12174
12722
|
case "arrow": {
|
|
12175
12723
|
let shape;
|
|
12176
|
-
const options = generateRoughOptions(element);
|
|
12724
|
+
const options = generateRoughOptions(element, false, isDarkMode);
|
|
12177
12725
|
const points = element.points.length ? element.points : [pointFrom13(0, 0)];
|
|
12178
12726
|
if (isElbowArrow(element)) {
|
|
12179
12727
|
if (!points.every(
|
|
@@ -12189,7 +12737,7 @@ var generateElementShape = (element, generator, {
|
|
|
12189
12737
|
shape = [
|
|
12190
12738
|
generator.path(
|
|
12191
12739
|
generateElbowArrowShape(points, 16),
|
|
12192
|
-
generateRoughOptions(element, true)
|
|
12740
|
+
generateRoughOptions(element, true, isDarkMode)
|
|
12193
12741
|
)
|
|
12194
12742
|
];
|
|
12195
12743
|
}
|
|
@@ -12216,7 +12764,8 @@ var generateElementShape = (element, generator, {
|
|
|
12216
12764
|
startArrowhead,
|
|
12217
12765
|
generator,
|
|
12218
12766
|
options,
|
|
12219
|
-
canvasBackgroundColor
|
|
12767
|
+
canvasBackgroundColor,
|
|
12768
|
+
isDarkMode
|
|
12220
12769
|
);
|
|
12221
12770
|
shape.push(...shapes);
|
|
12222
12771
|
}
|
|
@@ -12230,7 +12779,8 @@ var generateElementShape = (element, generator, {
|
|
|
12230
12779
|
endArrowhead,
|
|
12231
12780
|
generator,
|
|
12232
12781
|
options,
|
|
12233
|
-
canvasBackgroundColor
|
|
12782
|
+
canvasBackgroundColor,
|
|
12783
|
+
isDarkMode
|
|
12234
12784
|
);
|
|
12235
12785
|
shape.push(...shapes);
|
|
12236
12786
|
}
|
|
@@ -12238,21 +12788,21 @@ var generateElementShape = (element, generator, {
|
|
|
12238
12788
|
return shape;
|
|
12239
12789
|
}
|
|
12240
12790
|
case "freedraw": {
|
|
12241
|
-
|
|
12242
|
-
generateFreeDrawShape(element);
|
|
12791
|
+
const shapes = [];
|
|
12243
12792
|
if (isPathALoop(element.points)) {
|
|
12244
12793
|
const simplifiedPoints = simplify(
|
|
12245
12794
|
element.points,
|
|
12246
12795
|
0.75
|
|
12247
12796
|
);
|
|
12248
|
-
|
|
12249
|
-
|
|
12250
|
-
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
|
|
12797
|
+
shapes.push(
|
|
12798
|
+
generator.curve(simplifiedPoints, {
|
|
12799
|
+
...generateRoughOptions(element, false, isDarkMode),
|
|
12800
|
+
stroke: "none"
|
|
12801
|
+
})
|
|
12802
|
+
);
|
|
12254
12803
|
}
|
|
12255
|
-
|
|
12804
|
+
shapes.push(getFreeDrawSvgPath(element));
|
|
12805
|
+
return shapes;
|
|
12256
12806
|
}
|
|
12257
12807
|
case "frame":
|
|
12258
12808
|
case "magicframe":
|
|
@@ -12331,7 +12881,7 @@ var getElementShape = (element, elementsMap) => {
|
|
|
12331
12881
|
return getPolygonShape(element);
|
|
12332
12882
|
case "arrow":
|
|
12333
12883
|
case "line": {
|
|
12334
|
-
const roughShape = ShapeCache.
|
|
12884
|
+
const roughShape = ShapeCache.generateElementShape(element, null)[0];
|
|
12335
12885
|
const [, , , , cx, cy] = getElementAbsoluteCoords2(element, elementsMap);
|
|
12336
12886
|
return shouldTestInside(element) ? getClosedCurveShape(
|
|
12337
12887
|
element,
|
|
@@ -12385,6 +12935,45 @@ var toggleLinePolygonState = (element, nextPolygonState) => {
|
|
|
12385
12935
|
};
|
|
12386
12936
|
return ret;
|
|
12387
12937
|
};
|
|
12938
|
+
var getFreeDrawSvgPath = (element) => {
|
|
12939
|
+
return getSvgPathFromStroke(
|
|
12940
|
+
getFreedrawOutlinePoints(element)
|
|
12941
|
+
);
|
|
12942
|
+
};
|
|
12943
|
+
var getFreedrawOutlinePoints = (element) => {
|
|
12944
|
+
const inputPoints = element.simulatePressure ? element.points : element.points.length ? element.points.map(([x, y], i) => [x, y, element.pressures[i]]) : [[0, 0, 0.5]];
|
|
12945
|
+
return ae(inputPoints, {
|
|
12946
|
+
simulatePressure: element.simulatePressure,
|
|
12947
|
+
size: element.strokeWidth * 4.25,
|
|
12948
|
+
thinning: 0.6,
|
|
12949
|
+
smoothing: 0.5,
|
|
12950
|
+
streamline: 0.5,
|
|
12951
|
+
easing: (t) => Math.sin(t * Math.PI / 2),
|
|
12952
|
+
// https://easings.net/#easeOutSine
|
|
12953
|
+
last: true
|
|
12954
|
+
});
|
|
12955
|
+
};
|
|
12956
|
+
var med = (A2, B2) => {
|
|
12957
|
+
return [(A2[0] + B2[0]) / 2, (A2[1] + B2[1]) / 2];
|
|
12958
|
+
};
|
|
12959
|
+
var TO_FIXED_PRECISION = /(\s?[A-Z]?,?-?[0-9]*\.[0-9]{0,2})(([0-9]|e|-)*)/g;
|
|
12960
|
+
var getSvgPathFromStroke = (points) => {
|
|
12961
|
+
if (!points.length) {
|
|
12962
|
+
return "";
|
|
12963
|
+
}
|
|
12964
|
+
const max = points.length - 1;
|
|
12965
|
+
return points.reduce(
|
|
12966
|
+
(acc, point, i, arr) => {
|
|
12967
|
+
if (i === max) {
|
|
12968
|
+
acc.push(point, med(point, arr[0]), "L", arr[0], "Z");
|
|
12969
|
+
} else {
|
|
12970
|
+
acc.push(point, med(point, arr[i + 1]));
|
|
12971
|
+
}
|
|
12972
|
+
return acc;
|
|
12973
|
+
},
|
|
12974
|
+
["M", points[0], "Q"]
|
|
12975
|
+
).join(" ").replace(TO_FIXED_PRECISION, "$1");
|
|
12976
|
+
};
|
|
12388
12977
|
|
|
12389
12978
|
// src/bounds.ts
|
|
12390
12979
|
var ElementBounds = class _ElementBounds {
|
|
@@ -12983,7 +13572,7 @@ var getLinearElementRotatedBounds = (element, cx, cy, elementsMap) => {
|
|
|
12983
13572
|
}
|
|
12984
13573
|
return coords2;
|
|
12985
13574
|
}
|
|
12986
|
-
const cachedShape = ShapeCache.get(element)?.[0];
|
|
13575
|
+
const cachedShape = ShapeCache.get(element, null)?.[0];
|
|
12987
13576
|
const shape = cachedShape ?? generateLinearElementShape(element);
|
|
12988
13577
|
const ops = getCurvePathOps(shape);
|
|
12989
13578
|
const transformXY = ([x, y]) => pointRotateRads13(
|
|
@@ -13210,7 +13799,7 @@ var elementCenterPoint = (element, elementsMap, xOffset = 0, yOffset = 0) => {
|
|
|
13210
13799
|
var INVISIBLY_SMALL_ELEMENT_SIZE = 0.1;
|
|
13211
13800
|
var isInvisiblySmallElement = (element) => {
|
|
13212
13801
|
if (isLinearElement(element) || isFreeDrawElement(element)) {
|
|
13213
|
-
return element.points.length < 2 || element.points.length === 2 && isArrowElement(element) &&
|
|
13802
|
+
return element.points.length < 2 || element.points.length === 2 && isArrowElement(element) && pointsEqual7(
|
|
13214
13803
|
element.points[0],
|
|
13215
13804
|
element.points[element.points.length - 1],
|
|
13216
13805
|
INVISIBLY_SMALL_ELEMENT_SIZE
|
|
@@ -16435,7 +17024,7 @@ var ElementsDelta = class _ElementsDelta {
|
|
|
16435
17024
|
|
|
16436
17025
|
// src/distribute.ts
|
|
16437
17026
|
init_define_import_meta_env();
|
|
16438
|
-
var distributeElements = (selectedElements, elementsMap, distribution, appState) => {
|
|
17027
|
+
var distributeElements = (selectedElements, elementsMap, distribution, appState, scene) => {
|
|
16439
17028
|
const [start, mid, end, extent] = distribution.axis === "x" ? ["minX", "midX", "maxX", "width"] : ["minY", "midY", "maxY", "height"];
|
|
16440
17029
|
const bounds = getCommonBoundingBox(selectedElements);
|
|
16441
17030
|
const groups = getSelectedElementsByGroup(
|
|
@@ -16462,12 +17051,16 @@ var distributeElements = (selectedElements, elementsMap, distribution, appState)
|
|
|
16462
17051
|
pos2 += step2;
|
|
16463
17052
|
translation[distribution.axis] = pos2 - box[mid];
|
|
16464
17053
|
}
|
|
16465
|
-
return group.map(
|
|
16466
|
-
|
|
17054
|
+
return group.map((element) => {
|
|
17055
|
+
const updatedElement = scene.mutateElement(element, {
|
|
16467
17056
|
x: element.x + translation.x,
|
|
16468
17057
|
y: element.y + translation.y
|
|
16469
|
-
})
|
|
16470
|
-
|
|
17058
|
+
});
|
|
17059
|
+
updateBoundElements(element, scene, {
|
|
17060
|
+
simultaneouslyUpdated: group
|
|
17061
|
+
});
|
|
17062
|
+
return updatedElement;
|
|
17063
|
+
});
|
|
16471
17064
|
});
|
|
16472
17065
|
}
|
|
16473
17066
|
let pos = bounds[start];
|
|
@@ -16479,12 +17072,16 @@ var distributeElements = (selectedElements, elementsMap, distribution, appState)
|
|
|
16479
17072
|
translation[distribution.axis] = pos - box[start];
|
|
16480
17073
|
pos += step;
|
|
16481
17074
|
pos += box[extent];
|
|
16482
|
-
return group.map(
|
|
16483
|
-
|
|
17075
|
+
return group.map((element) => {
|
|
17076
|
+
const updatedElement = scene.mutateElement(element, {
|
|
16484
17077
|
x: element.x + translation.x,
|
|
16485
17078
|
y: element.y + translation.y
|
|
16486
|
-
})
|
|
16487
|
-
|
|
17079
|
+
});
|
|
17080
|
+
updateBoundElements(element, scene, {
|
|
17081
|
+
simultaneouslyUpdated: group
|
|
17082
|
+
});
|
|
17083
|
+
return updatedElement;
|
|
17084
|
+
});
|
|
16488
17085
|
});
|
|
16489
17086
|
};
|
|
16490
17087
|
|
|
@@ -17921,116 +18518,829 @@ var isNodeInFlowchart = (element, elementsMap) => {
|
|
|
17921
18518
|
return false;
|
|
17922
18519
|
};
|
|
17923
18520
|
|
|
17924
|
-
// src/
|
|
18521
|
+
// src/arrows/focus.ts
|
|
17925
18522
|
init_define_import_meta_env();
|
|
17926
|
-
import {
|
|
17927
|
-
|
|
17928
|
-
|
|
17929
|
-
|
|
17930
|
-
|
|
17931
|
-
|
|
17932
|
-
|
|
17933
|
-
|
|
17934
|
-
reject(error);
|
|
17935
|
-
};
|
|
17936
|
-
image.src = dataURL;
|
|
17937
|
-
});
|
|
18523
|
+
import { pointDistance as pointDistance8, pointFrom as pointFrom16 } from "@excalidraw/math";
|
|
18524
|
+
import { invariant as invariant12 } from "@excalidraw/common";
|
|
18525
|
+
|
|
18526
|
+
// src/zindex.ts
|
|
18527
|
+
init_define_import_meta_env();
|
|
18528
|
+
import { arrayToMap as arrayToMap11, findIndex, findLastIndex as findLastIndex2 } from "@excalidraw/common";
|
|
18529
|
+
var isOfTargetFrame = (element, frameId) => {
|
|
18530
|
+
return element.frameId === frameId || element.id === frameId;
|
|
17938
18531
|
};
|
|
17939
|
-
var
|
|
17940
|
-
|
|
17941
|
-
|
|
17942
|
-
|
|
17943
|
-
|
|
17944
|
-
const
|
|
17945
|
-
|
|
17946
|
-
|
|
17947
|
-
|
|
17948
|
-
|
|
17949
|
-
if (fileData && !updatedFiles.has(fileId)) {
|
|
17950
|
-
updatedFiles.set(fileId, true);
|
|
17951
|
-
return promises.concat(
|
|
17952
|
-
(async () => {
|
|
17953
|
-
try {
|
|
17954
|
-
if (fileData.mimeType === MIME_TYPES2.binary) {
|
|
17955
|
-
throw new Error("Only images can be added to ImageCache");
|
|
17956
|
-
}
|
|
17957
|
-
const imagePromise = loadHTMLImageElement(fileData.dataURL);
|
|
17958
|
-
const data = {
|
|
17959
|
-
image: imagePromise,
|
|
17960
|
-
mimeType: fileData.mimeType
|
|
17961
|
-
};
|
|
17962
|
-
imageCache.set(fileId, data);
|
|
17963
|
-
const image = await imagePromise;
|
|
17964
|
-
imageCache.set(fileId, { ...data, image });
|
|
17965
|
-
} catch (error) {
|
|
17966
|
-
erroredFiles.set(fileId, true);
|
|
17967
|
-
}
|
|
17968
|
-
})()
|
|
17969
|
-
);
|
|
17970
|
-
}
|
|
17971
|
-
return promises;
|
|
17972
|
-
}, [])
|
|
18532
|
+
var getIndicesToMove = (elements, appState, elementsToBeMoved) => {
|
|
18533
|
+
let selectedIndices = [];
|
|
18534
|
+
let deletedIndices = [];
|
|
18535
|
+
let includeDeletedIndex = null;
|
|
18536
|
+
let index = -1;
|
|
18537
|
+
const selectedElementIds = arrayToMap11(
|
|
18538
|
+
elementsToBeMoved ? elementsToBeMoved : getSelectedElements(elements, appState, {
|
|
18539
|
+
includeBoundTextElement: true,
|
|
18540
|
+
includeElementsInFrames: true
|
|
18541
|
+
})
|
|
17973
18542
|
);
|
|
17974
|
-
|
|
17975
|
-
|
|
17976
|
-
|
|
17977
|
-
|
|
17978
|
-
|
|
17979
|
-
|
|
17980
|
-
};
|
|
17981
|
-
};
|
|
17982
|
-
var getInitializedImageElements = (elements) => elements.filter(
|
|
17983
|
-
(element) => isInitializedImageElement(element)
|
|
17984
|
-
);
|
|
17985
|
-
var isHTMLSVGElement = (node) => {
|
|
17986
|
-
return node?.nodeName.toLowerCase() === "svg";
|
|
17987
|
-
};
|
|
17988
|
-
var normalizeSVG = (SVGString) => {
|
|
17989
|
-
const doc = new DOMParser().parseFromString(SVGString, MIME_TYPES2.svg);
|
|
17990
|
-
const svg = doc.querySelector("svg");
|
|
17991
|
-
const errorNode = doc.querySelector("parsererror");
|
|
17992
|
-
if (errorNode || !isHTMLSVGElement(svg)) {
|
|
17993
|
-
throw new Error("Invalid SVG");
|
|
17994
|
-
} else {
|
|
17995
|
-
if (!svg.hasAttribute("xmlns")) {
|
|
17996
|
-
svg.setAttribute("xmlns", SVG_NS);
|
|
17997
|
-
}
|
|
17998
|
-
let width = svg.getAttribute("width");
|
|
17999
|
-
let height = svg.getAttribute("height");
|
|
18000
|
-
if (width?.includes("%") || width === "auto") {
|
|
18001
|
-
width = null;
|
|
18002
|
-
}
|
|
18003
|
-
if (height?.includes("%") || height === "auto") {
|
|
18004
|
-
height = null;
|
|
18005
|
-
}
|
|
18006
|
-
const viewBox = svg.getAttribute("viewBox");
|
|
18007
|
-
if (!width || !height) {
|
|
18008
|
-
width = width || "50";
|
|
18009
|
-
height = height || "50";
|
|
18010
|
-
if (viewBox) {
|
|
18011
|
-
const match = viewBox.match(
|
|
18012
|
-
/\d+ +\d+ +(\d+(?:\.\d+)?) +(\d+(?:\.\d+)?)/
|
|
18013
|
-
);
|
|
18014
|
-
if (match) {
|
|
18015
|
-
[, width, height] = match;
|
|
18016
|
-
}
|
|
18543
|
+
while (++index < elements.length) {
|
|
18544
|
+
const element = elements[index];
|
|
18545
|
+
if (selectedElementIds.get(element.id)) {
|
|
18546
|
+
if (deletedIndices.length) {
|
|
18547
|
+
selectedIndices = selectedIndices.concat(deletedIndices);
|
|
18548
|
+
deletedIndices = [];
|
|
18017
18549
|
}
|
|
18018
|
-
|
|
18019
|
-
|
|
18020
|
-
}
|
|
18021
|
-
|
|
18022
|
-
|
|
18550
|
+
selectedIndices.push(index);
|
|
18551
|
+
includeDeletedIndex = index + 1;
|
|
18552
|
+
} else if (element.isDeleted && includeDeletedIndex === index) {
|
|
18553
|
+
includeDeletedIndex = index + 1;
|
|
18554
|
+
deletedIndices.push(index);
|
|
18555
|
+
} else {
|
|
18556
|
+
deletedIndices = [];
|
|
18023
18557
|
}
|
|
18024
|
-
return svg.outerHTML;
|
|
18025
18558
|
}
|
|
18559
|
+
return selectedIndices;
|
|
18026
18560
|
};
|
|
18027
|
-
|
|
18028
|
-
|
|
18029
|
-
|
|
18030
|
-
|
|
18031
|
-
|
|
18032
|
-
|
|
18033
|
-
|
|
18561
|
+
var toContiguousGroups = (array) => {
|
|
18562
|
+
let cursor = 0;
|
|
18563
|
+
return array.reduce((acc, value, index) => {
|
|
18564
|
+
if (index > 0 && array[index - 1] !== value - 1) {
|
|
18565
|
+
cursor = ++cursor;
|
|
18566
|
+
}
|
|
18567
|
+
(acc[cursor] || (acc[cursor] = [])).push(value);
|
|
18568
|
+
return acc;
|
|
18569
|
+
}, []);
|
|
18570
|
+
};
|
|
18571
|
+
var getTargetIndexAccountingForBinding = (nextElement, elements, direction, scene) => {
|
|
18572
|
+
if ("containerId" in nextElement && nextElement.containerId) {
|
|
18573
|
+
const containerElement = scene.getElement(nextElement.containerId);
|
|
18574
|
+
if (containerElement) {
|
|
18575
|
+
return direction === "left" ? Math.min(
|
|
18576
|
+
elements.indexOf(containerElement),
|
|
18577
|
+
elements.indexOf(nextElement)
|
|
18578
|
+
) : Math.max(
|
|
18579
|
+
elements.indexOf(containerElement),
|
|
18580
|
+
elements.indexOf(nextElement)
|
|
18581
|
+
);
|
|
18582
|
+
}
|
|
18583
|
+
} else {
|
|
18584
|
+
const boundElementId = nextElement.boundElements?.find(
|
|
18585
|
+
(binding) => binding.type !== "arrow"
|
|
18586
|
+
)?.id;
|
|
18587
|
+
if (boundElementId) {
|
|
18588
|
+
const boundTextElement = scene.getElement(boundElementId);
|
|
18589
|
+
if (boundTextElement) {
|
|
18590
|
+
return direction === "left" ? Math.min(
|
|
18591
|
+
elements.indexOf(boundTextElement),
|
|
18592
|
+
elements.indexOf(nextElement)
|
|
18593
|
+
) : Math.max(
|
|
18594
|
+
elements.indexOf(boundTextElement),
|
|
18595
|
+
elements.indexOf(nextElement)
|
|
18596
|
+
);
|
|
18597
|
+
}
|
|
18598
|
+
}
|
|
18599
|
+
}
|
|
18600
|
+
};
|
|
18601
|
+
var getContiguousFrameRangeElements = (allElements, frameId) => {
|
|
18602
|
+
let rangeStart = -1;
|
|
18603
|
+
let rangeEnd = -1;
|
|
18604
|
+
allElements.forEach((element, index) => {
|
|
18605
|
+
if (isOfTargetFrame(element, frameId)) {
|
|
18606
|
+
if (rangeStart === -1) {
|
|
18607
|
+
rangeStart = index;
|
|
18608
|
+
}
|
|
18609
|
+
rangeEnd = index;
|
|
18610
|
+
}
|
|
18611
|
+
});
|
|
18612
|
+
if (rangeStart === -1) {
|
|
18613
|
+
return [];
|
|
18614
|
+
}
|
|
18615
|
+
return allElements.slice(rangeStart, rangeEnd + 1);
|
|
18616
|
+
};
|
|
18617
|
+
var moveArrowAboveBindable2 = (point, arrow, elements, elementsMap, scene, hit) => {
|
|
18618
|
+
const hoveredElement = hit ? hit : getHoveredElementForBinding(point, elements, elementsMap);
|
|
18619
|
+
if (!hoveredElement) {
|
|
18620
|
+
return elements;
|
|
18621
|
+
}
|
|
18622
|
+
const boundTextElement = getBoundTextElement(hoveredElement, elementsMap);
|
|
18623
|
+
const containerElement = isTextElement(hoveredElement) ? getContainerElement(hoveredElement, elementsMap) : null;
|
|
18624
|
+
const bindableIds = [
|
|
18625
|
+
hoveredElement.id,
|
|
18626
|
+
boundTextElement?.id,
|
|
18627
|
+
containerElement?.id
|
|
18628
|
+
].filter((id) => !!id);
|
|
18629
|
+
const bindableIdx = elements.findIndex((el) => bindableIds.includes(el.id));
|
|
18630
|
+
const arrowIdx = elements.findIndex((el) => el.id === arrow.id);
|
|
18631
|
+
if (arrowIdx !== -1 && bindableIdx !== -1 && arrowIdx < bindableIdx) {
|
|
18632
|
+
const updatedElements = Array.from(elements);
|
|
18633
|
+
const arrow2 = updatedElements.splice(arrowIdx, 1)[0];
|
|
18634
|
+
updatedElements.splice(bindableIdx, 0, arrow2);
|
|
18635
|
+
scene.replaceAllElements(updatedElements);
|
|
18636
|
+
}
|
|
18637
|
+
return elements;
|
|
18638
|
+
};
|
|
18639
|
+
var getTargetIndex = (appState, elements, boundaryIndex, direction, containingFrame, scene) => {
|
|
18640
|
+
const sourceElement = elements[boundaryIndex];
|
|
18641
|
+
const indexFilter = (element) => {
|
|
18642
|
+
if (element.isDeleted) {
|
|
18643
|
+
return false;
|
|
18644
|
+
}
|
|
18645
|
+
if (containingFrame) {
|
|
18646
|
+
return element.frameId === containingFrame;
|
|
18647
|
+
}
|
|
18648
|
+
if (appState.editingGroupId) {
|
|
18649
|
+
return element.groupIds.includes(appState.editingGroupId);
|
|
18650
|
+
}
|
|
18651
|
+
return true;
|
|
18652
|
+
};
|
|
18653
|
+
const candidateIndex = direction === "left" ? findLastIndex2(
|
|
18654
|
+
elements,
|
|
18655
|
+
(el) => indexFilter(el),
|
|
18656
|
+
Math.max(0, boundaryIndex - 1)
|
|
18657
|
+
) : findIndex(elements, (el) => indexFilter(el), boundaryIndex + 1);
|
|
18658
|
+
const nextElement = elements[candidateIndex];
|
|
18659
|
+
if (!nextElement) {
|
|
18660
|
+
return -1;
|
|
18661
|
+
}
|
|
18662
|
+
if (appState.editingGroupId) {
|
|
18663
|
+
if (
|
|
18664
|
+
// candidate element is a sibling in current editing group → return
|
|
18665
|
+
sourceElement?.groupIds.join("") === nextElement?.groupIds.join("")
|
|
18666
|
+
) {
|
|
18667
|
+
return getTargetIndexAccountingForBinding(
|
|
18668
|
+
nextElement,
|
|
18669
|
+
elements,
|
|
18670
|
+
direction,
|
|
18671
|
+
scene
|
|
18672
|
+
) ?? candidateIndex;
|
|
18673
|
+
} else if (!nextElement?.groupIds.includes(appState.editingGroupId)) {
|
|
18674
|
+
return -1;
|
|
18675
|
+
}
|
|
18676
|
+
}
|
|
18677
|
+
if (!containingFrame && (nextElement.frameId || isFrameLikeElement(nextElement))) {
|
|
18678
|
+
const frameElements = getContiguousFrameRangeElements(
|
|
18679
|
+
elements,
|
|
18680
|
+
nextElement.frameId || nextElement.id
|
|
18681
|
+
);
|
|
18682
|
+
return direction === "left" ? elements.indexOf(frameElements[0]) : elements.indexOf(frameElements[frameElements.length - 1]);
|
|
18683
|
+
}
|
|
18684
|
+
if (!nextElement.groupIds.length) {
|
|
18685
|
+
return getTargetIndexAccountingForBinding(
|
|
18686
|
+
nextElement,
|
|
18687
|
+
elements,
|
|
18688
|
+
direction,
|
|
18689
|
+
scene
|
|
18690
|
+
) ?? candidateIndex;
|
|
18691
|
+
}
|
|
18692
|
+
const siblingGroupId = appState.editingGroupId ? nextElement.groupIds[nextElement.groupIds.indexOf(appState.editingGroupId) - 1] : nextElement.groupIds[nextElement.groupIds.length - 1];
|
|
18693
|
+
const elementsInSiblingGroup = getElementsInGroup(elements, siblingGroupId);
|
|
18694
|
+
if (elementsInSiblingGroup.length) {
|
|
18695
|
+
return direction === "left" ? elements.indexOf(elementsInSiblingGroup[0]) : elements.indexOf(
|
|
18696
|
+
elementsInSiblingGroup[elementsInSiblingGroup.length - 1]
|
|
18697
|
+
);
|
|
18698
|
+
}
|
|
18699
|
+
return candidateIndex;
|
|
18700
|
+
};
|
|
18701
|
+
var getTargetElementsMap = (elements, indices) => {
|
|
18702
|
+
return indices.reduce((acc, index) => {
|
|
18703
|
+
const element = elements[index];
|
|
18704
|
+
acc.set(element.id, element);
|
|
18705
|
+
return acc;
|
|
18706
|
+
}, /* @__PURE__ */ new Map());
|
|
18707
|
+
};
|
|
18708
|
+
var shiftElementsByOne = (elements, appState, direction, scene) => {
|
|
18709
|
+
const indicesToMove = getIndicesToMove(elements, appState);
|
|
18710
|
+
const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
|
|
18711
|
+
let groupedIndices = toContiguousGroups(indicesToMove);
|
|
18712
|
+
if (direction === "right") {
|
|
18713
|
+
groupedIndices = groupedIndices.reverse();
|
|
18714
|
+
}
|
|
18715
|
+
const selectedFrames = new Set(
|
|
18716
|
+
indicesToMove.filter((idx) => isFrameLikeElement(elements[idx])).map((idx) => elements[idx].id)
|
|
18717
|
+
);
|
|
18718
|
+
groupedIndices.forEach((indices, i) => {
|
|
18719
|
+
const leadingIndex = indices[0];
|
|
18720
|
+
const trailingIndex = indices[indices.length - 1];
|
|
18721
|
+
const boundaryIndex = direction === "left" ? leadingIndex : trailingIndex;
|
|
18722
|
+
const containingFrame = indices.some((idx) => {
|
|
18723
|
+
const el = elements[idx];
|
|
18724
|
+
return el.frameId && selectedFrames.has(el.frameId);
|
|
18725
|
+
}) ? null : elements[boundaryIndex]?.frameId;
|
|
18726
|
+
const targetIndex = getTargetIndex(
|
|
18727
|
+
appState,
|
|
18728
|
+
elements,
|
|
18729
|
+
boundaryIndex,
|
|
18730
|
+
direction,
|
|
18731
|
+
containingFrame,
|
|
18732
|
+
scene
|
|
18733
|
+
);
|
|
18734
|
+
if (targetIndex === -1 || boundaryIndex === targetIndex) {
|
|
18735
|
+
return;
|
|
18736
|
+
}
|
|
18737
|
+
const leadingElements = direction === "left" ? elements.slice(0, targetIndex) : elements.slice(0, leadingIndex);
|
|
18738
|
+
const targetElements = elements.slice(leadingIndex, trailingIndex + 1);
|
|
18739
|
+
const displacedElements = direction === "left" ? elements.slice(targetIndex, leadingIndex) : elements.slice(trailingIndex + 1, targetIndex + 1);
|
|
18740
|
+
const trailingElements = direction === "left" ? elements.slice(trailingIndex + 1) : elements.slice(targetIndex + 1);
|
|
18741
|
+
elements = direction === "left" ? [
|
|
18742
|
+
...leadingElements,
|
|
18743
|
+
...targetElements,
|
|
18744
|
+
...displacedElements,
|
|
18745
|
+
...trailingElements
|
|
18746
|
+
] : [
|
|
18747
|
+
...leadingElements,
|
|
18748
|
+
...displacedElements,
|
|
18749
|
+
...targetElements,
|
|
18750
|
+
...trailingElements
|
|
18751
|
+
];
|
|
18752
|
+
});
|
|
18753
|
+
syncMovedIndices(elements, targetElementsMap);
|
|
18754
|
+
return elements;
|
|
18755
|
+
};
|
|
18756
|
+
var shiftElementsToEnd = (elements, appState, direction, containingFrame, elementsToBeMoved) => {
|
|
18757
|
+
const indicesToMove = getIndicesToMove(elements, appState, elementsToBeMoved);
|
|
18758
|
+
const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
|
|
18759
|
+
const displacedElements = [];
|
|
18760
|
+
let leadingIndex;
|
|
18761
|
+
let trailingIndex;
|
|
18762
|
+
if (direction === "left") {
|
|
18763
|
+
if (containingFrame) {
|
|
18764
|
+
leadingIndex = findIndex(
|
|
18765
|
+
elements,
|
|
18766
|
+
(el) => isOfTargetFrame(el, containingFrame)
|
|
18767
|
+
);
|
|
18768
|
+
} else if (appState.editingGroupId) {
|
|
18769
|
+
const groupElements = getElementsInGroup(
|
|
18770
|
+
elements,
|
|
18771
|
+
appState.editingGroupId
|
|
18772
|
+
);
|
|
18773
|
+
if (!groupElements.length) {
|
|
18774
|
+
return elements;
|
|
18775
|
+
}
|
|
18776
|
+
leadingIndex = elements.indexOf(groupElements[0]);
|
|
18777
|
+
} else {
|
|
18778
|
+
leadingIndex = 0;
|
|
18779
|
+
}
|
|
18780
|
+
trailingIndex = indicesToMove[indicesToMove.length - 1];
|
|
18781
|
+
} else {
|
|
18782
|
+
if (containingFrame) {
|
|
18783
|
+
trailingIndex = findLastIndex2(
|
|
18784
|
+
elements,
|
|
18785
|
+
(el) => isOfTargetFrame(el, containingFrame)
|
|
18786
|
+
);
|
|
18787
|
+
} else if (appState.editingGroupId) {
|
|
18788
|
+
const groupElements = getElementsInGroup(
|
|
18789
|
+
elements,
|
|
18790
|
+
appState.editingGroupId
|
|
18791
|
+
);
|
|
18792
|
+
if (!groupElements.length) {
|
|
18793
|
+
return elements;
|
|
18794
|
+
}
|
|
18795
|
+
trailingIndex = elements.indexOf(groupElements[groupElements.length - 1]);
|
|
18796
|
+
} else {
|
|
18797
|
+
trailingIndex = elements.length - 1;
|
|
18798
|
+
}
|
|
18799
|
+
leadingIndex = indicesToMove[0];
|
|
18800
|
+
}
|
|
18801
|
+
if (leadingIndex === -1) {
|
|
18802
|
+
leadingIndex = 0;
|
|
18803
|
+
}
|
|
18804
|
+
for (let index = leadingIndex; index < trailingIndex + 1; index++) {
|
|
18805
|
+
if (!indicesToMove.includes(index)) {
|
|
18806
|
+
displacedElements.push(elements[index]);
|
|
18807
|
+
}
|
|
18808
|
+
}
|
|
18809
|
+
const targetElements = Array.from(targetElementsMap.values());
|
|
18810
|
+
const leadingElements = elements.slice(0, leadingIndex);
|
|
18811
|
+
const trailingElements = elements.slice(trailingIndex + 1);
|
|
18812
|
+
const nextElements = direction === "left" ? [
|
|
18813
|
+
...leadingElements,
|
|
18814
|
+
...targetElements,
|
|
18815
|
+
...displacedElements,
|
|
18816
|
+
...trailingElements
|
|
18817
|
+
] : [
|
|
18818
|
+
...leadingElements,
|
|
18819
|
+
...displacedElements,
|
|
18820
|
+
...targetElements,
|
|
18821
|
+
...trailingElements
|
|
18822
|
+
];
|
|
18823
|
+
syncMovedIndices(nextElements, targetElementsMap);
|
|
18824
|
+
return nextElements;
|
|
18825
|
+
};
|
|
18826
|
+
function shiftElementsAccountingForFrames(allElements, appState, direction, shiftFunction) {
|
|
18827
|
+
const elementsToMove = arrayToMap11(
|
|
18828
|
+
getSelectedElements(allElements, appState, {
|
|
18829
|
+
includeBoundTextElement: true,
|
|
18830
|
+
includeElementsInFrames: true
|
|
18831
|
+
})
|
|
18832
|
+
);
|
|
18833
|
+
const frameAwareContiguousElementsToMove = { regularElements: [], frameChildren: /* @__PURE__ */ new Map() };
|
|
18834
|
+
const fullySelectedFrames = /* @__PURE__ */ new Set();
|
|
18835
|
+
for (const element of allElements) {
|
|
18836
|
+
if (elementsToMove.has(element.id) && isFrameLikeElement(element)) {
|
|
18837
|
+
fullySelectedFrames.add(element.id);
|
|
18838
|
+
}
|
|
18839
|
+
}
|
|
18840
|
+
for (const element of allElements) {
|
|
18841
|
+
if (elementsToMove.has(element.id)) {
|
|
18842
|
+
if (isFrameLikeElement(element) || element.frameId && fullySelectedFrames.has(element.frameId)) {
|
|
18843
|
+
frameAwareContiguousElementsToMove.regularElements.push(element);
|
|
18844
|
+
} else if (!element.frameId) {
|
|
18845
|
+
frameAwareContiguousElementsToMove.regularElements.push(element);
|
|
18846
|
+
} else {
|
|
18847
|
+
const frameChildren = frameAwareContiguousElementsToMove.frameChildren.get(
|
|
18848
|
+
element.frameId
|
|
18849
|
+
) || [];
|
|
18850
|
+
frameChildren.push(element);
|
|
18851
|
+
frameAwareContiguousElementsToMove.frameChildren.set(
|
|
18852
|
+
element.frameId,
|
|
18853
|
+
frameChildren
|
|
18854
|
+
);
|
|
18855
|
+
}
|
|
18856
|
+
}
|
|
18857
|
+
}
|
|
18858
|
+
let nextElements = allElements;
|
|
18859
|
+
const frameChildrenSets = Array.from(
|
|
18860
|
+
frameAwareContiguousElementsToMove.frameChildren.entries()
|
|
18861
|
+
);
|
|
18862
|
+
for (const [frameId, children] of frameChildrenSets) {
|
|
18863
|
+
nextElements = shiftFunction(
|
|
18864
|
+
allElements,
|
|
18865
|
+
appState,
|
|
18866
|
+
direction,
|
|
18867
|
+
frameId,
|
|
18868
|
+
children
|
|
18869
|
+
);
|
|
18870
|
+
}
|
|
18871
|
+
return shiftFunction(
|
|
18872
|
+
nextElements,
|
|
18873
|
+
appState,
|
|
18874
|
+
direction,
|
|
18875
|
+
null,
|
|
18876
|
+
frameAwareContiguousElementsToMove.regularElements
|
|
18877
|
+
);
|
|
18878
|
+
}
|
|
18879
|
+
var moveOneLeft = (allElements, appState, scene) => {
|
|
18880
|
+
return shiftElementsByOne(allElements, appState, "left", scene);
|
|
18881
|
+
};
|
|
18882
|
+
var moveOneRight = (allElements, appState, scene) => {
|
|
18883
|
+
return shiftElementsByOne(allElements, appState, "right", scene);
|
|
18884
|
+
};
|
|
18885
|
+
var moveAllLeft = (allElements, appState) => {
|
|
18886
|
+
return shiftElementsAccountingForFrames(
|
|
18887
|
+
allElements,
|
|
18888
|
+
appState,
|
|
18889
|
+
"left",
|
|
18890
|
+
shiftElementsToEnd
|
|
18891
|
+
);
|
|
18892
|
+
};
|
|
18893
|
+
var moveAllRight = (allElements, appState) => {
|
|
18894
|
+
return shiftElementsAccountingForFrames(
|
|
18895
|
+
allElements,
|
|
18896
|
+
appState,
|
|
18897
|
+
"right",
|
|
18898
|
+
shiftElementsToEnd
|
|
18899
|
+
);
|
|
18900
|
+
};
|
|
18901
|
+
|
|
18902
|
+
// src/arrows/focus.ts
|
|
18903
|
+
var isFocusPointVisible = (focusPoint, arrow, bindableElement, elementsMap, appState, ignoreOverlap = false) => {
|
|
18904
|
+
if (isElbowArrow(arrow) || !isBindingEnabled(appState) || arrow.points.length !== 2) {
|
|
18905
|
+
return false;
|
|
18906
|
+
}
|
|
18907
|
+
if (!ignoreOverlap) {
|
|
18908
|
+
const associatedPointIdx = arrow.startBinding?.elementId === bindableElement.id ? 0 : arrow.points.length - 1;
|
|
18909
|
+
const associatedArrowPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
18910
|
+
arrow,
|
|
18911
|
+
associatedPointIdx,
|
|
18912
|
+
elementsMap
|
|
18913
|
+
);
|
|
18914
|
+
if (pointDistance8(focusPoint, associatedArrowPoint) < FOCUS_POINT_SIZE * 1.5 / appState.zoom.value) {
|
|
18915
|
+
return false;
|
|
18916
|
+
}
|
|
18917
|
+
}
|
|
18918
|
+
return hitElementItself({
|
|
18919
|
+
element: bindableElement,
|
|
18920
|
+
elementsMap,
|
|
18921
|
+
point: focusPoint,
|
|
18922
|
+
threshold: getBindingGap(bindableElement, arrow),
|
|
18923
|
+
overrideShouldTestInside: true
|
|
18924
|
+
});
|
|
18925
|
+
};
|
|
18926
|
+
var focusPointUpdate = (arrow, bindableElement, isStartBinding, elementsMap, scene, appState, switchToInsideBinding) => {
|
|
18927
|
+
const pointUpdates = /* @__PURE__ */ new Map();
|
|
18928
|
+
const bindingField = isStartBinding ? "startBinding" : "endBinding";
|
|
18929
|
+
const adjacentBindingField = isStartBinding ? "endBinding" : "startBinding";
|
|
18930
|
+
let currentBinding = arrow[bindingField];
|
|
18931
|
+
let adjacentBinding = arrow[adjacentBindingField];
|
|
18932
|
+
if (currentBinding && bindableElement) {
|
|
18933
|
+
const boundToSameElement = bindableElement && adjacentBinding && currentBinding.elementId === adjacentBinding.elementId;
|
|
18934
|
+
if (switchToInsideBinding || boundToSameElement) {
|
|
18935
|
+
currentBinding = {
|
|
18936
|
+
...currentBinding,
|
|
18937
|
+
mode: "inside"
|
|
18938
|
+
};
|
|
18939
|
+
} else {
|
|
18940
|
+
currentBinding = {
|
|
18941
|
+
...currentBinding,
|
|
18942
|
+
mode: "orbit"
|
|
18943
|
+
};
|
|
18944
|
+
}
|
|
18945
|
+
const pointIndex = isStartBinding ? 0 : arrow.points.length - 1;
|
|
18946
|
+
const newPoint = updateBoundPoint(
|
|
18947
|
+
arrow,
|
|
18948
|
+
bindingField,
|
|
18949
|
+
currentBinding,
|
|
18950
|
+
bindableElement,
|
|
18951
|
+
elementsMap
|
|
18952
|
+
);
|
|
18953
|
+
if (newPoint) {
|
|
18954
|
+
pointUpdates.set(pointIndex, { point: newPoint });
|
|
18955
|
+
}
|
|
18956
|
+
}
|
|
18957
|
+
if (adjacentBinding) {
|
|
18958
|
+
const adjacentBindableElement = elementsMap.get(
|
|
18959
|
+
adjacentBinding.elementId
|
|
18960
|
+
);
|
|
18961
|
+
if (adjacentBindableElement && isBindableElement(adjacentBindableElement) && isBindingEnabled(appState)) {
|
|
18962
|
+
const boundToSameElementAfterUpdate = bindableElement && adjacentBinding.elementId === bindableElement.id;
|
|
18963
|
+
if (switchToInsideBinding || boundToSameElementAfterUpdate) {
|
|
18964
|
+
adjacentBinding = {
|
|
18965
|
+
...adjacentBinding,
|
|
18966
|
+
mode: "inside"
|
|
18967
|
+
};
|
|
18968
|
+
} else {
|
|
18969
|
+
adjacentBinding = {
|
|
18970
|
+
...adjacentBinding,
|
|
18971
|
+
mode: "orbit"
|
|
18972
|
+
};
|
|
18973
|
+
}
|
|
18974
|
+
const adjacentPointIndex = isStartBinding ? arrow.points.length - 1 : 0;
|
|
18975
|
+
const adjacentNewPoint = updateBoundPoint(
|
|
18976
|
+
arrow,
|
|
18977
|
+
adjacentBindingField,
|
|
18978
|
+
adjacentBinding,
|
|
18979
|
+
adjacentBindableElement,
|
|
18980
|
+
elementsMap
|
|
18981
|
+
);
|
|
18982
|
+
if (adjacentNewPoint) {
|
|
18983
|
+
pointUpdates.set(adjacentPointIndex, {
|
|
18984
|
+
point: adjacentNewPoint
|
|
18985
|
+
});
|
|
18986
|
+
}
|
|
18987
|
+
}
|
|
18988
|
+
}
|
|
18989
|
+
if (pointUpdates.size > 0) {
|
|
18990
|
+
LinearElementEditor.movePoints(arrow, scene, pointUpdates, {
|
|
18991
|
+
[bindingField]: currentBinding,
|
|
18992
|
+
[adjacentBindingField]: adjacentBinding
|
|
18993
|
+
});
|
|
18994
|
+
}
|
|
18995
|
+
};
|
|
18996
|
+
var handleFocusPointDrag = (linearElementEditor, elementsMap, pointerCoords, scene, appState, gridSize, switchToInsideBinding) => {
|
|
18997
|
+
const arrow = LinearElementEditor.getElement(
|
|
18998
|
+
linearElementEditor.elementId,
|
|
18999
|
+
elementsMap
|
|
19000
|
+
);
|
|
19001
|
+
if (!arrow || !isBindingElement(arrow) || isElbowArrow(arrow) || !linearElementEditor.hoveredFocusPointBinding || !linearElementEditor.draggedFocusPointBinding) {
|
|
19002
|
+
return;
|
|
19003
|
+
}
|
|
19004
|
+
const isStartBinding = linearElementEditor.draggedFocusPointBinding === "start";
|
|
19005
|
+
const binding = isStartBinding ? arrow.startBinding : arrow.endBinding;
|
|
19006
|
+
const { x: offsetX, y: offsetY } = linearElementEditor.pointerOffset;
|
|
19007
|
+
const point = pointFrom16(
|
|
19008
|
+
pointerCoords.x - offsetX,
|
|
19009
|
+
pointerCoords.y - offsetY
|
|
19010
|
+
);
|
|
19011
|
+
const bindingField = isStartBinding ? "startBinding" : "endBinding";
|
|
19012
|
+
const hit = getHoveredElementForFocusPoint(
|
|
19013
|
+
point,
|
|
19014
|
+
arrow,
|
|
19015
|
+
scene.getNonDeletedElements(),
|
|
19016
|
+
elementsMap,
|
|
19017
|
+
maxBindingDistance_simple(appState.zoom)
|
|
19018
|
+
);
|
|
19019
|
+
if (hit && isBindingEnabled(appState)) {
|
|
19020
|
+
if (arrow[bindingField] && hit.id !== binding?.elementId) {
|
|
19021
|
+
unbindBindingElement(
|
|
19022
|
+
arrow,
|
|
19023
|
+
linearElementEditor.draggedFocusPointBinding,
|
|
19024
|
+
scene
|
|
19025
|
+
);
|
|
19026
|
+
}
|
|
19027
|
+
const newMode = switchToInsideBinding && arrow[bindingField]?.mode === "orbit" ? "inside" : !switchToInsideBinding && arrow[bindingField]?.mode === "inside" ? "orbit" : null;
|
|
19028
|
+
if (!arrow[bindingField] || newMode) {
|
|
19029
|
+
bindBindingElement(
|
|
19030
|
+
arrow,
|
|
19031
|
+
hit,
|
|
19032
|
+
newMode || "orbit",
|
|
19033
|
+
linearElementEditor.draggedFocusPointBinding,
|
|
19034
|
+
scene,
|
|
19035
|
+
point
|
|
19036
|
+
);
|
|
19037
|
+
}
|
|
19038
|
+
scene.mutateElement(arrow, {
|
|
19039
|
+
[bindingField]: {
|
|
19040
|
+
...arrow[bindingField],
|
|
19041
|
+
elementId: hit.id,
|
|
19042
|
+
mode: newMode || arrow[bindingField]?.mode || "orbit",
|
|
19043
|
+
...calculateFixedPointForNonElbowArrowBinding(
|
|
19044
|
+
arrow,
|
|
19045
|
+
hit,
|
|
19046
|
+
linearElementEditor.draggedFocusPointBinding,
|
|
19047
|
+
elementsMap,
|
|
19048
|
+
point
|
|
19049
|
+
)
|
|
19050
|
+
}
|
|
19051
|
+
});
|
|
19052
|
+
} else {
|
|
19053
|
+
const pointUpdates = /* @__PURE__ */ new Map();
|
|
19054
|
+
const pointIndex = isStartBinding ? 0 : arrow.points.length - 1;
|
|
19055
|
+
pointUpdates.set(pointIndex, {
|
|
19056
|
+
point: LinearElementEditor.createPointAt(
|
|
19057
|
+
arrow,
|
|
19058
|
+
elementsMap,
|
|
19059
|
+
point[0],
|
|
19060
|
+
point[1],
|
|
19061
|
+
gridSize
|
|
19062
|
+
)
|
|
19063
|
+
});
|
|
19064
|
+
LinearElementEditor.movePoints(arrow, scene, pointUpdates);
|
|
19065
|
+
if (arrow[bindingField]) {
|
|
19066
|
+
unbindBindingElement(arrow, isStartBinding ? "start" : "end", scene);
|
|
19067
|
+
}
|
|
19068
|
+
}
|
|
19069
|
+
focusPointUpdate(
|
|
19070
|
+
arrow,
|
|
19071
|
+
hit,
|
|
19072
|
+
isStartBinding,
|
|
19073
|
+
elementsMap,
|
|
19074
|
+
scene,
|
|
19075
|
+
appState,
|
|
19076
|
+
switchToInsideBinding
|
|
19077
|
+
);
|
|
19078
|
+
if (hit && isBindingEnabled(appState)) {
|
|
19079
|
+
moveArrowAboveBindable2(
|
|
19080
|
+
point,
|
|
19081
|
+
arrow,
|
|
19082
|
+
scene.getElementsIncludingDeleted(),
|
|
19083
|
+
elementsMap,
|
|
19084
|
+
scene,
|
|
19085
|
+
hit
|
|
19086
|
+
);
|
|
19087
|
+
}
|
|
19088
|
+
};
|
|
19089
|
+
var handleFocusPointPointerDown = (arrow, pointerDownState, elementsMap, appState) => {
|
|
19090
|
+
const pointerPos = pointFrom16(
|
|
19091
|
+
pointerDownState.origin.x,
|
|
19092
|
+
pointerDownState.origin.y
|
|
19093
|
+
);
|
|
19094
|
+
const hitThreshold = FOCUS_POINT_SIZE * 1.5 / appState.zoom.value;
|
|
19095
|
+
if (arrow.startBinding?.elementId) {
|
|
19096
|
+
const bindableElement = elementsMap.get(arrow.startBinding.elementId);
|
|
19097
|
+
if (bindableElement && isBindableElement(bindableElement) && !bindableElement.isDeleted) {
|
|
19098
|
+
const focusPoint = getGlobalFixedPointForBindableElement(
|
|
19099
|
+
arrow.startBinding.fixedPoint,
|
|
19100
|
+
bindableElement,
|
|
19101
|
+
elementsMap
|
|
19102
|
+
);
|
|
19103
|
+
if (isFocusPointVisible(
|
|
19104
|
+
focusPoint,
|
|
19105
|
+
arrow,
|
|
19106
|
+
bindableElement,
|
|
19107
|
+
elementsMap,
|
|
19108
|
+
appState
|
|
19109
|
+
) && pointDistance8(pointerPos, focusPoint) <= hitThreshold) {
|
|
19110
|
+
return {
|
|
19111
|
+
hitFocusPoint: "start",
|
|
19112
|
+
pointerOffset: {
|
|
19113
|
+
x: pointerPos[0] - focusPoint[0],
|
|
19114
|
+
y: pointerPos[1] - focusPoint[1]
|
|
19115
|
+
}
|
|
19116
|
+
};
|
|
19117
|
+
}
|
|
19118
|
+
}
|
|
19119
|
+
}
|
|
19120
|
+
if (arrow.endBinding?.elementId) {
|
|
19121
|
+
const bindableElement = elementsMap.get(arrow.endBinding.elementId);
|
|
19122
|
+
if (bindableElement && isBindableElement(bindableElement) && !bindableElement.isDeleted) {
|
|
19123
|
+
const focusPoint = getGlobalFixedPointForBindableElement(
|
|
19124
|
+
arrow.endBinding.fixedPoint,
|
|
19125
|
+
bindableElement,
|
|
19126
|
+
elementsMap
|
|
19127
|
+
);
|
|
19128
|
+
if (isFocusPointVisible(
|
|
19129
|
+
focusPoint,
|
|
19130
|
+
arrow,
|
|
19131
|
+
bindableElement,
|
|
19132
|
+
elementsMap,
|
|
19133
|
+
appState
|
|
19134
|
+
) && pointDistance8(pointerPos, focusPoint) <= hitThreshold) {
|
|
19135
|
+
return {
|
|
19136
|
+
hitFocusPoint: "end",
|
|
19137
|
+
pointerOffset: {
|
|
19138
|
+
x: pointerPos[0] - focusPoint[0],
|
|
19139
|
+
y: pointerPos[1] - focusPoint[1]
|
|
19140
|
+
}
|
|
19141
|
+
};
|
|
19142
|
+
}
|
|
19143
|
+
}
|
|
19144
|
+
}
|
|
19145
|
+
return {
|
|
19146
|
+
hitFocusPoint: null,
|
|
19147
|
+
pointerOffset: { x: 0, y: 0 }
|
|
19148
|
+
};
|
|
19149
|
+
};
|
|
19150
|
+
var handleFocusPointPointerUp = (linearElementEditor, scene) => {
|
|
19151
|
+
invariant12(
|
|
19152
|
+
linearElementEditor.draggedFocusPointBinding,
|
|
19153
|
+
"Must have a dragged focus point at pointer release"
|
|
19154
|
+
);
|
|
19155
|
+
const arrow = LinearElementEditor.getElement(
|
|
19156
|
+
linearElementEditor.elementId,
|
|
19157
|
+
scene.getNonDeletedElementsMap()
|
|
19158
|
+
);
|
|
19159
|
+
invariant12(arrow, "Arrow must be in the scene");
|
|
19160
|
+
const bindingKey = linearElementEditor.draggedFocusPointBinding === "start" ? "startBinding" : "endBinding";
|
|
19161
|
+
const otherBindingKey = linearElementEditor.draggedFocusPointBinding === "start" ? "endBinding" : "startBinding";
|
|
19162
|
+
const boundElementId = arrow[bindingKey]?.elementId;
|
|
19163
|
+
const otherBoundElementId = arrow[otherBindingKey]?.elementId;
|
|
19164
|
+
const oldBoundElement = boundElementId && scene.getNonDeletedElements().find(
|
|
19165
|
+
(element) => element.id !== boundElementId && element.id !== otherBoundElementId && isBindableElement(element) && element.boundElements?.find(({ id }) => id === arrow.id)
|
|
19166
|
+
);
|
|
19167
|
+
if (oldBoundElement) {
|
|
19168
|
+
scene.mutateElement(oldBoundElement, {
|
|
19169
|
+
boundElements: oldBoundElement.boundElements?.filter(
|
|
19170
|
+
({ id }) => id !== arrow.id
|
|
19171
|
+
)
|
|
19172
|
+
});
|
|
19173
|
+
}
|
|
19174
|
+
const boundElement = boundElementId && scene.getNonDeletedElementsMap().get(boundElementId);
|
|
19175
|
+
if (boundElement) {
|
|
19176
|
+
scene.mutateElement(boundElement, {
|
|
19177
|
+
boundElements: [
|
|
19178
|
+
...(boundElement.boundElements || [])?.filter(
|
|
19179
|
+
({ id }) => id !== arrow.id
|
|
19180
|
+
),
|
|
19181
|
+
{
|
|
19182
|
+
id: arrow.id,
|
|
19183
|
+
type: "arrow"
|
|
19184
|
+
}
|
|
19185
|
+
]
|
|
19186
|
+
});
|
|
19187
|
+
}
|
|
19188
|
+
};
|
|
19189
|
+
var handleFocusPointHover = (arrow, scenePointerX, scenePointerY, scene, appState) => {
|
|
19190
|
+
const elementsMap = scene.getNonDeletedElementsMap();
|
|
19191
|
+
const pointerPos = pointFrom16(scenePointerX, scenePointerY);
|
|
19192
|
+
const hitThreshold = FOCUS_POINT_SIZE * 1.5 / appState.zoom.value;
|
|
19193
|
+
if (arrow.startBinding?.elementId) {
|
|
19194
|
+
const bindableElement = elementsMap.get(arrow.startBinding.elementId);
|
|
19195
|
+
if (bindableElement && isBindableElement(bindableElement) && !bindableElement.isDeleted) {
|
|
19196
|
+
const focusPoint = getGlobalFixedPointForBindableElement(
|
|
19197
|
+
arrow.startBinding.fixedPoint,
|
|
19198
|
+
bindableElement,
|
|
19199
|
+
elementsMap
|
|
19200
|
+
);
|
|
19201
|
+
if (isFocusPointVisible(
|
|
19202
|
+
focusPoint,
|
|
19203
|
+
arrow,
|
|
19204
|
+
bindableElement,
|
|
19205
|
+
elementsMap,
|
|
19206
|
+
appState
|
|
19207
|
+
) && pointDistance8(pointerPos, focusPoint) <= hitThreshold) {
|
|
19208
|
+
return "start";
|
|
19209
|
+
}
|
|
19210
|
+
}
|
|
19211
|
+
}
|
|
19212
|
+
if (arrow.endBinding?.elementId) {
|
|
19213
|
+
const bindableElement = elementsMap.get(arrow.endBinding.elementId);
|
|
19214
|
+
if (bindableElement && isBindableElement(bindableElement) && !bindableElement.isDeleted) {
|
|
19215
|
+
const focusPoint = getGlobalFixedPointForBindableElement(
|
|
19216
|
+
arrow.endBinding.fixedPoint,
|
|
19217
|
+
bindableElement,
|
|
19218
|
+
elementsMap
|
|
19219
|
+
);
|
|
19220
|
+
if (isFocusPointVisible(
|
|
19221
|
+
focusPoint,
|
|
19222
|
+
arrow,
|
|
19223
|
+
bindableElement,
|
|
19224
|
+
elementsMap,
|
|
19225
|
+
appState
|
|
19226
|
+
) && pointDistance8(pointerPos, focusPoint) <= hitThreshold) {
|
|
19227
|
+
return "end";
|
|
19228
|
+
}
|
|
19229
|
+
}
|
|
19230
|
+
}
|
|
19231
|
+
return null;
|
|
19232
|
+
};
|
|
19233
|
+
|
|
19234
|
+
// src/image.ts
|
|
19235
|
+
init_define_import_meta_env();
|
|
19236
|
+
import { MIME_TYPES as MIME_TYPES2, SVG_NS } from "@excalidraw/common";
|
|
19237
|
+
var loadHTMLImageElement = (dataURL) => {
|
|
19238
|
+
return new Promise((resolve, reject) => {
|
|
19239
|
+
const image = new Image();
|
|
19240
|
+
image.onload = () => {
|
|
19241
|
+
resolve(image);
|
|
19242
|
+
};
|
|
19243
|
+
image.onerror = (error) => {
|
|
19244
|
+
reject(error);
|
|
19245
|
+
};
|
|
19246
|
+
image.src = dataURL;
|
|
19247
|
+
});
|
|
19248
|
+
};
|
|
19249
|
+
var updateImageCache = async ({
|
|
19250
|
+
fileIds,
|
|
19251
|
+
files,
|
|
19252
|
+
imageCache
|
|
19253
|
+
}) => {
|
|
19254
|
+
const updatedFiles = /* @__PURE__ */ new Map();
|
|
19255
|
+
const erroredFiles = /* @__PURE__ */ new Map();
|
|
19256
|
+
await Promise.all(
|
|
19257
|
+
fileIds.reduce((promises, fileId) => {
|
|
19258
|
+
const fileData = files[fileId];
|
|
19259
|
+
if (fileData && !updatedFiles.has(fileId)) {
|
|
19260
|
+
updatedFiles.set(fileId, true);
|
|
19261
|
+
return promises.concat(
|
|
19262
|
+
(async () => {
|
|
19263
|
+
try {
|
|
19264
|
+
if (fileData.mimeType === MIME_TYPES2.binary) {
|
|
19265
|
+
throw new Error("Only images can be added to ImageCache");
|
|
19266
|
+
}
|
|
19267
|
+
const imagePromise = loadHTMLImageElement(fileData.dataURL);
|
|
19268
|
+
const data = {
|
|
19269
|
+
image: imagePromise,
|
|
19270
|
+
mimeType: fileData.mimeType
|
|
19271
|
+
};
|
|
19272
|
+
imageCache.set(fileId, data);
|
|
19273
|
+
const image = await imagePromise;
|
|
19274
|
+
imageCache.set(fileId, { ...data, image });
|
|
19275
|
+
} catch (error) {
|
|
19276
|
+
erroredFiles.set(fileId, true);
|
|
19277
|
+
}
|
|
19278
|
+
})()
|
|
19279
|
+
);
|
|
19280
|
+
}
|
|
19281
|
+
return promises;
|
|
19282
|
+
}, [])
|
|
19283
|
+
);
|
|
19284
|
+
return {
|
|
19285
|
+
imageCache,
|
|
19286
|
+
/** includes errored files because they cache was updated nonetheless */
|
|
19287
|
+
updatedFiles,
|
|
19288
|
+
/** files that failed when creating HTMLImageElement */
|
|
19289
|
+
erroredFiles
|
|
19290
|
+
};
|
|
19291
|
+
};
|
|
19292
|
+
var getInitializedImageElements = (elements) => elements.filter(
|
|
19293
|
+
(element) => isInitializedImageElement(element)
|
|
19294
|
+
);
|
|
19295
|
+
var isHTMLSVGElement = (node) => {
|
|
19296
|
+
return node?.nodeName.toLowerCase() === "svg";
|
|
19297
|
+
};
|
|
19298
|
+
var normalizeSVG = (SVGString) => {
|
|
19299
|
+
const doc = new DOMParser().parseFromString(SVGString, MIME_TYPES2.svg);
|
|
19300
|
+
const svg = doc.querySelector("svg");
|
|
19301
|
+
const errorNode = doc.querySelector("parsererror");
|
|
19302
|
+
if (errorNode || !isHTMLSVGElement(svg)) {
|
|
19303
|
+
throw new Error("Invalid SVG");
|
|
19304
|
+
} else {
|
|
19305
|
+
if (!svg.hasAttribute("xmlns")) {
|
|
19306
|
+
svg.setAttribute("xmlns", SVG_NS);
|
|
19307
|
+
}
|
|
19308
|
+
let width = svg.getAttribute("width");
|
|
19309
|
+
let height = svg.getAttribute("height");
|
|
19310
|
+
if (width?.includes("%") || width === "auto") {
|
|
19311
|
+
width = null;
|
|
19312
|
+
}
|
|
19313
|
+
if (height?.includes("%") || height === "auto") {
|
|
19314
|
+
height = null;
|
|
19315
|
+
}
|
|
19316
|
+
const viewBox = svg.getAttribute("viewBox");
|
|
19317
|
+
if (!width || !height) {
|
|
19318
|
+
width = width || "50";
|
|
19319
|
+
height = height || "50";
|
|
19320
|
+
if (viewBox) {
|
|
19321
|
+
const match = viewBox.match(
|
|
19322
|
+
/\d+ +\d+ +(\d+(?:\.\d+)?) +(\d+(?:\.\d+)?)/
|
|
19323
|
+
);
|
|
19324
|
+
if (match) {
|
|
19325
|
+
[, width, height] = match;
|
|
19326
|
+
}
|
|
19327
|
+
}
|
|
19328
|
+
svg.setAttribute("width", width);
|
|
19329
|
+
svg.setAttribute("height", height);
|
|
19330
|
+
}
|
|
19331
|
+
if (!viewBox) {
|
|
19332
|
+
svg.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
19333
|
+
}
|
|
19334
|
+
return svg.outerHTML;
|
|
19335
|
+
}
|
|
19336
|
+
};
|
|
19337
|
+
|
|
19338
|
+
// src/positionElementsOnGrid.ts
|
|
19339
|
+
init_define_import_meta_env();
|
|
19340
|
+
var positionElementsOnGrid = (elements, centerX, centerY, padding = 50) => {
|
|
19341
|
+
if (!elements || elements.length === 0) {
|
|
19342
|
+
return [];
|
|
19343
|
+
}
|
|
18034
19344
|
const res = [];
|
|
18035
19345
|
const atomicUnits = Array.isArray(elements[0]) ? elements : elements.map((element) => [element]);
|
|
18036
19346
|
const numUnits = atomicUnits.length;
|
|
@@ -18097,7 +19407,7 @@ init_define_import_meta_env();
|
|
|
18097
19407
|
import {
|
|
18098
19408
|
pointCenter as pointCenter3,
|
|
18099
19409
|
normalizeRadians as normalizeRadians2,
|
|
18100
|
-
pointFrom as
|
|
19410
|
+
pointFrom as pointFrom17,
|
|
18101
19411
|
pointRotateRads as pointRotateRads14
|
|
18102
19412
|
} from "@excalidraw/math";
|
|
18103
19413
|
import {
|
|
@@ -18286,7 +19596,7 @@ var resizeSingleTextElement = (origElement, element, scene, transformHandleType,
|
|
|
18286
19596
|
return;
|
|
18287
19597
|
}
|
|
18288
19598
|
if (transformHandleType.includes("n") || transformHandleType.includes("s")) {
|
|
18289
|
-
const previousOrigin =
|
|
19599
|
+
const previousOrigin = pointFrom17(origElement.x, origElement.y);
|
|
18290
19600
|
const newOrigin = getResizedOrigin(
|
|
18291
19601
|
previousOrigin,
|
|
18292
19602
|
origElement.width,
|
|
@@ -18327,7 +19637,7 @@ var resizeSingleTextElement = (origElement, element, scene, transformHandleType,
|
|
|
18327
19637
|
element.lineHeight
|
|
18328
19638
|
);
|
|
18329
19639
|
const newHeight = metrics2.height;
|
|
18330
|
-
const previousOrigin =
|
|
19640
|
+
const previousOrigin = pointFrom17(origElement.x, origElement.y);
|
|
18331
19641
|
const newOrigin = getResizedOrigin(
|
|
18332
19642
|
previousOrigin,
|
|
18333
19643
|
origElement.width,
|
|
@@ -18365,8 +19675,8 @@ var rotateMultipleElements = (originalElements, elements, scene, pointerX, point
|
|
|
18365
19675
|
const cy = (y1 + y2) / 2;
|
|
18366
19676
|
const origAngle = originalElements.get(element.id)?.angle ?? element.angle;
|
|
18367
19677
|
const [rotatedCX, rotatedCY] = pointRotateRads14(
|
|
18368
|
-
|
|
18369
|
-
|
|
19678
|
+
pointFrom17(cx, cy),
|
|
19679
|
+
pointFrom17(centerX, centerY),
|
|
18370
19680
|
centerAngle + origAngle - element.angle
|
|
18371
19681
|
);
|
|
18372
19682
|
const updates = isElbowArrow(element) ? {
|
|
@@ -18416,43 +19726,43 @@ var getResizeOffsetXY = (transformHandleType, selectedElements, elementsMap, x,
|
|
|
18416
19726
|
const cy = (y1 + y2) / 2;
|
|
18417
19727
|
const angle = selectedElements.length === 1 ? selectedElements[0].angle : 0;
|
|
18418
19728
|
[x, y] = pointRotateRads14(
|
|
18419
|
-
|
|
18420
|
-
|
|
19729
|
+
pointFrom17(x, y),
|
|
19730
|
+
pointFrom17(cx, cy),
|
|
18421
19731
|
-angle
|
|
18422
19732
|
);
|
|
18423
19733
|
switch (transformHandleType) {
|
|
18424
19734
|
case "n":
|
|
18425
19735
|
return pointRotateRads14(
|
|
18426
|
-
|
|
18427
|
-
|
|
19736
|
+
pointFrom17(x - (x1 + x2) / 2, y - y1),
|
|
19737
|
+
pointFrom17(0, 0),
|
|
18428
19738
|
angle
|
|
18429
19739
|
);
|
|
18430
19740
|
case "s":
|
|
18431
19741
|
return pointRotateRads14(
|
|
18432
|
-
|
|
18433
|
-
|
|
19742
|
+
pointFrom17(x - (x1 + x2) / 2, y - y2),
|
|
19743
|
+
pointFrom17(0, 0),
|
|
18434
19744
|
angle
|
|
18435
19745
|
);
|
|
18436
19746
|
case "w":
|
|
18437
19747
|
return pointRotateRads14(
|
|
18438
|
-
|
|
18439
|
-
|
|
19748
|
+
pointFrom17(x - x1, y - (y1 + y2) / 2),
|
|
19749
|
+
pointFrom17(0, 0),
|
|
18440
19750
|
angle
|
|
18441
19751
|
);
|
|
18442
19752
|
case "e":
|
|
18443
19753
|
return pointRotateRads14(
|
|
18444
|
-
|
|
18445
|
-
|
|
19754
|
+
pointFrom17(x - x2, y - (y1 + y2) / 2),
|
|
19755
|
+
pointFrom17(0, 0),
|
|
18446
19756
|
angle
|
|
18447
19757
|
);
|
|
18448
19758
|
case "nw":
|
|
18449
|
-
return pointRotateRads14(
|
|
19759
|
+
return pointRotateRads14(pointFrom17(x - x1, y - y1), pointFrom17(0, 0), angle);
|
|
18450
19760
|
case "ne":
|
|
18451
|
-
return pointRotateRads14(
|
|
19761
|
+
return pointRotateRads14(pointFrom17(x - x2, y - y1), pointFrom17(0, 0), angle);
|
|
18452
19762
|
case "sw":
|
|
18453
|
-
return pointRotateRads14(
|
|
19763
|
+
return pointRotateRads14(pointFrom17(x - x1, y - y2), pointFrom17(0, 0), angle);
|
|
18454
19764
|
case "se":
|
|
18455
|
-
return pointRotateRads14(
|
|
19765
|
+
return pointRotateRads14(pointFrom17(x - x2, y - y2), pointFrom17(0, 0), angle);
|
|
18456
19766
|
default:
|
|
18457
19767
|
return [0, 0];
|
|
18458
19768
|
}
|
|
@@ -18615,10 +19925,10 @@ var resizeSingleElement = (nextWidth, nextHeight, latestElement, origElement, or
|
|
|
18615
19925
|
nextHeight,
|
|
18616
19926
|
true
|
|
18617
19927
|
);
|
|
18618
|
-
let previousOrigin =
|
|
19928
|
+
let previousOrigin = pointFrom17(origElement.x, origElement.y);
|
|
18619
19929
|
if (isLinearElement(origElement)) {
|
|
18620
19930
|
const [x1, y1] = getElementBounds(origElement, originalElementsMap);
|
|
18621
|
-
previousOrigin =
|
|
19931
|
+
previousOrigin = pointFrom17(x1, y1);
|
|
18622
19932
|
}
|
|
18623
19933
|
const newOrigin = getResizedOrigin(
|
|
18624
19934
|
previousOrigin,
|
|
@@ -18641,7 +19951,7 @@ var resizeSingleElement = (nextWidth, nextHeight, latestElement, origElement, or
|
|
|
18641
19951
|
newOrigin.x += scaledX;
|
|
18642
19952
|
newOrigin.y += scaledY;
|
|
18643
19953
|
rescaledPoints.points = rescaledPoints.points.map(
|
|
18644
|
-
(p) =>
|
|
19954
|
+
(p) => pointFrom17(p[0] - scaledX, p[1] - scaledY)
|
|
18645
19955
|
);
|
|
18646
19956
|
}
|
|
18647
19957
|
if (nextWidth < 0) {
|
|
@@ -18717,11 +20027,11 @@ var getNextSingleWidthAndHeightFromPointer = (latestElement, origElement, handle
|
|
|
18717
20027
|
origElement.height,
|
|
18718
20028
|
true
|
|
18719
20029
|
);
|
|
18720
|
-
const startTopLeft =
|
|
18721
|
-
const startBottomRight =
|
|
20030
|
+
const startTopLeft = pointFrom17(x1, y1);
|
|
20031
|
+
const startBottomRight = pointFrom17(x2, y2);
|
|
18722
20032
|
const startCenter = pointCenter3(startTopLeft, startBottomRight);
|
|
18723
20033
|
const rotatedPointer = pointRotateRads14(
|
|
18724
|
-
|
|
20034
|
+
pointFrom17(pointerX, pointerY),
|
|
18725
20035
|
startCenter,
|
|
18726
20036
|
-origElement.angle
|
|
18727
20037
|
);
|
|
@@ -19091,7 +20401,7 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
|
|
|
19091
20401
|
// src/resizeTest.ts
|
|
19092
20402
|
init_define_import_meta_env();
|
|
19093
20403
|
import {
|
|
19094
|
-
pointFrom as
|
|
20404
|
+
pointFrom as pointFrom19,
|
|
19095
20405
|
pointOnLineSegment,
|
|
19096
20406
|
pointRotateRads as pointRotateRads16
|
|
19097
20407
|
} from "@excalidraw/math";
|
|
@@ -19104,7 +20414,7 @@ init_define_import_meta_env();
|
|
|
19104
20414
|
import {
|
|
19105
20415
|
DEFAULT_TRANSFORM_HANDLE_SPACING
|
|
19106
20416
|
} from "@excalidraw/common";
|
|
19107
|
-
import { pointFrom as
|
|
20417
|
+
import { pointFrom as pointFrom18, pointRotateRads as pointRotateRads15 } from "@excalidraw/math";
|
|
19108
20418
|
var transformHandleSizes = {
|
|
19109
20419
|
mouse: 8,
|
|
19110
20420
|
pen: 16,
|
|
@@ -19146,8 +20456,8 @@ var OMIT_SIDES_FOR_LINE_BACKSLASH = {
|
|
|
19146
20456
|
};
|
|
19147
20457
|
var generateTransformHandle = (x, y, width, height, cx, cy, angle) => {
|
|
19148
20458
|
const [xx, yy] = pointRotateRads15(
|
|
19149
|
-
|
|
19150
|
-
|
|
20459
|
+
pointFrom18(x + width / 2, y + height / 2),
|
|
20460
|
+
pointFrom18(cx, cy),
|
|
19151
20461
|
angle
|
|
19152
20462
|
);
|
|
19153
20463
|
return [xx - width / 2, yy - height / 2, width, height];
|
|
@@ -19361,14 +20671,14 @@ var resizeTest = (element, elementsMap, appState, x, y, zoom, pointerType, edito
|
|
|
19361
20671
|
const SPACING = isImageElement(element) ? 0 : SIDE_RESIZING_THRESHOLD / zoom.value;
|
|
19362
20672
|
const ZOOMED_SIDE_RESIZING_THRESHOLD = SIDE_RESIZING_THRESHOLD / zoom.value;
|
|
19363
20673
|
const sides = getSelectionBorders(
|
|
19364
|
-
|
|
19365
|
-
|
|
19366
|
-
|
|
20674
|
+
pointFrom19(x1 - SPACING, y1 - SPACING),
|
|
20675
|
+
pointFrom19(x2 + SPACING, y2 + SPACING),
|
|
20676
|
+
pointFrom19(cx, cy),
|
|
19367
20677
|
element.angle
|
|
19368
20678
|
);
|
|
19369
20679
|
for (const [dir, side] of Object.entries(sides)) {
|
|
19370
20680
|
if (pointOnLineSegment(
|
|
19371
|
-
|
|
20681
|
+
pointFrom19(x, y),
|
|
19372
20682
|
side,
|
|
19373
20683
|
ZOOMED_SIDE_RESIZING_THRESHOLD
|
|
19374
20684
|
)) {
|
|
@@ -19417,14 +20727,14 @@ var getTransformHandleTypeFromCoords = ([x1, y1, x2, y2], scenePointerX, scenePo
|
|
|
19417
20727
|
const cy = (y1 + y2) / 2;
|
|
19418
20728
|
const SPACING = SIDE_RESIZING_THRESHOLD / zoom.value;
|
|
19419
20729
|
const sides = getSelectionBorders(
|
|
19420
|
-
|
|
19421
|
-
|
|
19422
|
-
|
|
20730
|
+
pointFrom19(x1 - SPACING, y1 - SPACING),
|
|
20731
|
+
pointFrom19(x2 + SPACING, y2 + SPACING),
|
|
20732
|
+
pointFrom19(cx, cy),
|
|
19423
20733
|
0
|
|
19424
20734
|
);
|
|
19425
20735
|
for (const [dir, side] of Object.entries(sides)) {
|
|
19426
20736
|
if (pointOnLineSegment(
|
|
19427
|
-
|
|
20737
|
+
pointFrom19(scenePointerX, scenePointerY),
|
|
19428
20738
|
side,
|
|
19429
20739
|
SPACING
|
|
19430
20740
|
)) {
|
|
@@ -19481,10 +20791,10 @@ var getCursorForResizingElement = (resizingElement) => {
|
|
|
19481
20791
|
return cursor ? `${cursor}-resize` : "";
|
|
19482
20792
|
};
|
|
19483
20793
|
var getSelectionBorders = ([x1, y1], [x2, y2], center, angle) => {
|
|
19484
|
-
const topLeft = pointRotateRads16(
|
|
19485
|
-
const topRight = pointRotateRads16(
|
|
19486
|
-
const bottomLeft = pointRotateRads16(
|
|
19487
|
-
const bottomRight = pointRotateRads16(
|
|
20794
|
+
const topLeft = pointRotateRads16(pointFrom19(x1, y1), center, angle);
|
|
20795
|
+
const topRight = pointRotateRads16(pointFrom19(x2, y1), center, angle);
|
|
20796
|
+
const bottomLeft = pointRotateRads16(pointFrom19(x1, y2), center, angle);
|
|
20797
|
+
const bottomRight = pointRotateRads16(pointFrom19(x2, y2), center, angle);
|
|
19488
20798
|
return {
|
|
19489
20799
|
n: [topLeft, topRight],
|
|
19490
20800
|
e: [topRight, bottomRight],
|
|
@@ -19497,386 +20807,545 @@ var getSelectionBorders = ([x1, y1], [x2, y2], center, angle) => {
|
|
|
19497
20807
|
init_define_import_meta_env();
|
|
19498
20808
|
var showSelectedShapeActions = (appState, elements) => Boolean(
|
|
19499
20809
|
!appState.viewModeEnabled && appState.openDialog?.name !== "elementLinkSelector" && (appState.activeTool.type !== "custom" && (appState.editingTextElement || appState.activeTool.type !== "selection" && appState.activeTool.type !== "lasso" && appState.activeTool.type !== "eraser" && appState.activeTool.type !== "hand" && appState.activeTool.type !== "laser") || getSelectedElements(elements, appState).length)
|
|
19500
|
-
);
|
|
19501
|
-
|
|
19502
|
-
// src/
|
|
19503
|
-
init_define_import_meta_env();
|
|
19504
|
-
import {
|
|
19505
|
-
|
|
19506
|
-
|
|
19507
|
-
|
|
19508
|
-
|
|
19509
|
-
|
|
19510
|
-
|
|
19511
|
-
|
|
19512
|
-
|
|
19513
|
-
|
|
19514
|
-
|
|
19515
|
-
|
|
19516
|
-
|
|
19517
|
-
|
|
19518
|
-
|
|
19519
|
-
|
|
19520
|
-
|
|
19521
|
-
|
|
19522
|
-
|
|
19523
|
-
|
|
19524
|
-
|
|
19525
|
-
|
|
19526
|
-
|
|
19527
|
-
|
|
19528
|
-
|
|
19529
|
-
|
|
19530
|
-
|
|
19531
|
-
|
|
19532
|
-
|
|
19533
|
-
|
|
19534
|
-
}
|
|
19535
|
-
|
|
19536
|
-
|
|
19537
|
-
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
|
|
19541
|
-
|
|
19542
|
-
|
|
19543
|
-
|
|
19544
|
-
|
|
19545
|
-
|
|
19546
|
-
|
|
19547
|
-
|
|
19548
|
-
|
|
19549
|
-
|
|
19550
|
-
|
|
19551
|
-
|
|
19552
|
-
|
|
19553
|
-
|
|
19554
|
-
|
|
19555
|
-
|
|
19556
|
-
|
|
19557
|
-
)
|
|
19558
|
-
|
|
19559
|
-
|
|
19560
|
-
|
|
19561
|
-
|
|
19562
|
-
|
|
19563
|
-
|
|
19564
|
-
|
|
19565
|
-
if (
|
|
19566
|
-
|
|
19567
|
-
|
|
19568
|
-
|
|
19569
|
-
|
|
19570
|
-
|
|
19571
|
-
|
|
19572
|
-
)
|
|
19573
|
-
|
|
19574
|
-
|
|
19575
|
-
|
|
19576
|
-
}
|
|
19577
|
-
|
|
19578
|
-
|
|
19579
|
-
|
|
19580
|
-
|
|
19581
|
-
|
|
19582
|
-
|
|
19583
|
-
|
|
19584
|
-
|
|
19585
|
-
|
|
19586
|
-
|
|
19587
|
-
|
|
19588
|
-
|
|
19589
|
-
|
|
19590
|
-
|
|
19591
|
-
|
|
19592
|
-
|
|
19593
|
-
|
|
19594
|
-
|
|
19595
|
-
|
|
19596
|
-
|
|
19597
|
-
|
|
19598
|
-
|
|
19599
|
-
|
|
19600
|
-
|
|
19601
|
-
|
|
19602
|
-
|
|
19603
|
-
|
|
19604
|
-
|
|
19605
|
-
|
|
19606
|
-
|
|
19607
|
-
|
|
19608
|
-
|
|
19609
|
-
|
|
19610
|
-
|
|
19611
|
-
|
|
19612
|
-
|
|
19613
|
-
const arrow2 = updatedElements.splice(arrowIdx, 1)[0];
|
|
19614
|
-
updatedElements.splice(bindableIdx, 0, arrow2);
|
|
19615
|
-
scene.replaceAllElements(updatedElements);
|
|
19616
|
-
}
|
|
19617
|
-
return elements;
|
|
19618
|
-
};
|
|
19619
|
-
var getTargetIndex = (appState, elements, boundaryIndex, direction, containingFrame, scene) => {
|
|
19620
|
-
const sourceElement = elements[boundaryIndex];
|
|
19621
|
-
const indexFilter = (element) => {
|
|
19622
|
-
if (element.isDeleted) {
|
|
19623
|
-
return false;
|
|
19624
|
-
}
|
|
19625
|
-
if (containingFrame) {
|
|
19626
|
-
return element.frameId === containingFrame;
|
|
19627
|
-
}
|
|
19628
|
-
if (appState.editingGroupId) {
|
|
19629
|
-
return element.groupIds.includes(appState.editingGroupId);
|
|
19630
|
-
}
|
|
19631
|
-
return true;
|
|
19632
|
-
};
|
|
19633
|
-
const candidateIndex = direction === "left" ? findLastIndex2(
|
|
19634
|
-
elements,
|
|
19635
|
-
(el) => indexFilter(el),
|
|
19636
|
-
Math.max(0, boundaryIndex - 1)
|
|
19637
|
-
) : findIndex(elements, (el) => indexFilter(el), boundaryIndex + 1);
|
|
19638
|
-
const nextElement = elements[candidateIndex];
|
|
19639
|
-
if (!nextElement) {
|
|
19640
|
-
return -1;
|
|
19641
|
-
}
|
|
19642
|
-
if (appState.editingGroupId) {
|
|
19643
|
-
if (
|
|
19644
|
-
// candidate element is a sibling in current editing group → return
|
|
19645
|
-
sourceElement?.groupIds.join("") === nextElement?.groupIds.join("")
|
|
19646
|
-
) {
|
|
19647
|
-
return getTargetIndexAccountingForBinding(
|
|
19648
|
-
nextElement,
|
|
19649
|
-
elements,
|
|
19650
|
-
direction,
|
|
19651
|
-
scene
|
|
19652
|
-
) ?? candidateIndex;
|
|
19653
|
-
} else if (!nextElement?.groupIds.includes(appState.editingGroupId)) {
|
|
19654
|
-
return -1;
|
|
19655
|
-
}
|
|
19656
|
-
}
|
|
19657
|
-
if (!containingFrame && (nextElement.frameId || isFrameLikeElement(nextElement))) {
|
|
19658
|
-
const frameElements = getContiguousFrameRangeElements(
|
|
19659
|
-
elements,
|
|
19660
|
-
nextElement.frameId || nextElement.id
|
|
19661
|
-
);
|
|
19662
|
-
return direction === "left" ? elements.indexOf(frameElements[0]) : elements.indexOf(frameElements[frameElements.length - 1]);
|
|
19663
|
-
}
|
|
19664
|
-
if (!nextElement.groupIds.length) {
|
|
19665
|
-
return getTargetIndexAccountingForBinding(
|
|
19666
|
-
nextElement,
|
|
19667
|
-
elements,
|
|
19668
|
-
direction,
|
|
19669
|
-
scene
|
|
19670
|
-
) ?? candidateIndex;
|
|
19671
|
-
}
|
|
19672
|
-
const siblingGroupId = appState.editingGroupId ? nextElement.groupIds[nextElement.groupIds.indexOf(appState.editingGroupId) - 1] : nextElement.groupIds[nextElement.groupIds.length - 1];
|
|
19673
|
-
const elementsInSiblingGroup = getElementsInGroup(elements, siblingGroupId);
|
|
19674
|
-
if (elementsInSiblingGroup.length) {
|
|
19675
|
-
return direction === "left" ? elements.indexOf(elementsInSiblingGroup[0]) : elements.indexOf(
|
|
19676
|
-
elementsInSiblingGroup[elementsInSiblingGroup.length - 1]
|
|
19677
|
-
);
|
|
19678
|
-
}
|
|
19679
|
-
return candidateIndex;
|
|
19680
|
-
};
|
|
19681
|
-
var getTargetElementsMap = (elements, indices) => {
|
|
19682
|
-
return indices.reduce((acc, index) => {
|
|
19683
|
-
const element = elements[index];
|
|
19684
|
-
acc.set(element.id, element);
|
|
19685
|
-
return acc;
|
|
19686
|
-
}, /* @__PURE__ */ new Map());
|
|
19687
|
-
};
|
|
19688
|
-
var shiftElementsByOne = (elements, appState, direction, scene) => {
|
|
19689
|
-
const indicesToMove = getIndicesToMove(elements, appState);
|
|
19690
|
-
const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
|
|
19691
|
-
let groupedIndices = toContiguousGroups(indicesToMove);
|
|
19692
|
-
if (direction === "right") {
|
|
19693
|
-
groupedIndices = groupedIndices.reverse();
|
|
19694
|
-
}
|
|
19695
|
-
const selectedFrames = new Set(
|
|
19696
|
-
indicesToMove.filter((idx) => isFrameLikeElement(elements[idx])).map((idx) => elements[idx].id)
|
|
19697
|
-
);
|
|
19698
|
-
groupedIndices.forEach((indices, i) => {
|
|
19699
|
-
const leadingIndex = indices[0];
|
|
19700
|
-
const trailingIndex = indices[indices.length - 1];
|
|
19701
|
-
const boundaryIndex = direction === "left" ? leadingIndex : trailingIndex;
|
|
19702
|
-
const containingFrame = indices.some((idx) => {
|
|
19703
|
-
const el = elements[idx];
|
|
19704
|
-
return el.frameId && selectedFrames.has(el.frameId);
|
|
19705
|
-
}) ? null : elements[boundaryIndex]?.frameId;
|
|
19706
|
-
const targetIndex = getTargetIndex(
|
|
19707
|
-
appState,
|
|
19708
|
-
elements,
|
|
19709
|
-
boundaryIndex,
|
|
19710
|
-
direction,
|
|
19711
|
-
containingFrame,
|
|
19712
|
-
scene
|
|
19713
|
-
);
|
|
19714
|
-
if (targetIndex === -1 || boundaryIndex === targetIndex) {
|
|
19715
|
-
return;
|
|
19716
|
-
}
|
|
19717
|
-
const leadingElements = direction === "left" ? elements.slice(0, targetIndex) : elements.slice(0, leadingIndex);
|
|
19718
|
-
const targetElements = elements.slice(leadingIndex, trailingIndex + 1);
|
|
19719
|
-
const displacedElements = direction === "left" ? elements.slice(targetIndex, leadingIndex) : elements.slice(trailingIndex + 1, targetIndex + 1);
|
|
19720
|
-
const trailingElements = direction === "left" ? elements.slice(trailingIndex + 1) : elements.slice(targetIndex + 1);
|
|
19721
|
-
elements = direction === "left" ? [
|
|
19722
|
-
...leadingElements,
|
|
19723
|
-
...targetElements,
|
|
19724
|
-
...displacedElements,
|
|
19725
|
-
...trailingElements
|
|
19726
|
-
] : [
|
|
19727
|
-
...leadingElements,
|
|
19728
|
-
...displacedElements,
|
|
19729
|
-
...targetElements,
|
|
19730
|
-
...trailingElements
|
|
19731
|
-
];
|
|
19732
|
-
});
|
|
19733
|
-
syncMovedIndices(elements, targetElementsMap);
|
|
19734
|
-
return elements;
|
|
19735
|
-
};
|
|
19736
|
-
var shiftElementsToEnd = (elements, appState, direction, containingFrame, elementsToBeMoved) => {
|
|
19737
|
-
const indicesToMove = getIndicesToMove(elements, appState, elementsToBeMoved);
|
|
19738
|
-
const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
|
|
19739
|
-
const displacedElements = [];
|
|
19740
|
-
let leadingIndex;
|
|
19741
|
-
let trailingIndex;
|
|
19742
|
-
if (direction === "left") {
|
|
19743
|
-
if (containingFrame) {
|
|
19744
|
-
leadingIndex = findIndex(
|
|
19745
|
-
elements,
|
|
19746
|
-
(el) => isOfTargetFrame(el, containingFrame)
|
|
19747
|
-
);
|
|
19748
|
-
} else if (appState.editingGroupId) {
|
|
19749
|
-
const groupElements = getElementsInGroup(
|
|
19750
|
-
elements,
|
|
19751
|
-
appState.editingGroupId
|
|
19752
|
-
);
|
|
19753
|
-
if (!groupElements.length) {
|
|
19754
|
-
return elements;
|
|
20810
|
+
);
|
|
20811
|
+
|
|
20812
|
+
// src/transform.ts
|
|
20813
|
+
init_define_import_meta_env();
|
|
20814
|
+
import { pointFrom as pointFrom20 } from "@excalidraw/math";
|
|
20815
|
+
import {
|
|
20816
|
+
DEFAULT_FONT_FAMILY as DEFAULT_FONT_FAMILY3,
|
|
20817
|
+
DEFAULT_FONT_SIZE as DEFAULT_FONT_SIZE4,
|
|
20818
|
+
TEXT_ALIGN as TEXT_ALIGN2,
|
|
20819
|
+
VERTICAL_ALIGN as VERTICAL_ALIGN4,
|
|
20820
|
+
getSizeFromPoints as getSizeFromPoints3,
|
|
20821
|
+
randomId as randomId4,
|
|
20822
|
+
arrayToMap as arrayToMap12,
|
|
20823
|
+
assertNever as assertNever5,
|
|
20824
|
+
cloneJSON,
|
|
20825
|
+
getFontString as getFontString8,
|
|
20826
|
+
isDevEnv as isDevEnv7,
|
|
20827
|
+
toBrandedType as toBrandedType3,
|
|
20828
|
+
getLineHeight as getLineHeight2
|
|
20829
|
+
} from "@excalidraw/common";
|
|
20830
|
+
var DEFAULT_LINEAR_ELEMENT_PROPS = {
|
|
20831
|
+
width: 100,
|
|
20832
|
+
height: 0
|
|
20833
|
+
};
|
|
20834
|
+
var DEFAULT_DIMENSION = 100;
|
|
20835
|
+
var bindTextToContainer = (container, textProps, scene) => {
|
|
20836
|
+
const textElement = newTextElement({
|
|
20837
|
+
x: 0,
|
|
20838
|
+
y: 0,
|
|
20839
|
+
textAlign: TEXT_ALIGN2.CENTER,
|
|
20840
|
+
verticalAlign: VERTICAL_ALIGN4.MIDDLE,
|
|
20841
|
+
...textProps,
|
|
20842
|
+
containerId: container.id,
|
|
20843
|
+
strokeColor: textProps.strokeColor || container.strokeColor
|
|
20844
|
+
});
|
|
20845
|
+
Object.assign(container, {
|
|
20846
|
+
boundElements: (container.boundElements || []).concat({
|
|
20847
|
+
type: "text",
|
|
20848
|
+
id: textElement.id
|
|
20849
|
+
})
|
|
20850
|
+
});
|
|
20851
|
+
redrawTextBoundingBox(textElement, container, scene);
|
|
20852
|
+
return [container, textElement];
|
|
20853
|
+
};
|
|
20854
|
+
var bindLinearElementToElement = (linearElement, start, end, elementStore, scene) => {
|
|
20855
|
+
let startBoundElement;
|
|
20856
|
+
let endBoundElement;
|
|
20857
|
+
Object.assign(linearElement, {
|
|
20858
|
+
startBinding: linearElement?.startBinding || null,
|
|
20859
|
+
endBinding: linearElement.endBinding || null
|
|
20860
|
+
});
|
|
20861
|
+
if (start) {
|
|
20862
|
+
const width = start?.width ?? DEFAULT_DIMENSION;
|
|
20863
|
+
const height = start?.height ?? DEFAULT_DIMENSION;
|
|
20864
|
+
let existingElement;
|
|
20865
|
+
if (start.id) {
|
|
20866
|
+
existingElement = elementStore.getElement(start.id);
|
|
20867
|
+
if (!existingElement) {
|
|
20868
|
+
console.error(`No element for start binding with id ${start.id} found`);
|
|
20869
|
+
}
|
|
20870
|
+
}
|
|
20871
|
+
const startX = start.x || linearElement.x - width;
|
|
20872
|
+
const startY = start.y || linearElement.y - height / 2;
|
|
20873
|
+
const startType = existingElement ? existingElement.type : start.type;
|
|
20874
|
+
if (startType) {
|
|
20875
|
+
if (startType === "text") {
|
|
20876
|
+
let text = "";
|
|
20877
|
+
if (existingElement && existingElement.type === "text") {
|
|
20878
|
+
text = existingElement.text;
|
|
20879
|
+
} else if (start.type === "text") {
|
|
20880
|
+
text = start.text;
|
|
20881
|
+
}
|
|
20882
|
+
if (!text) {
|
|
20883
|
+
console.error(
|
|
20884
|
+
`No text found for start binding text element for ${linearElement.id}`
|
|
20885
|
+
);
|
|
20886
|
+
}
|
|
20887
|
+
startBoundElement = newTextElement({
|
|
20888
|
+
x: startX,
|
|
20889
|
+
y: startY,
|
|
20890
|
+
type: "text",
|
|
20891
|
+
...existingElement,
|
|
20892
|
+
...start,
|
|
20893
|
+
text
|
|
20894
|
+
});
|
|
20895
|
+
Object.assign(startBoundElement, {
|
|
20896
|
+
x: start.x || linearElement.x - startBoundElement.width,
|
|
20897
|
+
y: start.y || linearElement.y - startBoundElement.height / 2
|
|
20898
|
+
});
|
|
20899
|
+
} else {
|
|
20900
|
+
switch (startType) {
|
|
20901
|
+
case "rectangle":
|
|
20902
|
+
case "ellipse":
|
|
20903
|
+
case "diamond": {
|
|
20904
|
+
startBoundElement = newElement({
|
|
20905
|
+
x: startX,
|
|
20906
|
+
y: startY,
|
|
20907
|
+
width,
|
|
20908
|
+
height,
|
|
20909
|
+
...existingElement,
|
|
20910
|
+
...start,
|
|
20911
|
+
type: startType
|
|
20912
|
+
});
|
|
20913
|
+
break;
|
|
20914
|
+
}
|
|
20915
|
+
default: {
|
|
20916
|
+
assertNever5(
|
|
20917
|
+
linearElement,
|
|
20918
|
+
`Unhandled element start type "${start.type}"`,
|
|
20919
|
+
true
|
|
20920
|
+
);
|
|
20921
|
+
}
|
|
20922
|
+
}
|
|
19755
20923
|
}
|
|
19756
|
-
|
|
19757
|
-
|
|
19758
|
-
|
|
19759
|
-
|
|
19760
|
-
|
|
19761
|
-
|
|
19762
|
-
if (containingFrame) {
|
|
19763
|
-
trailingIndex = findLastIndex2(
|
|
19764
|
-
elements,
|
|
19765
|
-
(el) => isOfTargetFrame(el, containingFrame)
|
|
19766
|
-
);
|
|
19767
|
-
} else if (appState.editingGroupId) {
|
|
19768
|
-
const groupElements = getElementsInGroup(
|
|
19769
|
-
elements,
|
|
19770
|
-
appState.editingGroupId
|
|
20924
|
+
bindBindingElement(
|
|
20925
|
+
linearElement,
|
|
20926
|
+
startBoundElement,
|
|
20927
|
+
"orbit",
|
|
20928
|
+
"start",
|
|
20929
|
+
scene
|
|
19771
20930
|
);
|
|
19772
|
-
|
|
19773
|
-
|
|
20931
|
+
}
|
|
20932
|
+
}
|
|
20933
|
+
if (end) {
|
|
20934
|
+
const height = end?.height ?? DEFAULT_DIMENSION;
|
|
20935
|
+
const width = end?.width ?? DEFAULT_DIMENSION;
|
|
20936
|
+
let existingElement;
|
|
20937
|
+
if (end.id) {
|
|
20938
|
+
existingElement = elementStore.getElement(end.id);
|
|
20939
|
+
if (!existingElement) {
|
|
20940
|
+
console.error(`No element for end binding with id ${end.id} found`);
|
|
20941
|
+
}
|
|
20942
|
+
}
|
|
20943
|
+
const endX = end.x || linearElement.x + linearElement.width;
|
|
20944
|
+
const endY = end.y || linearElement.y - height / 2;
|
|
20945
|
+
const endType = existingElement ? existingElement.type : end.type;
|
|
20946
|
+
if (endType) {
|
|
20947
|
+
if (endType === "text") {
|
|
20948
|
+
let text = "";
|
|
20949
|
+
if (existingElement && existingElement.type === "text") {
|
|
20950
|
+
text = existingElement.text;
|
|
20951
|
+
} else if (end.type === "text") {
|
|
20952
|
+
text = end.text;
|
|
20953
|
+
}
|
|
20954
|
+
if (!text) {
|
|
20955
|
+
console.error(
|
|
20956
|
+
`No text found for end binding text element for ${linearElement.id}`
|
|
20957
|
+
);
|
|
20958
|
+
}
|
|
20959
|
+
endBoundElement = newTextElement({
|
|
20960
|
+
x: endX,
|
|
20961
|
+
y: endY,
|
|
20962
|
+
type: "text",
|
|
20963
|
+
...existingElement,
|
|
20964
|
+
...end,
|
|
20965
|
+
text
|
|
20966
|
+
});
|
|
20967
|
+
Object.assign(endBoundElement, {
|
|
20968
|
+
y: end.y || linearElement.y - endBoundElement.height / 2
|
|
20969
|
+
});
|
|
20970
|
+
} else {
|
|
20971
|
+
switch (endType) {
|
|
20972
|
+
case "rectangle":
|
|
20973
|
+
case "ellipse":
|
|
20974
|
+
case "diamond": {
|
|
20975
|
+
endBoundElement = newElement({
|
|
20976
|
+
x: endX,
|
|
20977
|
+
y: endY,
|
|
20978
|
+
width,
|
|
20979
|
+
height,
|
|
20980
|
+
...existingElement,
|
|
20981
|
+
...end,
|
|
20982
|
+
type: endType
|
|
20983
|
+
});
|
|
20984
|
+
break;
|
|
20985
|
+
}
|
|
20986
|
+
default: {
|
|
20987
|
+
assertNever5(
|
|
20988
|
+
linearElement,
|
|
20989
|
+
`Unhandled element end type "${endType}"`,
|
|
20990
|
+
true
|
|
20991
|
+
);
|
|
20992
|
+
}
|
|
20993
|
+
}
|
|
19774
20994
|
}
|
|
19775
|
-
|
|
19776
|
-
|
|
19777
|
-
|
|
20995
|
+
bindBindingElement(
|
|
20996
|
+
linearElement,
|
|
20997
|
+
endBoundElement,
|
|
20998
|
+
"orbit",
|
|
20999
|
+
"end",
|
|
21000
|
+
scene
|
|
21001
|
+
);
|
|
19778
21002
|
}
|
|
19779
|
-
leadingIndex = indicesToMove[0];
|
|
19780
21003
|
}
|
|
19781
|
-
if (
|
|
19782
|
-
|
|
21004
|
+
if (linearElement.points.length < 2) {
|
|
21005
|
+
return {
|
|
21006
|
+
linearElement,
|
|
21007
|
+
startBoundElement,
|
|
21008
|
+
endBoundElement
|
|
21009
|
+
};
|
|
19783
21010
|
}
|
|
19784
|
-
|
|
19785
|
-
|
|
19786
|
-
|
|
19787
|
-
|
|
21011
|
+
const endPointIndex = linearElement.points.length - 1;
|
|
21012
|
+
const delta = 0.5;
|
|
21013
|
+
const newPoints = cloneJSON(linearElement.points);
|
|
21014
|
+
if (linearElement.points[endPointIndex][0] > linearElement.points[endPointIndex - 1][0]) {
|
|
21015
|
+
newPoints[0][0] = delta;
|
|
21016
|
+
newPoints[endPointIndex][0] -= delta;
|
|
19788
21017
|
}
|
|
19789
|
-
|
|
19790
|
-
|
|
19791
|
-
|
|
19792
|
-
|
|
19793
|
-
|
|
19794
|
-
|
|
19795
|
-
|
|
19796
|
-
|
|
19797
|
-
]
|
|
19798
|
-
|
|
19799
|
-
|
|
19800
|
-
|
|
19801
|
-
|
|
19802
|
-
|
|
19803
|
-
|
|
19804
|
-
|
|
19805
|
-
|
|
19806
|
-
function shiftElementsAccountingForFrames(allElements, appState, direction, shiftFunction) {
|
|
19807
|
-
const elementsToMove = arrayToMap11(
|
|
19808
|
-
getSelectedElements(allElements, appState, {
|
|
19809
|
-
includeBoundTextElement: true,
|
|
19810
|
-
includeElementsInFrames: true
|
|
21018
|
+
if (linearElement.points[endPointIndex][0] < linearElement.points[endPointIndex - 1][0]) {
|
|
21019
|
+
newPoints[0][0] = -delta;
|
|
21020
|
+
newPoints[endPointIndex][0] += delta;
|
|
21021
|
+
}
|
|
21022
|
+
if (linearElement.points[endPointIndex][1] > linearElement.points[endPointIndex - 1][1]) {
|
|
21023
|
+
newPoints[0][1] = delta;
|
|
21024
|
+
newPoints[endPointIndex][1] -= delta;
|
|
21025
|
+
}
|
|
21026
|
+
if (linearElement.points[endPointIndex][1] < linearElement.points[endPointIndex - 1][1]) {
|
|
21027
|
+
newPoints[0][1] = -delta;
|
|
21028
|
+
newPoints[endPointIndex][1] += delta;
|
|
21029
|
+
}
|
|
21030
|
+
Object.assign(
|
|
21031
|
+
linearElement,
|
|
21032
|
+
LinearElementEditor.getNormalizeElementPointsAndCoords({
|
|
21033
|
+
...linearElement,
|
|
21034
|
+
points: newPoints
|
|
19811
21035
|
})
|
|
19812
21036
|
);
|
|
19813
|
-
|
|
19814
|
-
|
|
19815
|
-
|
|
19816
|
-
|
|
19817
|
-
|
|
21037
|
+
return {
|
|
21038
|
+
linearElement,
|
|
21039
|
+
startBoundElement,
|
|
21040
|
+
endBoundElement
|
|
21041
|
+
};
|
|
21042
|
+
};
|
|
21043
|
+
var ElementStore = class {
|
|
21044
|
+
excalidrawElements = /* @__PURE__ */ new Map();
|
|
21045
|
+
add = (ele) => {
|
|
21046
|
+
if (!ele) {
|
|
21047
|
+
return;
|
|
19818
21048
|
}
|
|
21049
|
+
this.excalidrawElements.set(ele.id, ele);
|
|
21050
|
+
};
|
|
21051
|
+
getElements = () => {
|
|
21052
|
+
return syncInvalidIndices(Array.from(this.excalidrawElements.values()));
|
|
21053
|
+
};
|
|
21054
|
+
getElementsMap = () => {
|
|
21055
|
+
return toBrandedType3(
|
|
21056
|
+
arrayToMap12(this.getElements())
|
|
21057
|
+
);
|
|
21058
|
+
};
|
|
21059
|
+
getElement = (id) => {
|
|
21060
|
+
return this.excalidrawElements.get(id);
|
|
21061
|
+
};
|
|
21062
|
+
};
|
|
21063
|
+
var convertToExcalidrawElements = (elementsSkeleton, opts) => {
|
|
21064
|
+
if (!elementsSkeleton) {
|
|
21065
|
+
return [];
|
|
19819
21066
|
}
|
|
19820
|
-
|
|
19821
|
-
|
|
19822
|
-
|
|
19823
|
-
|
|
19824
|
-
|
|
19825
|
-
|
|
19826
|
-
|
|
19827
|
-
|
|
19828
|
-
|
|
19829
|
-
|
|
19830
|
-
|
|
19831
|
-
|
|
19832
|
-
|
|
19833
|
-
|
|
21067
|
+
const elements = cloneJSON(elementsSkeleton);
|
|
21068
|
+
const elementStore = new ElementStore();
|
|
21069
|
+
const elementsWithIds = /* @__PURE__ */ new Map();
|
|
21070
|
+
const oldToNewElementIdMap = /* @__PURE__ */ new Map();
|
|
21071
|
+
for (const element of elements) {
|
|
21072
|
+
let excalidrawElement;
|
|
21073
|
+
const originalId = element.id;
|
|
21074
|
+
if (opts?.regenerateIds !== false) {
|
|
21075
|
+
Object.assign(element, { id: randomId4() });
|
|
21076
|
+
}
|
|
21077
|
+
switch (element.type) {
|
|
21078
|
+
case "rectangle":
|
|
21079
|
+
case "ellipse":
|
|
21080
|
+
case "diamond": {
|
|
21081
|
+
const width = element?.label?.text && element.width === void 0 ? 0 : element?.width || DEFAULT_DIMENSION;
|
|
21082
|
+
const height = element?.label?.text && element.height === void 0 ? 0 : element?.height || DEFAULT_DIMENSION;
|
|
21083
|
+
excalidrawElement = newElement({
|
|
21084
|
+
...element,
|
|
21085
|
+
width,
|
|
21086
|
+
height
|
|
21087
|
+
});
|
|
21088
|
+
break;
|
|
21089
|
+
}
|
|
21090
|
+
case "line": {
|
|
21091
|
+
const width = element.width || DEFAULT_LINEAR_ELEMENT_PROPS.width;
|
|
21092
|
+
const height = element.height || DEFAULT_LINEAR_ELEMENT_PROPS.height;
|
|
21093
|
+
excalidrawElement = newLinearElement({
|
|
21094
|
+
width,
|
|
21095
|
+
height,
|
|
21096
|
+
points: [pointFrom20(0, 0), pointFrom20(width, height)],
|
|
21097
|
+
...element
|
|
21098
|
+
});
|
|
21099
|
+
break;
|
|
21100
|
+
}
|
|
21101
|
+
case "arrow": {
|
|
21102
|
+
const width = element.width || DEFAULT_LINEAR_ELEMENT_PROPS.width;
|
|
21103
|
+
const height = element.height || DEFAULT_LINEAR_ELEMENT_PROPS.height;
|
|
21104
|
+
excalidrawElement = newArrowElement({
|
|
21105
|
+
width,
|
|
21106
|
+
height,
|
|
21107
|
+
endArrowhead: "arrow",
|
|
21108
|
+
points: [pointFrom20(0, 0), pointFrom20(width, height)],
|
|
21109
|
+
...element,
|
|
21110
|
+
type: "arrow"
|
|
21111
|
+
});
|
|
21112
|
+
Object.assign(
|
|
21113
|
+
excalidrawElement,
|
|
21114
|
+
getSizeFromPoints3(excalidrawElement.points)
|
|
21115
|
+
);
|
|
21116
|
+
break;
|
|
21117
|
+
}
|
|
21118
|
+
case "text": {
|
|
21119
|
+
const fontFamily = element?.fontFamily || DEFAULT_FONT_FAMILY3;
|
|
21120
|
+
const fontSize = element?.fontSize || DEFAULT_FONT_SIZE4;
|
|
21121
|
+
const lineHeight = element?.lineHeight || getLineHeight2(fontFamily);
|
|
21122
|
+
const text = element.text ?? "";
|
|
21123
|
+
const normalizedText = normalizeText(text);
|
|
21124
|
+
const metrics = measureText(
|
|
21125
|
+
normalizedText,
|
|
21126
|
+
getFontString8({ fontFamily, fontSize }),
|
|
21127
|
+
lineHeight
|
|
21128
|
+
);
|
|
21129
|
+
excalidrawElement = newTextElement({
|
|
21130
|
+
width: metrics.width,
|
|
21131
|
+
height: metrics.height,
|
|
21132
|
+
fontFamily,
|
|
21133
|
+
fontSize,
|
|
21134
|
+
...element
|
|
21135
|
+
});
|
|
21136
|
+
break;
|
|
21137
|
+
}
|
|
21138
|
+
case "image": {
|
|
21139
|
+
excalidrawElement = newImageElement({
|
|
21140
|
+
width: element?.width || DEFAULT_DIMENSION,
|
|
21141
|
+
height: element?.height || DEFAULT_DIMENSION,
|
|
21142
|
+
...element
|
|
21143
|
+
});
|
|
21144
|
+
break;
|
|
21145
|
+
}
|
|
21146
|
+
case "frame": {
|
|
21147
|
+
excalidrawElement = newFrameElement({
|
|
21148
|
+
x: 0,
|
|
21149
|
+
y: 0,
|
|
21150
|
+
...element
|
|
21151
|
+
});
|
|
21152
|
+
break;
|
|
21153
|
+
}
|
|
21154
|
+
case "magicframe": {
|
|
21155
|
+
excalidrawElement = newMagicFrameElement({
|
|
21156
|
+
x: 0,
|
|
21157
|
+
y: 0,
|
|
21158
|
+
...element
|
|
21159
|
+
});
|
|
21160
|
+
break;
|
|
21161
|
+
}
|
|
21162
|
+
case "freedraw":
|
|
21163
|
+
case "iframe":
|
|
21164
|
+
case "embeddable": {
|
|
21165
|
+
excalidrawElement = element;
|
|
21166
|
+
break;
|
|
21167
|
+
}
|
|
21168
|
+
default: {
|
|
21169
|
+
excalidrawElement = element;
|
|
21170
|
+
assertNever5(
|
|
21171
|
+
element,
|
|
21172
|
+
`Unhandled element type "${element.type}"`,
|
|
21173
|
+
true
|
|
19834
21174
|
);
|
|
19835
21175
|
}
|
|
19836
21176
|
}
|
|
21177
|
+
const existingElement = elementStore.getElement(excalidrawElement.id);
|
|
21178
|
+
if (existingElement) {
|
|
21179
|
+
console.error(`Duplicate id found for ${excalidrawElement.id}`);
|
|
21180
|
+
} else {
|
|
21181
|
+
elementStore.add(excalidrawElement);
|
|
21182
|
+
elementsWithIds.set(excalidrawElement.id, element);
|
|
21183
|
+
if (originalId) {
|
|
21184
|
+
oldToNewElementIdMap.set(originalId, excalidrawElement.id);
|
|
21185
|
+
}
|
|
21186
|
+
}
|
|
21187
|
+
}
|
|
21188
|
+
const elementsMap = elementStore.getElementsMap();
|
|
21189
|
+
const scene = new Scene(elementsMap);
|
|
21190
|
+
for (const [id, element] of elementsWithIds) {
|
|
21191
|
+
const excalidrawElement = elementStore.getElement(id);
|
|
21192
|
+
switch (element.type) {
|
|
21193
|
+
case "rectangle":
|
|
21194
|
+
case "ellipse":
|
|
21195
|
+
case "diamond":
|
|
21196
|
+
case "arrow": {
|
|
21197
|
+
if (element.label?.text) {
|
|
21198
|
+
let [container, text] = bindTextToContainer(
|
|
21199
|
+
excalidrawElement,
|
|
21200
|
+
element?.label,
|
|
21201
|
+
scene
|
|
21202
|
+
);
|
|
21203
|
+
elementStore.add(container);
|
|
21204
|
+
elementStore.add(text);
|
|
21205
|
+
if (isArrowElement(container)) {
|
|
21206
|
+
const originalStart = element.type === "arrow" ? element?.start : void 0;
|
|
21207
|
+
const originalEnd = element.type === "arrow" ? element?.end : void 0;
|
|
21208
|
+
if (originalStart && originalStart.id) {
|
|
21209
|
+
const newStartId = oldToNewElementIdMap.get(originalStart.id);
|
|
21210
|
+
if (newStartId) {
|
|
21211
|
+
Object.assign(originalStart, { id: newStartId });
|
|
21212
|
+
}
|
|
21213
|
+
}
|
|
21214
|
+
if (originalEnd && originalEnd.id) {
|
|
21215
|
+
const newEndId = oldToNewElementIdMap.get(originalEnd.id);
|
|
21216
|
+
if (newEndId) {
|
|
21217
|
+
Object.assign(originalEnd, { id: newEndId });
|
|
21218
|
+
}
|
|
21219
|
+
}
|
|
21220
|
+
const { linearElement, startBoundElement, endBoundElement } = bindLinearElementToElement(
|
|
21221
|
+
container,
|
|
21222
|
+
originalStart,
|
|
21223
|
+
originalEnd,
|
|
21224
|
+
elementStore,
|
|
21225
|
+
scene
|
|
21226
|
+
);
|
|
21227
|
+
container = linearElement;
|
|
21228
|
+
elementStore.add(linearElement);
|
|
21229
|
+
elementStore.add(startBoundElement);
|
|
21230
|
+
elementStore.add(endBoundElement);
|
|
21231
|
+
}
|
|
21232
|
+
} else {
|
|
21233
|
+
switch (element.type) {
|
|
21234
|
+
case "arrow": {
|
|
21235
|
+
const { start, end } = element;
|
|
21236
|
+
if (start && start.id) {
|
|
21237
|
+
const newStartId = oldToNewElementIdMap.get(start.id);
|
|
21238
|
+
Object.assign(start, { id: newStartId });
|
|
21239
|
+
}
|
|
21240
|
+
if (end && end.id) {
|
|
21241
|
+
const newEndId = oldToNewElementIdMap.get(end.id);
|
|
21242
|
+
Object.assign(end, { id: newEndId });
|
|
21243
|
+
}
|
|
21244
|
+
const { linearElement, startBoundElement, endBoundElement } = bindLinearElementToElement(
|
|
21245
|
+
excalidrawElement,
|
|
21246
|
+
start,
|
|
21247
|
+
end,
|
|
21248
|
+
elementStore,
|
|
21249
|
+
scene
|
|
21250
|
+
);
|
|
21251
|
+
elementStore.add(linearElement);
|
|
21252
|
+
elementStore.add(startBoundElement);
|
|
21253
|
+
elementStore.add(endBoundElement);
|
|
21254
|
+
break;
|
|
21255
|
+
}
|
|
21256
|
+
}
|
|
21257
|
+
}
|
|
21258
|
+
break;
|
|
21259
|
+
}
|
|
21260
|
+
}
|
|
19837
21261
|
}
|
|
19838
|
-
|
|
19839
|
-
|
|
19840
|
-
|
|
19841
|
-
|
|
19842
|
-
|
|
19843
|
-
|
|
19844
|
-
|
|
19845
|
-
|
|
19846
|
-
|
|
19847
|
-
|
|
19848
|
-
|
|
19849
|
-
|
|
21262
|
+
for (const [id, element] of elementsWithIds) {
|
|
21263
|
+
if (element.type !== "frame" && element.type !== "magicframe") {
|
|
21264
|
+
continue;
|
|
21265
|
+
}
|
|
21266
|
+
const frame = elementStore.getElement(id);
|
|
21267
|
+
if (!frame) {
|
|
21268
|
+
throw new Error(`Excalidraw element with id ${id} doesn't exist`);
|
|
21269
|
+
}
|
|
21270
|
+
const childrenElements = [];
|
|
21271
|
+
element.children.forEach((id2) => {
|
|
21272
|
+
const newElementId = oldToNewElementIdMap.get(id2);
|
|
21273
|
+
if (!newElementId) {
|
|
21274
|
+
throw new Error(`Element with ${id2} wasn't mapped correctly`);
|
|
21275
|
+
}
|
|
21276
|
+
const elementInFrame = elementStore.getElement(newElementId);
|
|
21277
|
+
if (!elementInFrame) {
|
|
21278
|
+
throw new Error(`Frame element with id ${newElementId} doesn't exist`);
|
|
21279
|
+
}
|
|
21280
|
+
Object.assign(elementInFrame, { frameId: frame.id });
|
|
21281
|
+
elementInFrame?.boundElements?.forEach((boundElement) => {
|
|
21282
|
+
const ele = elementStore.getElement(boundElement.id);
|
|
21283
|
+
if (!ele) {
|
|
21284
|
+
throw new Error(
|
|
21285
|
+
`Bound element with id ${boundElement.id} doesn't exist`
|
|
21286
|
+
);
|
|
21287
|
+
}
|
|
21288
|
+
Object.assign(ele, { frameId: frame.id });
|
|
21289
|
+
childrenElements.push(ele);
|
|
21290
|
+
});
|
|
21291
|
+
childrenElements.push(elementInFrame);
|
|
21292
|
+
});
|
|
21293
|
+
let [minX, minY, maxX, maxY] = getCommonBounds(childrenElements);
|
|
21294
|
+
const PADDING = 10;
|
|
21295
|
+
minX = minX - PADDING;
|
|
21296
|
+
minY = minY - PADDING;
|
|
21297
|
+
maxX = maxX + PADDING;
|
|
21298
|
+
maxY = maxY + PADDING;
|
|
21299
|
+
const frameX = frame?.x || minX;
|
|
21300
|
+
const frameY = frame?.y || minY;
|
|
21301
|
+
const frameWidth = frame?.width || maxX - minX;
|
|
21302
|
+
const frameHeight = frame?.height || maxY - minY;
|
|
21303
|
+
Object.assign(frame, {
|
|
21304
|
+
x: frameX,
|
|
21305
|
+
y: frameY,
|
|
21306
|
+
width: frameWidth,
|
|
21307
|
+
height: frameHeight
|
|
21308
|
+
});
|
|
21309
|
+
if (isDevEnv7() && element.children.length && (frame?.x || frame?.y || frame?.width || frame?.height)) {
|
|
21310
|
+
console.info(
|
|
21311
|
+
"User provided frame attributes are being considered, if you find this inaccurate, please remove any of the attributes - x, y, width and height so frame coordinates and dimensions are calculated automatically"
|
|
21312
|
+
);
|
|
21313
|
+
}
|
|
19850
21314
|
}
|
|
19851
|
-
return
|
|
19852
|
-
nextElements,
|
|
19853
|
-
appState,
|
|
19854
|
-
direction,
|
|
19855
|
-
null,
|
|
19856
|
-
frameAwareContiguousElementsToMove.regularElements
|
|
19857
|
-
);
|
|
19858
|
-
}
|
|
19859
|
-
var moveOneLeft = (allElements, appState, scene) => {
|
|
19860
|
-
return shiftElementsByOne(allElements, appState, "left", scene);
|
|
19861
|
-
};
|
|
19862
|
-
var moveOneRight = (allElements, appState, scene) => {
|
|
19863
|
-
return shiftElementsByOne(allElements, appState, "right", scene);
|
|
19864
|
-
};
|
|
19865
|
-
var moveAllLeft = (allElements, appState) => {
|
|
19866
|
-
return shiftElementsAccountingForFrames(
|
|
19867
|
-
allElements,
|
|
19868
|
-
appState,
|
|
19869
|
-
"left",
|
|
19870
|
-
shiftElementsToEnd
|
|
19871
|
-
);
|
|
21315
|
+
return elementStore.getElements();
|
|
19872
21316
|
};
|
|
19873
|
-
|
|
19874
|
-
|
|
19875
|
-
|
|
19876
|
-
|
|
19877
|
-
|
|
19878
|
-
|
|
19879
|
-
|
|
21317
|
+
|
|
21318
|
+
// src/arrows/helpers.ts
|
|
21319
|
+
init_define_import_meta_env();
|
|
21320
|
+
var maybeHandleArrowPointlikeDrag = ({
|
|
21321
|
+
app,
|
|
21322
|
+
event
|
|
21323
|
+
}) => {
|
|
21324
|
+
const appState = app.state;
|
|
21325
|
+
if (appState.selectedLinearElement && app.lastPointerMoveCoords) {
|
|
21326
|
+
if (appState.selectedLinearElement.draggedFocusPointBinding) {
|
|
21327
|
+
handleFocusPointDrag(
|
|
21328
|
+
appState.selectedLinearElement,
|
|
21329
|
+
app.scene.getNonDeletedElementsMap(),
|
|
21330
|
+
app.lastPointerMoveCoords,
|
|
21331
|
+
app.scene,
|
|
21332
|
+
appState,
|
|
21333
|
+
app.getEffectiveGridSize(),
|
|
21334
|
+
event.altKey
|
|
21335
|
+
);
|
|
21336
|
+
return true;
|
|
21337
|
+
} else if (appState.selectedLinearElement.hoverPointIndex !== null && app.lastPointerMoveEvent && appState.selectedLinearElement.initialState.lastClickedPoint >= 0 && appState.selectedLinearElement.isDragging) {
|
|
21338
|
+
LinearElementEditor.handlePointDragging(
|
|
21339
|
+
app.lastPointerMoveEvent,
|
|
21340
|
+
app,
|
|
21341
|
+
app.lastPointerMoveCoords.x,
|
|
21342
|
+
app.lastPointerMoveCoords.y,
|
|
21343
|
+
appState.selectedLinearElement
|
|
21344
|
+
);
|
|
21345
|
+
return true;
|
|
21346
|
+
}
|
|
21347
|
+
}
|
|
21348
|
+
return false;
|
|
19880
21349
|
};
|
|
19881
21350
|
|
|
19882
21351
|
// src/index.ts
|
|
@@ -19916,13 +21385,13 @@ export {
|
|
|
19916
21385
|
ElementBounds,
|
|
19917
21386
|
ElementsDelta,
|
|
19918
21387
|
EphemeralIncrement,
|
|
21388
|
+
FOCUS_POINT_SIZE,
|
|
19919
21389
|
FlowChartCreator,
|
|
19920
21390
|
FlowChartNavigator,
|
|
19921
21391
|
HEADING_DOWN,
|
|
19922
21392
|
HEADING_LEFT,
|
|
19923
21393
|
HEADING_RIGHT,
|
|
19924
21394
|
HEADING_UP,
|
|
19925
|
-
IMAGE_INVERT_FILTER,
|
|
19926
21395
|
INVISIBLY_SMALL_ELEMENT_SIZE,
|
|
19927
21396
|
InvalidFractionalIndexError,
|
|
19928
21397
|
LinearElementEditor,
|
|
@@ -19962,6 +21431,7 @@ export {
|
|
|
19962
21431
|
computeBoundTextPosition,
|
|
19963
21432
|
computeContainerDimensionForBoundText,
|
|
19964
21433
|
containsCJK,
|
|
21434
|
+
convertToExcalidrawElements,
|
|
19965
21435
|
createPlaceholderEmbeddableLabel,
|
|
19966
21436
|
createSrcDoc,
|
|
19967
21437
|
cropElement,
|
|
@@ -19991,7 +21461,6 @@ export {
|
|
|
19991
21461
|
fixDuplicatedBindingsAfterDuplication,
|
|
19992
21462
|
flipHeading,
|
|
19993
21463
|
frameAndChildrenSelectedTogether,
|
|
19994
|
-
generateFreeDrawShape,
|
|
19995
21464
|
generateLinearCollisionShape,
|
|
19996
21465
|
generateRoughOptions,
|
|
19997
21466
|
getAllHoveredElementAtPoint,
|
|
@@ -20002,6 +21471,7 @@ export {
|
|
|
20002
21471
|
getArrowheadPoints,
|
|
20003
21472
|
getArrowheadSize,
|
|
20004
21473
|
getBindingGap,
|
|
21474
|
+
getBindingSideMidPoint,
|
|
20005
21475
|
getBindingStrategyForDraggingBindingElementEndpoints,
|
|
20006
21476
|
getBoundTextElement,
|
|
20007
21477
|
getBoundTextElementId,
|
|
@@ -20043,14 +21513,13 @@ export {
|
|
|
20043
21513
|
getFrameChildren,
|
|
20044
21514
|
getFrameLikeElements,
|
|
20045
21515
|
getFrameLikeTitle,
|
|
20046
|
-
getFreeDrawPath2D,
|
|
20047
|
-
getFreeDrawSvgPath,
|
|
20048
21516
|
getFreedrawOutlineAsSegments,
|
|
20049
21517
|
getFreedrawOutlinePoints,
|
|
20050
21518
|
getGlobalFixedPointForBindableElement,
|
|
20051
21519
|
getGlobalFixedPoints,
|
|
20052
21520
|
getHeadingForElbowArrowSnap,
|
|
20053
21521
|
getHoveredElementForBinding,
|
|
21522
|
+
getHoveredElementForFocusPoint,
|
|
20054
21523
|
getInitializedImageElements,
|
|
20055
21524
|
getLineHeightInPx,
|
|
20056
21525
|
getLineWidth,
|
|
@@ -20103,6 +21572,10 @@ export {
|
|
|
20103
21572
|
groupsAreAtLeastIntersectingTheFrame,
|
|
20104
21573
|
groupsAreCompletelyOutOfFrame,
|
|
20105
21574
|
handleBindTextResize,
|
|
21575
|
+
handleFocusPointDrag,
|
|
21576
|
+
handleFocusPointHover,
|
|
21577
|
+
handleFocusPointPointerDown,
|
|
21578
|
+
handleFocusPointPointerUp,
|
|
20106
21579
|
hasBackground,
|
|
20107
21580
|
hasBoundTextElement,
|
|
20108
21581
|
hasBoundingBox,
|
|
@@ -20129,7 +21602,6 @@ export {
|
|
|
20129
21602
|
isBindingElementType,
|
|
20130
21603
|
isBindingEnabled,
|
|
20131
21604
|
isBoundToContainer,
|
|
20132
|
-
isBounds,
|
|
20133
21605
|
isCursorInFrame,
|
|
20134
21606
|
isCurvedArrow,
|
|
20135
21607
|
isElbowArrow,
|
|
@@ -20143,6 +21615,7 @@ export {
|
|
|
20143
21615
|
isEmbeddableElement,
|
|
20144
21616
|
isExcalidrawElement,
|
|
20145
21617
|
isFlowchartNodeElement,
|
|
21618
|
+
isFocusPointVisible,
|
|
20146
21619
|
isFrameElement,
|
|
20147
21620
|
isFrameLikeElement,
|
|
20148
21621
|
isFreeDrawElement,
|
|
@@ -20178,6 +21651,7 @@ export {
|
|
|
20178
21651
|
loadHTMLImageElement,
|
|
20179
21652
|
makeNextSelectedElementIds,
|
|
20180
21653
|
maxBindingDistance_simple,
|
|
21654
|
+
maybeHandleArrowPointlikeDrag,
|
|
20181
21655
|
maybeParseEmbedSrc,
|
|
20182
21656
|
measureFontSizeFromWidth,
|
|
20183
21657
|
measureText,
|
|
@@ -20208,7 +21682,6 @@ export {
|
|
|
20208
21682
|
originalContainerCache,
|
|
20209
21683
|
parseElementLinkFromURL,
|
|
20210
21684
|
parseTokens,
|
|
20211
|
-
pathsCache,
|
|
20212
21685
|
pointInsideBounds,
|
|
20213
21686
|
positionElementsOnGrid,
|
|
20214
21687
|
projectFixedPointOntoDiagonal,
|