@excalidraw/excalidraw 0.17.1-1d71f84 → 0.17.1-1ed53b1
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 +14 -2
- package/dist/browser/dev/excalidraw-assets-dev/{blockDiagram-91b80b7a-ACFH36JV.js → blockDiagram-91b80b7a-H47FTXHA.js} +5 -5
- package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-b2a90758-QZ27YR47.js → c4Diagram-b2a90758-NNJK6GKC.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-HO2HMSK7.js → chunk-4KQVEBHW.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-USGV265L.js → chunk-53YI56GV.js} +4 -4
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-EDFX3S7X.js → chunk-A2WCJI4I.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-IX4V72YG.js → chunk-EFLPX7NE.js} +6 -6
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-AK7SWNLN.js → chunk-JKPJV7MZ.js} +6 -4
- package/dist/browser/dev/excalidraw-assets-dev/chunk-JKPJV7MZ.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-MXVETLVM.js → chunk-JYIQCNWV.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-YZIOORVX.js → chunk-LVIQQW6F.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-RWZVJAQU.js → chunk-OKAZAA6U.js} +4494 -2647
- package/dist/browser/dev/excalidraw-assets-dev/chunk-OKAZAA6U.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-6U7GQNJT.js → chunk-PXLO3FOU.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-7DACDEY3.js → chunk-TO2AW5PW.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-NJ77ZFNJ.js → chunk-VURILHLY.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-2T2GU7NF.js → chunk-ZAYGSUHF.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-Z3PH3V2B.js → chunk-ZQR5ML6Y.js} +26 -26
- package/dist/browser/dev/excalidraw-assets-dev/chunk-ZQR5ML6Y.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-30eddba6-QSLMH4JW.js → classDiagram-30eddba6-CUYIJICN.js} +5 -5
- package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-f2df5561-DY4DYQ5P.js → classDiagram-v2-f2df5561-K6WW6K73.js} +8 -8
- package/dist/browser/dev/excalidraw-assets-dev/{dist-Z46EOVOL.js → dist-ITJNUBZF.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{en-5TCZHGGJ.js → en-BF4XUPIZ.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-47591fe2-SOOJRTCB.js → erDiagram-47591fe2-XGAD7EEP.js} +4 -4
- package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-5540d9b9-AHGL4KPK.js → flowDiagram-5540d9b9-B6EOVNNO.js} +9 -9
- package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-3b53844e-56LDZZWY.js → flowDiagram-v2-3b53844e-NUG24FJH.js} +9 -9
- package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5fe447d6-27LUKRI6.js → flowchart-elk-definition-5fe447d6-25Y7PCBL.js} +5 -5
- package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-9a3bba1f-EHGYGNG6.js → ganttDiagram-9a3bba1f-GNL6ZDTC.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-96e6b4ee-AJQNBDW5.js → gitGraphDiagram-96e6b4ee-HNW52NVO.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{image-EDKQZH7Z.js → image-LVS32KQQ.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{image-OFRRV5MB.css → image-O66MQ7WQ.css} +1 -1
- package/dist/browser/dev/excalidraw-assets-dev/image-O66MQ7WQ.css.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-bcd20f53-SWLLQVES.js → infoDiagram-bcd20f53-FWEUVFLT.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-4fe6b3dc-7UAVCWOZ.js → journeyDiagram-4fe6b3dc-RZIUI7UG.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-f354de21-SROW5KGM.js → mindmap-definition-f354de21-GBVN45GU.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-79897490-QKCI6NCB.js → pieDiagram-79897490-ECENNII6.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-62f64e94-LNYJZFC5.js → quadrantDiagram-62f64e94-ZMEOFVNL.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-05bf5f74-ZZD7ZHFA.js → requirementDiagram-05bf5f74-FHZSFHCR.js} +4 -4
- package/dist/browser/dev/excalidraw-assets-dev/{sankeyDiagram-97764748-L75ZZ4UM.js → sankeyDiagram-97764748-VDKIKTA6.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-acc0e65c-6PCU7TDK.js → sequenceDiagram-acc0e65c-6JUSPVKX.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-0ff1cf1a-WM76WOPR.js → stateDiagram-0ff1cf1a-L3AKWENF.js} +5 -5
- package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-9a9d610d-N4HZW3O2.js → stateDiagram-v2-9a9d610d-NU3GGMCH.js} +8 -8
- package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-fea2a41d-ZHGCAXGP.js → timeline-definition-fea2a41d-JGP7XCHW.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{xychartDiagram-ab372869-2DLOVRAZ.js → xychartDiagram-ab372869-HLFHHF2I.js} +3 -3
- package/dist/browser/dev/index.css +72 -28
- package/dist/browser/dev/index.css.map +3 -3
- package/dist/browser/dev/index.js +2064 -1830
- package/dist/browser/dev/index.js.map +4 -4
- package/dist/browser/prod/excalidraw-assets/{blockDiagram-91b80b7a-ONPS22AM.js → blockDiagram-91b80b7a-FVCRVGN5.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{c4Diagram-b2a90758-XMIQY7ZT.js → c4Diagram-b2a90758-56CXO7GA.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-GCHQBOKV.js → chunk-635MQ3CK.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-P5M3G2RP.js → chunk-AIKXYJX3.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-E2YLWFZX.js → chunk-CR7VMNWC.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-WEYK4A2L.js → chunk-FFF2CSVG.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-R3HAIP6R.js → chunk-G4WDCSPE.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-HFOXJM22.js → chunk-HKZSHFLX.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-XIMFFJTE.js → chunk-IKCDYWMW.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-AHLLBBVJ.js → chunk-L5DS24G6.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-CQJF3C6G.js → chunk-MUNOKHUD.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-CTYINSWT.js → chunk-O4AI3NNG.js} +2 -2
- package/dist/browser/prod/excalidraw-assets/{chunk-NI6SYCUG.js → chunk-QOQYOOQ4.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/chunk-SXBDZOS3.js +55 -0
- package/dist/browser/prod/excalidraw-assets/{chunk-I2PZFXTK.js → chunk-ZTIWFPBM.js} +21 -21
- package/dist/browser/prod/excalidraw-assets/{classDiagram-30eddba6-IEJXXCVX.js → classDiagram-30eddba6-BCUTAUMD.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{classDiagram-v2-f2df5561-7LZDSWOS.js → classDiagram-v2-f2df5561-6SOXSGQ2.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{dist-PIPZXALV.js → dist-54276HPL.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{en-LROPV2RN.js → en-N7CLNF6C.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{erDiagram-47591fe2-E5V666CF.js → erDiagram-47591fe2-RE6HB7RM.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{flowDiagram-5540d9b9-GMBRCYVF.js → flowDiagram-5540d9b9-ZNJZBERW.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{flowDiagram-v2-3b53844e-Z4HUWP6B.js → flowDiagram-v2-3b53844e-LY44JLQJ.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{flowchart-elk-definition-5fe447d6-5ZCYTX5N.js → flowchart-elk-definition-5fe447d6-TMTJ6Z7O.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{ganttDiagram-9a3bba1f-WM32OMT5.js → ganttDiagram-9a3bba1f-5O6EA6LX.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{gitGraphDiagram-96e6b4ee-CAKZ2U6E.js → gitGraphDiagram-96e6b4ee-UHYNM5DI.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/image-VAGBVQ3G.js +1 -0
- package/dist/browser/prod/excalidraw-assets/{infoDiagram-bcd20f53-MUIKXGC4.js → infoDiagram-bcd20f53-BP77NQEH.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{journeyDiagram-4fe6b3dc-NYRV4HK2.js → journeyDiagram-4fe6b3dc-XMGKCMES.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{mindmap-definition-f354de21-MY55DRSM.js → mindmap-definition-f354de21-ZQRRBRWF.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{pieDiagram-79897490-47L6J6L2.js → pieDiagram-79897490-IGXEC2KX.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{quadrantDiagram-62f64e94-DF5C2GDT.js → quadrantDiagram-62f64e94-WTHHDYJL.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{requirementDiagram-05bf5f74-C4IMUBDN.js → requirementDiagram-05bf5f74-MV4OFRVW.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{sankeyDiagram-97764748-YHW7EUST.js → sankeyDiagram-97764748-ZGYUHEJT.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{sequenceDiagram-acc0e65c-H3XEHT32.js → sequenceDiagram-acc0e65c-IBSENK6W.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{stateDiagram-0ff1cf1a-Z5WB6Q3P.js → stateDiagram-0ff1cf1a-DB73XNZH.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{stateDiagram-v2-9a9d610d-T7OZETQC.js → stateDiagram-v2-9a9d610d-2OOBUPNR.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{timeline-definition-fea2a41d-VVC22BWF.js → timeline-definition-fea2a41d-P3NQQVDU.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{xychartDiagram-ab372869-JAXODQF7.js → xychartDiagram-ab372869-HI3XLK3Y.js} +1 -1
- package/dist/browser/prod/index.css +1 -1
- package/dist/browser/prod/index.js +24 -24
- package/dist/dev/{en-II4GK66F.json → en-UQDDYCH7.json} +5 -3
- package/dist/dev/index.css +72 -28
- package/dist/dev/index.css.map +3 -3
- package/dist/dev/index.js +5352 -3354
- package/dist/dev/index.js.map +4 -4
- package/dist/excalidraw/actions/actionAddToLibrary.d.ts +4 -4
- package/dist/excalidraw/actions/actionAddToLibrary.js +4 -3
- package/dist/excalidraw/actions/actionAlign.d.ts +22 -22
- package/dist/excalidraw/actions/actionAlign.js +7 -6
- package/dist/excalidraw/actions/actionBoundText.d.ts +10 -10
- package/dist/excalidraw/actions/actionBoundText.js +8 -4
- package/dist/excalidraw/actions/actionCanvas.d.ts +52 -52
- package/dist/excalidraw/actions/actionCanvas.js +19 -14
- package/dist/excalidraw/actions/actionClipboard.d.ts +24 -24
- package/dist/excalidraw/actions/actionClipboard.js +14 -13
- package/dist/excalidraw/actions/actionDeleteSelected.d.ts +10 -10
- package/dist/excalidraw/actions/actionDeleteSelected.js +6 -3
- package/dist/excalidraw/actions/actionDistribute.d.ts +10 -10
- package/dist/excalidraw/actions/actionDistribute.js +3 -2
- package/dist/excalidraw/actions/actionDuplicateSelection.d.ts +7 -8
- package/dist/excalidraw/actions/actionDuplicateSelection.js +7 -3
- package/dist/excalidraw/actions/actionElementLock.d.ts +9 -9
- package/dist/excalidraw/actions/actionElementLock.js +3 -2
- package/dist/excalidraw/actions/actionExport.d.ts +33 -33
- package/dist/excalidraw/actions/actionExport.js +15 -11
- package/dist/excalidraw/actions/actionFinalize.d.ts +9 -9
- package/dist/excalidraw/actions/actionFinalize.js +9 -5
- package/dist/excalidraw/actions/actionFlip.d.ts +10 -10
- package/dist/excalidraw/actions/actionFlip.js +12 -12
- package/dist/excalidraw/actions/actionFrame.d.ts +16 -171
- package/dist/excalidraw/actions/actionFrame.js +7 -6
- package/dist/excalidraw/actions/actionGroup.d.ts +12 -322
- package/dist/excalidraw/actions/actionGroup.js +9 -11
- package/dist/excalidraw/actions/actionHistory.d.ts +4 -3
- package/dist/excalidraw/actions/actionHistory.js +27 -28
- package/dist/excalidraw/actions/actionLinearEditor.d.ts +6 -4
- package/dist/excalidraw/actions/actionLinearEditor.js +21 -5
- package/dist/excalidraw/actions/actionLink.d.ts +5 -5
- package/dist/excalidraw/actions/actionLink.js +2 -1
- package/dist/excalidraw/actions/actionMenu.d.ts +8 -8
- package/dist/excalidraw/actions/actionMenu.js +4 -3
- package/dist/excalidraw/actions/actionNavigate.d.ts +4 -4
- package/dist/excalidraw/actions/actionNavigate.js +3 -2
- package/dist/excalidraw/actions/actionProperties.d.ts +34 -34
- package/dist/excalidraw/actions/actionProperties.js +18 -13
- package/dist/excalidraw/actions/actionSelectAll.d.ts +5 -5
- package/dist/excalidraw/actions/actionSelectAll.js +2 -1
- package/dist/excalidraw/actions/actionStyles.d.ts +9 -12
- package/dist/excalidraw/actions/actionStyles.js +4 -3
- package/dist/excalidraw/actions/actionToggleGridMode.d.ts +7 -5
- package/dist/excalidraw/actions/actionToggleGridMode.js +6 -2
- package/dist/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +4 -4
- package/dist/excalidraw/actions/actionToggleObjectsSnapMode.js +2 -1
- package/dist/excalidraw/actions/actionToggleStats.d.ts +4 -4
- package/dist/excalidraw/actions/actionToggleStats.js +2 -1
- package/dist/excalidraw/actions/actionToggleViewMode.d.ts +4 -4
- package/dist/excalidraw/actions/actionToggleViewMode.js +2 -1
- package/dist/excalidraw/actions/actionToggleZenMode.d.ts +4 -4
- package/dist/excalidraw/actions/actionToggleZenMode.js +2 -1
- package/dist/excalidraw/actions/actionZindex.d.ts +23 -19
- package/dist/excalidraw/actions/actionZindex.js +9 -4
- package/dist/excalidraw/actions/manager.d.ts +5 -5
- package/dist/excalidraw/actions/register.d.ts +1 -1
- package/dist/excalidraw/actions/shortcuts.d.ts +2 -2
- package/dist/excalidraw/actions/shortcuts.js +1 -1
- package/dist/excalidraw/actions/types.d.ts +7 -7
- package/dist/excalidraw/align.d.ts +1 -1
- package/dist/excalidraw/analytics.js +1 -1
- package/dist/excalidraw/animated-trail.d.ts +2 -2
- package/dist/excalidraw/appState.d.ts +5 -5
- package/dist/excalidraw/change.d.ts +191 -0
- package/dist/excalidraw/change.js +894 -0
- package/dist/excalidraw/charts.d.ts +1 -1
- package/dist/excalidraw/clients.d.ts +2 -2
- package/dist/excalidraw/clients.js +1 -1
- package/dist/excalidraw/clipboard.d.ts +3 -3
- package/dist/excalidraw/colors.d.ts +1 -1
- package/dist/excalidraw/components/Actions.d.ts +3 -3
- package/dist/excalidraw/components/Actions.js +8 -5
- package/dist/excalidraw/components/App.d.ts +27 -13
- package/dist/excalidraw/components/App.js +362 -157
- package/dist/excalidraw/components/ColorPicker/ColorInput.d.ts +1 -1
- package/dist/excalidraw/components/ColorPicker/ColorInput.js +1 -1
- package/dist/excalidraw/components/ColorPicker/ColorPicker.d.ts +4 -4
- package/dist/excalidraw/components/ColorPicker/ColorPicker.js +1 -1
- package/dist/excalidraw/components/ColorPicker/Picker.d.ts +3 -3
- package/dist/excalidraw/components/ColorPicker/PickerColorList.d.ts +1 -1
- package/dist/excalidraw/components/ColorPicker/PickerHeading.d.ts +1 -1
- package/dist/excalidraw/components/ColorPicker/ShadeList.d.ts +1 -1
- package/dist/excalidraw/components/ColorPicker/TopPicks.d.ts +1 -1
- package/dist/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +2 -2
- package/dist/excalidraw/components/ColorPicker/colorPickerUtils.js +1 -1
- package/dist/excalidraw/components/ColorPicker/keyboardNavHandlers.d.ts +2 -2
- package/dist/excalidraw/components/ColorPicker/keyboardNavHandlers.js +1 -1
- package/dist/excalidraw/components/CommandPalette/CommandPalette.d.ts +1 -1
- package/dist/excalidraw/components/CommandPalette/CommandPalette.js +28 -13
- package/dist/excalidraw/components/CommandPalette/defaultCommandPaletteItems.d.ts +1 -1
- package/dist/excalidraw/components/CommandPalette/types.d.ts +3 -3
- package/dist/excalidraw/components/ConfirmDialog.d.ts +1 -1
- package/dist/excalidraw/components/ContextMenu.d.ts +2 -2
- package/dist/excalidraw/components/ContextMenu.js +1 -1
- package/dist/excalidraw/components/DarkModeToggle.d.ts +1 -1
- package/dist/excalidraw/components/DarkModeToggle.js +3 -1
- package/dist/excalidraw/components/DefaultSidebar.d.ts +2 -2
- package/dist/excalidraw/components/DialogActionButton.d.ts +1 -1
- package/dist/excalidraw/components/EyeDropper.d.ts +2 -2
- package/dist/excalidraw/components/FollowMode/FollowMode.d.ts +1 -1
- package/dist/excalidraw/components/HelpDialog.js +8 -6
- package/dist/excalidraw/components/HintViewer.d.ts +1 -1
- package/dist/excalidraw/components/ImageExportDialog.d.ts +1 -1
- package/dist/excalidraw/components/InitializeApp.d.ts +2 -2
- package/dist/excalidraw/components/JSONExportDialog.d.ts +3 -3
- package/dist/excalidraw/components/LayerUI.d.ts +4 -4
- package/dist/excalidraw/components/LibraryMenu.d.ts +2 -2
- package/dist/excalidraw/components/LibraryMenuBrowseButton.d.ts +1 -1
- package/dist/excalidraw/components/LibraryMenuControlButtons.d.ts +1 -1
- package/dist/excalidraw/components/LibraryMenuHeaderContent.d.ts +2 -2
- package/dist/excalidraw/components/LibraryMenuItems.d.ts +1 -1
- package/dist/excalidraw/components/LibraryMenuSection.d.ts +5 -4
- package/dist/excalidraw/components/LibraryUnit.d.ts +2 -2
- package/dist/excalidraw/components/LoadingMessage.d.ts +1 -1
- package/dist/excalidraw/components/MagicSettings.js +2 -2
- package/dist/excalidraw/components/MobileMenu.d.ts +3 -3
- package/dist/excalidraw/components/Modal.d.ts +1 -1
- package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.d.ts +1 -1
- package/dist/excalidraw/components/PasteChartDialog.d.ts +1 -1
- package/dist/excalidraw/components/PublishLibrary.d.ts +1 -1
- package/dist/excalidraw/components/RadioGroup.d.ts +2 -1
- package/dist/excalidraw/components/RadioGroup.js +1 -1
- package/dist/excalidraw/components/SVGLayer.d.ts +1 -1
- package/dist/excalidraw/components/Sidebar/Sidebar.d.ts +2 -2
- package/dist/excalidraw/components/Sidebar/Sidebar.js +1 -1
- package/dist/excalidraw/components/Sidebar/SidebarTab.d.ts +1 -1
- package/dist/excalidraw/components/Sidebar/SidebarTabTrigger.d.ts +1 -1
- package/dist/excalidraw/components/Sidebar/SidebarTrigger.d.ts +1 -1
- package/dist/excalidraw/components/Sidebar/common.d.ts +1 -1
- package/dist/excalidraw/components/Stack.d.ts +2 -2
- package/dist/excalidraw/components/Stats.d.ts +2 -2
- package/dist/excalidraw/components/TTDDialog/MermaidToExcalidraw.d.ts +1 -1
- package/dist/excalidraw/components/TTDDialog/MermaidToExcalidraw.js +6 -2
- package/dist/excalidraw/components/TTDDialog/TTDDialog.js +2 -2
- package/dist/excalidraw/components/TTDDialog/TTDDialogInput.d.ts +1 -1
- package/dist/excalidraw/components/TTDDialog/TTDDialogPanel.d.ts +1 -1
- package/dist/excalidraw/components/TTDDialog/TTDDialogPanels.d.ts +1 -1
- package/dist/excalidraw/components/TTDDialog/TTDDialogTabs.d.ts +1 -1
- package/dist/excalidraw/components/TTDDialog/TTDDialogTrigger.d.ts +1 -1
- package/dist/excalidraw/components/TTDDialog/common.d.ts +4 -4
- package/dist/excalidraw/components/TextField.d.ts +1 -1
- package/dist/excalidraw/components/Toast.d.ts +1 -1
- package/dist/excalidraw/components/ToolButton.d.ts +4 -2
- package/dist/excalidraw/components/ToolButton.js +1 -1
- package/dist/excalidraw/components/Trans.d.ts +1 -1
- package/dist/excalidraw/components/UserList.d.ts +1 -1
- package/dist/excalidraw/components/canvases/InteractiveCanvas.d.ts +2 -1
- package/dist/excalidraw/components/canvases/InteractiveCanvas.js +1 -0
- package/dist/excalidraw/components/canvases/StaticCanvas.d.ts +1 -1
- package/dist/excalidraw/components/dropdownMenu/DropdownMenuItem.js +2 -2
- package/dist/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.d.ts +18 -0
- package/dist/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.js +9 -0
- package/dist/excalidraw/components/footer/Footer.d.ts +2 -2
- package/dist/excalidraw/components/hyperlink/Hyperlink.d.ts +2 -2
- package/dist/excalidraw/components/hyperlink/Hyperlink.js +3 -3
- package/dist/excalidraw/components/hyperlink/helpers.d.ts +3 -3
- package/dist/excalidraw/components/hyperlink/helpers.js +2 -3
- package/dist/excalidraw/components/icons.d.ts +6 -1
- package/dist/excalidraw/components/icons.js +19 -5
- package/dist/excalidraw/components/main-menu/DefaultItems.d.ts +12 -2
- package/dist/excalidraw/components/main-menu/DefaultItems.js +38 -7
- package/dist/excalidraw/constants.d.ts +5 -5
- package/dist/excalidraw/constants.js +6 -3
- package/dist/excalidraw/context/ui-appState.d.ts +1 -1
- package/dist/excalidraw/cursor.d.ts +1 -1
- package/dist/excalidraw/data/EditorLocalStorage.d.ts +2 -2
- package/dist/excalidraw/data/blob.d.ts +5 -5
- package/dist/excalidraw/data/filesystem.d.ts +2 -1
- package/dist/excalidraw/data/index.d.ts +4 -4
- package/dist/excalidraw/data/json.d.ts +3 -3
- package/dist/excalidraw/data/library.d.ts +3 -3
- package/dist/excalidraw/data/magic.d.ts +3 -3
- package/dist/excalidraw/data/magic.js +2 -1
- package/dist/excalidraw/data/reconcile.d.ts +6 -0
- package/dist/excalidraw/data/reconcile.js +49 -0
- package/dist/excalidraw/data/resave.d.ts +2 -2
- package/dist/excalidraw/data/restore.d.ts +5 -5
- package/dist/excalidraw/data/restore.js +6 -7
- package/dist/excalidraw/data/transform.d.ts +4 -4
- package/dist/excalidraw/data/transform.js +12 -3
- package/dist/excalidraw/data/types.d.ts +3 -3
- package/dist/excalidraw/data/url.d.ts +1 -0
- package/dist/excalidraw/data/url.js +4 -1
- package/dist/excalidraw/element/ElementCanvasButtons.d.ts +1 -1
- package/dist/excalidraw/element/binding.d.ts +50 -9
- package/dist/excalidraw/element/binding.js +712 -155
- package/dist/excalidraw/element/bounds.d.ts +3 -4
- package/dist/excalidraw/element/bounds.js +0 -3
- package/dist/excalidraw/element/collision.d.ts +14 -19
- package/dist/excalidraw/element/collision.js +36 -713
- package/dist/excalidraw/element/containerCache.d.ts +1 -1
- package/dist/excalidraw/element/dragElements.d.ts +3 -3
- package/dist/excalidraw/element/embeddable.d.ts +9 -6
- package/dist/excalidraw/element/embeddable.js +98 -62
- package/dist/excalidraw/element/image.d.ts +2 -2
- package/dist/excalidraw/element/index.d.ts +1 -2
- package/dist/excalidraw/element/index.js +0 -1
- package/dist/excalidraw/element/linearElementEditor.d.ts +12 -12
- package/dist/excalidraw/element/linearElementEditor.js +7 -5
- package/dist/excalidraw/element/mutateElement.d.ts +3 -4
- package/dist/excalidraw/element/newElement.d.ts +4 -4
- package/dist/excalidraw/element/newElement.js +2 -1
- package/dist/excalidraw/element/resizeElements.d.ts +4 -4
- package/dist/excalidraw/element/resizeElements.js +110 -86
- package/dist/excalidraw/element/resizeTest.d.ts +7 -7
- package/dist/excalidraw/element/resizeTest.js +55 -8
- package/dist/excalidraw/element/showSelectedShapeActions.d.ts +2 -2
- package/dist/excalidraw/element/sizeHelpers.d.ts +2 -2
- package/dist/excalidraw/element/sizeHelpers.js +3 -0
- package/dist/excalidraw/element/sortElements.d.ts +1 -1
- package/dist/excalidraw/element/textElement.d.ts +5 -6
- package/dist/excalidraw/element/textElement.js +5 -34
- package/dist/excalidraw/element/textWysiwyg.d.ts +2 -2
- package/dist/excalidraw/element/transformHandles.d.ts +24 -6
- package/dist/excalidraw/element/transformHandles.js +24 -3
- package/dist/excalidraw/element/typeChecks.d.ts +4 -4
- package/dist/excalidraw/element/types.d.ts +26 -10
- package/dist/excalidraw/emitter.d.ts +1 -1
- package/dist/excalidraw/errors.d.ts +3 -0
- package/dist/excalidraw/errors.js +3 -0
- package/dist/excalidraw/fractionalIndex.d.ts +40 -0
- package/dist/excalidraw/fractionalIndex.js +241 -0
- package/dist/excalidraw/frame.d.ts +4 -4
- package/dist/excalidraw/gatransforms.d.ts +1 -1
- package/dist/excalidraw/gesture.d.ts +1 -1
- package/dist/excalidraw/groups.d.ts +5 -3
- package/dist/excalidraw/groups.js +17 -0
- package/dist/excalidraw/history.d.ts +35 -47
- package/dist/excalidraw/history.js +100 -167
- package/dist/excalidraw/hooks/useCreatePortalContainer.js +2 -1
- package/dist/excalidraw/hooks/useEmitter.d.ts +2 -0
- package/dist/excalidraw/hooks/useEmitter.js +13 -0
- package/dist/excalidraw/hooks/useLibraryItemSvg.d.ts +1 -1
- package/dist/excalidraw/i18n.d.ts +1 -1
- package/dist/excalidraw/index.d.ts +3 -1
- package/dist/excalidraw/index.js +2 -0
- package/dist/excalidraw/jotai.d.ts +1 -1
- package/dist/excalidraw/laser-trails.d.ts +3 -2
- package/dist/excalidraw/locales/en.json +5 -3
- package/dist/excalidraw/math.d.ts +2 -2
- package/dist/excalidraw/points.d.ts +1 -1
- package/dist/excalidraw/queue.d.ts +1 -1
- package/dist/excalidraw/renderer/helpers.d.ts +2 -2
- package/dist/excalidraw/renderer/helpers.js +2 -2
- package/dist/excalidraw/renderer/interactiveScene.d.ts +2 -2
- package/dist/excalidraw/renderer/interactiveScene.js +8 -7
- package/dist/excalidraw/renderer/renderElement.d.ts +3 -3
- package/dist/excalidraw/renderer/renderElement.js +5 -5
- package/dist/excalidraw/renderer/renderSnaps.d.ts +1 -1
- package/dist/excalidraw/renderer/renderSnaps.js +2 -1
- package/dist/excalidraw/renderer/staticScene.d.ts +1 -1
- package/dist/excalidraw/renderer/staticScene.js +14 -3
- package/dist/excalidraw/renderer/staticSvgScene.d.ts +4 -4
- package/dist/excalidraw/renderer/staticSvgScene.js +10 -0
- package/dist/excalidraw/scene/Fonts.d.ts +1 -1
- package/dist/excalidraw/scene/Renderer.d.ts +3 -3
- package/dist/excalidraw/scene/Scene.d.ts +9 -8
- package/dist/excalidraw/scene/Scene.js +31 -16
- package/dist/excalidraw/scene/Shape.d.ts +1 -1
- package/dist/excalidraw/scene/ShapeCache.d.ts +4 -4
- package/dist/excalidraw/scene/comparisons.d.ts +2 -2
- package/dist/excalidraw/scene/export.d.ts +2 -2
- package/dist/excalidraw/scene/export.js +5 -4
- package/dist/excalidraw/scene/scroll.d.ts +2 -2
- package/dist/excalidraw/scene/scrollbars.d.ts +3 -3
- package/dist/excalidraw/scene/selection.d.ts +2 -2
- package/dist/excalidraw/scene/types.d.ts +5 -4
- package/dist/excalidraw/scene/zoom.d.ts +1 -1
- package/dist/excalidraw/snapping.d.ts +4 -4
- package/dist/excalidraw/store.d.ts +99 -0
- package/dist/excalidraw/store.js +269 -0
- package/dist/excalidraw/types.d.ts +33 -19
- package/dist/excalidraw/utils.d.ts +11 -4
- package/dist/excalidraw/utils.js +8 -0
- package/dist/excalidraw/zindex.d.ts +4 -4
- package/dist/excalidraw/zindex.js +9 -13
- package/dist/prod/{en-II4GK66F.json → en-UQDDYCH7.json} +5 -3
- package/dist/prod/index.css +1 -1
- package/dist/prod/index.js +44 -44
- package/dist/utils/bbox.d.ts +2 -2
- package/dist/utils/collision.d.ts +4 -0
- package/dist/utils/collision.js +48 -0
- package/dist/utils/export.d.ts +2 -2
- package/dist/utils/geometry/geometry.d.ts +71 -0
- package/dist/utils/geometry/geometry.js +674 -0
- package/dist/utils/geometry/shape.d.ts +56 -0
- package/dist/utils/geometry/shape.js +168 -0
- package/dist/utils/withinBounds.d.ts +1 -1
- package/history.ts +163 -218
- package/package.json +2 -1
- package/dist/browser/dev/excalidraw-assets-dev/chunk-AK7SWNLN.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/chunk-RWZVJAQU.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/chunk-Z3PH3V2B.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/image-OFRRV5MB.css.map +0 -7
- package/dist/browser/prod/excalidraw-assets/chunk-LL4GORAM.js +0 -55
- package/dist/browser/prod/excalidraw-assets/image-EFCJDJH3.js +0 -1
- /package/dist/browser/dev/excalidraw-assets-dev/{blockDiagram-91b80b7a-ACFH36JV.js.map → blockDiagram-91b80b7a-H47FTXHA.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-b2a90758-QZ27YR47.js.map → c4Diagram-b2a90758-NNJK6GKC.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-HO2HMSK7.js.map → chunk-4KQVEBHW.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-USGV265L.js.map → chunk-53YI56GV.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-EDFX3S7X.js.map → chunk-A2WCJI4I.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-IX4V72YG.js.map → chunk-EFLPX7NE.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-MXVETLVM.js.map → chunk-JYIQCNWV.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-YZIOORVX.js.map → chunk-LVIQQW6F.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-6U7GQNJT.js.map → chunk-PXLO3FOU.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-7DACDEY3.js.map → chunk-TO2AW5PW.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-NJ77ZFNJ.js.map → chunk-VURILHLY.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-2T2GU7NF.js.map → chunk-ZAYGSUHF.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-30eddba6-QSLMH4JW.js.map → classDiagram-30eddba6-CUYIJICN.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-f2df5561-DY4DYQ5P.js.map → classDiagram-v2-f2df5561-K6WW6K73.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{dist-Z46EOVOL.js.map → dist-ITJNUBZF.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{en-5TCZHGGJ.js.map → en-BF4XUPIZ.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-47591fe2-SOOJRTCB.js.map → erDiagram-47591fe2-XGAD7EEP.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-5540d9b9-AHGL4KPK.js.map → flowDiagram-5540d9b9-B6EOVNNO.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-3b53844e-56LDZZWY.js.map → flowDiagram-v2-3b53844e-NUG24FJH.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5fe447d6-27LUKRI6.js.map → flowchart-elk-definition-5fe447d6-25Y7PCBL.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-9a3bba1f-EHGYGNG6.js.map → ganttDiagram-9a3bba1f-GNL6ZDTC.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-96e6b4ee-AJQNBDW5.js.map → gitGraphDiagram-96e6b4ee-HNW52NVO.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{image-EDKQZH7Z.js.map → image-LVS32KQQ.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-bcd20f53-SWLLQVES.js.map → infoDiagram-bcd20f53-FWEUVFLT.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-4fe6b3dc-7UAVCWOZ.js.map → journeyDiagram-4fe6b3dc-RZIUI7UG.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-f354de21-SROW5KGM.js.map → mindmap-definition-f354de21-GBVN45GU.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-79897490-QKCI6NCB.js.map → pieDiagram-79897490-ECENNII6.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-62f64e94-LNYJZFC5.js.map → quadrantDiagram-62f64e94-ZMEOFVNL.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-05bf5f74-ZZD7ZHFA.js.map → requirementDiagram-05bf5f74-FHZSFHCR.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{sankeyDiagram-97764748-L75ZZ4UM.js.map → sankeyDiagram-97764748-VDKIKTA6.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-acc0e65c-6PCU7TDK.js.map → sequenceDiagram-acc0e65c-6JUSPVKX.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-0ff1cf1a-WM76WOPR.js.map → stateDiagram-0ff1cf1a-L3AKWENF.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-9a9d610d-N4HZW3O2.js.map → stateDiagram-v2-9a9d610d-NU3GGMCH.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-fea2a41d-ZHGCAXGP.js.map → timeline-definition-fea2a41d-JGP7XCHW.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{xychartDiagram-ab372869-2DLOVRAZ.js.map → xychartDiagram-ab372869-HLFHHF2I.js.map} +0 -0
|
@@ -10,31 +10,33 @@ import { ActionManager } from "../actions/manager";
|
|
|
10
10
|
import { actions } from "../actions/register";
|
|
11
11
|
import { trackEvent } from "../analytics";
|
|
12
12
|
import { getDefaultAppState, isEraserActive, isHandToolActive, } from "../appState";
|
|
13
|
-
import { copyTextToSystemClipboard, parseClipboard
|
|
14
|
-
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, } from "../constants";
|
|
13
|
+
import { copyTextToSystemClipboard, parseClipboard } from "../clipboard";
|
|
14
|
+
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, } from "../constants";
|
|
15
15
|
import { exportCanvas, loadFromBlob } from "../data";
|
|
16
16
|
import Library, { distributeLibraryItemsOnSquareGrid } from "../data/library";
|
|
17
17
|
import { restore, restoreElements } from "../data/restore";
|
|
18
|
-
import { dragNewElement, dragSelectedElements, duplicateElement, getCommonBounds, getCursorForResizingElement, getDragOffsetXY, getElementWithTransformHandleType, getNormalizedDimensions, getResizeArrowDirection, getResizeOffsetXY, getLockedLinearCursorAlignSize, getTransformHandleTypeFromCoords,
|
|
19
|
-
import { bindOrUnbindLinearElement,
|
|
18
|
+
import { dragNewElement, dragSelectedElements, duplicateElement, getCommonBounds, getCursorForResizingElement, getDragOffsetXY, getElementWithTransformHandleType, getNormalizedDimensions, getResizeArrowDirection, getResizeOffsetXY, getLockedLinearCursorAlignSize, getTransformHandleTypeFromCoords, isInvisiblySmallElement, isNonDeletedElement, isTextElement, newElement, newLinearElement, newTextElement, newImageElement, transformElements, updateTextElement, redrawTextBoundingBox, getElementAbsoluteCoords, } from "../element";
|
|
19
|
+
import { bindOrUnbindLinearElement, bindOrUnbindLinearElements, fixBindingsAfterDeletion, fixBindingsAfterDuplication, getHoveredElementForBinding, isBindingEnabled, isLinearElementSimpleAndAlreadyBound, maybeBindLinearElement, shouldEnableBindingForPointerEvent, updateBoundElements, getSuggestedBindingsForArrows, } from "../element/binding";
|
|
20
20
|
import { LinearElementEditor } from "../element/linearElementEditor";
|
|
21
21
|
import { mutateElement, newElementWith } from "../element/mutateElement";
|
|
22
22
|
import { deepCopyElement, duplicateElements, newFrameElement, newFreeDrawElement, newEmbeddableElement, newMagicFrameElement, newIframeElement, } from "../element/newElement";
|
|
23
|
-
import { hasBoundTextElement, isArrowElement, isBindingElement, isBindingElementType, isBoundToContainer, isFrameLikeElement, isImageElement, isEmbeddableElement, isInitializedImageElement, isLinearElement, isLinearElementType, isUsingAdaptiveRadius, isFrameElement, isIframeElement, isIframeLikeElement, isMagicFrameElement, } from "../element/typeChecks";
|
|
23
|
+
import { hasBoundTextElement, isArrowElement, isBindingElement, isBindingElementType, isBoundToContainer, isFrameLikeElement, isImageElement, isEmbeddableElement, isInitializedImageElement, isLinearElement, isLinearElementType, isUsingAdaptiveRadius, isFrameElement, isIframeElement, isIframeLikeElement, isMagicFrameElement, isTextBindableContainer, } from "../element/typeChecks";
|
|
24
24
|
import { getCenter, getDistance } from "../gesture";
|
|
25
25
|
import { editGroupForSelectedElement, getElementsInGroup, getSelectedGroupIdForElement, getSelectedGroupIds, isElementInGroup, isSelectedViaGroup, selectGroupsForSelectedElements, } from "../groups";
|
|
26
|
-
import History from "../history";
|
|
26
|
+
import { History } from "../history";
|
|
27
27
|
import { defaultLang, getLanguage, languages, setLanguage, t } from "../i18n";
|
|
28
28
|
import { CODES, shouldResizeFromCenter, shouldMaintainAspectRatio, shouldRotateWithDiscreteAngle, isArrowKey, KEYS, } from "../keys";
|
|
29
29
|
import { isElementInViewport } from "../element/sizeHelpers";
|
|
30
30
|
import { distance2d, getCornerRadius, getGridPoint, isPathALoop, } from "../math";
|
|
31
|
-
import { calculateScrollCenter,
|
|
31
|
+
import { calculateScrollCenter, getElementsWithinSelection, getNormalizedZoom, getSelectedElements, hasBackground, isSomeElementSelected, } from "../scene";
|
|
32
32
|
import Scene from "../scene/Scene";
|
|
33
33
|
import { getStateForZoom } from "../scene/zoom";
|
|
34
34
|
import { findShapeByKey } from "../shapes";
|
|
35
|
-
import {
|
|
35
|
+
import { getClosedCurveShape, getCurveShape, getEllipseShape, getFreedrawShape, getPolygonShape, getSelectionBoxShape, } from "../../utils/geometry/shape";
|
|
36
|
+
import { isPointInShape } from "../../utils/collision";
|
|
37
|
+
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";
|
|
36
38
|
import { createSrcDoc, embeddableURLValidator, maybeParseEmbedSrc, getEmbedLink, } from "../element/embeddable";
|
|
37
|
-
import { ContextMenu, CONTEXT_MENU_SEPARATOR
|
|
39
|
+
import { ContextMenu, CONTEXT_MENU_SEPARATOR } from "./ContextMenu";
|
|
38
40
|
import LayerUI from "./LayerUI";
|
|
39
41
|
import { Toast } from "./Toast";
|
|
40
42
|
import { actionToggleViewMode } from "../actions/actionToggleViewMode";
|
|
@@ -42,8 +44,7 @@ import { dataURLToFile, generateIdFromFile, getDataURL, getFileFromEvent, ImageU
|
|
|
42
44
|
import { getInitializedImageElements, loadHTMLImageElement, normalizeSVG, updateImageCache as _updateImageCache, } from "../element/image";
|
|
43
45
|
import throttle from "lodash.throttle";
|
|
44
46
|
import { fileOpen } from "../data/filesystem";
|
|
45
|
-
import { bindTextToShapeAfterDuplication, getApproxMinLineHeight, getApproxMinLineWidth, getBoundTextElement, getContainerCenter, getContainerElement, getDefaultLineHeight, getLineHeightInPx,
|
|
46
|
-
import { isHittingElementNotConsideringBoundingBox } from "../element/collision";
|
|
47
|
+
import { bindTextToShapeAfterDuplication, getApproxMinLineHeight, getApproxMinLineWidth, getBoundTextElement, getContainerCenter, getContainerElement, getDefaultLineHeight, getLineHeightInPx, isMeasureTextSupported, isValidTextContainer, } from "../element/textElement";
|
|
47
48
|
import { showHyperlinkTooltip, hideHyperlinkToolip, Hyperlink, } from "../components/hyperlink/Hyperlink";
|
|
48
49
|
import { isLocalLink, normalizeLink, toValidURL } from "../data/url";
|
|
49
50
|
import { shouldShowBoundingBox } from "../element/transformHandles";
|
|
@@ -61,7 +62,7 @@ import { getSnapLinesAtPointer, snapDraggedElements, isActiveToolNonLinearSnappa
|
|
|
61
62
|
import { actionWrapTextInContainer } from "../actions/actionBoundText";
|
|
62
63
|
import BraveMeasureTextError from "./BraveMeasureTextError";
|
|
63
64
|
import { activeEyeDropperAtom } from "./EyeDropper";
|
|
64
|
-
import { convertToExcalidrawElements
|
|
65
|
+
import { convertToExcalidrawElements } from "../data/transform";
|
|
65
66
|
import { isSidebarDockedAtom } from "./Sidebar/Sidebar";
|
|
66
67
|
import { StaticCanvas, InteractiveCanvas } from "./canvases";
|
|
67
68
|
import { Renderer } from "../scene/Renderer";
|
|
@@ -77,13 +78,16 @@ import { ElementCanvasButton } from "./MagicButton";
|
|
|
77
78
|
import { MagicIcon, copyIcon, fullscreenIcon } from "./icons";
|
|
78
79
|
import { EditorLocalStorage } from "../data/EditorLocalStorage";
|
|
79
80
|
import FollowMode from "./FollowMode/FollowMode";
|
|
81
|
+
import { Store, StoreAction } from "../store";
|
|
80
82
|
import { AnimationFrameHandler } from "../animation-frame-handler";
|
|
81
83
|
import { AnimatedTrail } from "../animated-trail";
|
|
82
84
|
import { LaserTrails } from "../laser-trails";
|
|
83
85
|
import { withBatchedUpdates, withBatchedUpdatesThrottled } from "../reactUtils";
|
|
84
86
|
import { getRenderOpacity } from "../renderer/renderElement";
|
|
87
|
+
import { hitElementBoundText, hitElementBoundingBoxOnly, hitElementItself, shouldTestInside, } from "../element/collision";
|
|
85
88
|
import { textWysiwyg } from "../element/textWysiwyg";
|
|
86
89
|
import { isOverScrollBars } from "../scene/scrollbars";
|
|
90
|
+
import { syncInvalidIndices, syncMovedIndices } from "../fractionalIndex";
|
|
87
91
|
import { isPointHittingLink, isPointHittingLinkIcon, } from "./hyperlink/helpers";
|
|
88
92
|
import { getShortcutFromShortcutName } from "../actions/shortcuts";
|
|
89
93
|
const AppContext = React.createContext(null);
|
|
@@ -165,6 +169,7 @@ class App extends React.Component {
|
|
|
165
169
|
library;
|
|
166
170
|
libraryItemsFromStorage;
|
|
167
171
|
id;
|
|
172
|
+
store;
|
|
168
173
|
history;
|
|
169
174
|
excalidrawContainerValue;
|
|
170
175
|
files = {};
|
|
@@ -236,6 +241,8 @@ class App extends React.Component {
|
|
|
236
241
|
this.canvas = document.createElement("canvas");
|
|
237
242
|
this.rc = rough.canvas(this.canvas);
|
|
238
243
|
this.renderer = new Renderer(this.scene);
|
|
244
|
+
this.store = new Store();
|
|
245
|
+
this.history = new History();
|
|
239
246
|
if (excalidrawAPI) {
|
|
240
247
|
const api = {
|
|
241
248
|
updateScene: this.updateScene,
|
|
@@ -285,8 +292,8 @@ class App extends React.Component {
|
|
|
285
292
|
});
|
|
286
293
|
this.history = new History();
|
|
287
294
|
this.actionManager.registerAll(actions);
|
|
288
|
-
this.actionManager.registerAction(createUndoAction(this.history));
|
|
289
|
-
this.actionManager.registerAction(createRedoAction(this.history));
|
|
295
|
+
this.actionManager.registerAction(createUndoAction(this.history, this.store));
|
|
296
|
+
this.actionManager.registerAction(createRedoAction(this.history, this.store));
|
|
290
297
|
}
|
|
291
298
|
onWindowMessage(event) {
|
|
292
299
|
if (event.origin !== "https://player.vimeo.com" &&
|
|
@@ -495,7 +502,7 @@ class App extends React.Component {
|
|
|
495
502
|
html, body {
|
|
496
503
|
width: 100%;
|
|
497
504
|
height: 100%;
|
|
498
|
-
color: ${this.state.theme ===
|
|
505
|
+
color: ${this.state.theme === THEME.DARK ? "white" : "black"};
|
|
499
506
|
}
|
|
500
507
|
body {
|
|
501
508
|
display: flex;
|
|
@@ -650,7 +657,7 @@ class App extends React.Component {
|
|
|
650
657
|
? src.srcdoc(this.state.theme)
|
|
651
658
|
: undefined, src: src?.type !== "document" ? src?.link ?? "" : undefined,
|
|
652
659
|
// https://stackoverflow.com/q/18470015
|
|
653
|
-
scrolling: "no", referrerPolicy: "no-referrer-when-downgrade", title: "Excalidraw Embedded Content", allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture", allowFullScreen: true, sandbox: "allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-downloads
|
|
660
|
+
scrolling: "no", referrerPolicy: "no-referrer-when-downgrade", title: "Excalidraw Embedded Content", allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture", allowFullScreen: true, sandbox: `${src?.sandbox?.allowSameOrigin ? "allow-same-origin" : ""} allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-downloads` })) })] }) }, el.id));
|
|
654
661
|
}) }));
|
|
655
662
|
}
|
|
656
663
|
getFrameNameDOMId = (frameElement) => {
|
|
@@ -692,7 +699,7 @@ class App extends React.Component {
|
|
|
692
699
|
if (!this.state.frameRendering.enabled || !this.state.frameRendering.name) {
|
|
693
700
|
return null;
|
|
694
701
|
}
|
|
695
|
-
const isDarkTheme = this.state.theme ===
|
|
702
|
+
const isDarkTheme = this.state.theme === THEME.DARK;
|
|
696
703
|
let frameIndex = 0;
|
|
697
704
|
let magicFrameIndex = 0;
|
|
698
705
|
return this.scene.getNonDeletedFramesLikes().map((f) => {
|
|
@@ -874,7 +881,7 @@ class App extends React.Component {
|
|
|
874
881
|
canvasBackgroundColor: this.state.viewBackgroundColor,
|
|
875
882
|
embedsValidationStatus: this.embedsValidationStatus,
|
|
876
883
|
elementsPendingErasure: this.elementsPendingErasure,
|
|
877
|
-
} }), _jsx(InteractiveCanvas, { containerRef: this.excalidrawContainerRef, canvas: this.interactiveCanvas, elementsMap: elementsMap, visibleElements: visibleElements, selectedElements: selectedElements, versionNonce: versionNonce, selectionNonce: this.state.selectionElement?.versionNonce, scale: window.devicePixelRatio, appState: this.state, renderInteractiveSceneCallback: this.renderInteractiveSceneCallback, handleCanvasRef: this.handleInteractiveCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.handleCanvasPointerUp, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove, onPointerDown: this.handleCanvasPointerDown, onDoubleClick: this.handleCanvasDoubleClick }), this.state.userToFollow && (_jsx(FollowMode, { width: this.state.width, height: this.state.height, userToFollow: this.state.userToFollow, onDisconnect: this.maybeUnfollowRemoteUser })), this.renderFrameNames()] }), this.renderEmbeddables()] }) }) }) }) }) }) }) }));
|
|
884
|
+
} }), _jsx(InteractiveCanvas, { containerRef: this.excalidrawContainerRef, canvas: this.interactiveCanvas, elementsMap: elementsMap, visibleElements: visibleElements, selectedElements: selectedElements, versionNonce: versionNonce, selectionNonce: this.state.selectionElement?.versionNonce, scale: window.devicePixelRatio, appState: this.state, device: this.device, renderInteractiveSceneCallback: this.renderInteractiveSceneCallback, handleCanvasRef: this.handleInteractiveCanvasRef, onContextMenu: this.handleCanvasContextMenu, onPointerMove: this.handleCanvasPointerMove, onPointerUp: this.handleCanvasPointerUp, onPointerCancel: this.removePointer, onTouchMove: this.handleTouchMove, onPointerDown: this.handleCanvasPointerDown, onDoubleClick: this.handleCanvasDoubleClick }), this.state.userToFollow && (_jsx(FollowMode, { width: this.state.width, height: this.state.height, userToFollow: this.state.userToFollow, onDisconnect: this.maybeUnfollowRemoteUser })), this.renderFrameNames()] }), this.renderEmbeddables()] }) }) }) }) }) }) }) }));
|
|
878
885
|
}
|
|
879
886
|
focusContainer = () => {
|
|
880
887
|
this.excalidrawContainerRef.current?.focus();
|
|
@@ -1122,7 +1129,7 @@ class App extends React.Component {
|
|
|
1122
1129
|
opacity: 100,
|
|
1123
1130
|
locked: false,
|
|
1124
1131
|
});
|
|
1125
|
-
this.scene.
|
|
1132
|
+
this.scene.insertElement(frame);
|
|
1126
1133
|
for (const child of selectedElements) {
|
|
1127
1134
|
mutateElement(child, { frameId: frame.id });
|
|
1128
1135
|
}
|
|
@@ -1146,13 +1153,13 @@ class App extends React.Component {
|
|
|
1146
1153
|
if (shouldUpdateStrokeColor) {
|
|
1147
1154
|
this.syncActionResult({
|
|
1148
1155
|
appState: { ...this.state, currentItemStrokeColor: color },
|
|
1149
|
-
|
|
1156
|
+
storeAction: StoreAction.CAPTURE,
|
|
1150
1157
|
});
|
|
1151
1158
|
}
|
|
1152
1159
|
else {
|
|
1153
1160
|
this.syncActionResult({
|
|
1154
1161
|
appState: { ...this.state, currentItemBackgroundColor: color },
|
|
1155
|
-
|
|
1162
|
+
storeAction: StoreAction.CAPTURE,
|
|
1156
1163
|
});
|
|
1157
1164
|
}
|
|
1158
1165
|
}
|
|
@@ -1166,6 +1173,7 @@ class App extends React.Component {
|
|
|
1166
1173
|
}
|
|
1167
1174
|
return el;
|
|
1168
1175
|
}),
|
|
1176
|
+
storeAction: StoreAction.CAPTURE,
|
|
1169
1177
|
});
|
|
1170
1178
|
}
|
|
1171
1179
|
},
|
|
@@ -1185,10 +1193,13 @@ class App extends React.Component {
|
|
|
1185
1193
|
editingElement = element;
|
|
1186
1194
|
}
|
|
1187
1195
|
});
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
this.history.resumeRecording();
|
|
1196
|
+
if (actionResult.storeAction === StoreAction.UPDATE) {
|
|
1197
|
+
this.store.shouldUpdateSnapshot();
|
|
1191
1198
|
}
|
|
1199
|
+
else if (actionResult.storeAction === StoreAction.CAPTURE) {
|
|
1200
|
+
this.store.shouldCaptureIncrement();
|
|
1201
|
+
}
|
|
1202
|
+
this.scene.replaceAllElements(actionResult.elements);
|
|
1192
1203
|
}
|
|
1193
1204
|
if (actionResult.files) {
|
|
1194
1205
|
this.files = actionResult.replaceFiles
|
|
@@ -1197,8 +1208,11 @@ class App extends React.Component {
|
|
|
1197
1208
|
this.addNewImagesToImageCache();
|
|
1198
1209
|
}
|
|
1199
1210
|
if (actionResult.appState || editingElement || this.state.contextMenu) {
|
|
1200
|
-
if (actionResult.
|
|
1201
|
-
this.
|
|
1211
|
+
if (actionResult.storeAction === StoreAction.UPDATE) {
|
|
1212
|
+
this.store.shouldUpdateSnapshot();
|
|
1213
|
+
}
|
|
1214
|
+
else if (actionResult.storeAction === StoreAction.CAPTURE) {
|
|
1215
|
+
this.store.shouldCaptureIncrement();
|
|
1202
1216
|
}
|
|
1203
1217
|
let viewModeEnabled = actionResult?.appState?.viewModeEnabled || false;
|
|
1204
1218
|
let zenModeEnabled = actionResult?.appState?.zenModeEnabled || false;
|
|
@@ -1237,10 +1251,6 @@ class App extends React.Component {
|
|
|
1237
1251
|
name,
|
|
1238
1252
|
errorMessage,
|
|
1239
1253
|
});
|
|
1240
|
-
}, () => {
|
|
1241
|
-
if (actionResult.syncHistory) {
|
|
1242
|
-
this.history.setCurrentState(this.state, this.scene.getElementsIncludingDeleted());
|
|
1243
|
-
}
|
|
1244
1254
|
});
|
|
1245
1255
|
}
|
|
1246
1256
|
});
|
|
@@ -1258,6 +1268,9 @@ class App extends React.Component {
|
|
|
1258
1268
|
resetHistory = () => {
|
|
1259
1269
|
this.history.clear();
|
|
1260
1270
|
};
|
|
1271
|
+
resetStore = () => {
|
|
1272
|
+
this.store.clear();
|
|
1273
|
+
};
|
|
1261
1274
|
/**
|
|
1262
1275
|
* Resets scene & history.
|
|
1263
1276
|
* ! Do not use to clear scene user action !
|
|
@@ -1269,6 +1282,7 @@ class App extends React.Component {
|
|
|
1269
1282
|
isLoading: opts?.resetLoadingState ? false : state.isLoading,
|
|
1270
1283
|
theme: this.state.theme,
|
|
1271
1284
|
}));
|
|
1285
|
+
this.resetStore();
|
|
1272
1286
|
this.resetHistory();
|
|
1273
1287
|
});
|
|
1274
1288
|
initializeScene = async () => {
|
|
@@ -1343,10 +1357,11 @@ class App extends React.Component {
|
|
|
1343
1357
|
// text elements on canvas, and rerender them once done. This also
|
|
1344
1358
|
// seems faster even in browsers that do fire the loadingdone event.
|
|
1345
1359
|
this.fonts.loadFontsForElements(scene.elements);
|
|
1360
|
+
this.resetStore();
|
|
1346
1361
|
this.resetHistory();
|
|
1347
1362
|
this.syncActionResult({
|
|
1348
1363
|
...scene,
|
|
1349
|
-
|
|
1364
|
+
storeAction: StoreAction.UPDATE,
|
|
1350
1365
|
});
|
|
1351
1366
|
};
|
|
1352
1367
|
isMobileBreakpoint = (width, height) => {
|
|
@@ -1417,8 +1432,15 @@ class App extends React.Component {
|
|
|
1417
1432
|
configurable: true,
|
|
1418
1433
|
value: this.history,
|
|
1419
1434
|
},
|
|
1435
|
+
store: {
|
|
1436
|
+
configurable: true,
|
|
1437
|
+
value: this.store,
|
|
1438
|
+
},
|
|
1420
1439
|
});
|
|
1421
1440
|
}
|
|
1441
|
+
this.store.onStoreIncrementEmitter.on((increment) => {
|
|
1442
|
+
this.history.record(increment.elementsChange, increment.appStateChange);
|
|
1443
|
+
});
|
|
1422
1444
|
this.scene.addCallback(this.onSceneUpdated);
|
|
1423
1445
|
this.addEventListeners();
|
|
1424
1446
|
if (this.props.autoFocus && this.excalidrawContainerRef.current) {
|
|
@@ -1468,6 +1490,7 @@ class App extends React.Component {
|
|
|
1468
1490
|
this.laserTrails.stop();
|
|
1469
1491
|
this.eraserTrail.stop();
|
|
1470
1492
|
this.onChangeEmitter.clear();
|
|
1493
|
+
this.store.onStoreIncrementEmitter.clear();
|
|
1471
1494
|
ShapeCache.destroy();
|
|
1472
1495
|
SnapCache.destroy();
|
|
1473
1496
|
clearTimeout(touchTimeout);
|
|
@@ -1535,7 +1558,8 @@ class App extends React.Component {
|
|
|
1535
1558
|
componentDidUpdate(prevProps, prevState) {
|
|
1536
1559
|
this.updateEmbeddables();
|
|
1537
1560
|
const elements = this.scene.getElementsIncludingDeleted();
|
|
1538
|
-
const elementsMap = this.scene.
|
|
1561
|
+
const elementsMap = this.scene.getElementsMapIncludingDeleted();
|
|
1562
|
+
const nonDeletedElementsMap = this.scene.getNonDeletedElementsMap();
|
|
1539
1563
|
if (!this.state.showWelcomeScreen && !elements.length) {
|
|
1540
1564
|
this.setState({ showWelcomeScreen: true });
|
|
1541
1565
|
}
|
|
@@ -1608,10 +1632,10 @@ class App extends React.Component {
|
|
|
1608
1632
|
gridSize: this.props.gridModeEnabled ? GRID_SIZE : null,
|
|
1609
1633
|
});
|
|
1610
1634
|
}
|
|
1611
|
-
this.excalidrawContainerRef.current?.classList.toggle("theme--dark", this.state.theme ===
|
|
1635
|
+
this.excalidrawContainerRef.current?.classList.toggle("theme--dark", this.state.theme === THEME.DARK);
|
|
1612
1636
|
if (this.state.editingLinearElement &&
|
|
1613
1637
|
!this.state.selectedElementIds[this.state.editingLinearElement.elementId]) {
|
|
1614
|
-
// defer so that the
|
|
1638
|
+
// defer so that the storeAction flag isn't reset via current update
|
|
1615
1639
|
setTimeout(() => {
|
|
1616
1640
|
// execute only if the condition still holds when the deferred callback
|
|
1617
1641
|
// executes (it can be scheduled multiple times depending on how
|
|
@@ -1636,9 +1660,9 @@ class App extends React.Component {
|
|
|
1636
1660
|
multiElement != null &&
|
|
1637
1661
|
isBindingEnabled(this.state) &&
|
|
1638
1662
|
isBindingElement(multiElement, false)) {
|
|
1639
|
-
maybeBindLinearElement(multiElement, this.state,
|
|
1663
|
+
maybeBindLinearElement(multiElement, this.state, tupleToCoors(LinearElementEditor.getPointAtIndexGlobalCoordinates(multiElement, -1, nonDeletedElementsMap)), this);
|
|
1640
1664
|
}
|
|
1641
|
-
this.
|
|
1665
|
+
this.store.commit(elementsMap, this.state);
|
|
1642
1666
|
// Do not notify consumers if we're still loading the scene. Among other
|
|
1643
1667
|
// potential issues, this fixes a case where the tab isn't focused during
|
|
1644
1668
|
// init, which would trigger onChange with empty elements, which would then
|
|
@@ -1894,16 +1918,15 @@ class App extends React.Component {
|
|
|
1894
1918
|
}), {
|
|
1895
1919
|
randomizeSeed: !opts.retainSeed,
|
|
1896
1920
|
});
|
|
1897
|
-
const
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
];
|
|
1921
|
+
const prevElements = this.scene.getElementsIncludingDeleted();
|
|
1922
|
+
const nextElements = [...prevElements, ...newElements];
|
|
1923
|
+
syncMovedIndices(nextElements, arrayToMap(newElements));
|
|
1901
1924
|
const topLayerFrame = this.getTopLayerFrameAtSceneCoords({ x, y });
|
|
1902
1925
|
if (topLayerFrame) {
|
|
1903
1926
|
const eligibleElements = filterElementsEligibleAsFrameChildren(newElements, topLayerFrame);
|
|
1904
|
-
addElementsToFrame(
|
|
1927
|
+
addElementsToFrame(nextElements, eligibleElements, topLayerFrame);
|
|
1905
1928
|
}
|
|
1906
|
-
this.scene.replaceAllElements(
|
|
1929
|
+
this.scene.replaceAllElements(nextElements);
|
|
1907
1930
|
newElements.forEach((newElement) => {
|
|
1908
1931
|
if (isTextElement(newElement) && isBoundToContainer(newElement)) {
|
|
1909
1932
|
const container = getContainerElement(newElement, this.scene.getElementsMapIncludingDeleted());
|
|
@@ -1913,7 +1936,7 @@ class App extends React.Component {
|
|
|
1913
1936
|
if (opts.files) {
|
|
1914
1937
|
this.files = { ...this.files, ...opts.files };
|
|
1915
1938
|
}
|
|
1916
|
-
this.
|
|
1939
|
+
this.store.shouldCaptureIncrement();
|
|
1917
1940
|
const nextElementsToSelect = excludeElementsInFramesFromSelection(newElements);
|
|
1918
1941
|
this.setState({
|
|
1919
1942
|
...this.state,
|
|
@@ -2071,16 +2094,7 @@ class App extends React.Component {
|
|
|
2071
2094
|
if (textElements.length === 0) {
|
|
2072
2095
|
return;
|
|
2073
2096
|
}
|
|
2074
|
-
|
|
2075
|
-
if (frameId) {
|
|
2076
|
-
this.scene.insertElementsAtIndex(textElements, this.scene.getElementIndex(frameId));
|
|
2077
|
-
}
|
|
2078
|
-
else {
|
|
2079
|
-
this.scene.replaceAllElements([
|
|
2080
|
-
...this.scene.getElementsIncludingDeleted(),
|
|
2081
|
-
...textElements,
|
|
2082
|
-
]);
|
|
2083
|
-
}
|
|
2097
|
+
this.scene.insertElements(textElements);
|
|
2084
2098
|
this.setState({
|
|
2085
2099
|
selectedElementIds: makeNextSelectedElementIds(Object.fromEntries(textElements.map((el) => [el.id, true])), this.state),
|
|
2086
2100
|
});
|
|
@@ -2096,7 +2110,7 @@ class App extends React.Component {
|
|
|
2096
2110
|
});
|
|
2097
2111
|
PLAIN_PASTE_TOAST_SHOWN = true;
|
|
2098
2112
|
}
|
|
2099
|
-
this.
|
|
2113
|
+
this.store.shouldCaptureIncrement();
|
|
2100
2114
|
}
|
|
2101
2115
|
setAppState = (state, callback) => {
|
|
2102
2116
|
this.setState(state, callback);
|
|
@@ -2282,14 +2296,31 @@ class App extends React.Component {
|
|
|
2282
2296
|
this.addNewImagesToImageCache();
|
|
2283
2297
|
});
|
|
2284
2298
|
updateScene = withBatchedUpdates((sceneData) => {
|
|
2285
|
-
|
|
2286
|
-
|
|
2299
|
+
const nextElements = syncInvalidIndices(sceneData.elements ?? []);
|
|
2300
|
+
if (sceneData.storeAction && sceneData.storeAction !== StoreAction.NONE) {
|
|
2301
|
+
const prevCommittedAppState = this.store.snapshot.appState;
|
|
2302
|
+
const prevCommittedElements = this.store.snapshot.elements;
|
|
2303
|
+
const nextCommittedAppState = sceneData.appState
|
|
2304
|
+
? Object.assign({}, prevCommittedAppState, sceneData.appState) // new instance, with partial appstate applied to previously captured one, including hidden prop inside `prevCommittedAppState`
|
|
2305
|
+
: prevCommittedAppState;
|
|
2306
|
+
const nextCommittedElements = sceneData.elements
|
|
2307
|
+
? this.store.filterUncomittedElements(this.scene.getElementsMapIncludingDeleted(), // Only used to detect uncomitted local elements
|
|
2308
|
+
arrayToMap(nextElements))
|
|
2309
|
+
: prevCommittedElements;
|
|
2310
|
+
// WARN: store action always performs deep clone of changed elements, for ephemeral remote updates (i.e. remote dragging, resizing, drawing) we might consider doing something smarter
|
|
2311
|
+
// do NOT schedule store actions (execute after re-render), as it might cause unexpected concurrency issues if not handled well
|
|
2312
|
+
if (sceneData.storeAction === StoreAction.CAPTURE) {
|
|
2313
|
+
this.store.captureIncrement(nextCommittedElements, nextCommittedAppState);
|
|
2314
|
+
}
|
|
2315
|
+
else if (sceneData.storeAction === StoreAction.UPDATE) {
|
|
2316
|
+
this.store.updateSnapshot(nextCommittedElements, nextCommittedAppState);
|
|
2317
|
+
}
|
|
2287
2318
|
}
|
|
2288
2319
|
if (sceneData.appState) {
|
|
2289
2320
|
this.setState(sceneData.appState);
|
|
2290
2321
|
}
|
|
2291
2322
|
if (sceneData.elements) {
|
|
2292
|
-
this.scene.replaceAllElements(
|
|
2323
|
+
this.scene.replaceAllElements(nextElements);
|
|
2293
2324
|
}
|
|
2294
2325
|
if (sceneData.collaborators) {
|
|
2295
2326
|
this.setState({ collaborators: sceneData.collaborators });
|
|
@@ -2355,8 +2386,7 @@ class App extends React.Component {
|
|
|
2355
2386
|
!event.altKey) {
|
|
2356
2387
|
this.setToast({
|
|
2357
2388
|
message: t("commandPalette.shortcutHint", {
|
|
2358
|
-
|
|
2359
|
-
shortcutTwo: getShortcutFromShortcutName("commandPalette", 1),
|
|
2389
|
+
shortcut: getShortcutFromShortcutName("commandPalette"),
|
|
2360
2390
|
}),
|
|
2361
2391
|
});
|
|
2362
2392
|
event.preventDefault();
|
|
@@ -2464,7 +2494,9 @@ class App extends React.Component {
|
|
|
2464
2494
|
simultaneouslyUpdated: selectedElements,
|
|
2465
2495
|
});
|
|
2466
2496
|
});
|
|
2467
|
-
this.
|
|
2497
|
+
this.setState({
|
|
2498
|
+
suggestedBindings: getSuggestedBindingsForArrows(selectedElements, this),
|
|
2499
|
+
});
|
|
2468
2500
|
event.preventDefault();
|
|
2469
2501
|
}
|
|
2470
2502
|
else if (event.key === KEYS.ENTER) {
|
|
@@ -2476,7 +2508,7 @@ class App extends React.Component {
|
|
|
2476
2508
|
if (!this.state.editingLinearElement ||
|
|
2477
2509
|
this.state.editingLinearElement.elementId !==
|
|
2478
2510
|
selectedElements[0].id) {
|
|
2479
|
-
this.
|
|
2511
|
+
this.store.shouldCaptureIncrement();
|
|
2480
2512
|
this.setState({
|
|
2481
2513
|
editingLinearElement: new LinearElementEditor(selectedElement),
|
|
2482
2514
|
});
|
|
@@ -2602,11 +2634,7 @@ class App extends React.Component {
|
|
|
2602
2634
|
this.setState({ isBindingEnabled: true });
|
|
2603
2635
|
}
|
|
2604
2636
|
if (isArrowKey(event.key)) {
|
|
2605
|
-
|
|
2606
|
-
const elementsMap = this.scene.getNonDeletedElementsMap();
|
|
2607
|
-
isBindingEnabled(this.state)
|
|
2608
|
-
? bindOrUnbindSelectedElements(selectedElements, this.scene.getNonDeletedElements(), elementsMap)
|
|
2609
|
-
: unbindLinearElements(selectedElements, elementsMap);
|
|
2637
|
+
bindOrUnbindLinearElements(this.scene.getSelectedElements(this.state).filter(isLinearElement), this, isBindingEnabled(this.state), this.state.selectedLinearElement?.selectedPointsIndices ?? []);
|
|
2610
2638
|
this.setState({ suggestedBindings: [] });
|
|
2611
2639
|
}
|
|
2612
2640
|
});
|
|
@@ -2644,6 +2672,9 @@ class App extends React.Component {
|
|
|
2644
2672
|
originSnapOffset: null,
|
|
2645
2673
|
activeEmbeddable: null,
|
|
2646
2674
|
};
|
|
2675
|
+
if (nextActiveTool.type === "freedraw") {
|
|
2676
|
+
this.store.shouldCaptureIncrement();
|
|
2677
|
+
}
|
|
2647
2678
|
if (nextActiveTool.type !== "selection") {
|
|
2648
2679
|
return {
|
|
2649
2680
|
...prevState,
|
|
@@ -2797,7 +2828,7 @@ class App extends React.Component {
|
|
|
2797
2828
|
]);
|
|
2798
2829
|
}
|
|
2799
2830
|
if (!isDeleted || isExistingElement) {
|
|
2800
|
-
this.
|
|
2831
|
+
this.store.shouldCaptureIncrement();
|
|
2801
2832
|
}
|
|
2802
2833
|
this.setState({
|
|
2803
2834
|
draggingElement: null,
|
|
@@ -2835,6 +2866,57 @@ class App extends React.Component {
|
|
|
2835
2866
|
}
|
|
2836
2867
|
return null;
|
|
2837
2868
|
}
|
|
2869
|
+
/**
|
|
2870
|
+
* get the pure geometric shape of an excalidraw element
|
|
2871
|
+
* which is then used for hit detection
|
|
2872
|
+
*/
|
|
2873
|
+
getElementShape(element) {
|
|
2874
|
+
switch (element.type) {
|
|
2875
|
+
case "rectangle":
|
|
2876
|
+
case "diamond":
|
|
2877
|
+
case "frame":
|
|
2878
|
+
case "magicframe":
|
|
2879
|
+
case "embeddable":
|
|
2880
|
+
case "image":
|
|
2881
|
+
case "iframe":
|
|
2882
|
+
case "text":
|
|
2883
|
+
case "selection":
|
|
2884
|
+
return getPolygonShape(element);
|
|
2885
|
+
case "arrow":
|
|
2886
|
+
case "line": {
|
|
2887
|
+
const roughShape = ShapeCache.get(element)?.[0] ??
|
|
2888
|
+
ShapeCache.generateElementShape(element, null)[0];
|
|
2889
|
+
const [, , , , cx, cy] = getElementAbsoluteCoords(element, this.scene.getNonDeletedElementsMap());
|
|
2890
|
+
return shouldTestInside(element)
|
|
2891
|
+
? getClosedCurveShape(element, roughShape, [element.x, element.y], element.angle, [cx, cy])
|
|
2892
|
+
: getCurveShape(roughShape, [element.x, element.y], element.angle, [
|
|
2893
|
+
cx,
|
|
2894
|
+
cy,
|
|
2895
|
+
]);
|
|
2896
|
+
}
|
|
2897
|
+
case "ellipse":
|
|
2898
|
+
return getEllipseShape(element);
|
|
2899
|
+
case "freedraw": {
|
|
2900
|
+
const [, , , , cx, cy] = getElementAbsoluteCoords(element, this.scene.getNonDeletedElementsMap());
|
|
2901
|
+
return getFreedrawShape(element, [cx, cy], shouldTestInside(element));
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
getBoundTextShape(element) {
|
|
2906
|
+
const boundTextElement = getBoundTextElement(element, this.scene.getNonDeletedElementsMap());
|
|
2907
|
+
if (boundTextElement) {
|
|
2908
|
+
if (element.type === "arrow") {
|
|
2909
|
+
return this.getElementShape({
|
|
2910
|
+
...boundTextElement,
|
|
2911
|
+
// arrow's bound text accurate position is not stored in the element's property
|
|
2912
|
+
// but rather calculated and returned from the following static method
|
|
2913
|
+
...LinearElementEditor.getBoundTextElementPosition(element, boundTextElement, this.scene.getNonDeletedElementsMap()),
|
|
2914
|
+
});
|
|
2915
|
+
}
|
|
2916
|
+
return this.getElementShape(boundTextElement);
|
|
2917
|
+
}
|
|
2918
|
+
return null;
|
|
2919
|
+
}
|
|
2838
2920
|
getElementAtPosition(x, y, opts) {
|
|
2839
2921
|
const allHitElements = this.getElementsAtPosition(x, y, opts?.includeBoundTextElement, opts?.includeLockedElements);
|
|
2840
2922
|
if (allHitElements.length > 1) {
|
|
@@ -2848,9 +2930,20 @@ class App extends React.Component {
|
|
|
2848
2930
|
const elementWithHighestZIndex = allHitElements[allHitElements.length - 1];
|
|
2849
2931
|
// If we're hitting element with highest z-index only on its bounding box
|
|
2850
2932
|
// while also hitting other element figure, the latter should be considered.
|
|
2851
|
-
return
|
|
2852
|
-
|
|
2853
|
-
|
|
2933
|
+
return hitElementItself({
|
|
2934
|
+
x,
|
|
2935
|
+
y,
|
|
2936
|
+
element: elementWithHighestZIndex,
|
|
2937
|
+
shape: this.getElementShape(elementWithHighestZIndex),
|
|
2938
|
+
// when overlapping, we would like to be more precise
|
|
2939
|
+
// this also avoids the need to update past tests
|
|
2940
|
+
threshold: this.getElementHitThreshold() / 2,
|
|
2941
|
+
frameNameBound: isFrameLikeElement(elementWithHighestZIndex)
|
|
2942
|
+
? this.frameNameBoundsCache.get(elementWithHighestZIndex)
|
|
2943
|
+
: null,
|
|
2944
|
+
})
|
|
2945
|
+
? elementWithHighestZIndex
|
|
2946
|
+
: allHitElements[allHitElements.length - 2];
|
|
2854
2947
|
}
|
|
2855
2948
|
if (allHitElements.length === 1) {
|
|
2856
2949
|
return allHitElements[0];
|
|
@@ -2858,15 +2951,17 @@ class App extends React.Component {
|
|
|
2858
2951
|
return null;
|
|
2859
2952
|
}
|
|
2860
2953
|
getElementsAtPosition(x, y, includeBoundTextElement = false, includeLockedElements = false) {
|
|
2861
|
-
const
|
|
2954
|
+
const iframeLikes = [];
|
|
2955
|
+
const elementsMap = this.scene.getNonDeletedElementsMap();
|
|
2956
|
+
const elements = (includeBoundTextElement && includeLockedElements
|
|
2862
2957
|
? this.scene.getNonDeletedElements()
|
|
2863
2958
|
: this.scene
|
|
2864
2959
|
.getNonDeletedElements()
|
|
2865
2960
|
.filter((element) => (includeLockedElements || !element.locked) &&
|
|
2866
2961
|
(includeBoundTextElement ||
|
|
2867
|
-
!(isTextElement(element) && element.containerId)))
|
|
2868
|
-
|
|
2869
|
-
|
|
2962
|
+
!(isTextElement(element) && element.containerId))))
|
|
2963
|
+
.filter((el) => this.hitElement(x, y, el))
|
|
2964
|
+
.filter((element) => {
|
|
2870
2965
|
// hitting a frame's element from outside the frame is not considered a hit
|
|
2871
2966
|
const containingFrame = getContainingFrame(element, elementsMap);
|
|
2872
2967
|
return containingFrame &&
|
|
@@ -2874,8 +2969,81 @@ class App extends React.Component {
|
|
|
2874
2969
|
this.state.frameRendering.clip
|
|
2875
2970
|
? isCursorInFrame({ x, y }, containingFrame, elementsMap)
|
|
2876
2971
|
: true;
|
|
2972
|
+
})
|
|
2973
|
+
.filter((el) => {
|
|
2974
|
+
// The parameter elements comes ordered from lower z-index to higher.
|
|
2975
|
+
// We want to preserve that order on the returned array.
|
|
2976
|
+
// Exception being embeddables which should be on top of everything else in
|
|
2977
|
+
// terms of hit testing.
|
|
2978
|
+
if (isIframeElement(el)) {
|
|
2979
|
+
iframeLikes.push(el);
|
|
2980
|
+
return false;
|
|
2981
|
+
}
|
|
2982
|
+
return true;
|
|
2983
|
+
})
|
|
2984
|
+
.concat(iframeLikes);
|
|
2985
|
+
return elements;
|
|
2986
|
+
}
|
|
2987
|
+
getElementHitThreshold() {
|
|
2988
|
+
return DEFAULT_COLLISION_THRESHOLD / this.state.zoom.value;
|
|
2989
|
+
}
|
|
2990
|
+
hitElement(x, y, element, considerBoundingBox = true) {
|
|
2991
|
+
// if the element is selected, then hit test is done against its bounding box
|
|
2992
|
+
if (considerBoundingBox &&
|
|
2993
|
+
this.state.selectedElementIds[element.id] &&
|
|
2994
|
+
shouldShowBoundingBox([element], this.state)) {
|
|
2995
|
+
const selectionShape = getSelectionBoxShape(element, this.scene.getNonDeletedElementsMap(), this.getElementHitThreshold());
|
|
2996
|
+
return isPointInShape([x, y], selectionShape);
|
|
2997
|
+
}
|
|
2998
|
+
// take bound text element into consideration for hit collision as well
|
|
2999
|
+
const hitBoundTextOfElement = hitElementBoundText(x, y, this.getBoundTextShape(element));
|
|
3000
|
+
if (hitBoundTextOfElement) {
|
|
3001
|
+
return true;
|
|
3002
|
+
}
|
|
3003
|
+
return hitElementItself({
|
|
3004
|
+
x,
|
|
3005
|
+
y,
|
|
3006
|
+
element,
|
|
3007
|
+
shape: this.getElementShape(element),
|
|
3008
|
+
threshold: this.getElementHitThreshold(),
|
|
3009
|
+
frameNameBound: isFrameLikeElement(element)
|
|
3010
|
+
? this.frameNameBoundsCache.get(element)
|
|
3011
|
+
: null,
|
|
2877
3012
|
});
|
|
2878
3013
|
}
|
|
3014
|
+
getTextBindableContainerAtPosition(x, y) {
|
|
3015
|
+
const elements = this.scene.getNonDeletedElements();
|
|
3016
|
+
const selectedElements = this.scene.getSelectedElements(this.state);
|
|
3017
|
+
if (selectedElements.length === 1) {
|
|
3018
|
+
return isTextBindableContainer(selectedElements[0], false)
|
|
3019
|
+
? selectedElements[0]
|
|
3020
|
+
: null;
|
|
3021
|
+
}
|
|
3022
|
+
let hitElement = null;
|
|
3023
|
+
// We need to do hit testing from front (end of the array) to back (beginning of the array)
|
|
3024
|
+
for (let index = elements.length - 1; index >= 0; --index) {
|
|
3025
|
+
if (elements[index].isDeleted) {
|
|
3026
|
+
continue;
|
|
3027
|
+
}
|
|
3028
|
+
const [x1, y1, x2, y2] = getElementAbsoluteCoords(elements[index], this.scene.getNonDeletedElementsMap());
|
|
3029
|
+
if (isArrowElement(elements[index]) &&
|
|
3030
|
+
hitElementItself({
|
|
3031
|
+
x,
|
|
3032
|
+
y,
|
|
3033
|
+
element: elements[index],
|
|
3034
|
+
shape: this.getElementShape(elements[index]),
|
|
3035
|
+
threshold: this.getElementHitThreshold(),
|
|
3036
|
+
})) {
|
|
3037
|
+
hitElement = elements[index];
|
|
3038
|
+
break;
|
|
3039
|
+
}
|
|
3040
|
+
else if (x1 < x && x < x2 && y1 < y && y < y2) {
|
|
3041
|
+
hitElement = elements[index];
|
|
3042
|
+
break;
|
|
3043
|
+
}
|
|
3044
|
+
}
|
|
3045
|
+
return isTextBindableContainer(hitElement, false) ? hitElement : null;
|
|
3046
|
+
}
|
|
2879
3047
|
startTextEditing = ({ sceneX, sceneY, insertAtParentCenter = true, container, }) => {
|
|
2880
3048
|
let shouldBindToContainer = false;
|
|
2881
3049
|
let parentCenterPosition = insertAtParentCenter &&
|
|
@@ -2974,7 +3142,7 @@ class App extends React.Component {
|
|
|
2974
3142
|
this.scene.insertElementAtIndex(element, containerIndex + 1);
|
|
2975
3143
|
}
|
|
2976
3144
|
else {
|
|
2977
|
-
this.scene.
|
|
3145
|
+
this.scene.insertElement(element);
|
|
2978
3146
|
}
|
|
2979
3147
|
}
|
|
2980
3148
|
this.setState({
|
|
@@ -2999,7 +3167,7 @@ class App extends React.Component {
|
|
|
2999
3167
|
if (event[KEYS.CTRL_OR_CMD] &&
|
|
3000
3168
|
(!this.state.editingLinearElement ||
|
|
3001
3169
|
this.state.editingLinearElement.elementId !== selectedElements[0].id)) {
|
|
3002
|
-
this.
|
|
3170
|
+
this.store.shouldCaptureIncrement();
|
|
3003
3171
|
this.setState({
|
|
3004
3172
|
editingLinearElement: new LinearElementEditor(selectedElements[0]),
|
|
3005
3173
|
});
|
|
@@ -3014,6 +3182,7 @@ class App extends React.Component {
|
|
|
3014
3182
|
const selectedGroupId = hitElement &&
|
|
3015
3183
|
getSelectedGroupIdForElement(hitElement, this.state.selectedGroupIds);
|
|
3016
3184
|
if (selectedGroupId) {
|
|
3185
|
+
this.store.shouldCaptureIncrement();
|
|
3017
3186
|
this.setState((prevState) => ({
|
|
3018
3187
|
...prevState,
|
|
3019
3188
|
...selectGroupsForSelectedElements({
|
|
@@ -3033,11 +3202,17 @@ class App extends React.Component {
|
|
|
3033
3202
|
});
|
|
3034
3203
|
return;
|
|
3035
3204
|
}
|
|
3036
|
-
const container =
|
|
3205
|
+
const container = this.getTextBindableContainerAtPosition(sceneX, sceneY);
|
|
3037
3206
|
if (container) {
|
|
3038
3207
|
if (hasBoundTextElement(container) ||
|
|
3039
3208
|
!isTransparent(container.backgroundColor) ||
|
|
3040
|
-
|
|
3209
|
+
hitElementItself({
|
|
3210
|
+
x: sceneX,
|
|
3211
|
+
y: sceneY,
|
|
3212
|
+
element: container,
|
|
3213
|
+
shape: this.getElementShape(container),
|
|
3214
|
+
threshold: this.getElementHitThreshold(),
|
|
3215
|
+
})) {
|
|
3041
3216
|
const midPoint = getContainerCenter(container, this.state, this.scene.getNonDeletedElementsMap());
|
|
3042
3217
|
sceneX = midPoint.x;
|
|
3043
3218
|
sceneY = midPoint.y;
|
|
@@ -3092,7 +3267,7 @@ class App extends React.Component {
|
|
|
3092
3267
|
}
|
|
3093
3268
|
if (!customEvent?.defaultPrevented) {
|
|
3094
3269
|
const target = isLocalLink(url) ? "_self" : "_blank";
|
|
3095
|
-
const newWindow = window.open(undefined, target
|
|
3270
|
+
const newWindow = window.open(undefined, target);
|
|
3096
3271
|
// https://mathiasbynens.github.io/rel-noopener/
|
|
3097
3272
|
if (newWindow) {
|
|
3098
3273
|
newWindow.opener = null;
|
|
@@ -3308,15 +3483,23 @@ class App extends React.Component {
|
|
|
3308
3483
|
if (selectedElements.length === 1 &&
|
|
3309
3484
|
!isOverScrollBar &&
|
|
3310
3485
|
!this.state.editingLinearElement) {
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3486
|
+
// for linear elements, we'd like to prioritize point dragging over edge resizing
|
|
3487
|
+
// therefore, we update and check hovered point index first
|
|
3488
|
+
if (this.state.selectedLinearElement) {
|
|
3489
|
+
this.handleHoverSelectedLinearElement(this.state.selectedLinearElement, scenePointerX, scenePointerY);
|
|
3490
|
+
}
|
|
3491
|
+
if (!this.state.selectedLinearElement ||
|
|
3492
|
+
this.state.selectedLinearElement.hoverPointIndex === -1) {
|
|
3493
|
+
const elementWithTransformHandleType = getElementWithTransformHandleType(elements, this.state, scenePointerX, scenePointerY, this.state.zoom, event.pointerType, this.scene.getNonDeletedElementsMap(), this.device);
|
|
3494
|
+
if (elementWithTransformHandleType &&
|
|
3495
|
+
elementWithTransformHandleType.transformHandleType) {
|
|
3496
|
+
setCursor(this.interactiveCanvas, getCursorForResizingElement(elementWithTransformHandleType));
|
|
3497
|
+
return;
|
|
3498
|
+
}
|
|
3316
3499
|
}
|
|
3317
3500
|
}
|
|
3318
3501
|
else if (selectedElements.length > 1 && !isOverScrollBar) {
|
|
3319
|
-
const transformHandleType = getTransformHandleTypeFromCoords(getCommonBounds(selectedElements), scenePointerX, scenePointerY, this.state.zoom, event.pointerType);
|
|
3502
|
+
const transformHandleType = getTransformHandleTypeFromCoords(getCommonBounds(selectedElements), scenePointerX, scenePointerY, this.state.zoom, event.pointerType, this.device);
|
|
3320
3503
|
if (transformHandleType) {
|
|
3321
3504
|
setCursor(this.interactiveCanvas, getCursorForResizingElement({
|
|
3322
3505
|
transformHandleType,
|
|
@@ -3420,7 +3603,7 @@ class App extends React.Component {
|
|
|
3420
3603
|
}
|
|
3421
3604
|
};
|
|
3422
3605
|
const distance = distance2d(pointerDownState.lastCoords.x, pointerDownState.lastCoords.y, scenePointer.x, scenePointer.y);
|
|
3423
|
-
const threshold =
|
|
3606
|
+
const threshold = this.getElementHitThreshold();
|
|
3424
3607
|
const point = { ...pointerDownState.lastCoords };
|
|
3425
3608
|
let samplingInterval = 0;
|
|
3426
3609
|
while (samplingInterval <= distance) {
|
|
@@ -3466,30 +3649,29 @@ class App extends React.Component {
|
|
|
3466
3649
|
handleHoverSelectedLinearElement(linearElementEditor, scenePointerX, scenePointerY) {
|
|
3467
3650
|
const elementsMap = this.scene.getNonDeletedElementsMap();
|
|
3468
3651
|
const element = LinearElementEditor.getElement(linearElementEditor.elementId, elementsMap);
|
|
3469
|
-
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
3470
3652
|
if (!element) {
|
|
3471
3653
|
return;
|
|
3472
3654
|
}
|
|
3473
3655
|
if (this.state.selectedLinearElement) {
|
|
3474
3656
|
let hoverPointIndex = -1;
|
|
3475
3657
|
let segmentMidPointHoveredCoords = null;
|
|
3476
|
-
if (
|
|
3658
|
+
if (hitElementItself({
|
|
3659
|
+
x: scenePointerX,
|
|
3660
|
+
y: scenePointerY,
|
|
3661
|
+
element,
|
|
3662
|
+
shape: this.getElementShape(element),
|
|
3663
|
+
})) {
|
|
3477
3664
|
hoverPointIndex = LinearElementEditor.getPointIndexUnderCursor(element, elementsMap, this.state.zoom, scenePointerX, scenePointerY);
|
|
3478
3665
|
segmentMidPointHoveredCoords =
|
|
3479
3666
|
LinearElementEditor.getSegmentMidpointHitCoords(linearElementEditor, { x: scenePointerX, y: scenePointerY }, this.state, this.scene.getNonDeletedElementsMap());
|
|
3480
3667
|
if (hoverPointIndex >= 0 || segmentMidPointHoveredCoords) {
|
|
3481
3668
|
setCursor(this.interactiveCanvas, CURSOR_TYPE.POINTER);
|
|
3482
3669
|
}
|
|
3483
|
-
else {
|
|
3670
|
+
else if (this.hitElement(scenePointerX, scenePointerY, element)) {
|
|
3484
3671
|
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
|
3485
3672
|
}
|
|
3486
3673
|
}
|
|
3487
|
-
else if (
|
|
3488
|
-
isHittingElementBoundingBoxWithoutHittingElement(element, this.state, this.frameNameBoundsCache, scenePointerX, scenePointerY, elementsMap)) {
|
|
3489
|
-
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
|
3490
|
-
}
|
|
3491
|
-
else if (boundTextElement &&
|
|
3492
|
-
hitTest(boundTextElement, this.state, this.frameNameBoundsCache, scenePointerX, scenePointerY, this.scene.getNonDeletedElementsMap())) {
|
|
3674
|
+
else if (this.hitElement(scenePointerX, scenePointerY, element)) {
|
|
3493
3675
|
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
|
3494
3676
|
}
|
|
3495
3677
|
if (this.state.selectedLinearElement.hoverPointIndex !== hoverPointIndex) {
|
|
@@ -3556,6 +3738,7 @@ class App extends React.Component {
|
|
|
3556
3738
|
return obj;
|
|
3557
3739
|
}, {}), this.state),
|
|
3558
3740
|
},
|
|
3741
|
+
storeAction: StoreAction.UPDATE,
|
|
3559
3742
|
});
|
|
3560
3743
|
return;
|
|
3561
3744
|
}
|
|
@@ -3995,8 +4178,11 @@ class App extends React.Component {
|
|
|
3995
4178
|
const elements = this.scene.getNonDeletedElements();
|
|
3996
4179
|
const elementsMap = this.scene.getNonDeletedElementsMap();
|
|
3997
4180
|
const selectedElements = this.scene.getSelectedElements(this.state);
|
|
3998
|
-
if (selectedElements.length === 1 &&
|
|
3999
|
-
|
|
4181
|
+
if (selectedElements.length === 1 &&
|
|
4182
|
+
!this.state.editingLinearElement &&
|
|
4183
|
+
!(this.state.selectedLinearElement &&
|
|
4184
|
+
this.state.selectedLinearElement.hoverPointIndex !== -1)) {
|
|
4185
|
+
const elementWithTransformHandleType = getElementWithTransformHandleType(elements, this.state, pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType, this.scene.getNonDeletedElementsMap(), this.device);
|
|
4000
4186
|
if (elementWithTransformHandleType != null) {
|
|
4001
4187
|
this.setState({
|
|
4002
4188
|
resizingElement: elementWithTransformHandleType.element,
|
|
@@ -4006,7 +4192,7 @@ class App extends React.Component {
|
|
|
4006
4192
|
}
|
|
4007
4193
|
}
|
|
4008
4194
|
else if (selectedElements.length > 1) {
|
|
4009
|
-
pointerDownState.resize.handleType = getTransformHandleTypeFromCoords(getCommonBounds(selectedElements), pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);
|
|
4195
|
+
pointerDownState.resize.handleType = getTransformHandleTypeFromCoords(getCommonBounds(selectedElements), pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType, this.device);
|
|
4010
4196
|
}
|
|
4011
4197
|
if (pointerDownState.resize.handleType) {
|
|
4012
4198
|
pointerDownState.resize.isResizing = true;
|
|
@@ -4020,7 +4206,7 @@ class App extends React.Component {
|
|
|
4020
4206
|
else {
|
|
4021
4207
|
if (this.state.selectedLinearElement) {
|
|
4022
4208
|
const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;
|
|
4023
|
-
const ret = LinearElementEditor.handlePointerDown(event, this.state, this.
|
|
4209
|
+
const ret = LinearElementEditor.handlePointerDown(event, this.state, this.store, pointerDownState.origin, linearElementEditor, this);
|
|
4024
4210
|
if (ret.hitElement) {
|
|
4025
4211
|
pointerDownState.hit.element = ret.hitElement;
|
|
4026
4212
|
}
|
|
@@ -4181,7 +4367,7 @@ class App extends React.Component {
|
|
|
4181
4367
|
return false;
|
|
4182
4368
|
}
|
|
4183
4369
|
// How many pixels off the shape boundary we still consider a hit
|
|
4184
|
-
const threshold =
|
|
4370
|
+
const threshold = this.getElementHitThreshold();
|
|
4185
4371
|
const [x1, y1, x2, y2] = getCommonBounds(selectedElements);
|
|
4186
4372
|
return (point.x > x1 - threshold &&
|
|
4187
4373
|
point.x < x2 + threshold &&
|
|
@@ -4201,7 +4387,7 @@ class App extends React.Component {
|
|
|
4201
4387
|
includeBoundTextElement: true,
|
|
4202
4388
|
});
|
|
4203
4389
|
// FIXME
|
|
4204
|
-
let container =
|
|
4390
|
+
let container = this.getTextBindableContainerAtPosition(sceneX, sceneY);
|
|
4205
4391
|
if (hasBoundTextElement(element)) {
|
|
4206
4392
|
container = element;
|
|
4207
4393
|
sceneX = element.x + element.width / 2;
|
|
@@ -4259,8 +4445,8 @@ class App extends React.Component {
|
|
|
4259
4445
|
points: [[0, 0]],
|
|
4260
4446
|
pressures,
|
|
4261
4447
|
});
|
|
4262
|
-
const boundElement = getHoveredElementForBinding(pointerDownState.origin, this
|
|
4263
|
-
this.scene.
|
|
4448
|
+
const boundElement = getHoveredElementForBinding(pointerDownState.origin, this);
|
|
4449
|
+
this.scene.insertElement(element);
|
|
4264
4450
|
this.setState({
|
|
4265
4451
|
draggingElement: element,
|
|
4266
4452
|
editingElement: element,
|
|
@@ -4288,10 +4474,7 @@ class App extends React.Component {
|
|
|
4288
4474
|
width,
|
|
4289
4475
|
height,
|
|
4290
4476
|
});
|
|
4291
|
-
this.scene.
|
|
4292
|
-
...this.scene.getElementsIncludingDeleted(),
|
|
4293
|
-
element,
|
|
4294
|
-
]);
|
|
4477
|
+
this.scene.insertElement(element);
|
|
4295
4478
|
return element;
|
|
4296
4479
|
};
|
|
4297
4480
|
//create rectangle element with youtube top left on nearest grid point width / hight 640/360
|
|
@@ -4326,10 +4509,7 @@ class App extends React.Component {
|
|
|
4326
4509
|
height: embedLink.intrinsicSize.h,
|
|
4327
4510
|
link,
|
|
4328
4511
|
});
|
|
4329
|
-
this.scene.
|
|
4330
|
-
...this.scene.getElementsIncludingDeleted(),
|
|
4331
|
-
element,
|
|
4332
|
-
]);
|
|
4512
|
+
this.scene.insertElement(element);
|
|
4333
4513
|
return element;
|
|
4334
4514
|
};
|
|
4335
4515
|
createImageElement = ({ sceneX, sceneY, addToFrameUnderCursor = true, }) => {
|
|
@@ -4437,8 +4617,8 @@ class App extends React.Component {
|
|
|
4437
4617
|
mutateElement(element, {
|
|
4438
4618
|
points: [...element.points, [0, 0]],
|
|
4439
4619
|
});
|
|
4440
|
-
const boundElement = getHoveredElementForBinding(pointerDownState.origin, this
|
|
4441
|
-
this.scene.
|
|
4620
|
+
const boundElement = getHoveredElementForBinding(pointerDownState.origin, this);
|
|
4621
|
+
this.scene.insertElement(element);
|
|
4442
4622
|
this.setState({
|
|
4443
4623
|
draggingElement: element,
|
|
4444
4624
|
editingElement: element,
|
|
@@ -4498,7 +4678,7 @@ class App extends React.Component {
|
|
|
4498
4678
|
});
|
|
4499
4679
|
}
|
|
4500
4680
|
else {
|
|
4501
|
-
this.scene.
|
|
4681
|
+
this.scene.insertElement(element);
|
|
4502
4682
|
this.setState({
|
|
4503
4683
|
multiElement: null,
|
|
4504
4684
|
draggingElement: element,
|
|
@@ -4520,10 +4700,7 @@ class App extends React.Component {
|
|
|
4520
4700
|
const frame = type === TOOL_TYPE.magicframe
|
|
4521
4701
|
? newMagicFrameElement(constructorOpts)
|
|
4522
4702
|
: newFrameElement(constructorOpts);
|
|
4523
|
-
this.scene.
|
|
4524
|
-
...this.scene.getElementsIncludingDeleted(),
|
|
4525
|
-
frame,
|
|
4526
|
-
]);
|
|
4703
|
+
this.scene.insertElement(frame);
|
|
4527
4704
|
this.setState({
|
|
4528
4705
|
multiElement: null,
|
|
4529
4706
|
draggingElement: frame,
|
|
@@ -4737,7 +4914,9 @@ class App extends React.Component {
|
|
|
4737
4914
|
// able to select and interact with the text input
|
|
4738
4915
|
!this.state.editingFrame &&
|
|
4739
4916
|
dragSelectedElements(pointerDownState, selectedElements, dragOffset, this.state, this.scene, snapOffset, event[KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);
|
|
4740
|
-
this.
|
|
4917
|
+
this.setState({
|
|
4918
|
+
suggestedBindings: getSuggestedBindingsForArrows(selectedElements, this),
|
|
4919
|
+
});
|
|
4741
4920
|
// We duplicate the selected element if alt is pressed on pointer move
|
|
4742
4921
|
if (event.altKey && !pointerDownState.hit.hasBeenDuplicated) {
|
|
4743
4922
|
// Move the currently selected elements to the top of the z index stack, and
|
|
@@ -4781,6 +4960,7 @@ class App extends React.Component {
|
|
|
4781
4960
|
}
|
|
4782
4961
|
}
|
|
4783
4962
|
const nextSceneElements = [...nextElements, ...elementsToAppend];
|
|
4963
|
+
syncMovedIndices(nextSceneElements, arrayToMap(elementsToAppend));
|
|
4784
4964
|
bindTextToShapeAfterDuplication(nextElements, elementsToAppend, oldIdToDuplicatedId);
|
|
4785
4965
|
fixBindingsAfterDuplication(nextSceneElements, elementsToAppend, oldIdToDuplicatedId, "duplicatesServeAsOld");
|
|
4786
4966
|
bindElementsToFramesAfterDuplication(nextSceneElements, elementsToAppend, oldIdToDuplicatedId);
|
|
@@ -4972,7 +5152,7 @@ class App extends React.Component {
|
|
|
4972
5152
|
this.actionManager.executeAction(actionFinalize);
|
|
4973
5153
|
}
|
|
4974
5154
|
else {
|
|
4975
|
-
const editingLinearElement = LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state, this
|
|
5155
|
+
const editingLinearElement = LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state, this);
|
|
4976
5156
|
if (editingLinearElement !== this.state.editingLinearElement) {
|
|
4977
5157
|
this.setState({
|
|
4978
5158
|
editingLinearElement,
|
|
@@ -4991,7 +5171,7 @@ class App extends React.Component {
|
|
|
4991
5171
|
}
|
|
4992
5172
|
}
|
|
4993
5173
|
else {
|
|
4994
|
-
const linearElementEditor = LinearElementEditor.handlePointerUp(childEvent, this.state.selectedLinearElement, this.state, this
|
|
5174
|
+
const linearElementEditor = LinearElementEditor.handlePointerUp(childEvent, this.state.selectedLinearElement, this.state, this);
|
|
4995
5175
|
const { startBindingElement, endBindingElement } = linearElementEditor;
|
|
4996
5176
|
const element = this.scene.getElement(linearElementEditor.elementId);
|
|
4997
5177
|
if (isBindingElement(element)) {
|
|
@@ -5060,7 +5240,7 @@ class App extends React.Component {
|
|
|
5060
5240
|
}
|
|
5061
5241
|
if (isLinearElement(draggingElement)) {
|
|
5062
5242
|
if (draggingElement.points.length > 1) {
|
|
5063
|
-
this.
|
|
5243
|
+
this.store.shouldCaptureIncrement();
|
|
5064
5244
|
}
|
|
5065
5245
|
const pointerCoords = viewportCoordsToSceneCoords(childEvent, this.state);
|
|
5066
5246
|
if (!pointerDownState.drag.hasOccurred &&
|
|
@@ -5083,7 +5263,7 @@ class App extends React.Component {
|
|
|
5083
5263
|
else if (pointerDownState.drag.hasOccurred && !multiElement) {
|
|
5084
5264
|
if (isBindingEnabled(this.state) &&
|
|
5085
5265
|
isBindingElement(draggingElement, false)) {
|
|
5086
|
-
maybeBindLinearElement(draggingElement, this.state,
|
|
5266
|
+
maybeBindLinearElement(draggingElement, this.state, pointerCoords, this);
|
|
5087
5267
|
}
|
|
5088
5268
|
this.setState({ suggestedBindings: [], startBoundElement: null });
|
|
5089
5269
|
if (!activeTool.locked) {
|
|
@@ -5112,11 +5292,15 @@ class App extends React.Component {
|
|
|
5112
5292
|
draggingElement &&
|
|
5113
5293
|
isInvisiblySmallElement(draggingElement)) {
|
|
5114
5294
|
// remove invisible element which was added in onPointerDown
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5295
|
+
// update the store snapshot, so that invisible elements are not captured by the store
|
|
5296
|
+
this.updateScene({
|
|
5297
|
+
elements: this.scene
|
|
5298
|
+
.getElementsIncludingDeleted()
|
|
5299
|
+
.filter((el) => el.id !== draggingElement.id),
|
|
5300
|
+
appState: {
|
|
5301
|
+
draggingElement: null,
|
|
5302
|
+
},
|
|
5303
|
+
storeAction: StoreAction.UPDATE,
|
|
5120
5304
|
});
|
|
5121
5305
|
return;
|
|
5122
5306
|
}
|
|
@@ -5197,12 +5381,16 @@ class App extends React.Component {
|
|
|
5197
5381
|
mutateElement(draggingElement, getNormalizedDimensions(draggingElement));
|
|
5198
5382
|
}
|
|
5199
5383
|
if (resizingElement) {
|
|
5200
|
-
this.
|
|
5384
|
+
this.store.shouldCaptureIncrement();
|
|
5201
5385
|
}
|
|
5202
5386
|
if (resizingElement && isInvisiblySmallElement(resizingElement)) {
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5387
|
+
// update the store snapshot, so that invisible elements are not captured by the store
|
|
5388
|
+
this.updateScene({
|
|
5389
|
+
elements: this.scene
|
|
5390
|
+
.getElementsIncludingDeleted()
|
|
5391
|
+
.filter((el) => el.id !== resizingElement.id),
|
|
5392
|
+
storeAction: StoreAction.UPDATE,
|
|
5393
|
+
});
|
|
5206
5394
|
}
|
|
5207
5395
|
// handle frame membership for resizing frames and/or selected elements
|
|
5208
5396
|
if (pointerDownState.resize.isResizing) {
|
|
@@ -5357,10 +5545,23 @@ class App extends React.Component {
|
|
|
5357
5545
|
}));
|
|
5358
5546
|
}
|
|
5359
5547
|
}
|
|
5360
|
-
if (
|
|
5548
|
+
if (
|
|
5549
|
+
// not dragged
|
|
5550
|
+
!pointerDownState.drag.hasOccurred &&
|
|
5551
|
+
// not resized
|
|
5361
5552
|
!this.state.isResizing &&
|
|
5553
|
+
// only hitting the bounding box of the previous hit element
|
|
5362
5554
|
((hitElement &&
|
|
5363
|
-
|
|
5555
|
+
hitElementBoundingBoxOnly({
|
|
5556
|
+
x: pointerDownState.origin.x,
|
|
5557
|
+
y: pointerDownState.origin.y,
|
|
5558
|
+
element: hitElement,
|
|
5559
|
+
shape: this.getElementShape(hitElement),
|
|
5560
|
+
threshold: this.getElementHitThreshold(),
|
|
5561
|
+
frameNameBound: isFrameLikeElement(hitElement)
|
|
5562
|
+
? this.frameNameBoundsCache.get(hitElement)
|
|
5563
|
+
: null,
|
|
5564
|
+
}, elementsMap)) ||
|
|
5364
5565
|
(!hitElement &&
|
|
5365
5566
|
pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements))) {
|
|
5366
5567
|
if (this.state.editingLinearElement) {
|
|
@@ -5375,6 +5576,8 @@ class App extends React.Component {
|
|
|
5375
5576
|
activeEmbeddable: null,
|
|
5376
5577
|
});
|
|
5377
5578
|
}
|
|
5579
|
+
// reset cursor
|
|
5580
|
+
setCursor(this.interactiveCanvas, CURSOR_TYPE.AUTO);
|
|
5378
5581
|
return;
|
|
5379
5582
|
}
|
|
5380
5583
|
if (!activeTool.locked &&
|
|
@@ -5392,13 +5595,17 @@ class App extends React.Component {
|
|
|
5392
5595
|
}));
|
|
5393
5596
|
}
|
|
5394
5597
|
if (activeTool.type !== "selection" ||
|
|
5395
|
-
isSomeElementSelected(this.scene.getNonDeletedElements(), this.state)
|
|
5396
|
-
this.
|
|
5598
|
+
isSomeElementSelected(this.scene.getNonDeletedElements(), this.state) ||
|
|
5599
|
+
!isShallowEqual(this.state.previousSelectedElementIds, this.state.selectedElementIds)) {
|
|
5600
|
+
this.store.shouldCaptureIncrement();
|
|
5397
5601
|
}
|
|
5398
5602
|
if (pointerDownState.drag.hasOccurred || isResizing || isRotating) {
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5603
|
+
// We only allow binding via linear elements, specifically via dragging
|
|
5604
|
+
// the endpoints ("start" or "end").
|
|
5605
|
+
const linearElements = this.scene
|
|
5606
|
+
.getSelectedElements(this.state)
|
|
5607
|
+
.filter(isLinearElement);
|
|
5608
|
+
bindOrUnbindLinearElements(linearElements, this, isBindingEnabled(this.state), this.state.selectedLinearElement?.selectedPointsIndices ?? []);
|
|
5402
5609
|
}
|
|
5403
5610
|
if (activeTool.type === "laser") {
|
|
5404
5611
|
this.laserTrails.endPath();
|
|
@@ -5449,7 +5656,7 @@ class App extends React.Component {
|
|
|
5449
5656
|
});
|
|
5450
5657
|
this.elementsPendingErasure = new Set();
|
|
5451
5658
|
if (didChange) {
|
|
5452
|
-
this.
|
|
5659
|
+
this.store.shouldCaptureIncrement();
|
|
5453
5660
|
this.scene.replaceAllElements(elements);
|
|
5454
5661
|
}
|
|
5455
5662
|
};
|
|
@@ -5552,7 +5759,7 @@ class App extends React.Component {
|
|
|
5552
5759
|
this.setState({ errorMessage: t("errors.imageToolNotSupported") });
|
|
5553
5760
|
return;
|
|
5554
5761
|
}
|
|
5555
|
-
this.scene.
|
|
5762
|
+
this.scene.insertElement(imageElement);
|
|
5556
5763
|
try {
|
|
5557
5764
|
return await this.initializeImage({
|
|
5558
5765
|
imageFile,
|
|
@@ -5741,7 +5948,7 @@ class App extends React.Component {
|
|
|
5741
5948
|
}
|
|
5742
5949
|
};
|
|
5743
5950
|
maybeSuggestBindingAtCursor = (pointerCoords) => {
|
|
5744
|
-
const hoveredBindableElement = getHoveredElementForBinding(pointerCoords, this
|
|
5951
|
+
const hoveredBindableElement = getHoveredElementForBinding(pointerCoords, this);
|
|
5745
5952
|
this.setState({
|
|
5746
5953
|
suggestedBindings: hoveredBindableElement != null ? [hoveredBindableElement] : [],
|
|
5747
5954
|
});
|
|
@@ -5756,7 +5963,7 @@ class App extends React.Component {
|
|
|
5756
5963
|
return;
|
|
5757
5964
|
}
|
|
5758
5965
|
const suggestedBindings = pointerCoords.reduce((acc, coords) => {
|
|
5759
|
-
const hoveredBindableElement = getHoveredElementForBinding(coords, this
|
|
5966
|
+
const hoveredBindableElement = getHoveredElementForBinding(coords, this);
|
|
5760
5967
|
if (hoveredBindableElement != null &&
|
|
5761
5968
|
!isLinearElementSimpleAndAlreadyBound(linearElement, oppositeBindingBoundElement?.id, hoveredBindableElement)) {
|
|
5762
5969
|
acc.push(hoveredBindableElement);
|
|
@@ -5765,13 +5972,6 @@ class App extends React.Component {
|
|
|
5765
5972
|
}, []);
|
|
5766
5973
|
this.setState({ suggestedBindings });
|
|
5767
5974
|
};
|
|
5768
|
-
maybeSuggestBindingForAll(selectedElements) {
|
|
5769
|
-
if (selectedElements.length > 50) {
|
|
5770
|
-
return;
|
|
5771
|
-
}
|
|
5772
|
-
const suggestedBindings = getEligibleElementsForBinding(selectedElements, this.scene.getNonDeletedElements(), this.scene.getNonDeletedElementsMap());
|
|
5773
|
-
this.setState({ suggestedBindings });
|
|
5774
|
-
}
|
|
5775
5975
|
clearSelection(hitElement) {
|
|
5776
5976
|
this.setState((prevState) => ({
|
|
5777
5977
|
selectedElementIds: makeNextSelectedElementIds({}, prevState),
|
|
@@ -5831,7 +6031,7 @@ class App extends React.Component {
|
|
|
5831
6031
|
isLoading: false,
|
|
5832
6032
|
},
|
|
5833
6033
|
replaceFiles: true,
|
|
5834
|
-
|
|
6034
|
+
storeAction: StoreAction.CAPTURE,
|
|
5835
6035
|
});
|
|
5836
6036
|
return;
|
|
5837
6037
|
}
|
|
@@ -5899,9 +6099,10 @@ class App extends React.Component {
|
|
|
5899
6099
|
loadFileToCanvas = async (file, fileHandle) => {
|
|
5900
6100
|
file = await normalizeFile(file);
|
|
5901
6101
|
try {
|
|
6102
|
+
const elements = this.scene.getElementsIncludingDeleted();
|
|
5902
6103
|
let ret;
|
|
5903
6104
|
try {
|
|
5904
|
-
ret = await loadSceneOrLibraryFromBlob(file, this.state,
|
|
6105
|
+
ret = await loadSceneOrLibraryFromBlob(file, this.state, elements, fileHandle);
|
|
5905
6106
|
}
|
|
5906
6107
|
catch (error) {
|
|
5907
6108
|
const imageSceneDataError = error instanceof ImageSceneDataError;
|
|
@@ -5926,6 +6127,10 @@ class App extends React.Component {
|
|
|
5926
6127
|
return;
|
|
5927
6128
|
}
|
|
5928
6129
|
if (ret.type === MIME_TYPES.excalidraw) {
|
|
6130
|
+
// restore the fractional indices by mutating elements
|
|
6131
|
+
syncInvalidIndices(elements.concat(ret.data.elements));
|
|
6132
|
+
// update the store snapshot for old elements, otherwise we would end up with duplicated fractional indices on undo
|
|
6133
|
+
this.store.updateSnapshot(arrayToMap(elements), this.state);
|
|
5929
6134
|
this.setState({ isLoading: true });
|
|
5930
6135
|
this.syncActionResult({
|
|
5931
6136
|
...ret.data,
|
|
@@ -5934,7 +6139,7 @@ class App extends React.Component {
|
|
|
5934
6139
|
isLoading: false,
|
|
5935
6140
|
},
|
|
5936
6141
|
replaceFiles: true,
|
|
5937
|
-
|
|
6142
|
+
storeAction: StoreAction.CAPTURE,
|
|
5938
6143
|
});
|
|
5939
6144
|
}
|
|
5940
6145
|
else if (ret.type === MIME_TYPES.excalidrawlib) {
|
|
@@ -6033,7 +6238,6 @@ class App extends React.Component {
|
|
|
6033
6238
|
dragNewElement(draggingElement, this.state.activeTool.type, pointerDownState.originInGrid.x, pointerDownState.originInGrid.y, gridX, gridY, distance(pointerDownState.originInGrid.x, gridX), distance(pointerDownState.originInGrid.y, gridY), isImageElement(draggingElement)
|
|
6034
6239
|
? !shouldMaintainAspectRatio(event)
|
|
6035
6240
|
: shouldMaintainAspectRatio(event), shouldResizeFromCenter(event), aspectRatio, this.state.originSnapOffset);
|
|
6036
|
-
this.maybeSuggestBindingForAll([draggingElement]);
|
|
6037
6241
|
// highlight elements that are to be added to frames on frames creation
|
|
6038
6242
|
if (this.state.activeTool.type === TOOL_TYPE.frame ||
|
|
6039
6243
|
this.state.activeTool.type === TOOL_TYPE.magicframe) {
|
|
@@ -6087,16 +6291,17 @@ class App extends React.Component {
|
|
|
6087
6291
|
snapLines,
|
|
6088
6292
|
});
|
|
6089
6293
|
}
|
|
6090
|
-
if (transformElements(pointerDownState.originalElements, transformHandleType, selectedElements, this.scene.getElementsMapIncludingDeleted(), shouldRotateWithDiscreteAngle(event), shouldResizeFromCenter(event), selectedElements.
|
|
6294
|
+
if (transformElements(pointerDownState.originalElements, transformHandleType, selectedElements, this.scene.getElementsMapIncludingDeleted(), shouldRotateWithDiscreteAngle(event), shouldResizeFromCenter(event), selectedElements.some((element) => isImageElement(element))
|
|
6091
6295
|
? !shouldMaintainAspectRatio(event)
|
|
6092
6296
|
: shouldMaintainAspectRatio(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y)) {
|
|
6093
|
-
|
|
6297
|
+
const suggestedBindings = getSuggestedBindingsForArrows(selectedElements, this);
|
|
6094
6298
|
const elementsToHighlight = new Set();
|
|
6095
6299
|
selectedFrames.forEach((frame) => {
|
|
6096
6300
|
getElementsInResizingFrame(this.scene.getNonDeletedElements(), frame, this.state, this.scene.getNonDeletedElementsMap()).forEach((element) => elementsToHighlight.add(element));
|
|
6097
6301
|
});
|
|
6098
6302
|
this.setState({
|
|
6099
6303
|
elementsToHighlight: [...elementsToHighlight],
|
|
6304
|
+
suggestedBindings,
|
|
6100
6305
|
});
|
|
6101
6306
|
return true;
|
|
6102
6307
|
}
|
|
@@ -6321,7 +6526,7 @@ export const createTestHook = () => {
|
|
|
6321
6526
|
return this.app?.scene.getElementsIncludingDeleted();
|
|
6322
6527
|
},
|
|
6323
6528
|
set(elements) {
|
|
6324
|
-
return this.app?.scene.replaceAllElements(elements);
|
|
6529
|
+
return this.app?.scene.replaceAllElements(syncInvalidIndices(elements));
|
|
6325
6530
|
},
|
|
6326
6531
|
},
|
|
6327
6532
|
});
|