@dwelle/excalidraw 0.5.0-da1c822 → 0.5.0-e8bcd96
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 +13 -2
- package/dist/browser/dev/excalidraw-assets-dev/{blockDiagram-91b80b7a-RHODGCTM.js → blockDiagram-91b80b7a-SWMOP5PL.js} +6 -6
- package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-b2a90758-W7NCR7LR.js → c4Diagram-b2a90758-N33A4OZ7.js} +4 -4
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-TKRIVTWP.js → chunk-3XV32LTV.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-B2MHJWXZ.js → chunk-CLMTS5EY.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-QFS4M5OJ.js → chunk-DIDQ2KEW.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-5747M6KP.js → chunk-G3PHSEXY.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-PPHFJLL7.js → chunk-HCMMCBMX.js} +4 -4
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-DQOPSCYA.js → chunk-K5QPOXOQ.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-52OGG53V.js → chunk-KMSH7QAI.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-SLLUETBM.js → chunk-TVSGJBCZ.js} +7 -7
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-GPOYIZPX.js → chunk-UEFQKRSO.js} +28 -28
- package/dist/browser/dev/excalidraw-assets-dev/chunk-UEFQKRSO.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-BESQLMCW.js → chunk-UONPRRXT.js} +5 -5
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-UETNA2WX.js → chunk-V6ITT7XZ.js} +7397 -5320
- package/dist/browser/dev/excalidraw-assets-dev/chunk-V6ITT7XZ.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-USLWOHUZ.js → chunk-VU32GUMX.js} +4 -4
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-GF7VCOUM.js → chunk-WQNNVZHO.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-GCA4S2OA.js → chunk-WXRCMPEJ.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-J5HRUYQR.js → chunk-YGAE3YWH.js} +6 -4
- package/dist/browser/dev/excalidraw-assets-dev/chunk-YGAE3YWH.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-30eddba6-GJGBT4TV.js → classDiagram-30eddba6-HGXEWQY2.js} +6 -6
- package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-f2df5561-LYWTIPJA.js → classDiagram-v2-f2df5561-ANW5DGKP.js} +9 -9
- package/dist/browser/dev/excalidraw-assets-dev/{directory-open-01563666-UREMLRIT.js → directory-open-01563666-67XPRP2W.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{directory-open-4ed118d0-UN3BUDZZ.js → directory-open-4ed118d0-TZOVUMX3.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/dist-JWLY7ZTC.js +10 -0
- package/dist/browser/dev/excalidraw-assets-dev/{en-UW5C5KGW.js → en-RSUSLGPV.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-47591fe2-Z7U2XW2Y.js → erDiagram-47591fe2-HB4S6KST.js} +5 -5
- package/dist/browser/dev/excalidraw-assets-dev/{file-open-002ab408-4QG336MG.js → file-open-002ab408-ODQEDP24.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{file-open-7c801643-3QI4ICCL.js → file-open-7c801643-RPLD6WZI.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{file-save-3189631c-TNNERCWV.js → file-save-3189631c-63VHNBWZ.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{file-save-745eba88-JFMH565P.js → file-save-745eba88-SJSX6XSD.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-5540d9b9-PARVG263.js → flowDiagram-5540d9b9-4QMRNUIV.js} +10 -10
- package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-3b53844e-ZJOPVRMB.js → flowDiagram-v2-3b53844e-EH5O3NBM.js} +10 -10
- package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5fe447d6-ULPNBSZX.js → flowchart-elk-definition-5fe447d6-7HGYBXUA.js} +6 -6
- package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-9a3bba1f-ESSYVTJ4.js → ganttDiagram-9a3bba1f-V5WA3IP4.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-96e6b4ee-6V6VVNNP.js → gitGraphDiagram-96e6b4ee-6JA3Z4O2.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{image-3LTGFHLF.js → image-GHNRJPTS.js} +6 -6
- package/dist/browser/dev/excalidraw-assets-dev/{image-ZNQQXS62.css → image-JYKIJPJC.css} +49 -29
- package/dist/browser/dev/excalidraw-assets-dev/image-JYKIJPJC.css.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{image-blob-reduce.esm-KTX27DAY.js → image-blob-reduce.esm-QYPUYIZK.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-bcd20f53-I22FLFX3.js → infoDiagram-bcd20f53-24MBINO2.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-4fe6b3dc-WAO6F52C.js → journeyDiagram-4fe6b3dc-KJ4YYJII.js} +4 -4
- package/dist/browser/dev/excalidraw-assets-dev/{katex-NWA2YFOP.js → katex-INYZI6LE.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-f354de21-K74IKX4Y.js → mindmap-definition-f354de21-VZEH45PD.js} +4 -4
- package/dist/browser/dev/excalidraw-assets-dev/{pica-3TH2EGXR.js → pica-YQGHCBVI.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-79897490-DOB2LVE5.js → pieDiagram-79897490-Z2LCRKGQ.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-62f64e94-MJV2X7WI.js → quadrantDiagram-62f64e94-J3AFAFGX.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-05bf5f74-H4YM3XN7.js → requirementDiagram-05bf5f74-M474HB6I.js} +5 -5
- package/dist/browser/dev/excalidraw-assets-dev/{roundRect-4S3QV2NZ.js → roundRect-ZCXXTYZ4.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{sankeyDiagram-97764748-7X74ABAN.js → sankeyDiagram-97764748-TNQP5HMX.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-acc0e65c-PPDIJFQP.js → sequenceDiagram-acc0e65c-3NIA26ZM.js} +4 -4
- package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-0ff1cf1a-JVBR7N35.js → stateDiagram-0ff1cf1a-V6UXRWCT.js} +6 -6
- package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-9a9d610d-QYAJLQJH.js → stateDiagram-v2-9a9d610d-7LTZXINB.js} +9 -9
- package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-fea2a41d-GL7U3WDB.js → timeline-definition-fea2a41d-X4VGA6IX.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{xychartDiagram-ab372869-4U4JE4TW.js → xychartDiagram-ab372869-UQCQVK6J.js} +4 -4
- package/dist/browser/dev/index.css +48 -28
- package/dist/browser/dev/index.css.map +2 -2
- package/dist/browser/dev/index.js +9 -5
- package/dist/browser/prod/excalidraw-assets/{blockDiagram-91b80b7a-BO7MW3VX.js → blockDiagram-91b80b7a-2ADOK2UH.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{c4Diagram-b2a90758-VCUPBVHR.js → c4Diagram-b2a90758-XJ3HR543.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-VXFFPRP2.js → chunk-4X2EVGJW.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-5PWM36DG.js → chunk-5ARJLPSL.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-B7CDQVNY.js → chunk-6RDIDVV6.js} +21 -21
- package/dist/browser/prod/excalidraw-assets/chunk-AWDUHWKA.js +269 -0
- package/dist/browser/prod/excalidraw-assets/{chunk-V7HUISEN.js → chunk-COMJOADH.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-NM5B2RBP.js → chunk-DHU3NMWJ.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-4JYQ3563.js → chunk-FKEWZS6G.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-3VCRCP5J.js → chunk-GID7HY42.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-7UJZVYSR.js → chunk-H4K7WCAG.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-3HZHH3PT.js → chunk-PDA7IERE.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-O77Z7CWL.js → chunk-SCYMUHNO.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-QLNFR4AJ.js → chunk-SCZE4QLN.js} +2 -2
- package/dist/browser/prod/excalidraw-assets/{chunk-HPA5W5VE.js → chunk-Y4AVKYKK.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-CVEF66PS.js → chunk-YFHFEESB.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-22FVL4I7.js → chunk-Z4B7QXT2.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{classDiagram-30eddba6-VXGNM3LI.js → classDiagram-30eddba6-RQ6VHNNF.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{classDiagram-v2-f2df5561-YALTASVE.js → classDiagram-v2-f2df5561-TL3XYHL6.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{directory-open-01563666-JWXY2QSC.js → directory-open-01563666-ORBUXLUB.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{directory-open-4ed118d0-6AL5X37W.js → directory-open-4ed118d0-HRBZ4CD4.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/dist-IRBESAGJ.js +1 -0
- package/dist/browser/prod/excalidraw-assets/{en-CPU3UVKT.js → en-SOC7FEW5.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{erDiagram-47591fe2-GKYANCN7.js → erDiagram-47591fe2-PBCROW3M.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{file-open-002ab408-3EPJOH45.js → file-open-002ab408-SRGK55ER.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{file-open-7c801643-QIP6HK4D.js → file-open-7c801643-IAPRROWG.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{file-save-3189631c-4TQJBQCS.js → file-save-3189631c-LO2KPJNL.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{file-save-745eba88-C4L3ZGCC.js → file-save-745eba88-2DRIRHNX.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{flowDiagram-5540d9b9-QBRW5SLP.js → flowDiagram-5540d9b9-6MWFBLXS.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/flowDiagram-v2-3b53844e-CD6XHMHV.js +1 -0
- package/dist/browser/prod/excalidraw-assets/{flowchart-elk-definition-5fe447d6-YYO2EYKS.js → flowchart-elk-definition-5fe447d6-4UPGJKHJ.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{ganttDiagram-9a3bba1f-3B2DUUUQ.js → ganttDiagram-9a3bba1f-PDRTJQZH.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{gitGraphDiagram-96e6b4ee-G6CKXXWQ.js → gitGraphDiagram-96e6b4ee-3J3YSPOQ.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/image-U235TWVW.css +1 -0
- package/dist/browser/prod/excalidraw-assets/image-ZYZR4L6P.js +1 -0
- package/dist/browser/prod/excalidraw-assets/{image-blob-reduce.esm-5DTGAOOI.js → image-blob-reduce.esm-XVCS6NNL.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{infoDiagram-bcd20f53-WJTZJERL.js → infoDiagram-bcd20f53-DVJQEG4I.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{journeyDiagram-4fe6b3dc-JF22KXXQ.js → journeyDiagram-4fe6b3dc-ASSTFADN.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{katex-N6R5DPQX.js → katex-RDNZD65H.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{mindmap-definition-f354de21-7SH5STU3.js → mindmap-definition-f354de21-4Y6OYM5B.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{pica-KWHN2PJ6.js → pica-P43LGTW6.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{pieDiagram-79897490-5O5EBEQB.js → pieDiagram-79897490-XJXBVFLX.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{quadrantDiagram-62f64e94-JTY6WOKB.js → quadrantDiagram-62f64e94-PC5DTCKV.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{requirementDiagram-05bf5f74-TSFQFY5X.js → requirementDiagram-05bf5f74-ILVOGHRN.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{roundRect-PUCZURYS.js → roundRect-HU3IUMCJ.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{sankeyDiagram-97764748-7G2R6W67.js → sankeyDiagram-97764748-SC5VBCT5.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{sequenceDiagram-acc0e65c-CTANNZCO.js → sequenceDiagram-acc0e65c-MFG2JCTS.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{stateDiagram-0ff1cf1a-I5COLKZ4.js → stateDiagram-0ff1cf1a-2HXG5RCM.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{stateDiagram-v2-9a9d610d-IIHI3AJN.js → stateDiagram-v2-9a9d610d-PKXRQ3RV.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{timeline-definition-fea2a41d-CXTGKWI4.js → timeline-definition-fea2a41d-LOYYYOFB.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{xychartDiagram-ab372869-QZGPPHJP.js → xychartDiagram-ab372869-LYHM7ECI.js} +1 -1
- package/dist/browser/prod/index.css +1 -1
- package/dist/browser/prod/index.js +1 -1
- package/dist/dev/{en-R7FEFJGC.json → en-GM5O55AO.json} +5 -3
- package/dist/dev/index.css +48 -28
- package/dist/dev/index.css.map +2 -2
- package/dist/dev/index.js +5324 -3292
- 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 +11 -5
- package/dist/excalidraw/actions/actionCanvas.d.ts +52 -52
- package/dist/excalidraw/actions/actionCanvas.js +16 -13
- 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 +37 -37
- 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 +19 -14
- 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/actionTextAutoResize.d.ts +17 -0
- package/dist/excalidraw/actions/actionTextAutoResize.js +38 -0
- 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/types.d.ts +8 -8
- package/dist/excalidraw/align.d.ts +1 -1
- package/dist/excalidraw/animated-trail.d.ts +2 -2
- package/dist/excalidraw/appState.d.ts +6 -6
- 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 +28 -14
- package/dist/excalidraw/components/App.js +385 -177
- 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 +6 -5
- 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/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 +1 -1
- 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/LayerUI.js +1 -1
- 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/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/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 +3 -2
- package/dist/excalidraw/components/canvases/InteractiveCanvas.js +3 -2
- package/dist/excalidraw/components/canvases/StaticCanvas.d.ts +2 -2
- package/dist/excalidraw/components/canvases/StaticCanvas.js +2 -2
- package/dist/excalidraw/components/dropdownMenu/DropdownMenuItem.js +2 -2
- 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 +4 -2
- package/dist/excalidraw/components/icons.js +20 -6
- package/dist/excalidraw/components/main-menu/DefaultItems.d.ts +1 -1
- 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/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/resave.js +1 -1
- package/dist/excalidraw/data/restore.d.ts +5 -5
- package/dist/excalidraw/data/restore.js +7 -7
- package/dist/excalidraw/data/transform.d.ts +4 -4
- package/dist/excalidraw/data/transform.js +4 -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 +88 -27
- package/dist/excalidraw/element/image.d.ts +2 -2
- package/dist/excalidraw/element/index.d.ts +2 -3
- package/dist/excalidraw/element/index.js +1 -2
- package/dist/excalidraw/element/linearElementEditor.d.ts +12 -12
- package/dist/excalidraw/element/linearElementEditor.js +7 -5
- package/dist/excalidraw/element/mutateElement.d.ts +4 -5
- package/dist/excalidraw/element/mutateElement.js +5 -3
- package/dist/excalidraw/element/newElement.d.ts +4 -9
- package/dist/excalidraw/element/newElement.js +17 -14
- package/dist/excalidraw/element/resizeElements.d.ts +4 -4
- package/dist/excalidraw/element/resizeElements.js +170 -97
- package/dist/excalidraw/element/resizeTest.d.ts +7 -7
- package/dist/excalidraw/element/resizeTest.js +53 -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 +13 -37
- package/dist/excalidraw/element/textWysiwyg.d.ts +10 -5
- package/dist/excalidraw/element/textWysiwyg.js +6 -8
- package/dist/excalidraw/element/transformHandles.d.ts +24 -6
- package/dist/excalidraw/element/transformHandles.js +22 -11
- package/dist/excalidraw/element/typeChecks.d.ts +4 -4
- package/dist/excalidraw/element/types.d.ts +30 -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/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/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 +2 -2
- package/dist/excalidraw/renderer/renderSnaps.d.ts +1 -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 +2 -4
- package/dist/excalidraw/scene/Fonts.js +6 -12
- package/dist/excalidraw/scene/Renderer.d.ts +4 -4
- package/dist/excalidraw/scene/Renderer.js +2 -3
- package/dist/excalidraw/scene/Scene.d.ts +19 -12
- package/dist/excalidraw/scene/Scene.js +44 -23
- package/dist/excalidraw/scene/Shape.d.ts +1 -1
- package/dist/excalidraw/scene/ShapeCache.d.ts +5 -4
- package/dist/excalidraw/scene/comparisons.d.ts +2 -2
- package/dist/excalidraw/scene/export.d.ts +3 -3
- package/dist/excalidraw/scene/export.js +4 -3
- 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 +10 -4
- package/dist/excalidraw/utils.js +7 -0
- package/dist/excalidraw/zindex.d.ts +4 -4
- package/dist/excalidraw/zindex.js +9 -13
- package/dist/prod/{en-R7FEFJGC.json → en-GM5O55AO.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 +1 -1
- 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-GPOYIZPX.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/chunk-J5HRUYQR.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/chunk-UETNA2WX.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/dist-Y7S5GOTG.js +0 -10
- package/dist/browser/dev/excalidraw-assets-dev/image-ZNQQXS62.css.map +0 -7
- package/dist/browser/prod/excalidraw-assets/chunk-EEN6AFMH.js +0 -269
- package/dist/browser/prod/excalidraw-assets/dist-7FHVDAZ2.js +0 -1
- package/dist/browser/prod/excalidraw-assets/flowDiagram-v2-3b53844e-CRHRHP7H.js +0 -1
- package/dist/browser/prod/excalidraw-assets/image-VXYNPVOG.js +0 -1
- package/dist/browser/prod/excalidraw-assets/image-WE6NA2G6.css +0 -1
- /package/dist/browser/dev/excalidraw-assets-dev/{blockDiagram-91b80b7a-RHODGCTM.js.map → blockDiagram-91b80b7a-SWMOP5PL.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-b2a90758-W7NCR7LR.js.map → c4Diagram-b2a90758-N33A4OZ7.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-TKRIVTWP.js.map → chunk-3XV32LTV.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-B2MHJWXZ.js.map → chunk-CLMTS5EY.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-QFS4M5OJ.js.map → chunk-DIDQ2KEW.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-5747M6KP.js.map → chunk-G3PHSEXY.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-PPHFJLL7.js.map → chunk-HCMMCBMX.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-DQOPSCYA.js.map → chunk-K5QPOXOQ.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-52OGG53V.js.map → chunk-KMSH7QAI.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-SLLUETBM.js.map → chunk-TVSGJBCZ.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-BESQLMCW.js.map → chunk-UONPRRXT.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-USLWOHUZ.js.map → chunk-VU32GUMX.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-GF7VCOUM.js.map → chunk-WQNNVZHO.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-GCA4S2OA.js.map → chunk-WXRCMPEJ.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-30eddba6-GJGBT4TV.js.map → classDiagram-30eddba6-HGXEWQY2.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-f2df5561-LYWTIPJA.js.map → classDiagram-v2-f2df5561-ANW5DGKP.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{directory-open-01563666-UREMLRIT.js.map → directory-open-01563666-67XPRP2W.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{directory-open-4ed118d0-UN3BUDZZ.js.map → directory-open-4ed118d0-TZOVUMX3.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{dist-Y7S5GOTG.js.map → dist-JWLY7ZTC.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{en-UW5C5KGW.js.map → en-RSUSLGPV.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-47591fe2-Z7U2XW2Y.js.map → erDiagram-47591fe2-HB4S6KST.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{file-open-002ab408-4QG336MG.js.map → file-open-002ab408-ODQEDP24.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{file-open-7c801643-3QI4ICCL.js.map → file-open-7c801643-RPLD6WZI.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{file-save-3189631c-TNNERCWV.js.map → file-save-3189631c-63VHNBWZ.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{file-save-745eba88-JFMH565P.js.map → file-save-745eba88-SJSX6XSD.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-5540d9b9-PARVG263.js.map → flowDiagram-5540d9b9-4QMRNUIV.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-3b53844e-ZJOPVRMB.js.map → flowDiagram-v2-3b53844e-EH5O3NBM.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5fe447d6-ULPNBSZX.js.map → flowchart-elk-definition-5fe447d6-7HGYBXUA.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-9a3bba1f-ESSYVTJ4.js.map → ganttDiagram-9a3bba1f-V5WA3IP4.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-96e6b4ee-6V6VVNNP.js.map → gitGraphDiagram-96e6b4ee-6JA3Z4O2.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{image-3LTGFHLF.js.map → image-GHNRJPTS.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{image-blob-reduce.esm-KTX27DAY.js.map → image-blob-reduce.esm-QYPUYIZK.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-bcd20f53-I22FLFX3.js.map → infoDiagram-bcd20f53-24MBINO2.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-4fe6b3dc-WAO6F52C.js.map → journeyDiagram-4fe6b3dc-KJ4YYJII.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{katex-NWA2YFOP.js.map → katex-INYZI6LE.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-f354de21-K74IKX4Y.js.map → mindmap-definition-f354de21-VZEH45PD.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{pica-3TH2EGXR.js.map → pica-YQGHCBVI.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-79897490-DOB2LVE5.js.map → pieDiagram-79897490-Z2LCRKGQ.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-62f64e94-MJV2X7WI.js.map → quadrantDiagram-62f64e94-J3AFAFGX.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-05bf5f74-H4YM3XN7.js.map → requirementDiagram-05bf5f74-M474HB6I.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{roundRect-4S3QV2NZ.js.map → roundRect-ZCXXTYZ4.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{sankeyDiagram-97764748-7X74ABAN.js.map → sankeyDiagram-97764748-TNQP5HMX.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-acc0e65c-PPDIJFQP.js.map → sequenceDiagram-acc0e65c-3NIA26ZM.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-0ff1cf1a-JVBR7N35.js.map → stateDiagram-0ff1cf1a-V6UXRWCT.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-9a9d610d-QYAJLQJH.js.map → stateDiagram-v2-9a9d610d-7LTZXINB.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-fea2a41d-GL7U3WDB.js.map → timeline-definition-fea2a41d-X4VGA6IX.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{xychartDiagram-ab372869-4U4JE4TW.js.map → xychartDiagram-ab372869-UQCQVK6J.js.map} +0 -0
|
@@ -10,32 +10,34 @@ 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 { exportAsImage, 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, refreshTextDimensions, 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
31
|
import { clearRenderCache } from "../renderer/renderElement";
|
|
32
|
-
import { calculateScrollCenter,
|
|
32
|
+
import { calculateScrollCenter, getElementsWithinSelection, getNormalizedZoom, getSelectedElements, hasBackground, isSomeElementSelected, } from "../scene";
|
|
33
33
|
import Scene from "../scene/Scene";
|
|
34
34
|
import { getStateForZoom } from "../scene/zoom";
|
|
35
35
|
import { findShapeByKey } from "../shapes";
|
|
36
|
-
import {
|
|
36
|
+
import { getClosedCurveShape, getCurveShape, getEllipseShape, getFreedrawShape, getPolygonShape, getSelectionBoxShape, } from "../../utils/geometry/shape";
|
|
37
|
+
import { isPointInShape } from "../../utils/collision";
|
|
38
|
+
import { debounce, distance, getFontString, getNearestScrollableContainer, isInputLike, isToolIcon, isWritableElement, sceneCoordsToViewportCoords, tupleToCoors, viewportCoordsToSceneCoords, wrapEvent, updateObject, updateActiveTool, getShortcutKey, isTransparent, easeToValuesRAF, muteFSAbortError, isTestEnv, easeOut, updateStable, addEventListener, normalizeEOL, getDateTime, isShallowEqual, arrayToMap, } from "../utils";
|
|
37
39
|
import { createSrcDoc, embeddableURLValidator, maybeParseEmbedSrc, getEmbedLink, } from "../element/embeddable";
|
|
38
|
-
import { ContextMenu, CONTEXT_MENU_SEPARATOR
|
|
40
|
+
import { ContextMenu, CONTEXT_MENU_SEPARATOR } from "./ContextMenu";
|
|
39
41
|
import LayerUI from "./LayerUI";
|
|
40
42
|
import { Toast } from "./Toast";
|
|
41
43
|
import { actionToggleViewMode } from "../actions/actionToggleViewMode";
|
|
@@ -43,8 +45,7 @@ import { dataURLToFile, generateIdFromFile, getDataURL, getFileFromEvent, ImageU
|
|
|
43
45
|
import { getInitializedImageElements, loadHTMLImageElement, normalizeSVG, updateImageCache as _updateImageCache, } from "../element/image";
|
|
44
46
|
import throttle from "lodash.throttle";
|
|
45
47
|
import { fileOpen } from "../data/filesystem";
|
|
46
|
-
import { bindTextToShapeAfterDuplication, getApproxMinLineHeight, getApproxMinLineWidth, getBoundTextElement, getContainerCenter, getContainerElement, getDefaultLineHeight, getLineHeightInPx,
|
|
47
|
-
import { isHittingElementNotConsideringBoundingBox } from "../element/collision";
|
|
48
|
+
import { bindTextToShapeAfterDuplication, getApproxMinLineHeight, getApproxMinLineWidth, getBoundTextElement, getContainerCenter, getContainerElement, getDefaultLineHeight, getLineHeightInPx, isMeasureTextSupported, isValidTextContainer, } from "../element/textElement";
|
|
48
49
|
import { showHyperlinkTooltip, hideHyperlinkToolip, Hyperlink, } from "../components/hyperlink/Hyperlink";
|
|
49
50
|
import { isLocalLink, normalizeLink, toValidURL } from "../data/url";
|
|
50
51
|
import { shouldShowBoundingBox } from "../element/transformHandles";
|
|
@@ -62,7 +63,7 @@ import { getSnapLinesAtPointer, snapDraggedElements, isActiveToolNonLinearSnappa
|
|
|
62
63
|
import { actionWrapTextInContainer } from "../actions/actionBoundText";
|
|
63
64
|
import BraveMeasureTextError from "./BraveMeasureTextError";
|
|
64
65
|
import { activeEyeDropperAtom } from "./EyeDropper";
|
|
65
|
-
import { convertToExcalidrawElements
|
|
66
|
+
import { convertToExcalidrawElements } from "../data/transform";
|
|
66
67
|
import { isSidebarDockedAtom } from "./Sidebar/Sidebar";
|
|
67
68
|
import { StaticCanvas, InteractiveCanvas } from "./canvases";
|
|
68
69
|
import { Renderer } from "../scene/Renderer";
|
|
@@ -78,15 +79,19 @@ import { ElementCanvasButton } from "./MagicButton";
|
|
|
78
79
|
import { MagicIcon, copyIcon, fullscreenIcon } from "./icons";
|
|
79
80
|
import { EditorLocalStorage } from "../data/EditorLocalStorage";
|
|
80
81
|
import FollowMode from "./FollowMode/FollowMode";
|
|
82
|
+
import { Store, StoreAction } from "../store";
|
|
81
83
|
import { AnimationFrameHandler } from "../animation-frame-handler";
|
|
82
84
|
import { AnimatedTrail } from "../animated-trail";
|
|
83
85
|
import { LaserTrails } from "../laser-trails";
|
|
84
86
|
import { withBatchedUpdates, withBatchedUpdatesThrottled } from "../reactUtils";
|
|
85
87
|
import { getRenderOpacity } from "../renderer/renderElement";
|
|
88
|
+
import { hitElementBoundText, hitElementBoundingBoxOnly, hitElementItself, shouldTestInside, } from "../element/collision";
|
|
86
89
|
import { textWysiwyg } from "../element/textWysiwyg";
|
|
87
90
|
import { isOverScrollBars } from "../scene/scrollbars";
|
|
91
|
+
import { syncInvalidIndices, syncMovedIndices } from "../fractionalIndex";
|
|
88
92
|
import { isPointHittingLink, isPointHittingLinkIcon, } from "./hyperlink/helpers";
|
|
89
93
|
import { getShortcutFromShortcutName } from "../actions/shortcuts";
|
|
94
|
+
import { actionTextAutoResize } from "../actions/actionTextAutoResize";
|
|
90
95
|
const AppContext = React.createContext(null);
|
|
91
96
|
const AppPropsContext = React.createContext(null);
|
|
92
97
|
const deviceContextInitialValue = {
|
|
@@ -166,6 +171,7 @@ class App extends React.Component {
|
|
|
166
171
|
library;
|
|
167
172
|
libraryItemsFromStorage;
|
|
168
173
|
id;
|
|
174
|
+
store;
|
|
169
175
|
history;
|
|
170
176
|
excalidrawContainerValue;
|
|
171
177
|
files = {};
|
|
@@ -237,6 +243,8 @@ class App extends React.Component {
|
|
|
237
243
|
this.canvas = document.createElement("canvas");
|
|
238
244
|
this.rc = rough.canvas(this.canvas);
|
|
239
245
|
this.renderer = new Renderer(this.scene);
|
|
246
|
+
this.store = new Store();
|
|
247
|
+
this.history = new History();
|
|
240
248
|
if (excalidrawAPI) {
|
|
241
249
|
const api = {
|
|
242
250
|
updateScene: this.updateScene,
|
|
@@ -281,14 +289,11 @@ class App extends React.Component {
|
|
|
281
289
|
container: this.excalidrawContainerRef.current,
|
|
282
290
|
id: this.id,
|
|
283
291
|
};
|
|
284
|
-
this.fonts = new Fonts({
|
|
285
|
-
scene: this.scene,
|
|
286
|
-
onSceneUpdated: this.onSceneUpdated,
|
|
287
|
-
});
|
|
292
|
+
this.fonts = new Fonts({ scene: this.scene });
|
|
288
293
|
this.history = new History();
|
|
289
294
|
this.actionManager.registerAll(actions);
|
|
290
|
-
this.actionManager.registerAction(createUndoAction(this.history));
|
|
291
|
-
this.actionManager.registerAction(createRedoAction(this.history));
|
|
295
|
+
this.actionManager.registerAction(createUndoAction(this.history, this.store));
|
|
296
|
+
this.actionManager.registerAction(createRedoAction(this.history, this.store));
|
|
292
297
|
}
|
|
293
298
|
onWindowMessage(event) {
|
|
294
299
|
if (event.origin !== "https://player.vimeo.com" &&
|
|
@@ -439,7 +444,7 @@ class App extends React.Component {
|
|
|
439
444
|
return false;
|
|
440
445
|
});
|
|
441
446
|
if (updated) {
|
|
442
|
-
this.scene.
|
|
447
|
+
this.scene.triggerUpdate();
|
|
443
448
|
}
|
|
444
449
|
// GC
|
|
445
450
|
this.iFrameRefs.forEach((ref, id) => {
|
|
@@ -798,9 +803,9 @@ class App extends React.Component {
|
|
|
798
803
|
render() {
|
|
799
804
|
const selectedElements = this.scene.getSelectedElements(this.state);
|
|
800
805
|
const { renderTopRightUI, renderCustomStats } = this.props;
|
|
801
|
-
const
|
|
806
|
+
const sceneNonce = this.scene.getSceneNonce();
|
|
802
807
|
const { elementsMap, visibleElements } = this.renderer.getRenderableElements({
|
|
803
|
-
|
|
808
|
+
sceneNonce,
|
|
804
809
|
zoom: this.state.zoom,
|
|
805
810
|
offsetLeft: this.state.offsetLeft,
|
|
806
811
|
offsetTop: this.state.offsetTop,
|
|
@@ -872,14 +877,14 @@ class App extends React.Component {
|
|
|
872
877
|
this.focusContainer();
|
|
873
878
|
callback?.();
|
|
874
879
|
});
|
|
875
|
-
} })), _jsx(StaticCanvas, { canvas: this.canvas, rc: this.rc, elementsMap: elementsMap, allElementsMap: allElementsMap, visibleElements: visibleElements,
|
|
880
|
+
} })), _jsx(StaticCanvas, { canvas: this.canvas, rc: this.rc, elementsMap: elementsMap, allElementsMap: allElementsMap, visibleElements: visibleElements, sceneNonce: sceneNonce, selectionNonce: this.state.selectionElement?.versionNonce, scale: window.devicePixelRatio, appState: this.state, renderConfig: {
|
|
876
881
|
imageCache: this.imageCache,
|
|
877
882
|
isExporting: false,
|
|
878
883
|
renderGrid: true,
|
|
879
884
|
canvasBackgroundColor: this.state.viewBackgroundColor,
|
|
880
885
|
embedsValidationStatus: this.embedsValidationStatus,
|
|
881
886
|
elementsPendingErasure: this.elementsPendingErasure,
|
|
882
|
-
} }), _jsx(InteractiveCanvas, { containerRef: this.excalidrawContainerRef, canvas: this.interactiveCanvas, elementsMap: elementsMap, visibleElements: visibleElements, selectedElements: selectedElements,
|
|
887
|
+
} }), _jsx(InteractiveCanvas, { containerRef: this.excalidrawContainerRef, canvas: this.interactiveCanvas, elementsMap: elementsMap, visibleElements: visibleElements, selectedElements: selectedElements, sceneNonce: sceneNonce, 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()] }) }) }) }) }) }) }) }));
|
|
883
888
|
}
|
|
884
889
|
focusContainer = () => {
|
|
885
890
|
this.excalidrawContainerRef.current?.focus();
|
|
@@ -937,7 +942,7 @@ class App extends React.Component {
|
|
|
937
942
|
mutateElement(frameElement, { customData: { generationData: data } }, false);
|
|
938
943
|
}
|
|
939
944
|
this.magicGenerations.set(frameElement.id, data);
|
|
940
|
-
this.
|
|
945
|
+
this.triggerRender();
|
|
941
946
|
};
|
|
942
947
|
getTextFromElements(elements) {
|
|
943
948
|
const text = elements
|
|
@@ -1139,7 +1144,7 @@ class App extends React.Component {
|
|
|
1139
1144
|
opacity: 100,
|
|
1140
1145
|
locked: false,
|
|
1141
1146
|
});
|
|
1142
|
-
this.scene.
|
|
1147
|
+
this.scene.insertElement(frame);
|
|
1143
1148
|
for (const child of selectedElements) {
|
|
1144
1149
|
mutateElement(child, { frameId: frame.id });
|
|
1145
1150
|
}
|
|
@@ -1163,13 +1168,13 @@ class App extends React.Component {
|
|
|
1163
1168
|
if (shouldUpdateStrokeColor) {
|
|
1164
1169
|
this.syncActionResult({
|
|
1165
1170
|
appState: { ...this.state, currentItemStrokeColor: color },
|
|
1166
|
-
|
|
1171
|
+
storeAction: StoreAction.CAPTURE,
|
|
1167
1172
|
});
|
|
1168
1173
|
}
|
|
1169
1174
|
else {
|
|
1170
1175
|
this.syncActionResult({
|
|
1171
1176
|
appState: { ...this.state, currentItemBackgroundColor: color },
|
|
1172
|
-
|
|
1177
|
+
storeAction: StoreAction.CAPTURE,
|
|
1173
1178
|
});
|
|
1174
1179
|
}
|
|
1175
1180
|
}
|
|
@@ -1183,6 +1188,7 @@ class App extends React.Component {
|
|
|
1183
1188
|
}
|
|
1184
1189
|
return el;
|
|
1185
1190
|
}),
|
|
1191
|
+
storeAction: StoreAction.CAPTURE,
|
|
1186
1192
|
});
|
|
1187
1193
|
}
|
|
1188
1194
|
},
|
|
@@ -1202,10 +1208,13 @@ class App extends React.Component {
|
|
|
1202
1208
|
editingElement = element;
|
|
1203
1209
|
}
|
|
1204
1210
|
});
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1211
|
+
if (actionResult.storeAction === StoreAction.UPDATE) {
|
|
1212
|
+
this.store.shouldUpdateSnapshot();
|
|
1213
|
+
}
|
|
1214
|
+
else if (actionResult.storeAction === StoreAction.CAPTURE) {
|
|
1215
|
+
this.store.shouldCaptureIncrement();
|
|
1208
1216
|
}
|
|
1217
|
+
this.scene.replaceAllElements(actionResult.elements);
|
|
1209
1218
|
}
|
|
1210
1219
|
if (actionResult.files) {
|
|
1211
1220
|
this.files = actionResult.replaceFiles
|
|
@@ -1214,8 +1223,11 @@ class App extends React.Component {
|
|
|
1214
1223
|
this.addNewImagesToImageCache();
|
|
1215
1224
|
}
|
|
1216
1225
|
if (actionResult.appState || editingElement || this.state.contextMenu) {
|
|
1217
|
-
if (actionResult.
|
|
1218
|
-
this.
|
|
1226
|
+
if (actionResult.storeAction === StoreAction.UPDATE) {
|
|
1227
|
+
this.store.shouldUpdateSnapshot();
|
|
1228
|
+
}
|
|
1229
|
+
else if (actionResult.storeAction === StoreAction.CAPTURE) {
|
|
1230
|
+
this.store.shouldCaptureIncrement();
|
|
1219
1231
|
}
|
|
1220
1232
|
let viewModeEnabled = actionResult?.appState?.viewModeEnabled || false;
|
|
1221
1233
|
let zenModeEnabled = actionResult?.appState?.zenModeEnabled || false;
|
|
@@ -1254,10 +1266,6 @@ class App extends React.Component {
|
|
|
1254
1266
|
name,
|
|
1255
1267
|
errorMessage,
|
|
1256
1268
|
});
|
|
1257
|
-
}, () => {
|
|
1258
|
-
if (actionResult.syncHistory) {
|
|
1259
|
-
this.history.setCurrentState(this.state, this.scene.getElementsIncludingDeleted());
|
|
1260
|
-
}
|
|
1261
1269
|
});
|
|
1262
1270
|
}
|
|
1263
1271
|
});
|
|
@@ -1275,6 +1283,9 @@ class App extends React.Component {
|
|
|
1275
1283
|
resetHistory = () => {
|
|
1276
1284
|
this.history.clear();
|
|
1277
1285
|
};
|
|
1286
|
+
resetStore = () => {
|
|
1287
|
+
this.store.clear();
|
|
1288
|
+
};
|
|
1278
1289
|
/**
|
|
1279
1290
|
* Resets scene & history.
|
|
1280
1291
|
* ! Do not use to clear scene user action !
|
|
@@ -1286,6 +1297,7 @@ class App extends React.Component {
|
|
|
1286
1297
|
isLoading: opts?.resetLoadingState ? false : state.isLoading,
|
|
1287
1298
|
theme: this.state.theme,
|
|
1288
1299
|
}));
|
|
1300
|
+
this.resetStore();
|
|
1289
1301
|
this.resetHistory();
|
|
1290
1302
|
});
|
|
1291
1303
|
initializeScene = async () => {
|
|
@@ -1360,6 +1372,7 @@ class App extends React.Component {
|
|
|
1360
1372
|
// text elements on canvas, and rerender them once done. This also
|
|
1361
1373
|
// seems faster even in browsers that do fire the loadingdone event.
|
|
1362
1374
|
this.fonts.loadFontsForElements(scene.elements);
|
|
1375
|
+
this.resetStore();
|
|
1363
1376
|
if (initialData?.scrollX != null) {
|
|
1364
1377
|
scene.appState.scrollX = initialData.scrollX;
|
|
1365
1378
|
}
|
|
@@ -1369,7 +1382,7 @@ class App extends React.Component {
|
|
|
1369
1382
|
this.resetHistory();
|
|
1370
1383
|
this.syncActionResult({
|
|
1371
1384
|
...scene,
|
|
1372
|
-
|
|
1385
|
+
storeAction: StoreAction.UPDATE,
|
|
1373
1386
|
});
|
|
1374
1387
|
};
|
|
1375
1388
|
isMobileBreakpoint = (width, height) => {
|
|
@@ -1440,9 +1453,16 @@ class App extends React.Component {
|
|
|
1440
1453
|
configurable: true,
|
|
1441
1454
|
value: this.history,
|
|
1442
1455
|
},
|
|
1456
|
+
store: {
|
|
1457
|
+
configurable: true,
|
|
1458
|
+
value: this.store,
|
|
1459
|
+
},
|
|
1443
1460
|
});
|
|
1444
1461
|
}
|
|
1445
|
-
this.
|
|
1462
|
+
this.store.onStoreIncrementEmitter.on((increment) => {
|
|
1463
|
+
this.history.record(increment.elementsChange, increment.appStateChange);
|
|
1464
|
+
});
|
|
1465
|
+
this.scene.onUpdate(this.triggerRender);
|
|
1446
1466
|
this.addEventListeners();
|
|
1447
1467
|
if (this.props.autoFocus && this.excalidrawContainerRef.current) {
|
|
1448
1468
|
this.focusContainer();
|
|
@@ -1480,6 +1500,7 @@ class App extends React.Component {
|
|
|
1480
1500
|
componentWillUnmount() {
|
|
1481
1501
|
this.renderer.destroy();
|
|
1482
1502
|
this.scene = new Scene();
|
|
1503
|
+
this.fonts = new Fonts({ scene: this.scene });
|
|
1483
1504
|
this.renderer = new Renderer(this.scene);
|
|
1484
1505
|
this.files = {};
|
|
1485
1506
|
this.imageCache.clear();
|
|
@@ -1491,6 +1512,7 @@ class App extends React.Component {
|
|
|
1491
1512
|
this.laserTrails.stop();
|
|
1492
1513
|
this.eraserTrail.stop();
|
|
1493
1514
|
this.onChangeEmitter.clear();
|
|
1515
|
+
this.store.onStoreIncrementEmitter.clear();
|
|
1494
1516
|
ShapeCache.destroy();
|
|
1495
1517
|
SnapCache.destroy();
|
|
1496
1518
|
clearRenderCache();
|
|
@@ -1574,7 +1596,8 @@ class App extends React.Component {
|
|
|
1574
1596
|
componentDidUpdate(prevProps, prevState) {
|
|
1575
1597
|
this.updateEmbeddables();
|
|
1576
1598
|
const elements = this.scene.getElementsIncludingDeleted();
|
|
1577
|
-
const elementsMap = this.scene.
|
|
1599
|
+
const elementsMap = this.scene.getElementsMapIncludingDeleted();
|
|
1600
|
+
const nonDeletedElementsMap = this.scene.getNonDeletedElementsMap();
|
|
1578
1601
|
if (!this.state.showWelcomeScreen && !elements.length) {
|
|
1579
1602
|
this.setState({ showWelcomeScreen: true });
|
|
1580
1603
|
}
|
|
@@ -1660,7 +1683,7 @@ class App extends React.Component {
|
|
|
1660
1683
|
this.excalidrawContainerRef.current?.classList.toggle("theme--dark", this.state.theme === THEME.DARK);
|
|
1661
1684
|
if (this.state.editingLinearElement &&
|
|
1662
1685
|
!this.state.selectedElementIds[this.state.editingLinearElement.elementId]) {
|
|
1663
|
-
// defer so that the
|
|
1686
|
+
// defer so that the storeAction flag isn't reset via current update
|
|
1664
1687
|
setTimeout(() => {
|
|
1665
1688
|
// execute only if the condition still holds when the deferred callback
|
|
1666
1689
|
// executes (it can be scheduled multiple times depending on how
|
|
@@ -1685,9 +1708,9 @@ class App extends React.Component {
|
|
|
1685
1708
|
multiElement != null &&
|
|
1686
1709
|
isBindingEnabled(this.state) &&
|
|
1687
1710
|
isBindingElement(multiElement, false)) {
|
|
1688
|
-
maybeBindLinearElement(multiElement, this.state,
|
|
1711
|
+
maybeBindLinearElement(multiElement, this.state, tupleToCoors(LinearElementEditor.getPointAtIndexGlobalCoordinates(multiElement, -1, nonDeletedElementsMap)), this);
|
|
1689
1712
|
}
|
|
1690
|
-
this.
|
|
1713
|
+
this.store.commit(elementsMap, this.state);
|
|
1691
1714
|
// Do not notify consumers if we're still loading the scene. Among other
|
|
1692
1715
|
// potential issues, this fixes a case where the tab isn't focused during
|
|
1693
1716
|
// init, which would trigger onChange with empty elements, which would then
|
|
@@ -1952,16 +1975,15 @@ class App extends React.Component {
|
|
|
1952
1975
|
}), {
|
|
1953
1976
|
randomizeSeed: !opts.retainSeed,
|
|
1954
1977
|
});
|
|
1955
|
-
const
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
];
|
|
1978
|
+
const prevElements = this.scene.getElementsIncludingDeleted();
|
|
1979
|
+
const nextElements = [...prevElements, ...newElements];
|
|
1980
|
+
syncMovedIndices(nextElements, arrayToMap(newElements));
|
|
1959
1981
|
const topLayerFrame = this.getTopLayerFrameAtSceneCoords({ x, y });
|
|
1960
1982
|
if (topLayerFrame) {
|
|
1961
1983
|
const eligibleElements = filterElementsEligibleAsFrameChildren(newElements, topLayerFrame);
|
|
1962
|
-
addElementsToFrame(
|
|
1984
|
+
addElementsToFrame(nextElements, eligibleElements, topLayerFrame);
|
|
1963
1985
|
}
|
|
1964
|
-
this.scene.replaceAllElements(
|
|
1986
|
+
this.scene.replaceAllElements(nextElements);
|
|
1965
1987
|
newElements.forEach((newElement) => {
|
|
1966
1988
|
if (isTextElement(newElement) && isBoundToContainer(newElement)) {
|
|
1967
1989
|
const container = getContainerElement(newElement, this.scene.getElementsMapIncludingDeleted());
|
|
@@ -1971,7 +1993,7 @@ class App extends React.Component {
|
|
|
1971
1993
|
if (opts.files) {
|
|
1972
1994
|
this.files = { ...this.files, ...opts.files };
|
|
1973
1995
|
}
|
|
1974
|
-
this.
|
|
1996
|
+
this.store.shouldCaptureIncrement();
|
|
1975
1997
|
const nextElementsToSelect = excludeElementsInFramesFromSelection(newElements);
|
|
1976
1998
|
this.setState({
|
|
1977
1999
|
...this.state,
|
|
@@ -2129,16 +2151,7 @@ class App extends React.Component {
|
|
|
2129
2151
|
if (textElements.length === 0) {
|
|
2130
2152
|
return;
|
|
2131
2153
|
}
|
|
2132
|
-
|
|
2133
|
-
if (frameId) {
|
|
2134
|
-
this.scene.insertElementsAtIndex(textElements, this.scene.getElementIndex(frameId));
|
|
2135
|
-
}
|
|
2136
|
-
else {
|
|
2137
|
-
this.scene.replaceAllElements([
|
|
2138
|
-
...this.scene.getElementsIncludingDeleted(),
|
|
2139
|
-
...textElements,
|
|
2140
|
-
]);
|
|
2141
|
-
}
|
|
2154
|
+
this.scene.insertElements(textElements);
|
|
2142
2155
|
this.setState({
|
|
2143
2156
|
selectedElementIds: makeNextSelectedElementIds(Object.fromEntries(textElements.map((el) => [el.id, true])), this.state),
|
|
2144
2157
|
});
|
|
@@ -2154,7 +2167,7 @@ class App extends React.Component {
|
|
|
2154
2167
|
});
|
|
2155
2168
|
PLAIN_PASTE_TOAST_SHOWN = true;
|
|
2156
2169
|
}
|
|
2157
|
-
this.
|
|
2170
|
+
this.store.shouldCaptureIncrement();
|
|
2158
2171
|
}
|
|
2159
2172
|
setAppState = (state, callback) => {
|
|
2160
2173
|
this.setState(state, callback);
|
|
@@ -2336,24 +2349,41 @@ class App extends React.Component {
|
|
|
2336
2349
|
ShapeCache.delete(element);
|
|
2337
2350
|
}
|
|
2338
2351
|
});
|
|
2339
|
-
this.scene.
|
|
2352
|
+
this.scene.triggerUpdate();
|
|
2340
2353
|
this.addNewImagesToImageCache();
|
|
2341
2354
|
});
|
|
2342
2355
|
updateScene = withBatchedUpdates((sceneData) => {
|
|
2343
|
-
|
|
2344
|
-
|
|
2356
|
+
const nextElements = syncInvalidIndices(sceneData.elements ?? []);
|
|
2357
|
+
if (sceneData.storeAction && sceneData.storeAction !== StoreAction.NONE) {
|
|
2358
|
+
const prevCommittedAppState = this.store.snapshot.appState;
|
|
2359
|
+
const prevCommittedElements = this.store.snapshot.elements;
|
|
2360
|
+
const nextCommittedAppState = sceneData.appState
|
|
2361
|
+
? Object.assign({}, prevCommittedAppState, sceneData.appState) // new instance, with partial appstate applied to previously captured one, including hidden prop inside `prevCommittedAppState`
|
|
2362
|
+
: prevCommittedAppState;
|
|
2363
|
+
const nextCommittedElements = sceneData.elements
|
|
2364
|
+
? this.store.filterUncomittedElements(this.scene.getElementsMapIncludingDeleted(), // Only used to detect uncomitted local elements
|
|
2365
|
+
arrayToMap(nextElements))
|
|
2366
|
+
: prevCommittedElements;
|
|
2367
|
+
// 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
|
|
2368
|
+
// do NOT schedule store actions (execute after re-render), as it might cause unexpected concurrency issues if not handled well
|
|
2369
|
+
if (sceneData.storeAction === StoreAction.CAPTURE) {
|
|
2370
|
+
this.store.captureIncrement(nextCommittedElements, nextCommittedAppState);
|
|
2371
|
+
}
|
|
2372
|
+
else if (sceneData.storeAction === StoreAction.UPDATE) {
|
|
2373
|
+
this.store.updateSnapshot(nextCommittedElements, nextCommittedAppState);
|
|
2374
|
+
}
|
|
2345
2375
|
}
|
|
2346
2376
|
if (sceneData.appState) {
|
|
2347
2377
|
this.setState(sceneData.appState);
|
|
2348
2378
|
}
|
|
2349
2379
|
if (sceneData.elements) {
|
|
2350
|
-
this.scene.replaceAllElements(
|
|
2380
|
+
this.scene.replaceAllElements(nextElements);
|
|
2351
2381
|
}
|
|
2352
2382
|
if (sceneData.collaborators) {
|
|
2353
2383
|
this.setState({ collaborators: sceneData.collaborators });
|
|
2354
2384
|
}
|
|
2355
2385
|
});
|
|
2356
|
-
|
|
2386
|
+
triggerRender = () => {
|
|
2357
2387
|
this.setState({});
|
|
2358
2388
|
};
|
|
2359
2389
|
/**
|
|
@@ -2521,7 +2551,9 @@ class App extends React.Component {
|
|
|
2521
2551
|
simultaneouslyUpdated: selectedElements,
|
|
2522
2552
|
});
|
|
2523
2553
|
});
|
|
2524
|
-
this.
|
|
2554
|
+
this.setState({
|
|
2555
|
+
suggestedBindings: getSuggestedBindingsForArrows(selectedElements, this),
|
|
2556
|
+
});
|
|
2525
2557
|
event.preventDefault();
|
|
2526
2558
|
}
|
|
2527
2559
|
else if (event.key === KEYS.ENTER) {
|
|
@@ -2533,7 +2565,7 @@ class App extends React.Component {
|
|
|
2533
2565
|
if (!this.state.editingLinearElement ||
|
|
2534
2566
|
this.state.editingLinearElement.elementId !==
|
|
2535
2567
|
selectedElements[0].id) {
|
|
2536
|
-
this.
|
|
2568
|
+
this.store.shouldCaptureIncrement();
|
|
2537
2569
|
this.setState({
|
|
2538
2570
|
editingLinearElement: new LinearElementEditor(selectedElement),
|
|
2539
2571
|
});
|
|
@@ -2659,11 +2691,7 @@ class App extends React.Component {
|
|
|
2659
2691
|
this.setState({ isBindingEnabled: true });
|
|
2660
2692
|
}
|
|
2661
2693
|
if (isArrowKey(event.key)) {
|
|
2662
|
-
|
|
2663
|
-
const elementsMap = this.scene.getNonDeletedElementsMap();
|
|
2664
|
-
isBindingEnabled(this.state)
|
|
2665
|
-
? bindOrUnbindSelectedElements(selectedElements, this.scene.getNonDeletedElements(), elementsMap)
|
|
2666
|
-
: unbindLinearElements(selectedElements, elementsMap);
|
|
2694
|
+
bindOrUnbindLinearElements(this.scene.getSelectedElements(this.state).filter(isLinearElement), this, isBindingEnabled(this.state), this.state.selectedLinearElement?.selectedPointsIndices ?? []);
|
|
2667
2695
|
this.setState({ suggestedBindings: [] });
|
|
2668
2696
|
}
|
|
2669
2697
|
});
|
|
@@ -2695,6 +2723,9 @@ class App extends React.Component {
|
|
|
2695
2723
|
originSnapOffset: null,
|
|
2696
2724
|
activeEmbeddable: null,
|
|
2697
2725
|
};
|
|
2726
|
+
if (nextActiveTool.type === "freedraw") {
|
|
2727
|
+
this.store.shouldCaptureIncrement();
|
|
2728
|
+
}
|
|
2698
2729
|
let nextState;
|
|
2699
2730
|
if (nextActiveTool.type !== "selection") {
|
|
2700
2731
|
nextState = {
|
|
@@ -2811,15 +2842,16 @@ class App extends React.Component {
|
|
|
2811
2842
|
});
|
|
2812
2843
|
handleTextWysiwyg(element, { isExistingElement = false, }) {
|
|
2813
2844
|
const elementsMap = this.scene.getElementsMapIncludingDeleted();
|
|
2814
|
-
const updateElement = (
|
|
2845
|
+
const updateElement = (nextOriginalText, isDeleted) => {
|
|
2815
2846
|
this.scene.replaceAllElements([
|
|
2816
2847
|
// Not sure why we include deleted elements as well hence using deleted elements map
|
|
2817
2848
|
...this.scene.getElementsIncludingDeleted().map((_element) => {
|
|
2818
2849
|
if (_element.id === element.id && isTextElement(_element)) {
|
|
2819
|
-
return
|
|
2820
|
-
|
|
2821
|
-
isDeleted,
|
|
2822
|
-
|
|
2850
|
+
return newElementWith(_element, {
|
|
2851
|
+
originalText: nextOriginalText,
|
|
2852
|
+
isDeleted: isDeleted ?? _element.isDeleted,
|
|
2853
|
+
// returns (wrapped) text and new dimensions
|
|
2854
|
+
...refreshTextDimensions(_element, getContainerElement(_element, elementsMap), elementsMap, nextOriginalText),
|
|
2823
2855
|
});
|
|
2824
2856
|
}
|
|
2825
2857
|
return _element;
|
|
@@ -2839,15 +2871,15 @@ class App extends React.Component {
|
|
|
2839
2871
|
viewportY - this.state.offsetTop,
|
|
2840
2872
|
];
|
|
2841
2873
|
},
|
|
2842
|
-
onChange: withBatchedUpdates((
|
|
2843
|
-
updateElement(
|
|
2874
|
+
onChange: withBatchedUpdates((nextOriginalText) => {
|
|
2875
|
+
updateElement(nextOriginalText, false);
|
|
2844
2876
|
if (isNonDeletedElement(element)) {
|
|
2845
2877
|
updateBoundElements(element, elementsMap);
|
|
2846
2878
|
}
|
|
2847
2879
|
}),
|
|
2848
|
-
onSubmit: withBatchedUpdates(({
|
|
2849
|
-
const isDeleted = !
|
|
2850
|
-
updateElement(
|
|
2880
|
+
onSubmit: withBatchedUpdates(({ viaKeyboard, nextOriginalText }) => {
|
|
2881
|
+
const isDeleted = !nextOriginalText.trim();
|
|
2882
|
+
updateElement(nextOriginalText, isDeleted);
|
|
2851
2883
|
// select the created text element only if submitting via keyboard
|
|
2852
2884
|
// (when submitting via click it should act as signal to deselect)
|
|
2853
2885
|
if (!isDeleted && viaKeyboard) {
|
|
@@ -2867,7 +2899,7 @@ class App extends React.Component {
|
|
|
2867
2899
|
]);
|
|
2868
2900
|
}
|
|
2869
2901
|
if (!isDeleted || isExistingElement) {
|
|
2870
|
-
this.
|
|
2902
|
+
this.store.shouldCaptureIncrement();
|
|
2871
2903
|
}
|
|
2872
2904
|
this.setState({
|
|
2873
2905
|
draggingElement: null,
|
|
@@ -2886,7 +2918,7 @@ class App extends React.Component {
|
|
|
2886
2918
|
this.deselectElements();
|
|
2887
2919
|
// do an initial update to re-initialize element position since we were
|
|
2888
2920
|
// modifying element's x/y for sake of editor (case: syncing to remote)
|
|
2889
|
-
updateElement(element.
|
|
2921
|
+
updateElement(element.originalText, false);
|
|
2890
2922
|
}
|
|
2891
2923
|
deselectElements() {
|
|
2892
2924
|
this.setState({
|
|
@@ -2905,6 +2937,57 @@ class App extends React.Component {
|
|
|
2905
2937
|
}
|
|
2906
2938
|
return null;
|
|
2907
2939
|
}
|
|
2940
|
+
/**
|
|
2941
|
+
* get the pure geometric shape of an excalidraw element
|
|
2942
|
+
* which is then used for hit detection
|
|
2943
|
+
*/
|
|
2944
|
+
getElementShape(element) {
|
|
2945
|
+
switch (element.type) {
|
|
2946
|
+
case "rectangle":
|
|
2947
|
+
case "diamond":
|
|
2948
|
+
case "frame":
|
|
2949
|
+
case "magicframe":
|
|
2950
|
+
case "embeddable":
|
|
2951
|
+
case "image":
|
|
2952
|
+
case "iframe":
|
|
2953
|
+
case "text":
|
|
2954
|
+
case "selection":
|
|
2955
|
+
return getPolygonShape(element);
|
|
2956
|
+
case "arrow":
|
|
2957
|
+
case "line": {
|
|
2958
|
+
const roughShape = ShapeCache.get(element)?.[0] ??
|
|
2959
|
+
ShapeCache.generateElementShape(element, null)[0];
|
|
2960
|
+
const [, , , , cx, cy] = getElementAbsoluteCoords(element, this.scene.getNonDeletedElementsMap());
|
|
2961
|
+
return shouldTestInside(element)
|
|
2962
|
+
? getClosedCurveShape(element, roughShape, [element.x, element.y], element.angle, [cx, cy])
|
|
2963
|
+
: getCurveShape(roughShape, [element.x, element.y], element.angle, [
|
|
2964
|
+
cx,
|
|
2965
|
+
cy,
|
|
2966
|
+
]);
|
|
2967
|
+
}
|
|
2968
|
+
case "ellipse":
|
|
2969
|
+
return getEllipseShape(element);
|
|
2970
|
+
case "freedraw": {
|
|
2971
|
+
const [, , , , cx, cy] = getElementAbsoluteCoords(element, this.scene.getNonDeletedElementsMap());
|
|
2972
|
+
return getFreedrawShape(element, [cx, cy], shouldTestInside(element));
|
|
2973
|
+
}
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2976
|
+
getBoundTextShape(element) {
|
|
2977
|
+
const boundTextElement = getBoundTextElement(element, this.scene.getNonDeletedElementsMap());
|
|
2978
|
+
if (boundTextElement) {
|
|
2979
|
+
if (element.type === "arrow") {
|
|
2980
|
+
return this.getElementShape({
|
|
2981
|
+
...boundTextElement,
|
|
2982
|
+
// arrow's bound text accurate position is not stored in the element's property
|
|
2983
|
+
// but rather calculated and returned from the following static method
|
|
2984
|
+
...LinearElementEditor.getBoundTextElementPosition(element, boundTextElement, this.scene.getNonDeletedElementsMap()),
|
|
2985
|
+
});
|
|
2986
|
+
}
|
|
2987
|
+
return this.getElementShape(boundTextElement);
|
|
2988
|
+
}
|
|
2989
|
+
return null;
|
|
2990
|
+
}
|
|
2908
2991
|
getElementAtPosition(x, y, opts) {
|
|
2909
2992
|
const allHitElements = this.getElementsAtPosition(x, y, opts?.includeBoundTextElement, opts?.includeLockedElements);
|
|
2910
2993
|
if (allHitElements.length > 1) {
|
|
@@ -2918,9 +3001,20 @@ class App extends React.Component {
|
|
|
2918
3001
|
const elementWithHighestZIndex = allHitElements[allHitElements.length - 1];
|
|
2919
3002
|
// If we're hitting element with highest z-index only on its bounding box
|
|
2920
3003
|
// while also hitting other element figure, the latter should be considered.
|
|
2921
|
-
return
|
|
2922
|
-
|
|
2923
|
-
|
|
3004
|
+
return hitElementItself({
|
|
3005
|
+
x,
|
|
3006
|
+
y,
|
|
3007
|
+
element: elementWithHighestZIndex,
|
|
3008
|
+
shape: this.getElementShape(elementWithHighestZIndex),
|
|
3009
|
+
// when overlapping, we would like to be more precise
|
|
3010
|
+
// this also avoids the need to update past tests
|
|
3011
|
+
threshold: this.getElementHitThreshold() / 2,
|
|
3012
|
+
frameNameBound: isFrameLikeElement(elementWithHighestZIndex)
|
|
3013
|
+
? this.frameNameBoundsCache.get(elementWithHighestZIndex)
|
|
3014
|
+
: null,
|
|
3015
|
+
})
|
|
3016
|
+
? elementWithHighestZIndex
|
|
3017
|
+
: allHitElements[allHitElements.length - 2];
|
|
2924
3018
|
}
|
|
2925
3019
|
if (allHitElements.length === 1) {
|
|
2926
3020
|
return allHitElements[0];
|
|
@@ -2928,15 +3022,17 @@ class App extends React.Component {
|
|
|
2928
3022
|
return null;
|
|
2929
3023
|
}
|
|
2930
3024
|
getElementsAtPosition(x, y, includeBoundTextElement = false, includeLockedElements = false) {
|
|
2931
|
-
const
|
|
3025
|
+
const iframeLikes = [];
|
|
3026
|
+
const elementsMap = this.scene.getNonDeletedElementsMap();
|
|
3027
|
+
const elements = (includeBoundTextElement && includeLockedElements
|
|
2932
3028
|
? this.scene.getNonDeletedElements()
|
|
2933
3029
|
: this.scene
|
|
2934
3030
|
.getNonDeletedElements()
|
|
2935
3031
|
.filter((element) => (includeLockedElements || !element.locked) &&
|
|
2936
3032
|
(includeBoundTextElement ||
|
|
2937
|
-
!(isTextElement(element) && element.containerId)))
|
|
2938
|
-
|
|
2939
|
-
|
|
3033
|
+
!(isTextElement(element) && element.containerId))))
|
|
3034
|
+
.filter((el) => this.hitElement(x, y, el))
|
|
3035
|
+
.filter((element) => {
|
|
2940
3036
|
// hitting a frame's element from outside the frame is not considered a hit
|
|
2941
3037
|
const containingFrame = getContainingFrame(element, elementsMap);
|
|
2942
3038
|
return containingFrame &&
|
|
@@ -2944,8 +3040,81 @@ class App extends React.Component {
|
|
|
2944
3040
|
this.state.frameRendering.clip
|
|
2945
3041
|
? isCursorInFrame({ x, y }, containingFrame, elementsMap)
|
|
2946
3042
|
: true;
|
|
3043
|
+
})
|
|
3044
|
+
.filter((el) => {
|
|
3045
|
+
// The parameter elements comes ordered from lower z-index to higher.
|
|
3046
|
+
// We want to preserve that order on the returned array.
|
|
3047
|
+
// Exception being embeddables which should be on top of everything else in
|
|
3048
|
+
// terms of hit testing.
|
|
3049
|
+
if (isIframeElement(el)) {
|
|
3050
|
+
iframeLikes.push(el);
|
|
3051
|
+
return false;
|
|
3052
|
+
}
|
|
3053
|
+
return true;
|
|
3054
|
+
})
|
|
3055
|
+
.concat(iframeLikes);
|
|
3056
|
+
return elements;
|
|
3057
|
+
}
|
|
3058
|
+
getElementHitThreshold() {
|
|
3059
|
+
return DEFAULT_COLLISION_THRESHOLD / this.state.zoom.value;
|
|
3060
|
+
}
|
|
3061
|
+
hitElement(x, y, element, considerBoundingBox = true) {
|
|
3062
|
+
// if the element is selected, then hit test is done against its bounding box
|
|
3063
|
+
if (considerBoundingBox &&
|
|
3064
|
+
this.state.selectedElementIds[element.id] &&
|
|
3065
|
+
shouldShowBoundingBox([element], this.state)) {
|
|
3066
|
+
const selectionShape = getSelectionBoxShape(element, this.scene.getNonDeletedElementsMap(), this.getElementHitThreshold());
|
|
3067
|
+
return isPointInShape([x, y], selectionShape);
|
|
3068
|
+
}
|
|
3069
|
+
// take bound text element into consideration for hit collision as well
|
|
3070
|
+
const hitBoundTextOfElement = hitElementBoundText(x, y, this.getBoundTextShape(element));
|
|
3071
|
+
if (hitBoundTextOfElement) {
|
|
3072
|
+
return true;
|
|
3073
|
+
}
|
|
3074
|
+
return hitElementItself({
|
|
3075
|
+
x,
|
|
3076
|
+
y,
|
|
3077
|
+
element,
|
|
3078
|
+
shape: this.getElementShape(element),
|
|
3079
|
+
threshold: this.getElementHitThreshold(),
|
|
3080
|
+
frameNameBound: isFrameLikeElement(element)
|
|
3081
|
+
? this.frameNameBoundsCache.get(element)
|
|
3082
|
+
: null,
|
|
2947
3083
|
});
|
|
2948
3084
|
}
|
|
3085
|
+
getTextBindableContainerAtPosition(x, y) {
|
|
3086
|
+
const elements = this.scene.getNonDeletedElements();
|
|
3087
|
+
const selectedElements = this.scene.getSelectedElements(this.state);
|
|
3088
|
+
if (selectedElements.length === 1) {
|
|
3089
|
+
return isTextBindableContainer(selectedElements[0], false)
|
|
3090
|
+
? selectedElements[0]
|
|
3091
|
+
: null;
|
|
3092
|
+
}
|
|
3093
|
+
let hitElement = null;
|
|
3094
|
+
// We need to do hit testing from front (end of the array) to back (beginning of the array)
|
|
3095
|
+
for (let index = elements.length - 1; index >= 0; --index) {
|
|
3096
|
+
if (elements[index].isDeleted) {
|
|
3097
|
+
continue;
|
|
3098
|
+
}
|
|
3099
|
+
const [x1, y1, x2, y2] = getElementAbsoluteCoords(elements[index], this.scene.getNonDeletedElementsMap());
|
|
3100
|
+
if (isArrowElement(elements[index]) &&
|
|
3101
|
+
hitElementItself({
|
|
3102
|
+
x,
|
|
3103
|
+
y,
|
|
3104
|
+
element: elements[index],
|
|
3105
|
+
shape: this.getElementShape(elements[index]),
|
|
3106
|
+
threshold: this.getElementHitThreshold(),
|
|
3107
|
+
})) {
|
|
3108
|
+
hitElement = elements[index];
|
|
3109
|
+
break;
|
|
3110
|
+
}
|
|
3111
|
+
else if (x1 < x && x < x2 && y1 < y && y < y2) {
|
|
3112
|
+
hitElement = elements[index];
|
|
3113
|
+
break;
|
|
3114
|
+
}
|
|
3115
|
+
}
|
|
3116
|
+
return isTextBindableContainer(hitElement, false) ? hitElement : null;
|
|
3117
|
+
}
|
|
2949
3118
|
startTextEditing = ({ sceneX, sceneY, insertAtParentCenter = true, container, }) => {
|
|
2950
3119
|
let shouldBindToContainer = false;
|
|
2951
3120
|
let parentCenterPosition = insertAtParentCenter &&
|
|
@@ -3044,7 +3213,7 @@ class App extends React.Component {
|
|
|
3044
3213
|
this.scene.insertElementAtIndex(element, containerIndex + 1);
|
|
3045
3214
|
}
|
|
3046
3215
|
else {
|
|
3047
|
-
this.scene.
|
|
3216
|
+
this.scene.insertElement(element);
|
|
3048
3217
|
}
|
|
3049
3218
|
}
|
|
3050
3219
|
this.setState({
|
|
@@ -3069,7 +3238,7 @@ class App extends React.Component {
|
|
|
3069
3238
|
if (event[KEYS.CTRL_OR_CMD] &&
|
|
3070
3239
|
(!this.state.editingLinearElement ||
|
|
3071
3240
|
this.state.editingLinearElement.elementId !== selectedElements[0].id)) {
|
|
3072
|
-
this.
|
|
3241
|
+
this.store.shouldCaptureIncrement();
|
|
3073
3242
|
this.setState({
|
|
3074
3243
|
editingLinearElement: new LinearElementEditor(selectedElements[0]),
|
|
3075
3244
|
});
|
|
@@ -3084,6 +3253,7 @@ class App extends React.Component {
|
|
|
3084
3253
|
const selectedGroupId = hitElement &&
|
|
3085
3254
|
getSelectedGroupIdForElement(hitElement, this.state.selectedGroupIds);
|
|
3086
3255
|
if (selectedGroupId) {
|
|
3256
|
+
this.store.shouldCaptureIncrement();
|
|
3087
3257
|
this.setState((prevState) => ({
|
|
3088
3258
|
...prevState,
|
|
3089
3259
|
...selectGroupsForSelectedElements({
|
|
@@ -3103,11 +3273,17 @@ class App extends React.Component {
|
|
|
3103
3273
|
});
|
|
3104
3274
|
return;
|
|
3105
3275
|
}
|
|
3106
|
-
const container =
|
|
3276
|
+
const container = this.getTextBindableContainerAtPosition(sceneX, sceneY);
|
|
3107
3277
|
if (container) {
|
|
3108
3278
|
if (hasBoundTextElement(container) ||
|
|
3109
3279
|
!isTransparent(container.backgroundColor) ||
|
|
3110
|
-
|
|
3280
|
+
hitElementItself({
|
|
3281
|
+
x: sceneX,
|
|
3282
|
+
y: sceneY,
|
|
3283
|
+
element: container,
|
|
3284
|
+
shape: this.getElementShape(container),
|
|
3285
|
+
threshold: this.getElementHitThreshold(),
|
|
3286
|
+
})) {
|
|
3111
3287
|
const midPoint = getContainerCenter(container, this.state, this.scene.getNonDeletedElementsMap());
|
|
3112
3288
|
sceneX = midPoint.x;
|
|
3113
3289
|
sceneY = midPoint.y;
|
|
@@ -3381,15 +3557,23 @@ class App extends React.Component {
|
|
|
3381
3557
|
if (selectedElements.length === 1 &&
|
|
3382
3558
|
!isOverScrollBar &&
|
|
3383
3559
|
!this.state.editingLinearElement) {
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3560
|
+
// for linear elements, we'd like to prioritize point dragging over edge resizing
|
|
3561
|
+
// therefore, we update and check hovered point index first
|
|
3562
|
+
if (this.state.selectedLinearElement) {
|
|
3563
|
+
this.handleHoverSelectedLinearElement(this.state.selectedLinearElement, scenePointerX, scenePointerY);
|
|
3564
|
+
}
|
|
3565
|
+
if (!this.state.selectedLinearElement ||
|
|
3566
|
+
this.state.selectedLinearElement.hoverPointIndex === -1) {
|
|
3567
|
+
const elementWithTransformHandleType = getElementWithTransformHandleType(elements, this.state, scenePointerX, scenePointerY, this.state.zoom, event.pointerType, this.scene.getNonDeletedElementsMap(), this.device);
|
|
3568
|
+
if (elementWithTransformHandleType &&
|
|
3569
|
+
elementWithTransformHandleType.transformHandleType) {
|
|
3570
|
+
setCursor(this.interactiveCanvas, getCursorForResizingElement(elementWithTransformHandleType));
|
|
3571
|
+
return;
|
|
3572
|
+
}
|
|
3389
3573
|
}
|
|
3390
3574
|
}
|
|
3391
3575
|
else if (selectedElements.length > 1 && !isOverScrollBar) {
|
|
3392
|
-
const transformHandleType = getTransformHandleTypeFromCoords(getCommonBounds(selectedElements), scenePointerX, scenePointerY, this.state.zoom, event.pointerType);
|
|
3576
|
+
const transformHandleType = getTransformHandleTypeFromCoords(getCommonBounds(selectedElements), scenePointerX, scenePointerY, this.state.zoom, event.pointerType, this.device);
|
|
3393
3577
|
if (transformHandleType) {
|
|
3394
3578
|
setCursor(this.interactiveCanvas, getCursorForResizingElement({
|
|
3395
3579
|
transformHandleType,
|
|
@@ -3493,7 +3677,7 @@ class App extends React.Component {
|
|
|
3493
3677
|
}
|
|
3494
3678
|
};
|
|
3495
3679
|
const distance = distance2d(pointerDownState.lastCoords.x, pointerDownState.lastCoords.y, scenePointer.x, scenePointer.y);
|
|
3496
|
-
const threshold =
|
|
3680
|
+
const threshold = this.getElementHitThreshold();
|
|
3497
3681
|
const point = { ...pointerDownState.lastCoords };
|
|
3498
3682
|
let samplingInterval = 0;
|
|
3499
3683
|
while (samplingInterval <= distance) {
|
|
@@ -3529,7 +3713,7 @@ class App extends React.Component {
|
|
|
3529
3713
|
}
|
|
3530
3714
|
}
|
|
3531
3715
|
this.elementsPendingErasure = new Set(this.elementsPendingErasure);
|
|
3532
|
-
this.
|
|
3716
|
+
this.triggerRender();
|
|
3533
3717
|
}
|
|
3534
3718
|
};
|
|
3535
3719
|
// set touch moving for mobile context menu
|
|
@@ -3539,30 +3723,29 @@ class App extends React.Component {
|
|
|
3539
3723
|
handleHoverSelectedLinearElement(linearElementEditor, scenePointerX, scenePointerY) {
|
|
3540
3724
|
const elementsMap = this.scene.getNonDeletedElementsMap();
|
|
3541
3725
|
const element = LinearElementEditor.getElement(linearElementEditor.elementId, elementsMap);
|
|
3542
|
-
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
3543
3726
|
if (!element) {
|
|
3544
3727
|
return;
|
|
3545
3728
|
}
|
|
3546
3729
|
if (this.state.selectedLinearElement) {
|
|
3547
3730
|
let hoverPointIndex = -1;
|
|
3548
3731
|
let segmentMidPointHoveredCoords = null;
|
|
3549
|
-
if (
|
|
3732
|
+
if (hitElementItself({
|
|
3733
|
+
x: scenePointerX,
|
|
3734
|
+
y: scenePointerY,
|
|
3735
|
+
element,
|
|
3736
|
+
shape: this.getElementShape(element),
|
|
3737
|
+
})) {
|
|
3550
3738
|
hoverPointIndex = LinearElementEditor.getPointIndexUnderCursor(element, elementsMap, this.state.zoom, scenePointerX, scenePointerY);
|
|
3551
3739
|
segmentMidPointHoveredCoords =
|
|
3552
3740
|
LinearElementEditor.getSegmentMidpointHitCoords(linearElementEditor, { x: scenePointerX, y: scenePointerY }, this.state, this.scene.getNonDeletedElementsMap());
|
|
3553
3741
|
if (hoverPointIndex >= 0 || segmentMidPointHoveredCoords) {
|
|
3554
3742
|
setCursor(this.interactiveCanvas, CURSOR_TYPE.POINTER);
|
|
3555
3743
|
}
|
|
3556
|
-
else {
|
|
3744
|
+
else if (this.hitElement(scenePointerX, scenePointerY, element)) {
|
|
3557
3745
|
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
|
3558
3746
|
}
|
|
3559
3747
|
}
|
|
3560
|
-
else if (
|
|
3561
|
-
isHittingElementBoundingBoxWithoutHittingElement(element, this.state, this.frameNameBoundsCache, scenePointerX, scenePointerY, elementsMap)) {
|
|
3562
|
-
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
|
3563
|
-
}
|
|
3564
|
-
else if (boundTextElement &&
|
|
3565
|
-
hitTest(boundTextElement, this.state, this.frameNameBoundsCache, scenePointerX, scenePointerY, this.scene.getNonDeletedElementsMap())) {
|
|
3748
|
+
else if (this.hitElement(scenePointerX, scenePointerY, element)) {
|
|
3566
3749
|
setCursor(this.interactiveCanvas, CURSOR_TYPE.MOVE);
|
|
3567
3750
|
}
|
|
3568
3751
|
if (this.state.selectedLinearElement.hoverPointIndex !== hoverPointIndex) {
|
|
@@ -3629,6 +3812,7 @@ class App extends React.Component {
|
|
|
3629
3812
|
return obj;
|
|
3630
3813
|
}, {}), this.state),
|
|
3631
3814
|
},
|
|
3815
|
+
storeAction: StoreAction.UPDATE,
|
|
3632
3816
|
});
|
|
3633
3817
|
return;
|
|
3634
3818
|
}
|
|
@@ -4071,8 +4255,11 @@ class App extends React.Component {
|
|
|
4071
4255
|
const elements = this.scene.getNonDeletedElements();
|
|
4072
4256
|
const elementsMap = this.scene.getNonDeletedElementsMap();
|
|
4073
4257
|
const selectedElements = this.scene.getSelectedElements(this.state);
|
|
4074
|
-
if (selectedElements.length === 1 &&
|
|
4075
|
-
|
|
4258
|
+
if (selectedElements.length === 1 &&
|
|
4259
|
+
!this.state.editingLinearElement &&
|
|
4260
|
+
!(this.state.selectedLinearElement &&
|
|
4261
|
+
this.state.selectedLinearElement.hoverPointIndex !== -1)) {
|
|
4262
|
+
const elementWithTransformHandleType = getElementWithTransformHandleType(elements, this.state, pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType, this.scene.getNonDeletedElementsMap(), this.device);
|
|
4076
4263
|
if (elementWithTransformHandleType != null) {
|
|
4077
4264
|
this.setState({
|
|
4078
4265
|
resizingElement: elementWithTransformHandleType.element,
|
|
@@ -4082,7 +4269,7 @@ class App extends React.Component {
|
|
|
4082
4269
|
}
|
|
4083
4270
|
}
|
|
4084
4271
|
else if (selectedElements.length > 1) {
|
|
4085
|
-
pointerDownState.resize.handleType = getTransformHandleTypeFromCoords(getCommonBounds(selectedElements), pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType);
|
|
4272
|
+
pointerDownState.resize.handleType = getTransformHandleTypeFromCoords(getCommonBounds(selectedElements), pointerDownState.origin.x, pointerDownState.origin.y, this.state.zoom, event.pointerType, this.device);
|
|
4086
4273
|
}
|
|
4087
4274
|
if (pointerDownState.resize.handleType) {
|
|
4088
4275
|
pointerDownState.resize.isResizing = true;
|
|
@@ -4096,7 +4283,7 @@ class App extends React.Component {
|
|
|
4096
4283
|
else {
|
|
4097
4284
|
if (this.state.selectedLinearElement) {
|
|
4098
4285
|
const linearElementEditor = this.state.editingLinearElement || this.state.selectedLinearElement;
|
|
4099
|
-
const ret = LinearElementEditor.handlePointerDown(event, this.state, this.
|
|
4286
|
+
const ret = LinearElementEditor.handlePointerDown(event, this.state, this.store, pointerDownState.origin, linearElementEditor, this);
|
|
4100
4287
|
if (ret.hitElement) {
|
|
4101
4288
|
pointerDownState.hit.element = ret.hitElement;
|
|
4102
4289
|
}
|
|
@@ -4257,7 +4444,7 @@ class App extends React.Component {
|
|
|
4257
4444
|
return false;
|
|
4258
4445
|
}
|
|
4259
4446
|
// How many pixels off the shape boundary we still consider a hit
|
|
4260
|
-
const threshold =
|
|
4447
|
+
const threshold = this.getElementHitThreshold();
|
|
4261
4448
|
const [x1, y1, x2, y2] = getCommonBounds(selectedElements);
|
|
4262
4449
|
return (point.x > x1 - threshold &&
|
|
4263
4450
|
point.x < x2 + threshold &&
|
|
@@ -4277,7 +4464,7 @@ class App extends React.Component {
|
|
|
4277
4464
|
includeBoundTextElement: true,
|
|
4278
4465
|
});
|
|
4279
4466
|
// FIXME
|
|
4280
|
-
let container =
|
|
4467
|
+
let container = this.getTextBindableContainerAtPosition(sceneX, sceneY);
|
|
4281
4468
|
if (hasBoundTextElement(element)) {
|
|
4282
4469
|
container = element;
|
|
4283
4470
|
sceneX = element.x + element.width / 2;
|
|
@@ -4335,8 +4522,8 @@ class App extends React.Component {
|
|
|
4335
4522
|
points: [[0, 0]],
|
|
4336
4523
|
pressures,
|
|
4337
4524
|
});
|
|
4338
|
-
const boundElement = getHoveredElementForBinding(pointerDownState.origin, this
|
|
4339
|
-
this.scene.
|
|
4525
|
+
const boundElement = getHoveredElementForBinding(pointerDownState.origin, this);
|
|
4526
|
+
this.scene.insertElement(element);
|
|
4340
4527
|
this.setState({
|
|
4341
4528
|
draggingElement: element,
|
|
4342
4529
|
editingElement: element,
|
|
@@ -4364,10 +4551,7 @@ class App extends React.Component {
|
|
|
4364
4551
|
width,
|
|
4365
4552
|
height,
|
|
4366
4553
|
});
|
|
4367
|
-
this.scene.
|
|
4368
|
-
...this.scene.getElementsIncludingDeleted(),
|
|
4369
|
-
element,
|
|
4370
|
-
]);
|
|
4554
|
+
this.scene.insertElement(element);
|
|
4371
4555
|
return element;
|
|
4372
4556
|
};
|
|
4373
4557
|
//create rectangle element with youtube top left on nearest grid point width / hight 640/360
|
|
@@ -4402,10 +4586,7 @@ class App extends React.Component {
|
|
|
4402
4586
|
height: embedLink.intrinsicSize.h,
|
|
4403
4587
|
link,
|
|
4404
4588
|
});
|
|
4405
|
-
this.scene.
|
|
4406
|
-
...this.scene.getElementsIncludingDeleted(),
|
|
4407
|
-
element,
|
|
4408
|
-
]);
|
|
4589
|
+
this.scene.insertElement(element);
|
|
4409
4590
|
return element;
|
|
4410
4591
|
};
|
|
4411
4592
|
createImageElement = ({ sceneX, sceneY, addToFrameUnderCursor = true, }) => {
|
|
@@ -4513,8 +4694,8 @@ class App extends React.Component {
|
|
|
4513
4694
|
mutateElement(element, {
|
|
4514
4695
|
points: [...element.points, [0, 0]],
|
|
4515
4696
|
});
|
|
4516
|
-
const boundElement = getHoveredElementForBinding(pointerDownState.origin, this
|
|
4517
|
-
this.scene.
|
|
4697
|
+
const boundElement = getHoveredElementForBinding(pointerDownState.origin, this);
|
|
4698
|
+
this.scene.insertElement(element);
|
|
4518
4699
|
this.setState({
|
|
4519
4700
|
draggingElement: element,
|
|
4520
4701
|
editingElement: element,
|
|
@@ -4574,7 +4755,7 @@ class App extends React.Component {
|
|
|
4574
4755
|
});
|
|
4575
4756
|
}
|
|
4576
4757
|
else {
|
|
4577
|
-
this.scene.
|
|
4758
|
+
this.scene.insertElement(element);
|
|
4578
4759
|
this.setState({
|
|
4579
4760
|
multiElement: null,
|
|
4580
4761
|
draggingElement: element,
|
|
@@ -4596,10 +4777,7 @@ class App extends React.Component {
|
|
|
4596
4777
|
const frame = type === TOOL_TYPE.magicframe
|
|
4597
4778
|
? newMagicFrameElement(constructorOpts)
|
|
4598
4779
|
: newFrameElement(constructorOpts);
|
|
4599
|
-
this.scene.
|
|
4600
|
-
...this.scene.getElementsIncludingDeleted(),
|
|
4601
|
-
frame,
|
|
4602
|
-
]);
|
|
4780
|
+
this.scene.insertElement(frame);
|
|
4603
4781
|
this.setState({
|
|
4604
4782
|
multiElement: null,
|
|
4605
4783
|
draggingElement: frame,
|
|
@@ -4813,7 +4991,9 @@ class App extends React.Component {
|
|
|
4813
4991
|
// able to select and interact with the text input
|
|
4814
4992
|
!this.state.editingFrame &&
|
|
4815
4993
|
dragSelectedElements(pointerDownState, selectedElements, dragOffset, this.state, this.scene, snapOffset, event[KEYS.CTRL_OR_CMD] ? null : this.state.gridSize);
|
|
4816
|
-
this.
|
|
4994
|
+
this.setState({
|
|
4995
|
+
suggestedBindings: getSuggestedBindingsForArrows(selectedElements, this),
|
|
4996
|
+
});
|
|
4817
4997
|
// We duplicate the selected element if alt is pressed on pointer move
|
|
4818
4998
|
if (event.altKey && !pointerDownState.hit.hasBeenDuplicated) {
|
|
4819
4999
|
// Move the currently selected elements to the top of the z index stack, and
|
|
@@ -4857,6 +5037,7 @@ class App extends React.Component {
|
|
|
4857
5037
|
}
|
|
4858
5038
|
}
|
|
4859
5039
|
const nextSceneElements = [...nextElements, ...elementsToAppend];
|
|
5040
|
+
syncMovedIndices(nextSceneElements, arrayToMap(elementsToAppend));
|
|
4860
5041
|
bindTextToShapeAfterDuplication(nextElements, elementsToAppend, oldIdToDuplicatedId);
|
|
4861
5042
|
fixBindingsAfterDuplication(nextSceneElements, elementsToAppend, oldIdToDuplicatedId, "duplicatesServeAsOld");
|
|
4862
5043
|
bindElementsToFramesAfterDuplication(nextSceneElements, elementsToAppend, oldIdToDuplicatedId);
|
|
@@ -5049,7 +5230,7 @@ class App extends React.Component {
|
|
|
5049
5230
|
this.actionManager.executeAction(actionFinalize);
|
|
5050
5231
|
}
|
|
5051
5232
|
else {
|
|
5052
|
-
const editingLinearElement = LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state, this
|
|
5233
|
+
const editingLinearElement = LinearElementEditor.handlePointerUp(childEvent, this.state.editingLinearElement, this.state, this);
|
|
5053
5234
|
if (editingLinearElement !== this.state.editingLinearElement) {
|
|
5054
5235
|
this.setState({
|
|
5055
5236
|
editingLinearElement,
|
|
@@ -5068,7 +5249,7 @@ class App extends React.Component {
|
|
|
5068
5249
|
}
|
|
5069
5250
|
}
|
|
5070
5251
|
else {
|
|
5071
|
-
const linearElementEditor = LinearElementEditor.handlePointerUp(childEvent, this.state.selectedLinearElement, this.state, this
|
|
5252
|
+
const linearElementEditor = LinearElementEditor.handlePointerUp(childEvent, this.state.selectedLinearElement, this.state, this);
|
|
5072
5253
|
const { startBindingElement, endBindingElement } = linearElementEditor;
|
|
5073
5254
|
const element = this.scene.getElement(linearElementEditor.elementId);
|
|
5074
5255
|
if (isBindingElement(element)) {
|
|
@@ -5137,7 +5318,7 @@ class App extends React.Component {
|
|
|
5137
5318
|
}
|
|
5138
5319
|
if (isLinearElement(draggingElement)) {
|
|
5139
5320
|
if (draggingElement.points.length > 1) {
|
|
5140
|
-
this.
|
|
5321
|
+
this.store.shouldCaptureIncrement();
|
|
5141
5322
|
}
|
|
5142
5323
|
const pointerCoords = viewportCoordsToSceneCoords(childEvent, this.state);
|
|
5143
5324
|
if (!pointerDownState.drag.hasOccurred &&
|
|
@@ -5160,7 +5341,7 @@ class App extends React.Component {
|
|
|
5160
5341
|
else if (pointerDownState.drag.hasOccurred && !multiElement) {
|
|
5161
5342
|
if (isBindingEnabled(this.state) &&
|
|
5162
5343
|
isBindingElement(draggingElement, false)) {
|
|
5163
|
-
maybeBindLinearElement(draggingElement, this.state,
|
|
5344
|
+
maybeBindLinearElement(draggingElement, this.state, pointerCoords, this);
|
|
5164
5345
|
}
|
|
5165
5346
|
this.setState({ suggestedBindings: [], startBoundElement: null });
|
|
5166
5347
|
if (!activeTool.locked) {
|
|
@@ -5189,11 +5370,15 @@ class App extends React.Component {
|
|
|
5189
5370
|
draggingElement &&
|
|
5190
5371
|
isInvisiblySmallElement(draggingElement)) {
|
|
5191
5372
|
// remove invisible element which was added in onPointerDown
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5373
|
+
// update the store snapshot, so that invisible elements are not captured by the store
|
|
5374
|
+
this.updateScene({
|
|
5375
|
+
elements: this.scene
|
|
5376
|
+
.getElementsIncludingDeleted()
|
|
5377
|
+
.filter((el) => el.id !== draggingElement.id),
|
|
5378
|
+
appState: {
|
|
5379
|
+
draggingElement: null,
|
|
5380
|
+
},
|
|
5381
|
+
storeAction: StoreAction.UPDATE,
|
|
5197
5382
|
});
|
|
5198
5383
|
return;
|
|
5199
5384
|
}
|
|
@@ -5216,7 +5401,7 @@ class App extends React.Component {
|
|
|
5216
5401
|
groupIds: [],
|
|
5217
5402
|
});
|
|
5218
5403
|
removeElementsFromFrame([linearElement], this.scene.getNonDeletedElementsMap());
|
|
5219
|
-
this.scene.
|
|
5404
|
+
this.scene.triggerUpdate();
|
|
5220
5405
|
}
|
|
5221
5406
|
}
|
|
5222
5407
|
}
|
|
@@ -5274,12 +5459,16 @@ class App extends React.Component {
|
|
|
5274
5459
|
mutateElement(draggingElement, getNormalizedDimensions(draggingElement));
|
|
5275
5460
|
}
|
|
5276
5461
|
if (resizingElement) {
|
|
5277
|
-
this.
|
|
5462
|
+
this.store.shouldCaptureIncrement();
|
|
5278
5463
|
}
|
|
5279
5464
|
if (resizingElement && isInvisiblySmallElement(resizingElement)) {
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5465
|
+
// update the store snapshot, so that invisible elements are not captured by the store
|
|
5466
|
+
this.updateScene({
|
|
5467
|
+
elements: this.scene
|
|
5468
|
+
.getElementsIncludingDeleted()
|
|
5469
|
+
.filter((el) => el.id !== resizingElement.id),
|
|
5470
|
+
storeAction: StoreAction.UPDATE,
|
|
5471
|
+
});
|
|
5283
5472
|
}
|
|
5284
5473
|
// handle frame membership for resizing frames and/or selected elements
|
|
5285
5474
|
if (pointerDownState.resize.isResizing) {
|
|
@@ -5434,10 +5623,23 @@ class App extends React.Component {
|
|
|
5434
5623
|
}));
|
|
5435
5624
|
}
|
|
5436
5625
|
}
|
|
5437
|
-
if (
|
|
5626
|
+
if (
|
|
5627
|
+
// not dragged
|
|
5628
|
+
!pointerDownState.drag.hasOccurred &&
|
|
5629
|
+
// not resized
|
|
5438
5630
|
!this.state.isResizing &&
|
|
5631
|
+
// only hitting the bounding box of the previous hit element
|
|
5439
5632
|
((hitElement &&
|
|
5440
|
-
|
|
5633
|
+
hitElementBoundingBoxOnly({
|
|
5634
|
+
x: pointerDownState.origin.x,
|
|
5635
|
+
y: pointerDownState.origin.y,
|
|
5636
|
+
element: hitElement,
|
|
5637
|
+
shape: this.getElementShape(hitElement),
|
|
5638
|
+
threshold: this.getElementHitThreshold(),
|
|
5639
|
+
frameNameBound: isFrameLikeElement(hitElement)
|
|
5640
|
+
? this.frameNameBoundsCache.get(hitElement)
|
|
5641
|
+
: null,
|
|
5642
|
+
}, elementsMap)) ||
|
|
5441
5643
|
(!hitElement &&
|
|
5442
5644
|
pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements))) {
|
|
5443
5645
|
if (this.state.editingLinearElement) {
|
|
@@ -5452,6 +5654,8 @@ class App extends React.Component {
|
|
|
5452
5654
|
activeEmbeddable: null,
|
|
5453
5655
|
});
|
|
5454
5656
|
}
|
|
5657
|
+
// reset cursor
|
|
5658
|
+
setCursor(this.interactiveCanvas, CURSOR_TYPE.AUTO);
|
|
5455
5659
|
return;
|
|
5456
5660
|
}
|
|
5457
5661
|
if (!activeTool.locked &&
|
|
@@ -5469,13 +5673,17 @@ class App extends React.Component {
|
|
|
5469
5673
|
}));
|
|
5470
5674
|
}
|
|
5471
5675
|
if (activeTool.type !== "selection" ||
|
|
5472
|
-
isSomeElementSelected(this.scene.getNonDeletedElements(), this.state)
|
|
5473
|
-
this.
|
|
5676
|
+
isSomeElementSelected(this.scene.getNonDeletedElements(), this.state) ||
|
|
5677
|
+
!isShallowEqual(this.state.previousSelectedElementIds, this.state.selectedElementIds)) {
|
|
5678
|
+
this.store.shouldCaptureIncrement();
|
|
5474
5679
|
}
|
|
5475
5680
|
if (pointerDownState.drag.hasOccurred || isResizing || isRotating) {
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5681
|
+
// We only allow binding via linear elements, specifically via dragging
|
|
5682
|
+
// the endpoints ("start" or "end").
|
|
5683
|
+
const linearElements = this.scene
|
|
5684
|
+
.getSelectedElements(this.state)
|
|
5685
|
+
.filter(isLinearElement);
|
|
5686
|
+
bindOrUnbindLinearElements(linearElements, this, isBindingEnabled(this.state), this.state.selectedLinearElement?.selectedPointsIndices ?? []);
|
|
5479
5687
|
}
|
|
5480
5688
|
if (activeTool.type === "laser") {
|
|
5481
5689
|
this.laserTrails.endPath();
|
|
@@ -5510,7 +5718,7 @@ class App extends React.Component {
|
|
|
5510
5718
|
}
|
|
5511
5719
|
restoreReadyToEraseElements = () => {
|
|
5512
5720
|
this.elementsPendingErasure = new Set();
|
|
5513
|
-
this.
|
|
5721
|
+
this.triggerRender();
|
|
5514
5722
|
};
|
|
5515
5723
|
eraseElements = () => {
|
|
5516
5724
|
let didChange = false;
|
|
@@ -5526,7 +5734,7 @@ class App extends React.Component {
|
|
|
5526
5734
|
});
|
|
5527
5735
|
this.elementsPendingErasure = new Set();
|
|
5528
5736
|
if (didChange) {
|
|
5529
|
-
this.
|
|
5737
|
+
this.store.shouldCaptureIncrement();
|
|
5530
5738
|
this.scene.replaceAllElements(elements);
|
|
5531
5739
|
}
|
|
5532
5740
|
};
|
|
@@ -5629,7 +5837,7 @@ class App extends React.Component {
|
|
|
5629
5837
|
this.setState({ errorMessage: t("errors.imageToolNotSupported") });
|
|
5630
5838
|
return;
|
|
5631
5839
|
}
|
|
5632
|
-
this.scene.
|
|
5840
|
+
this.scene.insertElement(imageElement);
|
|
5633
5841
|
try {
|
|
5634
5842
|
return await this.initializeImage({
|
|
5635
5843
|
imageFile,
|
|
@@ -5802,7 +6010,7 @@ class App extends React.Component {
|
|
|
5802
6010
|
if (uncachedImageElements.length) {
|
|
5803
6011
|
const { updatedFiles } = await this.updateImageCache(uncachedImageElements, files);
|
|
5804
6012
|
if (updatedFiles.size) {
|
|
5805
|
-
this.scene.
|
|
6013
|
+
this.scene.triggerUpdate();
|
|
5806
6014
|
}
|
|
5807
6015
|
}
|
|
5808
6016
|
};
|
|
@@ -5818,7 +6026,7 @@ class App extends React.Component {
|
|
|
5818
6026
|
}
|
|
5819
6027
|
};
|
|
5820
6028
|
maybeSuggestBindingAtCursor = (pointerCoords) => {
|
|
5821
|
-
const hoveredBindableElement = getHoveredElementForBinding(pointerCoords, this
|
|
6029
|
+
const hoveredBindableElement = getHoveredElementForBinding(pointerCoords, this);
|
|
5822
6030
|
this.setState({
|
|
5823
6031
|
suggestedBindings: hoveredBindableElement != null ? [hoveredBindableElement] : [],
|
|
5824
6032
|
});
|
|
@@ -5833,7 +6041,7 @@ class App extends React.Component {
|
|
|
5833
6041
|
return;
|
|
5834
6042
|
}
|
|
5835
6043
|
const suggestedBindings = pointerCoords.reduce((acc, coords) => {
|
|
5836
|
-
const hoveredBindableElement = getHoveredElementForBinding(coords, this
|
|
6044
|
+
const hoveredBindableElement = getHoveredElementForBinding(coords, this);
|
|
5837
6045
|
if (hoveredBindableElement != null &&
|
|
5838
6046
|
!isLinearElementSimpleAndAlreadyBound(linearElement, oppositeBindingBoundElement?.id, hoveredBindableElement)) {
|
|
5839
6047
|
acc.push(hoveredBindableElement);
|
|
@@ -5842,13 +6050,6 @@ class App extends React.Component {
|
|
|
5842
6050
|
}, []);
|
|
5843
6051
|
this.setState({ suggestedBindings });
|
|
5844
6052
|
};
|
|
5845
|
-
maybeSuggestBindingForAll(selectedElements) {
|
|
5846
|
-
if (selectedElements.length > 50) {
|
|
5847
|
-
return;
|
|
5848
|
-
}
|
|
5849
|
-
const suggestedBindings = getEligibleElementsForBinding(selectedElements, this.scene.getNonDeletedElements(), this.scene.getNonDeletedElementsMap());
|
|
5850
|
-
this.setState({ suggestedBindings });
|
|
5851
|
-
}
|
|
5852
6053
|
clearSelection(hitElement) {
|
|
5853
6054
|
this.setState((prevState) => ({
|
|
5854
6055
|
selectedElementIds: makeNextSelectedElementIds({}, prevState),
|
|
@@ -5908,7 +6109,7 @@ class App extends React.Component {
|
|
|
5908
6109
|
isLoading: false,
|
|
5909
6110
|
},
|
|
5910
6111
|
replaceFiles: true,
|
|
5911
|
-
|
|
6112
|
+
storeAction: StoreAction.CAPTURE,
|
|
5912
6113
|
});
|
|
5913
6114
|
return;
|
|
5914
6115
|
}
|
|
@@ -5976,9 +6177,10 @@ class App extends React.Component {
|
|
|
5976
6177
|
loadFileToCanvas = async (file, fileHandle) => {
|
|
5977
6178
|
file = await normalizeFile(file);
|
|
5978
6179
|
try {
|
|
6180
|
+
const elements = this.scene.getElementsIncludingDeleted();
|
|
5979
6181
|
let ret;
|
|
5980
6182
|
try {
|
|
5981
|
-
ret = await loadSceneOrLibraryFromBlob(file, this.state,
|
|
6183
|
+
ret = await loadSceneOrLibraryFromBlob(file, this.state, elements, fileHandle);
|
|
5982
6184
|
}
|
|
5983
6185
|
catch (error) {
|
|
5984
6186
|
const imageSceneDataError = error instanceof ImageSceneDataError;
|
|
@@ -6003,6 +6205,10 @@ class App extends React.Component {
|
|
|
6003
6205
|
return;
|
|
6004
6206
|
}
|
|
6005
6207
|
if (ret.type === MIME_TYPES.excalidraw) {
|
|
6208
|
+
// restore the fractional indices by mutating elements
|
|
6209
|
+
syncInvalidIndices(elements.concat(ret.data.elements));
|
|
6210
|
+
// update the store snapshot for old elements, otherwise we would end up with duplicated fractional indices on undo
|
|
6211
|
+
this.store.updateSnapshot(arrayToMap(elements), this.state);
|
|
6006
6212
|
this.setState({ isLoading: true });
|
|
6007
6213
|
this.syncActionResult({
|
|
6008
6214
|
...ret.data,
|
|
@@ -6011,7 +6217,7 @@ class App extends React.Component {
|
|
|
6011
6217
|
isLoading: false,
|
|
6012
6218
|
},
|
|
6013
6219
|
replaceFiles: true,
|
|
6014
|
-
|
|
6220
|
+
storeAction: StoreAction.CAPTURE,
|
|
6015
6221
|
});
|
|
6016
6222
|
}
|
|
6017
6223
|
else if (ret.type === MIME_TYPES.excalidrawlib) {
|
|
@@ -6113,7 +6319,6 @@ class App extends React.Component {
|
|
|
6113
6319
|
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)
|
|
6114
6320
|
? !shouldMaintainAspectRatio(event)
|
|
6115
6321
|
: shouldMaintainAspectRatio(event), shouldResizeFromCenter(event), aspectRatio, this.state.originSnapOffset);
|
|
6116
|
-
this.maybeSuggestBindingForAll([draggingElement]);
|
|
6117
6322
|
// highlight elements that are to be added to frames on frames creation
|
|
6118
6323
|
if (this.state.activeTool.type === TOOL_TYPE.frame ||
|
|
6119
6324
|
this.state.activeTool.type === TOOL_TYPE.magicframe) {
|
|
@@ -6167,16 +6372,17 @@ class App extends React.Component {
|
|
|
6167
6372
|
snapLines,
|
|
6168
6373
|
});
|
|
6169
6374
|
}
|
|
6170
|
-
if (transformElements(pointerDownState.originalElements, transformHandleType, selectedElements, this.scene.getElementsMapIncludingDeleted(), shouldRotateWithDiscreteAngle(event), shouldResizeFromCenter(event), selectedElements.
|
|
6375
|
+
if (transformElements(pointerDownState.originalElements, transformHandleType, selectedElements, this.scene.getElementsMapIncludingDeleted(), shouldRotateWithDiscreteAngle(event), shouldResizeFromCenter(event), selectedElements.some((element) => isImageElement(element))
|
|
6171
6376
|
? !shouldMaintainAspectRatio(event)
|
|
6172
6377
|
: shouldMaintainAspectRatio(event), resizeX, resizeY, pointerDownState.resize.center.x, pointerDownState.resize.center.y)) {
|
|
6173
|
-
|
|
6378
|
+
const suggestedBindings = getSuggestedBindingsForArrows(selectedElements, this);
|
|
6174
6379
|
const elementsToHighlight = new Set();
|
|
6175
6380
|
selectedFrames.forEach((frame) => {
|
|
6176
6381
|
getElementsInResizingFrame(this.scene.getNonDeletedElements(), frame, this.state, this.scene.getNonDeletedElementsMap()).forEach((element) => elementsToHighlight.add(element));
|
|
6177
6382
|
});
|
|
6178
6383
|
this.setState({
|
|
6179
6384
|
elementsToHighlight: [...elementsToHighlight],
|
|
6385
|
+
suggestedBindings,
|
|
6180
6386
|
});
|
|
6181
6387
|
return true;
|
|
6182
6388
|
}
|
|
@@ -6221,6 +6427,7 @@ class App extends React.Component {
|
|
|
6221
6427
|
return [actionCopy, ...options];
|
|
6222
6428
|
}
|
|
6223
6429
|
return [
|
|
6430
|
+
CONTEXT_MENU_SEPARATOR,
|
|
6224
6431
|
actionCut,
|
|
6225
6432
|
actionCopy,
|
|
6226
6433
|
actionPaste,
|
|
@@ -6233,6 +6440,7 @@ class App extends React.Component {
|
|
|
6233
6440
|
actionPasteStyles,
|
|
6234
6441
|
CONTEXT_MENU_SEPARATOR,
|
|
6235
6442
|
actionGroup,
|
|
6443
|
+
actionTextAutoResize,
|
|
6236
6444
|
actionUnbindText,
|
|
6237
6445
|
actionBindText,
|
|
6238
6446
|
actionWrapTextInContainer,
|
|
@@ -6401,7 +6609,7 @@ export const createTestHook = () => {
|
|
|
6401
6609
|
return this.app?.scene.getElementsIncludingDeleted();
|
|
6402
6610
|
},
|
|
6403
6611
|
set(elements) {
|
|
6404
|
-
return this.app?.scene.replaceAllElements(elements);
|
|
6612
|
+
return this.app?.scene.replaceAllElements(syncInvalidIndices(elements));
|
|
6405
6613
|
},
|
|
6406
6614
|
},
|
|
6407
6615
|
});
|