@excalidraw/excalidraw 0.17.1-d2f67e6 → 0.17.1-e63dd02
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/CHANGELOG.md +4 -0
- package/dist/browser/dev/excalidraw-assets-dev/CascadiaCode-Regular-TMZI7IJ5.woff2 +0 -0
- package/dist/browser/dev/excalidraw-assets-dev/ComicShanns-Regular-6TOETDFT.woff2 +0 -0
- package/dist/browser/dev/excalidraw-assets-dev/Excalifont-Regular-CPKEUDVM.woff2 +0 -0
- package/dist/browser/dev/excalidraw-assets-dev/LiberationSans-Regular-ZQD73GJM.woff2 +0 -0
- package/dist/browser/dev/excalidraw-assets-dev/Virgil-Regular-YHAB2VGJ.woff2 +0 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-EM6LVGFW.js → chunk-IT7T3AIK.js} +23 -5
- package/dist/browser/dev/excalidraw-assets-dev/chunk-IT7T3AIK.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-B4UMSLQQ.js → chunk-RNHSD5AR.js} +7451 -2098
- package/dist/browser/dev/excalidraw-assets-dev/chunk-RNHSD5AR.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{dist-6QVAH5JA.js → dist-DNSPZDOZ.js} +31 -19
- package/dist/browser/dev/excalidraw-assets-dev/dist-DNSPZDOZ.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{en-AZFA5HJJ.js → en-XV7OZCPP.js} +6 -2
- package/dist/browser/dev/excalidraw-assets-dev/{image-V7E6IT6R.js → image-77HZYGLG.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{image-O66MQ7WQ.css → image-WDHYGKKP.css} +1 -1
- package/dist/browser/dev/excalidraw-assets-dev/{image-O66MQ7WQ.css.map → image-WDHYGKKP.css.map} +2 -2
- package/dist/browser/dev/index.css +449 -114
- package/dist/browser/dev/index.css.map +3 -3
- package/dist/browser/dev/index.js +4143 -5956
- package/dist/browser/dev/index.js.map +4 -4
- package/dist/browser/prod/excalidraw-assets/CascadiaCode-Regular-TMZI7IJ5.woff2 +0 -0
- package/dist/browser/prod/excalidraw-assets/ComicShanns-Regular-6TOETDFT.woff2 +0 -0
- package/dist/browser/prod/excalidraw-assets/Excalifont-Regular-CPKEUDVM.woff2 +0 -0
- package/dist/browser/prod/excalidraw-assets/LiberationSans-Regular-ZQD73GJM.woff2 +0 -0
- package/dist/browser/prod/excalidraw-assets/Virgil-Regular-YHAB2VGJ.woff2 +0 -0
- package/dist/browser/prod/excalidraw-assets/chunk-OYEADJSR.js +63 -0
- package/dist/browser/prod/excalidraw-assets/{chunk-7DXALCB2.js → chunk-PDYFZJMS.js} +3 -3
- package/dist/browser/prod/excalidraw-assets/dist-NLUQPPQQ.js +7 -0
- package/dist/browser/prod/excalidraw-assets/en-YVAVVILW.js +1 -0
- package/dist/browser/prod/excalidraw-assets/image-X3GFZHNN.js +1 -0
- package/dist/browser/prod/index.css +1 -1
- package/dist/browser/prod/index.js +40 -50
- package/dist/dev/CascadiaCode-Regular-TMZI7IJ5.woff2 +0 -0
- package/dist/dev/ComicShanns-Regular-6TOETDFT.woff2 +0 -0
- package/dist/dev/Excalifont-Regular-CPKEUDVM.woff2 +0 -0
- package/dist/dev/LiberationSans-Regular-ZQD73GJM.woff2 +0 -0
- package/dist/dev/Virgil-Regular-YHAB2VGJ.woff2 +0 -0
- package/dist/dev/{en-EB2MBPAV.json → en-YNVBSAIL.json} +18 -4
- package/dist/dev/index.css +449 -114
- package/dist/dev/index.css.map +3 -3
- package/dist/dev/index.js +21626 -18122
- package/dist/dev/index.js.map +4 -4
- package/dist/excalidraw/actions/actionAddToLibrary.d.ts +9 -3
- package/dist/excalidraw/actions/actionBoundText.d.ts +6 -2
- package/dist/excalidraw/actions/actionCanvas.d.ts +36 -12
- package/dist/excalidraw/actions/actionClipboard.d.ts +22 -7
- package/dist/excalidraw/actions/actionDeleteSelected.d.ts +12 -5
- package/dist/excalidraw/actions/actionDeleteSelected.js +24 -5
- package/dist/excalidraw/actions/actionDuplicateSelection.js +1 -2
- package/dist/excalidraw/actions/actionElementLock.d.ts +6 -2
- package/dist/excalidraw/actions/actionExport.d.ts +27 -9
- package/dist/excalidraw/actions/actionFinalize.d.ts +6 -2
- package/dist/excalidraw/actions/actionFinalize.js +2 -2
- package/dist/excalidraw/actions/actionFlip.js +2 -2
- package/dist/excalidraw/actions/actionFrame.d.ts +12 -4
- package/dist/excalidraw/actions/actionGroup.d.ts +6 -2
- package/dist/excalidraw/actions/actionHistory.js +4 -4
- package/dist/excalidraw/actions/actionLinearEditor.d.ts +3 -1
- package/dist/excalidraw/actions/actionLinearEditor.js +3 -2
- package/dist/excalidraw/actions/actionLink.d.ts +3 -1
- package/dist/excalidraw/actions/actionMenu.d.ts +9 -3
- package/dist/excalidraw/actions/actionNavigate.d.ts +6 -2
- package/dist/excalidraw/actions/actionProperties.d.ts +411 -56
- package/dist/excalidraw/actions/actionProperties.js +383 -58
- package/dist/excalidraw/actions/actionSelectAll.d.ts +3 -1
- package/dist/excalidraw/actions/actionStyles.d.ts +3 -1
- package/dist/excalidraw/actions/actionStyles.js +3 -2
- package/dist/excalidraw/actions/actionToggleGridMode.d.ts +3 -1
- package/dist/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +3 -1
- package/dist/excalidraw/actions/actionToggleStats.d.ts +3 -1
- package/dist/excalidraw/actions/actionToggleViewMode.d.ts +3 -1
- package/dist/excalidraw/actions/actionToggleZenMode.d.ts +3 -1
- package/dist/excalidraw/actions/types.d.ts +1 -1
- package/dist/excalidraw/analytics.js +9 -7
- package/dist/excalidraw/appState.d.ts +1 -0
- package/dist/excalidraw/appState.js +9 -1
- package/dist/excalidraw/binaryheap.d.ts +12 -0
- package/dist/excalidraw/binaryheap.js +93 -0
- package/dist/excalidraw/change.d.ts +2 -1
- package/dist/excalidraw/change.js +6 -4
- package/dist/excalidraw/charts.js +0 -10
- package/dist/excalidraw/components/Actions.js +7 -5
- package/dist/excalidraw/components/App.d.ts +5 -9
- package/dist/excalidraw/components/App.js +218 -161
- package/dist/excalidraw/components/ButtonIcon.d.ts +15 -0
- package/dist/excalidraw/components/ButtonIcon.js +8 -0
- package/dist/excalidraw/components/ButtonIconSelect.js +2 -3
- package/dist/excalidraw/components/ButtonSeparator.d.ts +2 -0
- package/dist/excalidraw/components/ButtonSeparator.js +7 -0
- package/dist/excalidraw/components/ColorPicker/ColorPicker.js +47 -79
- package/dist/excalidraw/components/ColorPicker/Picker.js +1 -1
- package/dist/excalidraw/components/FontPicker/FontPicker.d.ts +21 -0
- package/dist/excalidraw/components/FontPicker/FontPicker.js +49 -0
- package/dist/excalidraw/components/FontPicker/FontPickerList.d.ts +25 -0
- package/dist/excalidraw/components/FontPicker/FontPickerList.js +119 -0
- package/dist/excalidraw/components/FontPicker/FontPickerTrigger.d.ts +7 -0
- package/dist/excalidraw/components/FontPicker/FontPickerTrigger.js +13 -0
- package/dist/excalidraw/components/FontPicker/keyboardNavHandlers.d.ts +14 -0
- package/dist/excalidraw/components/FontPicker/keyboardNavHandlers.js +38 -0
- package/dist/excalidraw/components/HelpDialog.js +1 -1
- package/dist/excalidraw/components/HintViewer.js +6 -3
- package/dist/excalidraw/components/PropertiesPopover.d.ts +15 -0
- package/dist/excalidraw/components/PropertiesPopover.js +31 -0
- package/dist/excalidraw/components/QuickSearch.d.ts +9 -0
- package/dist/excalidraw/components/QuickSearch.js +8 -0
- package/dist/excalidraw/components/ScrollableList.d.ts +9 -0
- package/dist/excalidraw/components/ScrollableList.js +8 -0
- package/dist/excalidraw/components/Stats/Angle.d.ts +7 -3
- package/dist/excalidraw/components/Stats/Angle.js +39 -31
- package/dist/excalidraw/components/Stats/Dimension.d.ts +6 -3
- package/dist/excalidraw/components/Stats/Dimension.js +51 -49
- package/dist/excalidraw/components/Stats/DragInput.d.ts +15 -6
- package/dist/excalidraw/components/Stats/DragInput.js +59 -26
- package/dist/excalidraw/components/Stats/FontSize.d.ts +8 -4
- package/dist/excalidraw/components/Stats/FontSize.js +39 -36
- package/dist/excalidraw/components/Stats/MultiAngle.d.ts +5 -3
- package/dist/excalidraw/components/Stats/MultiAngle.js +43 -34
- package/dist/excalidraw/components/Stats/MultiDimension.d.ts +5 -3
- package/dist/excalidraw/components/Stats/MultiDimension.js +101 -99
- package/dist/excalidraw/components/Stats/MultiFontSize.d.ts +6 -3
- package/dist/excalidraw/components/Stats/MultiFontSize.js +47 -32
- package/dist/excalidraw/components/Stats/MultiPosition.d.ts +3 -1
- package/dist/excalidraw/components/Stats/MultiPosition.js +52 -48
- package/dist/excalidraw/components/Stats/Position.d.ts +5 -1
- package/dist/excalidraw/components/Stats/Position.js +31 -29
- package/dist/excalidraw/components/Stats/index.js +5 -17
- package/dist/excalidraw/components/Stats/utils.d.ts +14 -3
- package/dist/excalidraw/components/Stats/utils.js +48 -9
- package/dist/excalidraw/components/TTDDialog/common.d.ts +2 -2
- package/dist/excalidraw/components/TTDDialog/common.js +3 -7
- package/dist/excalidraw/components/UserList.js +22 -22
- package/dist/excalidraw/components/canvases/StaticCanvas.js +1 -0
- package/dist/excalidraw/components/dropdownMenu/DropdownMenu.d.ts +12 -3
- package/dist/excalidraw/components/dropdownMenu/DropdownMenuItem.d.ts +24 -4
- package/dist/excalidraw/components/dropdownMenu/DropdownMenuItem.js +55 -14
- package/dist/excalidraw/components/dropdownMenu/DropdownMenuItemContent.d.ts +2 -1
- package/dist/excalidraw/components/dropdownMenu/DropdownMenuItemContent.js +2 -2
- package/dist/excalidraw/components/dropdownMenu/common.d.ts +1 -1
- package/dist/excalidraw/components/dropdownMenu/common.js +3 -2
- package/dist/excalidraw/components/icons.d.ts +4 -0
- package/dist/excalidraw/components/icons.js +7 -0
- package/dist/excalidraw/components/main-menu/MainMenu.d.ts +12 -3
- package/dist/excalidraw/components/welcome-screen/WelcomeScreen.Center.js +2 -2
- package/dist/excalidraw/components/welcome-screen/WelcomeScreen.Hints.js +3 -3
- package/dist/excalidraw/constants.d.ts +17 -2
- package/dist/excalidraw/constants.js +21 -4
- package/dist/excalidraw/data/reconcile.js +18 -1
- package/dist/excalidraw/data/restore.js +55 -9
- package/dist/excalidraw/data/transform.js +8 -5
- package/dist/excalidraw/element/binding.d.ts +28 -9
- package/dist/excalidraw/element/binding.js +303 -71
- package/dist/excalidraw/element/collision.d.ts +1 -1
- package/dist/excalidraw/element/collision.js +4 -1
- package/dist/excalidraw/element/dragElements.d.ts +2 -2
- package/dist/excalidraw/element/dragElements.js +13 -3
- package/dist/excalidraw/element/embeddable.d.ts +3 -1
- package/dist/excalidraw/element/heading.d.ts +11 -0
- package/dist/excalidraw/element/heading.js +81 -0
- package/dist/excalidraw/element/index.d.ts +1 -1
- package/dist/excalidraw/element/index.js +1 -1
- package/dist/excalidraw/element/linearElementEditor.d.ts +21 -13
- package/dist/excalidraw/element/linearElementEditor.js +133 -56
- package/dist/excalidraw/element/newElement.d.ts +8 -3
- package/dist/excalidraw/element/newElement.js +15 -2
- package/dist/excalidraw/element/resizeElements.d.ts +4 -3
- package/dist/excalidraw/element/resizeElements.js +47 -23
- package/dist/excalidraw/element/routing.d.ts +13 -0
- package/dist/excalidraw/element/routing.js +641 -0
- package/dist/excalidraw/element/textElement.d.ts +3 -26
- package/dist/excalidraw/element/textElement.js +54 -110
- package/dist/excalidraw/element/textWysiwyg.js +39 -47
- package/dist/excalidraw/element/transformHandles.js +7 -2
- package/dist/excalidraw/element/typeChecks.d.ts +5 -2
- package/dist/excalidraw/element/typeChecks.js +17 -0
- package/dist/excalidraw/element/types.d.ts +12 -1
- package/dist/excalidraw/fonts/ExcalidrawFont.d.ts +21 -0
- package/dist/excalidraw/fonts/ExcalidrawFont.js +112 -0
- package/dist/excalidraw/fonts/index.d.ts +58 -0
- package/dist/excalidraw/fonts/index.js +240 -0
- package/dist/excalidraw/fonts/metadata.d.ts +36 -0
- package/dist/excalidraw/fonts/metadata.js +91 -0
- package/dist/excalidraw/fractionalIndex.d.ts +11 -4
- package/dist/excalidraw/fractionalIndex.js +38 -6
- package/dist/excalidraw/frame.d.ts +1 -1
- package/dist/excalidraw/frame.js +3 -3
- package/dist/excalidraw/history.d.ts +4 -3
- package/dist/excalidraw/history.js +8 -8
- package/dist/excalidraw/index.d.ts +1 -1
- package/dist/excalidraw/index.js +3 -3
- package/dist/excalidraw/locales/en.json +18 -4
- package/dist/excalidraw/math.d.ts +43 -0
- package/dist/excalidraw/math.js +110 -0
- package/dist/excalidraw/mermaid.js +4 -3
- package/dist/excalidraw/renderer/interactiveScene.js +33 -17
- package/dist/excalidraw/renderer/renderElement.d.ts +2 -0
- package/dist/excalidraw/renderer/renderElement.js +74 -54
- package/dist/excalidraw/renderer/staticSvgScene.js +2 -1
- package/dist/excalidraw/scene/Scene.js +9 -3
- package/dist/excalidraw/scene/Shape.js +56 -5
- package/dist/excalidraw/scene/comparisons.d.ts +1 -0
- package/dist/excalidraw/scene/comparisons.js +1 -1
- package/dist/excalidraw/scene/export.d.ts +2 -1
- package/dist/excalidraw/scene/export.js +33 -35
- package/dist/excalidraw/scene/types.d.ts +1 -4
- package/dist/excalidraw/shapes.d.ts +8 -0
- package/dist/excalidraw/shapes.js +57 -0
- package/dist/excalidraw/types.d.ts +8 -3
- package/dist/excalidraw/utils.d.ts +11 -1
- package/dist/excalidraw/utils.js +22 -0
- package/dist/prod/CascadiaCode-Regular-TMZI7IJ5.woff2 +0 -0
- package/dist/prod/ComicShanns-Regular-6TOETDFT.woff2 +0 -0
- package/dist/prod/Excalifont-Regular-CPKEUDVM.woff2 +0 -0
- package/dist/prod/LiberationSans-Regular-ZQD73GJM.woff2 +0 -0
- package/dist/prod/Virgil-Regular-YHAB2VGJ.woff2 +0 -0
- package/dist/prod/{en-EB2MBPAV.json → en-YNVBSAIL.json} +18 -4
- package/dist/prod/index.css +1 -1
- package/dist/prod/index.js +49 -53
- package/dist/utils/export.d.ts +2 -1
- package/dist/utils/export.js +2 -1
- package/dist/utils/geometry/geometry.d.ts +2 -1
- package/dist/utils/geometry/geometry.js +5 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/history.ts +9 -2
- package/package.json +2 -2
- package/dist/browser/dev/Cascadia-CYPE3OJC.woff2 +0 -0
- package/dist/browser/dev/Virgil-UZN6MUT6.woff2 +0 -0
- package/dist/browser/dev/excalidraw-assets-dev/chunk-B4UMSLQQ.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/chunk-EM6LVGFW.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/dist-6QVAH5JA.js.map +0 -7
- package/dist/browser/prod/Cascadia-CYPE3OJC.woff2 +0 -0
- package/dist/browser/prod/Virgil-UZN6MUT6.woff2 +0 -0
- package/dist/browser/prod/excalidraw-assets/chunk-EGOLGOLD.js +0 -55
- package/dist/browser/prod/excalidraw-assets/dist-567JAXHK.js +0 -7
- package/dist/browser/prod/excalidraw-assets/en-6E7MYLWO.js +0 -1
- package/dist/browser/prod/excalidraw-assets/image-SI7BKULC.js +0 -1
- package/dist/dev/Cascadia-CYPE3OJC.woff2 +0 -0
- package/dist/dev/Virgil-UZN6MUT6.woff2 +0 -0
- package/dist/excalidraw/scene/Fonts.d.ts +0 -19
- package/dist/excalidraw/scene/Fonts.js +0 -66
- package/dist/prod/Cascadia-CYPE3OJC.woff2 +0 -0
- package/dist/prod/Virgil-UZN6MUT6.woff2 +0 -0
- /package/dist/browser/dev/{Assistant-Bold-ZDZZ6JHA.woff2 → excalidraw-assets-dev/Assistant-Bold-ZDZZ6JHA.woff2} +0 -0
- /package/dist/browser/dev/{Assistant-Medium-DZ25RZU3.woff2 → excalidraw-assets-dev/Assistant-Medium-DZ25RZU3.woff2} +0 -0
- /package/dist/browser/dev/{Assistant-Regular-PLF2XOGW.woff2 → excalidraw-assets-dev/Assistant-Regular-PLF2XOGW.woff2} +0 -0
- /package/dist/browser/dev/{Assistant-SemiBold-CZ5MX6FK.woff2 → excalidraw-assets-dev/Assistant-SemiBold-CZ5MX6FK.woff2} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{en-AZFA5HJJ.js.map → en-XV7OZCPP.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{image-V7E6IT6R.js.map → image-77HZYGLG.js.map} +0 -0
- /package/dist/browser/prod/{Assistant-Bold-ZDZZ6JHA.woff2 → excalidraw-assets/Assistant-Bold-ZDZZ6JHA.woff2} +0 -0
- /package/dist/browser/prod/{Assistant-Medium-DZ25RZU3.woff2 → excalidraw-assets/Assistant-Medium-DZ25RZU3.woff2} +0 -0
- /package/dist/browser/prod/{Assistant-Regular-PLF2XOGW.woff2 → excalidraw-assets/Assistant-Regular-PLF2XOGW.woff2} +0 -0
- /package/dist/browser/prod/{Assistant-SemiBold-CZ5MX6FK.woff2 → excalidraw-assets/Assistant-SemiBold-CZ5MX6FK.woff2} +0 -0
|
@@ -11,7 +11,7 @@ import { actions } from "../actions/register";
|
|
|
11
11
|
import { trackEvent } from "../analytics";
|
|
12
12
|
import { getDefaultAppState, isEraserActive, isHandToolActive, } from "../appState";
|
|
13
13
|
import { copyTextToSystemClipboard, parseClipboard } from "../clipboard";
|
|
14
|
-
import {
|
|
14
|
+
import { ARROW_TYPE } from "../constants";
|
|
15
15
|
import { APP_NAME, CURSOR_TYPE, DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT, DEFAULT_VERTICAL_ALIGN, DRAGGING_THRESHOLD, ELEMENT_SHIFT_TRANSLATE_AMOUNT, ELEMENT_TRANSLATE_AMOUNT, ENV, EVENT, FRAME_STYLE, GRID_SIZE, IMAGE_MIME_TYPES, IMAGE_RENDER_TIMEOUT, isBrave, LINE_CONFIRM_THRESHOLD, MAX_ALLOWED_FILE_BYTES, MIME_TYPES, MQ_MAX_HEIGHT_LANDSCAPE, MQ_MAX_WIDTH_LANDSCAPE, MQ_MAX_WIDTH_PORTRAIT, MQ_RIGHT_SIDEBAR_MIN_WIDTH, POINTER_BUTTON, ROUNDNESS, SCROLL_TIMEOUT, TAP_TWICE_TIMEOUT, TEXT_TO_CENTER_SNAP_THRESHOLD, THEME, THEME_FILTER, TOUCH_CTX_MENU_TIMEOUT, VERTICAL_ALIGN, YOUTUBE_STATES, ZOOM_STEP, POINTER_EVENTS, TOOL_TYPE, EDITOR_LS_KEYS, isIOS, supportsResizeObserver, DEFAULT_COLLISION_THRESHOLD, DEFAULT_TEXT_ALIGN, } from "../constants";
|
|
16
16
|
import { exportCanvas, loadFromBlob } from "../data";
|
|
17
17
|
import Library, { distributeLibraryItemsOnSquareGrid } from "../data/library";
|
|
@@ -20,8 +20,8 @@ import { dragNewElement, dragSelectedElements, duplicateElement, getCommonBounds
|
|
|
20
20
|
import { bindOrUnbindLinearElement, bindOrUnbindLinearElements, fixBindingsAfterDeletion, fixBindingsAfterDuplication, getHoveredElementForBinding, isBindingEnabled, isLinearElementSimpleAndAlreadyBound, maybeBindLinearElement, shouldEnableBindingForPointerEvent, updateBoundElements, getSuggestedBindingsForArrows, } from "../element/binding";
|
|
21
21
|
import { LinearElementEditor } from "../element/linearElementEditor";
|
|
22
22
|
import { mutateElement, newElementWith } from "../element/mutateElement";
|
|
23
|
-
import { deepCopyElement, duplicateElements, newFrameElement, newFreeDrawElement, newEmbeddableElement, newMagicFrameElement, newIframeElement, } from "../element/newElement";
|
|
24
|
-
import { hasBoundTextElement, isArrowElement, isBindingElement, isBindingElementType, isBoundToContainer, isFrameLikeElement, isImageElement, isEmbeddableElement, isInitializedImageElement, isLinearElement, isLinearElementType, isUsingAdaptiveRadius,
|
|
23
|
+
import { deepCopyElement, duplicateElements, newFrameElement, newFreeDrawElement, newEmbeddableElement, newMagicFrameElement, newIframeElement, newArrowElement, } from "../element/newElement";
|
|
24
|
+
import { hasBoundTextElement, isArrowElement, isBindingElement, isBindingElementType, isBoundToContainer, isFrameLikeElement, isImageElement, isEmbeddableElement, isInitializedImageElement, isLinearElement, isLinearElementType, isUsingAdaptiveRadius, isIframeElement, isIframeLikeElement, isMagicFrameElement, isTextBindableContainer, isElbowArrow, } from "../element/typeChecks";
|
|
25
25
|
import { getCenter, getDistance } from "../gesture";
|
|
26
26
|
import { editGroupForSelectedElement, getElementsInGroup, getSelectedGroupIdForElement, getSelectedGroupIds, isElementInGroup, isSelectedViaGroup, selectGroupsForSelectedElements, } from "../groups";
|
|
27
27
|
import { History } from "../history";
|
|
@@ -32,8 +32,8 @@ import { distance2d, getCornerRadius, getGridPoint, isPathALoop, } from "../math
|
|
|
32
32
|
import { calculateScrollCenter, getElementsWithinSelection, getNormalizedZoom, getSelectedElements, hasBackground, isSomeElementSelected, } from "../scene";
|
|
33
33
|
import Scene from "../scene/Scene";
|
|
34
34
|
import { getStateForZoom } from "../scene/zoom";
|
|
35
|
-
import { findShapeByKey } from "../shapes";
|
|
36
|
-
import {
|
|
35
|
+
import { findShapeByKey, getBoundTextShape, getElementShape } from "../shapes";
|
|
36
|
+
import { getSelectionBoxShape } from "../../utils/geometry/shape";
|
|
37
37
|
import { isPointInShape } from "../../utils/collision";
|
|
38
38
|
import { debounce, distance, getFontString, getNearestScrollableContainer, isInputLike, isToolIcon, isWritableElement, sceneCoordsToViewportCoords, tupleToCoors, viewportCoordsToSceneCoords, wrapEvent, updateObject, updateActiveTool, getShortcutKey, isTransparent, easeToValuesRAF, muteFSAbortError, isTestEnv, easeOut, updateStable, addEventListener, normalizeEOL, getDateTime, isShallowEqual, arrayToMap, } from "../utils";
|
|
39
39
|
import { createSrcDoc, embeddableURLValidator, maybeParseEmbedSrc, getEmbedLink, } from "../element/embeddable";
|
|
@@ -45,12 +45,12 @@ import { dataURLToFile, generateIdFromFile, getDataURL, getFileFromEvent, ImageU
|
|
|
45
45
|
import { getInitializedImageElements, loadHTMLImageElement, normalizeSVG, updateImageCache as _updateImageCache, } from "../element/image";
|
|
46
46
|
import throttle from "lodash.throttle";
|
|
47
47
|
import { fileOpen } from "../data/filesystem";
|
|
48
|
-
import { bindTextToShapeAfterDuplication, getApproxMinLineHeight, getApproxMinLineWidth, getBoundTextElement, getContainerCenter, getContainerElement,
|
|
48
|
+
import { bindTextToShapeAfterDuplication, getApproxMinLineHeight, getApproxMinLineWidth, getBoundTextElement, getContainerCenter, getContainerElement, getLineHeightInPx, getMinTextElementWidth, isMeasureTextSupported, isValidTextContainer, measureText, wrapText, } from "../element/textElement";
|
|
49
49
|
import { showHyperlinkTooltip, hideHyperlinkToolip, Hyperlink, } from "../components/hyperlink/Hyperlink";
|
|
50
50
|
import { isLocalLink, normalizeLink, toValidURL } from "../data/url";
|
|
51
51
|
import { shouldShowBoundingBox } from "../element/transformHandles";
|
|
52
52
|
import { actionUnlockAllElements } from "../actions/actionElementLock";
|
|
53
|
-
import { Fonts } from "../
|
|
53
|
+
import { Fonts, getLineHeight } from "../fonts";
|
|
54
54
|
import { getFrameChildren, isCursorInFrame, bindElementsToFramesAfterDuplication, addElementsToFrame, replaceAllElementsInFrame, removeElementsFromFrame, getElementsInResizingFrame, getElementsInNewFrame, getContainingFrame, elementOverlapsWithFrame, updateFrameMembershipOfSelectedElements, isElementInFrame, getFrameLikeTitle, getElementsOverlappingFrame, filterElementsEligibleAsFrameChildren, } from "../frame";
|
|
55
55
|
import { excludeElementsInFramesFromSelection, makeNextSelectedElementIds, } from "../scene/selection";
|
|
56
56
|
import { actionPaste } from "../actions/actionClipboard";
|
|
@@ -85,7 +85,7 @@ import { AnimatedTrail } from "../animated-trail";
|
|
|
85
85
|
import { LaserTrails } from "../laser-trails";
|
|
86
86
|
import { withBatchedUpdates, withBatchedUpdatesThrottled } from "../reactUtils";
|
|
87
87
|
import { getRenderOpacity } from "../renderer/renderElement";
|
|
88
|
-
import { hitElementBoundText, hitElementBoundingBoxOnly, hitElementItself,
|
|
88
|
+
import { hitElementBoundText, hitElementBoundingBoxOnly, hitElementItself, } from "../element/collision";
|
|
89
89
|
import { textWysiwyg } from "../element/textWysiwyg";
|
|
90
90
|
import { isOverScrollBars } from "../scene/scrollbars";
|
|
91
91
|
import { syncInvalidIndices, syncMovedIndices } from "../fractionalIndex";
|
|
@@ -94,6 +94,7 @@ import { getShortcutFromShortcutName } from "../actions/shortcuts";
|
|
|
94
94
|
import { actionTextAutoResize } from "../actions/actionTextAutoResize";
|
|
95
95
|
import { getVisibleSceneBounds } from "../element/bounds";
|
|
96
96
|
import { isMaybeMermaidDefinition } from "../mermaid";
|
|
97
|
+
import { mutateElbowArrow } from "../element/routing";
|
|
97
98
|
const AppContext = React.createContext(null);
|
|
98
99
|
const AppPropsContext = React.createContext(null);
|
|
99
100
|
const deviceContextInitialValue = {
|
|
@@ -166,8 +167,8 @@ class App extends React.Component {
|
|
|
166
167
|
device = deviceContextInitialValue;
|
|
167
168
|
excalidrawContainerRef = React.createRef();
|
|
168
169
|
scene;
|
|
169
|
-
renderer;
|
|
170
170
|
fonts;
|
|
171
|
+
renderer;
|
|
171
172
|
resizeObserver;
|
|
172
173
|
nearestScrollableContainer;
|
|
173
174
|
library;
|
|
@@ -701,15 +702,7 @@ class App extends React.Component {
|
|
|
701
702
|
return null;
|
|
702
703
|
}
|
|
703
704
|
const isDarkTheme = this.state.theme === THEME.DARK;
|
|
704
|
-
let frameIndex = 0;
|
|
705
|
-
let magicFrameIndex = 0;
|
|
706
705
|
return this.scene.getNonDeletedFramesLikes().map((f) => {
|
|
707
|
-
if (isFrameElement(f)) {
|
|
708
|
-
frameIndex++;
|
|
709
|
-
}
|
|
710
|
-
else {
|
|
711
|
-
magicFrameIndex++;
|
|
712
|
-
}
|
|
713
706
|
if (!isElementInViewport(f, this.canvas.width / window.devicePixelRatio, this.canvas.height / window.devicePixelRatio, {
|
|
714
707
|
offsetLeft: this.state.offsetLeft,
|
|
715
708
|
offsetTop: this.state.offsetTop,
|
|
@@ -727,7 +720,7 @@ class App extends React.Component {
|
|
|
727
720
|
this.setState({ editingFrame: null });
|
|
728
721
|
};
|
|
729
722
|
let frameNameJSX;
|
|
730
|
-
const frameName = getFrameLikeTitle(f
|
|
723
|
+
const frameName = getFrameLikeTitle(f);
|
|
731
724
|
if (f.id === this.state.editingFrame) {
|
|
732
725
|
const frameNameInEdit = frameName;
|
|
733
726
|
frameNameJSX = (_jsx("input", { autoFocus: true, value: frameNameInEdit, onChange: (e) => {
|
|
@@ -1181,6 +1174,13 @@ class App extends React.Component {
|
|
|
1181
1174
|
keepOpenOnAlt: false,
|
|
1182
1175
|
});
|
|
1183
1176
|
};
|
|
1177
|
+
dismissLinearEditor = () => {
|
|
1178
|
+
setTimeout(() => {
|
|
1179
|
+
this.setState({
|
|
1180
|
+
editingLinearElement: null,
|
|
1181
|
+
});
|
|
1182
|
+
});
|
|
1183
|
+
};
|
|
1184
1184
|
syncActionResult = withBatchedUpdates((actionResult) => {
|
|
1185
1185
|
if (this.unmounted || actionResult === false) {
|
|
1186
1186
|
return;
|
|
@@ -1305,7 +1305,12 @@ class App extends React.Component {
|
|
|
1305
1305
|
}
|
|
1306
1306
|
let initialData = null;
|
|
1307
1307
|
try {
|
|
1308
|
-
|
|
1308
|
+
if (typeof this.props.initialData === "function") {
|
|
1309
|
+
initialData = (await this.props.initialData()) || null;
|
|
1310
|
+
}
|
|
1311
|
+
else {
|
|
1312
|
+
initialData = (await this.props.initialData) || null;
|
|
1313
|
+
}
|
|
1309
1314
|
if (initialData?.libraryItems) {
|
|
1310
1315
|
this.library
|
|
1311
1316
|
.updateLibrary({
|
|
@@ -1353,17 +1358,17 @@ class App extends React.Component {
|
|
|
1353
1358
|
}),
|
|
1354
1359
|
};
|
|
1355
1360
|
}
|
|
1356
|
-
// FontFaceSet loadingdone event we listen on may not always fire
|
|
1357
|
-
// (looking at you Safari), so on init we manually load fonts for current
|
|
1358
|
-
// text elements on canvas, and rerender them once done. This also
|
|
1359
|
-
// seems faster even in browsers that do fire the loadingdone event.
|
|
1360
|
-
this.fonts.loadFontsForElements(scene.elements);
|
|
1361
1361
|
this.resetStore();
|
|
1362
1362
|
this.resetHistory();
|
|
1363
1363
|
this.syncActionResult({
|
|
1364
1364
|
...scene,
|
|
1365
1365
|
storeAction: StoreAction.UPDATE,
|
|
1366
1366
|
});
|
|
1367
|
+
// FontFaceSet loadingdone event we listen on may not always
|
|
1368
|
+
// fire (looking at you Safari), so on init we manually load all
|
|
1369
|
+
// fonts and rerender scene text elements once done. This also
|
|
1370
|
+
// seems faster even in browsers that do fire the loadingdone event.
|
|
1371
|
+
this.fonts.loadSceneFonts();
|
|
1367
1372
|
};
|
|
1368
1373
|
isMobileBreakpoint = (width, height) => {
|
|
1369
1374
|
return (width < MQ_MAX_WIDTH_PORTRAIT ||
|
|
@@ -1437,6 +1442,10 @@ class App extends React.Component {
|
|
|
1437
1442
|
configurable: true,
|
|
1438
1443
|
value: this.store,
|
|
1439
1444
|
},
|
|
1445
|
+
fonts: {
|
|
1446
|
+
configurable: true,
|
|
1447
|
+
value: this.fonts,
|
|
1448
|
+
},
|
|
1440
1449
|
});
|
|
1441
1450
|
}
|
|
1442
1451
|
this.store.onStoreIncrementEmitter.on((increment) => {
|
|
@@ -1478,7 +1487,9 @@ class App extends React.Component {
|
|
|
1478
1487
|
}
|
|
1479
1488
|
}
|
|
1480
1489
|
componentWillUnmount() {
|
|
1490
|
+
window.launchQueue?.setConsumer(() => { });
|
|
1481
1491
|
this.renderer.destroy();
|
|
1492
|
+
this.scene.destroy();
|
|
1482
1493
|
this.scene = new Scene();
|
|
1483
1494
|
this.fonts = new Fonts({ scene: this.scene });
|
|
1484
1495
|
this.renderer = new Renderer(this.scene);
|
|
@@ -1487,7 +1498,6 @@ class App extends React.Component {
|
|
|
1487
1498
|
this.resizeObserver?.disconnect();
|
|
1488
1499
|
this.unmounted = true;
|
|
1489
1500
|
this.removeEventListeners();
|
|
1490
|
-
this.scene.destroy();
|
|
1491
1501
|
this.library.destroy();
|
|
1492
1502
|
this.laserTrails.stop();
|
|
1493
1503
|
this.eraserTrail.stop();
|
|
@@ -1540,7 +1550,7 @@ class App extends React.Component {
|
|
|
1540
1550
|
// rerender text elements on font load to fix #637 && #1553
|
|
1541
1551
|
addEventListener(document.fonts, "loadingdone", (event) => {
|
|
1542
1552
|
const loadedFontFaces = event.fontfaces;
|
|
1543
|
-
this.fonts.
|
|
1553
|
+
this.fonts.onLoaded(loadedFontFaces);
|
|
1544
1554
|
}),
|
|
1545
1555
|
// Safari-only desktop pinch zoom
|
|
1546
1556
|
addEventListener(document, EVENT.GESTURE_START, this.onGestureStart, false), addEventListener(document, EVENT.GESTURE_CHANGE, this.onGestureChange, false), addEventListener(document, EVENT.GESTURE_END, this.onGestureEnd, false), addEventListener(window, EVENT.FOCUS, () => {
|
|
@@ -1665,7 +1675,7 @@ class App extends React.Component {
|
|
|
1665
1675
|
multiElement != null &&
|
|
1666
1676
|
isBindingEnabled(this.state) &&
|
|
1667
1677
|
isBindingElement(multiElement, false)) {
|
|
1668
|
-
maybeBindLinearElement(multiElement, this.state, tupleToCoors(LinearElementEditor.getPointAtIndexGlobalCoordinates(multiElement, -1, nonDeletedElementsMap)), this);
|
|
1678
|
+
maybeBindLinearElement(multiElement, this.state, tupleToCoors(LinearElementEditor.getPointAtIndexGlobalCoordinates(multiElement, -1, nonDeletedElementsMap)), this.scene.getNonDeletedElementsMap(), this.scene.getNonDeletedElements());
|
|
1669
1679
|
}
|
|
1670
1680
|
this.store.commit(elementsMap, this.state);
|
|
1671
1681
|
// Do not notify consumers if we're still loading the scene. Among other
|
|
@@ -1857,9 +1867,7 @@ class App extends React.Component {
|
|
|
1857
1867
|
if (data.text && isMaybeMermaidDefinition(data.text)) {
|
|
1858
1868
|
const api = await import("@excalidraw/mermaid-to-excalidraw");
|
|
1859
1869
|
try {
|
|
1860
|
-
const { elements: skeletonElements, files } = await api.parseMermaidToExcalidraw(data.text
|
|
1861
|
-
fontSize: DEFAULT_FONT_SIZE,
|
|
1862
|
-
});
|
|
1870
|
+
const { elements: skeletonElements, files } = await api.parseMermaidToExcalidraw(data.text);
|
|
1863
1871
|
const elements = convertToExcalidrawElements(skeletonElements, {
|
|
1864
1872
|
regenerateIds: true,
|
|
1865
1873
|
});
|
|
@@ -2086,7 +2094,7 @@ class App extends React.Component {
|
|
|
2086
2094
|
fontSize: textElementProps.fontSize,
|
|
2087
2095
|
fontFamily: textElementProps.fontFamily,
|
|
2088
2096
|
});
|
|
2089
|
-
const lineHeight =
|
|
2097
|
+
const lineHeight = getLineHeight(textElementProps.fontFamily);
|
|
2090
2098
|
const [x1, , x2] = getVisibleSceneBounds(this.state);
|
|
2091
2099
|
// long texts should not go beyond 800 pixels in width nor should it go below 200 px
|
|
2092
2100
|
const maxTextWidth = Math.max(Math.min((x2 - x1) * 0.5, 800), 200);
|
|
@@ -2101,11 +2109,11 @@ class App extends React.Component {
|
|
|
2101
2109
|
y: currentY,
|
|
2102
2110
|
});
|
|
2103
2111
|
let metrics = measureText(originalText, fontString, lineHeight);
|
|
2104
|
-
const
|
|
2105
|
-
const text =
|
|
2112
|
+
const isTextUnwrapped = metrics.width > maxTextWidth;
|
|
2113
|
+
const text = isTextUnwrapped
|
|
2106
2114
|
? wrapText(originalText, fontString, maxTextWidth)
|
|
2107
2115
|
: originalText;
|
|
2108
|
-
metrics =
|
|
2116
|
+
metrics = isTextUnwrapped
|
|
2109
2117
|
? measureText(text, fontString, lineHeight)
|
|
2110
2118
|
: metrics;
|
|
2111
2119
|
const startX = x - metrics.width / 2;
|
|
@@ -2117,7 +2125,7 @@ class App extends React.Component {
|
|
|
2117
2125
|
text,
|
|
2118
2126
|
originalText,
|
|
2119
2127
|
lineHeight,
|
|
2120
|
-
autoResize: !
|
|
2128
|
+
autoResize: !isTextUnwrapped,
|
|
2121
2129
|
frameId: topLayerFrame ? topLayerFrame.id : null,
|
|
2122
2130
|
});
|
|
2123
2131
|
acc.push(element);
|
|
@@ -2510,13 +2518,23 @@ class App extends React.Component {
|
|
|
2510
2518
|
this.setState({ isBindingEnabled: false });
|
|
2511
2519
|
}
|
|
2512
2520
|
if (isArrowKey(event.key)) {
|
|
2513
|
-
const
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2521
|
+
const selectedElements = this.scene.getSelectedElements({
|
|
2522
|
+
selectedElementIds: this.state.selectedElementIds,
|
|
2523
|
+
includeBoundTextElement: true,
|
|
2524
|
+
includeElementsInFrames: true,
|
|
2525
|
+
});
|
|
2526
|
+
const elbowArrow = selectedElements.find(isElbowArrow);
|
|
2527
|
+
const step = elbowArrow
|
|
2528
|
+
? elbowArrow.startBinding || elbowArrow.endBinding
|
|
2529
|
+
? 0
|
|
2530
|
+
: ELEMENT_TRANSLATE_AMOUNT
|
|
2531
|
+
: (this.state.gridSize &&
|
|
2532
|
+
(event.shiftKey
|
|
2533
|
+
? ELEMENT_TRANSLATE_AMOUNT
|
|
2534
|
+
: this.state.gridSize)) ||
|
|
2535
|
+
(event.shiftKey
|
|
2536
|
+
? ELEMENT_SHIFT_TRANSLATE_AMOUNT
|
|
2537
|
+
: ELEMENT_TRANSLATE_AMOUNT);
|
|
2520
2538
|
let offsetX = 0;
|
|
2521
2539
|
let offsetY = 0;
|
|
2522
2540
|
if (event.key === KEYS.ARROW_LEFT) {
|
|
@@ -2531,22 +2549,17 @@ class App extends React.Component {
|
|
|
2531
2549
|
else if (event.key === KEYS.ARROW_DOWN) {
|
|
2532
2550
|
offsetY = step;
|
|
2533
2551
|
}
|
|
2534
|
-
const selectedElements = this.scene.getSelectedElements({
|
|
2535
|
-
selectedElementIds: this.state.selectedElementIds,
|
|
2536
|
-
includeBoundTextElement: true,
|
|
2537
|
-
includeElementsInFrames: true,
|
|
2538
|
-
});
|
|
2539
2552
|
selectedElements.forEach((element) => {
|
|
2540
2553
|
mutateElement(element, {
|
|
2541
2554
|
x: element.x + offsetX,
|
|
2542
2555
|
y: element.y + offsetY,
|
|
2543
2556
|
});
|
|
2544
|
-
updateBoundElements(element, this.scene.getNonDeletedElementsMap(), {
|
|
2557
|
+
updateBoundElements(element, this.scene.getNonDeletedElementsMap(), this.scene, {
|
|
2545
2558
|
simultaneouslyUpdated: selectedElements,
|
|
2546
2559
|
});
|
|
2547
2560
|
});
|
|
2548
2561
|
this.setState({
|
|
2549
|
-
suggestedBindings: getSuggestedBindingsForArrows(selectedElements, this),
|
|
2562
|
+
suggestedBindings: getSuggestedBindingsForArrows(selectedElements.filter((element) => element.id !== elbowArrow?.id || step !== 0), this.scene.getNonDeletedElementsMap()),
|
|
2550
2563
|
});
|
|
2551
2564
|
event.preventDefault();
|
|
2552
2565
|
}
|
|
@@ -2560,9 +2573,11 @@ class App extends React.Component {
|
|
|
2560
2573
|
this.state.editingLinearElement.elementId !==
|
|
2561
2574
|
selectedElements[0].id) {
|
|
2562
2575
|
this.store.shouldCaptureIncrement();
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2576
|
+
if (!isElbowArrow(selectedElement)) {
|
|
2577
|
+
this.setState({
|
|
2578
|
+
editingLinearElement: new LinearElementEditor(selectedElement),
|
|
2579
|
+
});
|
|
2580
|
+
}
|
|
2566
2581
|
}
|
|
2567
2582
|
}
|
|
2568
2583
|
}
|
|
@@ -2599,6 +2614,15 @@ class App extends React.Component {
|
|
|
2599
2614
|
if (this.state.activeTool.type !== shape) {
|
|
2600
2615
|
trackEvent("toolbar", shape, `keyboard (${this.device.editor.isMobile ? "mobile" : "desktop"})`);
|
|
2601
2616
|
}
|
|
2617
|
+
if (shape === "arrow" && this.state.activeTool.type === "arrow") {
|
|
2618
|
+
this.setState((prevState) => ({
|
|
2619
|
+
currentItemArrowType: prevState.currentItemArrowType === ARROW_TYPE.sharp
|
|
2620
|
+
? ARROW_TYPE.round
|
|
2621
|
+
: prevState.currentItemArrowType === ARROW_TYPE.round
|
|
2622
|
+
? ARROW_TYPE.elbow
|
|
2623
|
+
: ARROW_TYPE.sharp,
|
|
2624
|
+
}));
|
|
2625
|
+
}
|
|
2602
2626
|
this.setActiveTool({ type: shape });
|
|
2603
2627
|
event.stopPropagation();
|
|
2604
2628
|
}
|
|
@@ -2631,6 +2655,21 @@ class App extends React.Component {
|
|
|
2631
2655
|
event.stopPropagation();
|
|
2632
2656
|
}
|
|
2633
2657
|
}
|
|
2658
|
+
if (!event[KEYS.CTRL_OR_CMD] &&
|
|
2659
|
+
event.shiftKey &&
|
|
2660
|
+
event.key.toLowerCase() === KEYS.F) {
|
|
2661
|
+
const selectedElements = this.scene.getSelectedElements(this.state);
|
|
2662
|
+
if (this.state.activeTool.type === "selection" &&
|
|
2663
|
+
!selectedElements.length) {
|
|
2664
|
+
return;
|
|
2665
|
+
}
|
|
2666
|
+
if (this.state.activeTool.type === "text" ||
|
|
2667
|
+
selectedElements.find((element) => isTextElement(element) ||
|
|
2668
|
+
getBoundTextElement(element, this.scene.getNonDeletedElementsMap()))) {
|
|
2669
|
+
event.preventDefault();
|
|
2670
|
+
this.setState({ openPopup: "fontFamily" });
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2634
2673
|
if (event.key === KEYS.K && !event.altKey && !event[KEYS.CTRL_OR_CMD]) {
|
|
2635
2674
|
if (this.state.activeTool.type === "laser") {
|
|
2636
2675
|
this.setActiveTool({ type: "selection" });
|
|
@@ -2685,7 +2724,7 @@ class App extends React.Component {
|
|
|
2685
2724
|
this.setState({ isBindingEnabled: true });
|
|
2686
2725
|
}
|
|
2687
2726
|
if (isArrowKey(event.key)) {
|
|
2688
|
-
bindOrUnbindLinearElements(this.scene.getSelectedElements(this.state).filter(isLinearElement), this, isBindingEnabled(this.state), this.state.selectedLinearElement?.selectedPointsIndices ?? []);
|
|
2727
|
+
bindOrUnbindLinearElements(this.scene.getSelectedElements(this.state).filter(isLinearElement), this.scene.getNonDeletedElementsMap(), this.scene.getNonDeletedElements(), this.scene, isBindingEnabled(this.state), this.state.selectedLinearElement?.selectedPointsIndices ?? []);
|
|
2689
2728
|
this.setState({ suggestedBindings: [] });
|
|
2690
2729
|
}
|
|
2691
2730
|
});
|
|
@@ -2855,7 +2894,7 @@ class App extends React.Component {
|
|
|
2855
2894
|
onChange: withBatchedUpdates((nextOriginalText) => {
|
|
2856
2895
|
updateElement(nextOriginalText, false);
|
|
2857
2896
|
if (isNonDeletedElement(element)) {
|
|
2858
|
-
updateBoundElements(element, elementsMap);
|
|
2897
|
+
updateBoundElements(element, elementsMap, this.scene);
|
|
2859
2898
|
}
|
|
2860
2899
|
}),
|
|
2861
2900
|
onSubmit: withBatchedUpdates(({ viaKeyboard, nextOriginalText }) => {
|
|
@@ -2923,57 +2962,6 @@ class App extends React.Component {
|
|
|
2923
2962
|
}
|
|
2924
2963
|
return null;
|
|
2925
2964
|
}
|
|
2926
|
-
/**
|
|
2927
|
-
* get the pure geometric shape of an excalidraw element
|
|
2928
|
-
* which is then used for hit detection
|
|
2929
|
-
*/
|
|
2930
|
-
getElementShape(element) {
|
|
2931
|
-
switch (element.type) {
|
|
2932
|
-
case "rectangle":
|
|
2933
|
-
case "diamond":
|
|
2934
|
-
case "frame":
|
|
2935
|
-
case "magicframe":
|
|
2936
|
-
case "embeddable":
|
|
2937
|
-
case "image":
|
|
2938
|
-
case "iframe":
|
|
2939
|
-
case "text":
|
|
2940
|
-
case "selection":
|
|
2941
|
-
return getPolygonShape(element);
|
|
2942
|
-
case "arrow":
|
|
2943
|
-
case "line": {
|
|
2944
|
-
const roughShape = ShapeCache.get(element)?.[0] ??
|
|
2945
|
-
ShapeCache.generateElementShape(element, null)[0];
|
|
2946
|
-
const [, , , , cx, cy] = getElementAbsoluteCoords(element, this.scene.getNonDeletedElementsMap());
|
|
2947
|
-
return shouldTestInside(element)
|
|
2948
|
-
? getClosedCurveShape(element, roughShape, [element.x, element.y], element.angle, [cx, cy])
|
|
2949
|
-
: getCurveShape(roughShape, [element.x, element.y], element.angle, [
|
|
2950
|
-
cx,
|
|
2951
|
-
cy,
|
|
2952
|
-
]);
|
|
2953
|
-
}
|
|
2954
|
-
case "ellipse":
|
|
2955
|
-
return getEllipseShape(element);
|
|
2956
|
-
case "freedraw": {
|
|
2957
|
-
const [, , , , cx, cy] = getElementAbsoluteCoords(element, this.scene.getNonDeletedElementsMap());
|
|
2958
|
-
return getFreedrawShape(element, [cx, cy], shouldTestInside(element));
|
|
2959
|
-
}
|
|
2960
|
-
}
|
|
2961
|
-
}
|
|
2962
|
-
getBoundTextShape(element) {
|
|
2963
|
-
const boundTextElement = getBoundTextElement(element, this.scene.getNonDeletedElementsMap());
|
|
2964
|
-
if (boundTextElement) {
|
|
2965
|
-
if (element.type === "arrow") {
|
|
2966
|
-
return this.getElementShape({
|
|
2967
|
-
...boundTextElement,
|
|
2968
|
-
// arrow's bound text accurate position is not stored in the element's property
|
|
2969
|
-
// but rather calculated and returned from the following static method
|
|
2970
|
-
...LinearElementEditor.getBoundTextElementPosition(element, boundTextElement, this.scene.getNonDeletedElementsMap()),
|
|
2971
|
-
});
|
|
2972
|
-
}
|
|
2973
|
-
return this.getElementShape(boundTextElement);
|
|
2974
|
-
}
|
|
2975
|
-
return null;
|
|
2976
|
-
}
|
|
2977
2965
|
getElementAtPosition(x, y, opts) {
|
|
2978
2966
|
const allHitElements = this.getElementsAtPosition(x, y, opts?.includeBoundTextElement, opts?.includeLockedElements);
|
|
2979
2967
|
if (allHitElements.length > 1) {
|
|
@@ -2991,7 +2979,7 @@ class App extends React.Component {
|
|
|
2991
2979
|
x,
|
|
2992
2980
|
y,
|
|
2993
2981
|
element: elementWithHighestZIndex,
|
|
2994
|
-
shape: this.
|
|
2982
|
+
shape: getElementShape(elementWithHighestZIndex, this.scene.getNonDeletedElementsMap()),
|
|
2995
2983
|
// when overlapping, we would like to be more precise
|
|
2996
2984
|
// this also avoids the need to update past tests
|
|
2997
2985
|
threshold: this.getElementHitThreshold() / 2,
|
|
@@ -3053,7 +3041,7 @@ class App extends React.Component {
|
|
|
3053
3041
|
return isPointInShape([x, y], selectionShape);
|
|
3054
3042
|
}
|
|
3055
3043
|
// take bound text element into consideration for hit collision as well
|
|
3056
|
-
const hitBoundTextOfElement = hitElementBoundText(x, y, this.
|
|
3044
|
+
const hitBoundTextOfElement = hitElementBoundText(x, y, getBoundTextShape(element, this.scene.getNonDeletedElementsMap()));
|
|
3057
3045
|
if (hitBoundTextOfElement) {
|
|
3058
3046
|
return true;
|
|
3059
3047
|
}
|
|
@@ -3061,7 +3049,7 @@ class App extends React.Component {
|
|
|
3061
3049
|
x,
|
|
3062
3050
|
y,
|
|
3063
3051
|
element,
|
|
3064
|
-
shape: this.
|
|
3052
|
+
shape: getElementShape(element, this.scene.getNonDeletedElementsMap()),
|
|
3065
3053
|
threshold: this.getElementHitThreshold(),
|
|
3066
3054
|
frameNameBound: isFrameLikeElement(element)
|
|
3067
3055
|
? this.frameNameBoundsCache.get(element)
|
|
@@ -3088,7 +3076,7 @@ class App extends React.Component {
|
|
|
3088
3076
|
x,
|
|
3089
3077
|
y,
|
|
3090
3078
|
element: elements[index],
|
|
3091
|
-
shape:
|
|
3079
|
+
shape: getElementShape(elements[index], this.scene.getNonDeletedElementsMap()),
|
|
3092
3080
|
threshold: this.getElementHitThreshold(),
|
|
3093
3081
|
})) {
|
|
3094
3082
|
hitElement = elements[index];
|
|
@@ -3128,7 +3116,7 @@ class App extends React.Component {
|
|
|
3128
3116
|
existingTextElement = this.getTextElementAtPosition(sceneX, sceneY);
|
|
3129
3117
|
}
|
|
3130
3118
|
const fontFamily = existingTextElement?.fontFamily || this.state.currentItemFontFamily;
|
|
3131
|
-
const lineHeight = existingTextElement?.lineHeight ||
|
|
3119
|
+
const lineHeight = existingTextElement?.lineHeight || getLineHeight(fontFamily);
|
|
3132
3120
|
const fontSize = this.state.currentItemFontSize;
|
|
3133
3121
|
if (!existingTextElement &&
|
|
3134
3122
|
shouldBindToContainer &&
|
|
@@ -3228,7 +3216,9 @@ class App extends React.Component {
|
|
|
3228
3216
|
if (selectedElements.length === 1 && isLinearElement(selectedElements[0])) {
|
|
3229
3217
|
if (event[KEYS.CTRL_OR_CMD] &&
|
|
3230
3218
|
(!this.state.editingLinearElement ||
|
|
3231
|
-
this.state.editingLinearElement.elementId !==
|
|
3219
|
+
this.state.editingLinearElement.elementId !==
|
|
3220
|
+
selectedElements[0].id) &&
|
|
3221
|
+
!isElbowArrow(selectedElements[0])) {
|
|
3232
3222
|
this.store.shouldCaptureIncrement();
|
|
3233
3223
|
this.setState({
|
|
3234
3224
|
editingLinearElement: new LinearElementEditor(selectedElements[0]),
|
|
@@ -3272,7 +3262,7 @@ class App extends React.Component {
|
|
|
3272
3262
|
x: sceneX,
|
|
3273
3263
|
y: sceneY,
|
|
3274
3264
|
element: container,
|
|
3275
|
-
shape: this.
|
|
3265
|
+
shape: getElementShape(container, this.scene.getNonDeletedElementsMap()),
|
|
3276
3266
|
threshold: this.getElementHitThreshold(),
|
|
3277
3267
|
})) {
|
|
3278
3268
|
const midPoint = getContainerCenter(container, this.state, this.scene.getNonDeletedElementsMap());
|
|
@@ -3446,7 +3436,7 @@ class App extends React.Component {
|
|
|
3446
3436
|
}
|
|
3447
3437
|
if (this.state.editingLinearElement &&
|
|
3448
3438
|
!this.state.editingLinearElement.isDragging) {
|
|
3449
|
-
const editingLinearElement = LinearElementEditor.handlePointerMove(event, scenePointerX, scenePointerY, this.state, this.scene
|
|
3439
|
+
const editingLinearElement = LinearElementEditor.handlePointerMove(event, scenePointerX, scenePointerY, this.state, this.scene);
|
|
3450
3440
|
if (editingLinearElement &&
|
|
3451
3441
|
editingLinearElement !== this.state.editingLinearElement) {
|
|
3452
3442
|
// Since we are reading from previous state which is not possible with
|
|
@@ -3508,7 +3498,9 @@ class App extends React.Component {
|
|
|
3508
3498
|
});
|
|
3509
3499
|
}
|
|
3510
3500
|
else {
|
|
3511
|
-
const [gridX, gridY] = getGridPoint(scenePointerX, scenePointerY, event[KEYS.CTRL_OR_CMD]
|
|
3501
|
+
const [gridX, gridY] = getGridPoint(scenePointerX, scenePointerY, event[KEYS.CTRL_OR_CMD] || isElbowArrow(multiElement)
|
|
3502
|
+
? null
|
|
3503
|
+
: this.state.gridSize);
|
|
3512
3504
|
const [lastCommittedX, lastCommittedY] = multiElement?.lastCommittedPoint ?? [0, 0];
|
|
3513
3505
|
let dxFromLastCommitted = gridX - rx - lastCommittedX;
|
|
3514
3506
|
let dyFromLastCommitted = gridY - ry - lastCommittedY;
|
|
@@ -3523,16 +3515,29 @@ class App extends React.Component {
|
|
|
3523
3515
|
if (isPathALoop(points, this.state.zoom.value)) {
|
|
3524
3516
|
setCursor(this.interactiveCanvas, CURSOR_TYPE.POINTER);
|
|
3525
3517
|
}
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
points: [
|
|
3518
|
+
if (isElbowArrow(multiElement)) {
|
|
3519
|
+
mutateElbowArrow(multiElement, this.scene, [
|
|
3529
3520
|
...points.slice(0, -1),
|
|
3530
3521
|
[
|
|
3531
3522
|
lastCommittedX + dxFromLastCommitted,
|
|
3532
3523
|
lastCommittedY + dyFromLastCommitted,
|
|
3533
3524
|
],
|
|
3534
|
-
],
|
|
3535
|
-
|
|
3525
|
+
], undefined, undefined, {
|
|
3526
|
+
isDragging: true,
|
|
3527
|
+
});
|
|
3528
|
+
}
|
|
3529
|
+
else {
|
|
3530
|
+
// update last uncommitted point
|
|
3531
|
+
mutateElement(multiElement, {
|
|
3532
|
+
points: [
|
|
3533
|
+
...points.slice(0, -1),
|
|
3534
|
+
[
|
|
3535
|
+
lastCommittedX + dxFromLastCommitted,
|
|
3536
|
+
lastCommittedY + dyFromLastCommitted,
|
|
3537
|
+
],
|
|
3538
|
+
],
|
|
3539
|
+
});
|
|
3540
|
+
}
|
|
3536
3541
|
}
|
|
3537
3542
|
return;
|
|
3538
3543
|
}
|
|
@@ -3553,8 +3558,9 @@ class App extends React.Component {
|
|
|
3553
3558
|
if (this.state.selectedLinearElement) {
|
|
3554
3559
|
this.handleHoverSelectedLinearElement(this.state.selectedLinearElement, scenePointerX, scenePointerY);
|
|
3555
3560
|
}
|
|
3556
|
-
if (!this.state.selectedLinearElement ||
|
|
3557
|
-
this.state.selectedLinearElement.hoverPointIndex === -1)
|
|
3561
|
+
if ((!this.state.selectedLinearElement ||
|
|
3562
|
+
this.state.selectedLinearElement.hoverPointIndex === -1) &&
|
|
3563
|
+
!(selectedElements.length === 1 && isElbowArrow(selectedElements[0]))) {
|
|
3558
3564
|
const elementWithTransformHandleType = getElementWithTransformHandleType(elements, this.state, scenePointerX, scenePointerY, this.state.zoom, event.pointerType, this.scene.getNonDeletedElementsMap(), this.device);
|
|
3559
3565
|
if (elementWithTransformHandleType &&
|
|
3560
3566
|
elementWithTransformHandleType.transformHandleType) {
|
|
@@ -3724,7 +3730,7 @@ class App extends React.Component {
|
|
|
3724
3730
|
x: scenePointerX,
|
|
3725
3731
|
y: scenePointerY,
|
|
3726
3732
|
element,
|
|
3727
|
-
shape: this.
|
|
3733
|
+
shape: getElementShape(element, this.scene.getNonDeletedElementsMap()),
|
|
3728
3734
|
})) {
|
|
3729
3735
|
hoverPointIndex = LinearElementEditor.getPointIndexUnderCursor(element, elementsMap, this.state.zoom, scenePointerX, scenePointerY);
|
|
3730
3736
|
segmentMidPointHoveredCoords =
|
|
@@ -3737,7 +3743,10 @@ class App extends React.Component {
|
|
|
3737
3743
|
}
|
|
3738
3744
|
}
|
|
3739
3745
|
else if (this.hitElement(scenePointerX, scenePointerY, element)) {
|
|
3740
|
-
|
|
3746
|
+
if (!isElbowArrow(element) ||
|
|
3747
|
+
!(element.startBinding || element.endBinding)) {
|
|
3748
|
+
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
|
3749
|
+
}
|
|
3741
3750
|
}
|
|
3742
3751
|
if (this.state.selectedLinearElement.hoverPointIndex !== hoverPointIndex) {
|
|
3743
3752
|
this.setState({
|
|
@@ -4150,10 +4159,13 @@ class App extends React.Component {
|
|
|
4150
4159
|
const origin = viewportCoordsToSceneCoords(event, this.state);
|
|
4151
4160
|
const selectedElements = this.scene.getSelectedElements(this.state);
|
|
4152
4161
|
const [minX, minY, maxX, maxY] = getCommonBounds(selectedElements);
|
|
4162
|
+
const isElbowArrowOnly = selectedElements.findIndex(isElbowArrow) === 0;
|
|
4153
4163
|
return {
|
|
4154
4164
|
origin,
|
|
4155
4165
|
withCmdOrCtrl: event[KEYS.CTRL_OR_CMD],
|
|
4156
|
-
originInGrid: tupleToCoors(getGridPoint(origin.x, origin.y, event[KEYS.CTRL_OR_CMD]
|
|
4166
|
+
originInGrid: tupleToCoors(getGridPoint(origin.x, origin.y, event[KEYS.CTRL_OR_CMD] || isElbowArrowOnly
|
|
4167
|
+
? null
|
|
4168
|
+
: this.state.gridSize)),
|
|
4157
4169
|
scrollbars: isOverScrollBars(currentScrollBars, event.clientX - this.state.offsetLeft, event.clientY - this.state.offsetTop),
|
|
4158
4170
|
// we need to duplicate because we'll be updating this state
|
|
4159
4171
|
lastCoords: { ...origin },
|
|
@@ -4270,7 +4282,7 @@ class App extends React.Component {
|
|
|
4270
4282
|
else {
|
|
4271
4283
|
if (this.state.selectedLinearElement) {
|
|
4272
4284
|
const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;
|
|
4273
|
-
const ret = LinearElementEditor.handlePointerDown(event, this.state, this.store, pointerDownState.origin, linearElementEditor, this);
|
|
4285
|
+
const ret = LinearElementEditor.handlePointerDown(event, this.state, this.store, pointerDownState.origin, linearElementEditor, this.scene);
|
|
4274
4286
|
if (ret.hitElement) {
|
|
4275
4287
|
pointerDownState.hit.element = ret.hitElement;
|
|
4276
4288
|
}
|
|
@@ -4510,7 +4522,7 @@ class App extends React.Component {
|
|
|
4510
4522
|
points: [[0, 0]],
|
|
4511
4523
|
pressures,
|
|
4512
4524
|
});
|
|
4513
|
-
const boundElement = getHoveredElementForBinding(pointerDownState.origin, this);
|
|
4525
|
+
const boundElement = getHoveredElementForBinding(pointerDownState.origin, this.scene.getNonDeletedElements(), this.scene.getNonDeletedElementsMap());
|
|
4514
4526
|
this.scene.insertElement(element);
|
|
4515
4527
|
this.setState({
|
|
4516
4528
|
draggingElement: element,
|
|
@@ -4616,6 +4628,15 @@ class App extends React.Component {
|
|
|
4616
4628
|
this.actionManager.executeAction(actionFinalize);
|
|
4617
4629
|
return;
|
|
4618
4630
|
}
|
|
4631
|
+
// Elbow arrows cannot be created by putting down points
|
|
4632
|
+
// only the start and end points can be defined
|
|
4633
|
+
if (isElbowArrow(multiElement) && multiElement.points.length > 1) {
|
|
4634
|
+
mutateElement(multiElement, {
|
|
4635
|
+
lastCommittedPoint: multiElement.points[multiElement.points.length - 1],
|
|
4636
|
+
});
|
|
4637
|
+
this.actionManager.executeAction(actionFinalize);
|
|
4638
|
+
return;
|
|
4639
|
+
}
|
|
4619
4640
|
const { x: rx, y: ry, lastCommittedPoint } = multiElement;
|
|
4620
4641
|
// clicking inside commit zone → finalize arrow
|
|
4621
4642
|
if (multiElement.points.length > 1 &&
|
|
@@ -4651,25 +4672,46 @@ class App extends React.Component {
|
|
|
4651
4672
|
const [startArrowhead, endArrowhead] = elementType === "arrow"
|
|
4652
4673
|
? [currentItemStartArrowhead, currentItemEndArrowhead]
|
|
4653
4674
|
: [null, null];
|
|
4654
|
-
const element =
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4675
|
+
const element = elementType === "arrow"
|
|
4676
|
+
? newArrowElement({
|
|
4677
|
+
type: elementType,
|
|
4678
|
+
x: gridX,
|
|
4679
|
+
y: gridY,
|
|
4680
|
+
strokeColor: this.state.currentItemStrokeColor,
|
|
4681
|
+
backgroundColor: this.state.currentItemBackgroundColor,
|
|
4682
|
+
fillStyle: this.state.currentItemFillStyle,
|
|
4683
|
+
strokeWidth: this.state.currentItemStrokeWidth,
|
|
4684
|
+
strokeStyle: this.state.currentItemStrokeStyle,
|
|
4685
|
+
roughness: this.state.currentItemRoughness,
|
|
4686
|
+
opacity: this.state.currentItemOpacity,
|
|
4687
|
+
roundness: this.state.currentItemArrowType === ARROW_TYPE.round
|
|
4688
|
+
? { type: ROUNDNESS.PROPORTIONAL_RADIUS }
|
|
4689
|
+
: // note, roundness doesn't have any effect for elbow arrows,
|
|
4690
|
+
// but it's best to set it to null as well
|
|
4691
|
+
null,
|
|
4692
|
+
startArrowhead,
|
|
4693
|
+
endArrowhead,
|
|
4694
|
+
locked: false,
|
|
4695
|
+
frameId: topLayerFrame ? topLayerFrame.id : null,
|
|
4696
|
+
elbowed: this.state.currentItemArrowType === ARROW_TYPE.elbow,
|
|
4697
|
+
})
|
|
4698
|
+
: newLinearElement({
|
|
4699
|
+
type: elementType,
|
|
4700
|
+
x: gridX,
|
|
4701
|
+
y: gridY,
|
|
4702
|
+
strokeColor: this.state.currentItemStrokeColor,
|
|
4703
|
+
backgroundColor: this.state.currentItemBackgroundColor,
|
|
4704
|
+
fillStyle: this.state.currentItemFillStyle,
|
|
4705
|
+
strokeWidth: this.state.currentItemStrokeWidth,
|
|
4706
|
+
strokeStyle: this.state.currentItemStrokeStyle,
|
|
4707
|
+
roughness: this.state.currentItemRoughness,
|
|
4708
|
+
opacity: this.state.currentItemOpacity,
|
|
4709
|
+
roundness: this.state.currentItemRoundness === "round"
|
|
4710
|
+
? { type: ROUNDNESS.PROPORTIONAL_RADIUS }
|
|
4711
|
+
: null,
|
|
4712
|
+
locked: false,
|
|
4713
|
+
frameId: topLayerFrame ? topLayerFrame.id : null,
|
|
4714
|
+
});
|
|
4673
4715
|
this.setState((prevState) => {
|
|
4674
4716
|
const nextSelectedElementIds = {
|
|
4675
4717
|
...prevState.selectedElementIds,
|
|
@@ -4682,7 +4724,7 @@ class App extends React.Component {
|
|
|
4682
4724
|
mutateElement(element, {
|
|
4683
4725
|
points: [...element.points, [0, 0]],
|
|
4684
4726
|
});
|
|
4685
|
-
const boundElement = getHoveredElementForBinding(pointerDownState.origin, this);
|
|
4727
|
+
const boundElement = getHoveredElementForBinding(pointerDownState.origin, this.scene.getNonDeletedElements(), this.scene.getNonDeletedElementsMap(), isElbowArrow(element));
|
|
4686
4728
|
this.scene.insertElement(element);
|
|
4687
4729
|
this.setState({
|
|
4688
4730
|
draggingElement: element,
|
|
@@ -4892,7 +4934,7 @@ class App extends React.Component {
|
|
|
4892
4934
|
}
|
|
4893
4935
|
const didDrag = LinearElementEditor.handlePointDragging(event, this.state, pointerCoords.x, pointerCoords.y, (element, pointsSceneCoords) => {
|
|
4894
4936
|
this.maybeSuggestBindingsForLinearElementAtCoords(element, pointsSceneCoords);
|
|
4895
|
-
}, linearElementEditor, this.scene
|
|
4937
|
+
}, linearElementEditor, this.scene);
|
|
4896
4938
|
if (didDrag) {
|
|
4897
4939
|
pointerDownState.lastCoords.x = pointerCoords.x;
|
|
4898
4940
|
pointerDownState.lastCoords.y = pointerCoords.y;
|
|
@@ -4978,10 +5020,14 @@ class App extends React.Component {
|
|
|
4978
5020
|
// when we're editing the name of a frame, we want the user to be
|
|
4979
5021
|
// able to select and interact with the text input
|
|
4980
5022
|
!this.state.editingFrame &&
|
|
4981
|
-
dragSelectedElements(pointerDownState, selectedElements, dragOffset, this.
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
5023
|
+
dragSelectedElements(pointerDownState, selectedElements, dragOffset, this.scene, snapOffset, event[KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);
|
|
5024
|
+
if (selectedElements.length !== 1 ||
|
|
5025
|
+
!isElbowArrow(selectedElements[0])) {
|
|
5026
|
+
this.setState({
|
|
5027
|
+
suggestedBindings: getSuggestedBindingsForArrows(selectedElements, this.scene.getNonDeletedElementsMap()),
|
|
5028
|
+
});
|
|
5029
|
+
}
|
|
5030
|
+
//}
|
|
4985
5031
|
// We duplicate the selected element if alt is pressed on pointer move
|
|
4986
5032
|
if (event.altKey && !pointerDownState.hit.hasBeenDuplicated) {
|
|
4987
5033
|
// Move the currently selected elements to the top of the z index stack, and
|
|
@@ -5074,6 +5120,11 @@ class App extends React.Component {
|
|
|
5074
5120
|
points: [...points, [dx, dy]],
|
|
5075
5121
|
});
|
|
5076
5122
|
}
|
|
5123
|
+
else if (points.length > 1 && isElbowArrow(draggingElement)) {
|
|
5124
|
+
mutateElbowArrow(draggingElement, this.scene, [...points.slice(0, -1), [dx, dy]], [0, 0], undefined, {
|
|
5125
|
+
isDragging: true,
|
|
5126
|
+
});
|
|
5127
|
+
}
|
|
5077
5128
|
else if (points.length === 2) {
|
|
5078
5129
|
mutateElement(draggingElement, {
|
|
5079
5130
|
points: [...points.slice(0, -1), [dx, dy]],
|
|
@@ -5217,7 +5268,7 @@ class App extends React.Component {
|
|
|
5217
5268
|
this.actionManager.executeAction(actionFinalize);
|
|
5218
5269
|
}
|
|
5219
5270
|
else {
|
|
5220
|
-
const editingLinearElement = LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state, this);
|
|
5271
|
+
const editingLinearElement = LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state, this.scene);
|
|
5221
5272
|
if (editingLinearElement !== this.state.editingLinearElement) {
|
|
5222
5273
|
this.setState({
|
|
5223
5274
|
editingLinearElement,
|
|
@@ -5236,11 +5287,11 @@ class App extends React.Component {
|
|
|
5236
5287
|
}
|
|
5237
5288
|
}
|
|
5238
5289
|
else {
|
|
5239
|
-
const linearElementEditor = LinearElementEditor.handlePointerUp(childEvent, this.state.selectedLinearElement, this.state, this);
|
|
5290
|
+
const linearElementEditor = LinearElementEditor.handlePointerUp(childEvent, this.state.selectedLinearElement, this.state, this.scene);
|
|
5240
5291
|
const { startBindingElement, endBindingElement } = linearElementEditor;
|
|
5241
5292
|
const element = this.scene.getElement(linearElementEditor.elementId);
|
|
5242
5293
|
if (isBindingElement(element)) {
|
|
5243
|
-
bindOrUnbindLinearElement(element, startBindingElement, endBindingElement, elementsMap);
|
|
5294
|
+
bindOrUnbindLinearElement(element, startBindingElement, endBindingElement, elementsMap, this.scene);
|
|
5244
5295
|
}
|
|
5245
5296
|
if (linearElementEditor !== this.state.selectedLinearElement) {
|
|
5246
5297
|
this.setState({
|
|
@@ -5328,7 +5379,7 @@ class App extends React.Component {
|
|
|
5328
5379
|
else if (pointerDownState.drag.hasOccurred && !multiElement) {
|
|
5329
5380
|
if (isBindingEnabled(this.state) &&
|
|
5330
5381
|
isBindingElement(draggingElement, false)) {
|
|
5331
|
-
maybeBindLinearElement(draggingElement, this.state, pointerCoords, this);
|
|
5382
|
+
maybeBindLinearElement(draggingElement, this.state, pointerCoords, this.scene.getNonDeletedElementsMap(), this.scene.getNonDeletedElements());
|
|
5332
5383
|
}
|
|
5333
5384
|
this.setState({ suggestedBindings: [], startBoundElement: null });
|
|
5334
5385
|
if (!activeTool.locked) {
|
|
@@ -5636,7 +5687,7 @@ class App extends React.Component {
|
|
|
5636
5687
|
x: pointerDownState.origin.x,
|
|
5637
5688
|
y: pointerDownState.origin.y,
|
|
5638
5689
|
element: hitElement,
|
|
5639
|
-
shape: this.
|
|
5690
|
+
shape: getElementShape(hitElement, this.scene.getNonDeletedElementsMap()),
|
|
5640
5691
|
threshold: this.getElementHitThreshold(),
|
|
5641
5692
|
frameNameBound: isFrameLikeElement(hitElement)
|
|
5642
5693
|
? this.frameNameBoundsCache.get(hitElement)
|
|
@@ -5685,7 +5736,7 @@ class App extends React.Component {
|
|
|
5685
5736
|
const linearElements = this.scene
|
|
5686
5737
|
.getSelectedElements(this.state)
|
|
5687
5738
|
.filter(isLinearElement);
|
|
5688
|
-
bindOrUnbindLinearElements(linearElements, this, isBindingEnabled(this.state), this.state.selectedLinearElement?.selectedPointsIndices ?? []);
|
|
5739
|
+
bindOrUnbindLinearElements(linearElements, this.scene.getNonDeletedElementsMap(), this.scene.getNonDeletedElements(), this.scene, isBindingEnabled(this.state), this.state.selectedLinearElement?.selectedPointsIndices ?? []);
|
|
5689
5740
|
}
|
|
5690
5741
|
if (activeTool.type === "laser") {
|
|
5691
5742
|
this.laserTrails.endPath();
|
|
@@ -6028,7 +6079,7 @@ class App extends React.Component {
|
|
|
6028
6079
|
}
|
|
6029
6080
|
};
|
|
6030
6081
|
maybeSuggestBindingAtCursor = (pointerCoords) => {
|
|
6031
|
-
const hoveredBindableElement = getHoveredElementForBinding(pointerCoords, this);
|
|
6082
|
+
const hoveredBindableElement = getHoveredElementForBinding(pointerCoords, this.scene.getNonDeletedElements(), this.scene.getNonDeletedElementsMap());
|
|
6032
6083
|
this.setState({
|
|
6033
6084
|
suggestedBindings: hoveredBindableElement != null ? [hoveredBindableElement] : [],
|
|
6034
6085
|
});
|
|
@@ -6043,7 +6094,7 @@ class App extends React.Component {
|
|
|
6043
6094
|
return;
|
|
6044
6095
|
}
|
|
6045
6096
|
const suggestedBindings = pointerCoords.reduce((acc, coords) => {
|
|
6046
|
-
const hoveredBindableElement = getHoveredElementForBinding(coords, this);
|
|
6097
|
+
const hoveredBindableElement = getHoveredElementForBinding(coords, this.scene.getNonDeletedElements(), this.scene.getNonDeletedElementsMap(), isArrowElement(linearElement) && isElbowArrow(linearElement));
|
|
6047
6098
|
if (hoveredBindableElement != null &&
|
|
6048
6099
|
!isLinearElementSimpleAndAlreadyBound(linearElement, oppositeBindingBoundElement?.id, hoveredBindableElement)) {
|
|
6049
6100
|
acc.push(hoveredBindableElement);
|
|
@@ -6373,8 +6424,8 @@ class App extends React.Component {
|
|
|
6373
6424
|
}
|
|
6374
6425
|
if (transformElements(pointerDownState.originalElements, transformHandleType, selectedElements, this.scene.getElementsMapIncludingDeleted(), shouldRotateWithDiscreteAngle(event), shouldResizeFromCenter(event), selectedElements.some((element) => isImageElement(element))
|
|
6375
6426
|
? !shouldMaintainAspectRatio(event)
|
|
6376
|
-
: shouldMaintainAspectRatio(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y)) {
|
|
6377
|
-
const suggestedBindings = getSuggestedBindingsForArrows(selectedElements, this);
|
|
6427
|
+
: shouldMaintainAspectRatio(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y, this.scene)) {
|
|
6428
|
+
const suggestedBindings = getSuggestedBindingsForArrows(selectedElements, this.scene.getNonDeletedElementsMap());
|
|
6378
6429
|
const elementsToHighlight = new Set();
|
|
6379
6430
|
selectedFrames.forEach((frame) => {
|
|
6380
6431
|
getElementsInResizingFrame(this.scene.getNonDeletedElements(), frame, this.state, this.scene.getNonDeletedElementsMap()).forEach((element) => elementsToHighlight.add(element));
|
|
@@ -6611,6 +6662,12 @@ export const createTestHook = () => {
|
|
|
6611
6662
|
return this.app?.scene.replaceAllElements(syncInvalidIndices(elements));
|
|
6612
6663
|
},
|
|
6613
6664
|
},
|
|
6665
|
+
scene: {
|
|
6666
|
+
configurable: true,
|
|
6667
|
+
get() {
|
|
6668
|
+
return this.app?.scene;
|
|
6669
|
+
},
|
|
6670
|
+
},
|
|
6614
6671
|
});
|
|
6615
6672
|
}
|
|
6616
6673
|
};
|