kritzel-stencil 0.0.144 → 0.0.146
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{index-C9GjuVAx.js → default-text-tool.config-C0W0noF9.js} +15960 -1098
- package/dist/cjs/default-text-tool.config-C0W0noF9.js.map +1 -0
- package/dist/cjs/{index-DcTwXs_q.js → index-Cj__YTlG.js} +9 -11
- package/dist/cjs/index-Cj__YTlG.js.map +1 -0
- package/dist/cjs/index.cjs.js +1369 -12
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/cjs/kritzel-brush-style.cjs.entry.js +1 -1
- package/dist/cjs/kritzel-color_22.cjs.entry.js +777 -754
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/stencil.cjs.js +3 -3
- package/dist/cjs/stencil.cjs.js.map +1 -1
- package/dist/collection/classes/core/core.class.js +263 -211
- package/dist/collection/classes/core/core.class.js.map +1 -1
- package/dist/collection/classes/core/store.class.js +21 -3
- package/dist/collection/classes/core/store.class.js.map +1 -1
- package/dist/collection/classes/core/viewport.class.js +4 -1
- package/dist/collection/classes/core/viewport.class.js.map +1 -1
- package/dist/collection/classes/core/workspace.class.js +2 -3
- package/dist/collection/classes/core/workspace.class.js.map +1 -1
- package/dist/collection/classes/handlers/context-menu.handler.js +11 -14
- package/dist/collection/classes/handlers/context-menu.handler.js.map +1 -1
- package/dist/collection/classes/handlers/key.handler.js +13 -13
- package/dist/collection/classes/handlers/key.handler.js.map +1 -1
- package/dist/collection/classes/handlers/move.handler.js +12 -9
- package/dist/collection/classes/handlers/move.handler.js.map +1 -1
- package/dist/collection/classes/handlers/resize.handler.js +20 -17
- package/dist/collection/classes/handlers/resize.handler.js.map +1 -1
- package/dist/collection/classes/handlers/rotation.handler.js +26 -23
- package/dist/collection/classes/handlers/rotation.handler.js.map +1 -1
- package/dist/collection/classes/handlers/selection.handler.js +32 -30
- package/dist/collection/classes/handlers/selection.handler.js.map +1 -1
- package/dist/collection/classes/objects/base-object.class.js +6 -15
- package/dist/collection/classes/objects/base-object.class.js.map +1 -1
- package/dist/collection/classes/objects/custom-element.class.js +2 -0
- package/dist/collection/classes/objects/custom-element.class.js.map +1 -1
- package/dist/collection/classes/objects/image.class.js +2 -0
- package/dist/collection/classes/objects/image.class.js.map +1 -1
- package/dist/collection/classes/objects/path.class.js +4 -0
- package/dist/collection/classes/objects/path.class.js.map +1 -1
- package/dist/collection/classes/objects/selection-box.class.js +3 -4
- package/dist/collection/classes/objects/selection-box.class.js.map +1 -1
- package/dist/collection/classes/objects/selection-group.class.js +109 -49
- package/dist/collection/classes/objects/selection-group.class.js.map +1 -1
- package/dist/collection/classes/objects/text.class.js +37 -43
- package/dist/collection/classes/objects/text.class.js.map +1 -1
- package/dist/collection/classes/providers/broadcast-sync-provider.class.js +93 -0
- package/dist/collection/classes/providers/broadcast-sync-provider.class.js.map +1 -0
- package/dist/collection/classes/providers/hocuspocus-sync-provider.class.js +232 -0
- package/dist/collection/classes/providers/hocuspocus-sync-provider.class.js.map +1 -0
- package/dist/collection/classes/providers/indexeddb-sync-provider.class.js +35 -0
- package/dist/collection/classes/providers/indexeddb-sync-provider.class.js.map +1 -0
- package/dist/collection/classes/providers/websocket-sync-provider.class.js +89 -0
- package/dist/collection/classes/providers/websocket-sync-provider.class.js.map +1 -0
- package/dist/collection/classes/structures/app-state-map.structure.js +189 -0
- package/dist/collection/classes/structures/app-state-map.structure.js.map +1 -0
- package/dist/collection/classes/structures/object-map.structure.js +260 -1
- package/dist/collection/classes/structures/object-map.structure.js.map +1 -1
- package/dist/collection/classes/tools/brush-tool.class.js +48 -37
- package/dist/collection/classes/tools/brush-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/eraser-tool.class.js +10 -12
- package/dist/collection/classes/tools/eraser-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/image-tool.class.js +2 -10
- package/dist/collection/classes/tools/image-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/selection-tool.class.js +11 -8
- package/dist/collection/classes/tools/selection-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/text-tool.class.js +13 -26
- package/dist/collection/classes/tools/text-tool.class.js.map +1 -1
- package/dist/collection/collection-manifest.json +1 -1
- package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.js +1 -1
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +36 -1
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js.map +1 -1
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +61 -35
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -1
- package/dist/collection/components/shared/kritzel-color/kritzel-color.js +2 -2
- package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.js +1 -1
- package/dist/collection/components/shared/kritzel-font/kritzel-font.js +1 -1
- package/dist/collection/components/shared/kritzel-font-family/kritzel-font-family.js +1 -1
- package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.js +1 -1
- package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js +1 -1
- package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.js +2 -2
- package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js +1 -1
- package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.js +1 -1
- package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.js +1 -1
- package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.js +4 -4
- package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js +1 -1
- package/dist/collection/components/ui/kritzel-control-brush-config/kritzel-control-brush-config.js +2 -2
- package/dist/collection/components/ui/kritzel-control-text-config/kritzel-control-text-config.js +2 -2
- package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +3 -3
- package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js +1 -1
- package/dist/collection/configs/{default-engine-state.js → default-engine-config.js} +2 -8
- package/dist/collection/configs/default-engine-config.js.map +1 -0
- package/dist/collection/configs/default-sync.config.js +12 -0
- package/dist/collection/configs/default-sync.config.js.map +1 -0
- package/dist/collection/constants/core.constants.js +2 -0
- package/dist/collection/constants/core.constants.js.map +1 -0
- package/dist/collection/index.js +8 -1
- package/dist/collection/index.js.map +1 -1
- package/dist/collection/interfaces/debug-info.interface.js.map +1 -1
- package/dist/collection/interfaces/engine-state.interface.js.map +1 -1
- package/dist/collection/interfaces/object.interface.js.map +1 -1
- package/dist/collection/interfaces/selection-state.interface.js.map +1 -1
- package/dist/collection/interfaces/sync-config.interface.js +2 -0
- package/dist/collection/interfaces/sync-config.interface.js.map +1 -0
- package/dist/collection/interfaces/sync-provider.interface.js +2 -0
- package/dist/collection/interfaces/sync-provider.interface.js.map +1 -0
- package/dist/components/index.js +1361 -4
- package/dist/components/index.js.map +1 -1
- package/dist/components/kritzel-brush-style.js +4 -4
- package/dist/components/kritzel-color-palette.js +1 -1
- package/dist/components/kritzel-color.js +1 -1
- package/dist/components/kritzel-context-menu.js +1 -1
- package/dist/components/kritzel-control-brush-config.js +1 -1
- package/dist/components/kritzel-control-text-config.js +1 -1
- package/dist/components/kritzel-controls.js +1 -1
- package/dist/components/kritzel-cursor-trail.js +1 -1
- package/dist/components/kritzel-dropdown.js +1 -1
- package/dist/components/kritzel-editor.js +39 -27
- package/dist/components/kritzel-editor.js.map +1 -1
- package/dist/components/kritzel-engine.js +1 -1
- package/dist/components/kritzel-font-family.js +1 -1
- package/dist/components/kritzel-font-size.js +1 -1
- package/dist/components/kritzel-font.js +1 -1
- package/dist/components/kritzel-icon.js +1 -1
- package/dist/components/kritzel-menu-item.js +1 -1
- package/dist/components/kritzel-menu.js +1 -1
- package/dist/components/kritzel-portal.js +1 -1
- package/dist/components/kritzel-split-button.js +1 -1
- package/dist/components/kritzel-stroke-size.js +1 -1
- package/dist/components/kritzel-tooltip.js +1 -1
- package/dist/components/kritzel-utility-panel.js +1 -1
- package/dist/components/kritzel-workspace-manager.js +1 -1
- package/dist/components/{p-C_hSH2nN.js → p-8iFF5GHL.js} +6 -6
- package/dist/components/{p-C_hSH2nN.js.map → p-8iFF5GHL.js.map} +1 -1
- package/dist/components/{p-BycHaC-9.js → p-BCrMfH5n.js} +6 -6
- package/dist/components/{p-BycHaC-9.js.map → p-BCrMfH5n.js.map} +1 -1
- package/dist/components/{p-D_RcVGj0.js → p-BHDOht0m.js} +6 -6
- package/dist/components/{p-D_RcVGj0.js.map → p-BHDOht0m.js.map} +1 -1
- package/dist/components/{p-DqsgZIHC.js → p-BHT7_POQ.js} +6 -6
- package/dist/components/{p-DqsgZIHC.js.map → p-BHT7_POQ.js.map} +1 -1
- package/dist/components/{p-DzyZA2GT.js → p-BQ5cdSqE.js} +11 -11
- package/dist/components/{p-DzyZA2GT.js.map → p-BQ5cdSqE.js.map} +1 -1
- package/dist/components/{p-Co5lU_7h.js → p-BaHZYvfq.js} +13 -13
- package/dist/components/{p-Co5lU_7h.js.map → p-BaHZYvfq.js.map} +1 -1
- package/dist/components/{p-BJbN3vca.js → p-BctNMdxr.js} +8 -8
- package/dist/components/{p-BJbN3vca.js.map → p-BctNMdxr.js.map} +1 -1
- package/dist/components/{p-D27d2rKT.js → p-Bhtn9qay.js} +5 -5
- package/dist/components/{p-D27d2rKT.js.map → p-Bhtn9qay.js.map} +1 -1
- package/dist/components/{p-CEn1WeG3.js → p-Bit0z7Yg.js} +9 -9
- package/dist/components/{p-CEn1WeG3.js.map → p-Bit0z7Yg.js.map} +1 -1
- package/dist/components/{p-CGb-8cK4.js → p-BlI4vzRZ.js} +5 -5
- package/dist/components/{p-CGb-8cK4.js.map → p-BlI4vzRZ.js.map} +1 -1
- package/dist/components/{p-fiFoOjv0.js → p-C3_LIgzd.js} +10 -10
- package/dist/components/{p-fiFoOjv0.js.map → p-C3_LIgzd.js.map} +1 -1
- package/dist/components/{p-DPxzgBs0.js → p-CIXPLjCu.js} +4 -4
- package/dist/components/{p-DPxzgBs0.js.map → p-CIXPLjCu.js.map} +1 -1
- package/dist/components/{p-dcR2uxM3.js → p-CURq0twf.js} +6 -6
- package/dist/components/{p-dcR2uxM3.js.map → p-CURq0twf.js.map} +1 -1
- package/dist/components/p-CwHz5s2a.js +18262 -0
- package/dist/components/p-CwHz5s2a.js.map +1 -0
- package/dist/components/{p-C9hrbrUN.js → p-CwkUrTy1.js} +5 -7
- package/dist/{cjs/index-DcTwXs_q.js.map → components/p-CwkUrTy1.js.map} +1 -1
- package/dist/components/{p-ByAzDzS5.js → p-D13ydJjo.js} +5 -5
- package/dist/components/{p-ByAzDzS5.js.map → p-D13ydJjo.js.map} +1 -1
- package/dist/components/{p-1bVCRi-d.js → p-DPN0PZvw.js} +20 -20
- package/dist/components/{p-1bVCRi-d.js.map → p-DPN0PZvw.js.map} +1 -1
- package/dist/components/{p-BFNwskCY.js → p-Dbp5YJIa.js} +5 -5
- package/dist/components/{p-BFNwskCY.js.map → p-Dbp5YJIa.js.map} +1 -1
- package/dist/components/{p-BEKicPnH.js → p-Dcf7tVJW.js} +5 -5
- package/dist/components/{p-BEKicPnH.js.map → p-Dcf7tVJW.js.map} +1 -1
- package/dist/components/{p-CieOx1XL.js → p-EBtkRix7.js} +8 -8
- package/dist/components/{p-CieOx1XL.js.map → p-EBtkRix7.js.map} +1 -1
- package/dist/components/{p-UsToUu6G.js → p-G2HGJcNm.js} +118 -196
- package/dist/components/p-G2HGJcNm.js.map +1 -0
- package/dist/components/{p-gCHmJzc2.js → p-NXPGXBZ2.js} +6 -6
- package/dist/components/{p-gCHmJzc2.js.map → p-NXPGXBZ2.js.map} +1 -1
- package/dist/components/{p-YqK8ch2R.js → p-n789Y3S-.js} +4 -5
- package/dist/components/p-n789Y3S-.js.map +1 -0
- package/dist/esm/{index-YVlgItFD.js → default-text-tool.config-nXXHSTK9.js} +15920 -1090
- package/dist/esm/default-text-tool.config-nXXHSTK9.js.map +1 -0
- package/dist/esm/{index-Cw77zP6g.js → index-SGde3HXB.js} +9 -11
- package/dist/esm/index-SGde3HXB.js.map +1 -0
- package/dist/esm/index.js +1358 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/kritzel-brush-style.entry.js +1 -1
- package/dist/esm/kritzel-color_22.entry.js +732 -709
- package/dist/esm/loader.js +3 -3
- package/dist/esm/stencil.js +4 -4
- package/dist/esm/stencil.js.map +1 -1
- package/dist/stencil/index.esm.js +1 -1
- package/dist/stencil/index.esm.js.map +1 -1
- package/dist/stencil/{p-Cw77zP6g.js → p-SGde3HXB.js} +2 -2
- package/dist/stencil/p-SGde3HXB.js.map +1 -0
- package/dist/stencil/{p-8b831c94.entry.js → p-d702c5af.entry.js} +2 -2
- package/dist/stencil/p-f8a8a8d7.entry.js +2 -0
- package/dist/stencil/p-f8a8a8d7.entry.js.map +1 -0
- package/dist/stencil/p-nXXHSTK9.js +2 -0
- package/dist/stencil/p-nXXHSTK9.js.map +1 -0
- package/dist/stencil/stencil.esm.js +1 -1
- package/dist/stencil/stencil.esm.js.map +1 -1
- package/dist/types/classes/core/core.class.d.ts +34 -21
- package/dist/types/classes/core/store.class.d.ts +8 -0
- package/dist/types/classes/objects/base-object.class.d.ts +1 -5
- package/dist/types/classes/objects/path.class.d.ts +1 -0
- package/dist/types/classes/objects/selection-box.class.d.ts +2 -3
- package/dist/types/classes/objects/selection-group.class.d.ts +24 -5
- package/dist/types/classes/objects/text.class.d.ts +1 -3
- package/dist/types/classes/providers/broadcast-sync-provider.class.d.ts +18 -0
- package/dist/types/classes/providers/hocuspocus-sync-provider.class.d.ts +120 -0
- package/dist/types/classes/providers/indexeddb-sync-provider.class.d.ts +22 -0
- package/dist/types/classes/providers/websocket-sync-provider.class.d.ts +52 -0
- package/dist/types/classes/structures/app-state-map.structure.d.ts +30 -0
- package/dist/types/classes/structures/object-map.structure.d.ts +39 -1
- package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +3 -0
- package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +2 -0
- package/dist/types/components.d.ts +6 -0
- package/dist/types/configs/{default-engine-state.d.ts → default-engine-config.d.ts} +1 -1
- package/dist/types/configs/default-sync.config.d.ts +5 -0
- package/dist/types/constants/core.constants.d.ts +0 -0
- package/dist/types/index.d.ts +8 -1
- package/dist/types/interfaces/debug-info.interface.d.ts +0 -1
- package/dist/types/interfaces/engine-state.interface.d.ts +1 -10
- package/dist/types/interfaces/object.interface.d.ts +1 -1
- package/dist/types/interfaces/selection-state.interface.d.ts +0 -4
- package/dist/types/interfaces/sync-config.interface.d.ts +22 -0
- package/dist/types/interfaces/sync-provider.interface.d.ts +29 -0
- package/dist/types/stencil-public-runtime.d.ts +1 -1
- package/package.json +16 -11
- package/dist/cjs/index-C9GjuVAx.js.map +0 -1
- package/dist/collection/classes/commands/add-object.command.js +0 -18
- package/dist/collection/classes/commands/add-object.command.js.map +0 -1
- package/dist/collection/classes/commands/add-selection-group.command.js +0 -24
- package/dist/collection/classes/commands/add-selection-group.command.js.map +0 -1
- package/dist/collection/classes/commands/base.command.js +0 -19
- package/dist/collection/classes/commands/base.command.js.map +0 -1
- package/dist/collection/classes/commands/batch.command.js +0 -15
- package/dist/collection/classes/commands/batch.command.js.map +0 -1
- package/dist/collection/classes/commands/move-selection-group.command.js +0 -44
- package/dist/collection/classes/commands/move-selection-group.command.js.map +0 -1
- package/dist/collection/classes/commands/remove-object.command.js +0 -18
- package/dist/collection/classes/commands/remove-object.command.js.map +0 -1
- package/dist/collection/classes/commands/remove-selection-group.command.js +0 -19
- package/dist/collection/classes/commands/remove-selection-group.command.js.map +0 -1
- package/dist/collection/classes/commands/resize-selection-group.command.js +0 -29
- package/dist/collection/classes/commands/resize-selection-group.command.js.map +0 -1
- package/dist/collection/classes/commands/rotate-selection-group.command.js +0 -29
- package/dist/collection/classes/commands/rotate-selection-group.command.js.map +0 -1
- package/dist/collection/classes/commands/update-object.command.js +0 -38
- package/dist/collection/classes/commands/update-object.command.js.map +0 -1
- package/dist/collection/classes/commands/update-viewport.command.js +0 -25
- package/dist/collection/classes/commands/update-viewport.command.js.map +0 -1
- package/dist/collection/classes/core/command-manager.class.js +0 -51
- package/dist/collection/classes/core/command-manager.class.js.map +0 -1
- package/dist/collection/classes/core/database.class.js +0 -236
- package/dist/collection/classes/core/database.class.js.map +0 -1
- package/dist/collection/classes/core/history.class.js +0 -51
- package/dist/collection/classes/core/history.class.js.map +0 -1
- package/dist/collection/classes/structures/circular-buffer.structure.js +0 -48
- package/dist/collection/classes/structures/circular-buffer.structure.js.map +0 -1
- package/dist/collection/configs/default-engine-state.js.map +0 -1
- package/dist/collection/interfaces/command.interface.js +0 -2
- package/dist/collection/interfaces/command.interface.js.map +0 -1
- package/dist/components/p-C9hrbrUN.js.map +0 -1
- package/dist/components/p-UsToUu6G.js.map +0 -1
- package/dist/components/p-YqK8ch2R.js.map +0 -1
- package/dist/components/p-kn4eunyR.js +0 -3338
- package/dist/components/p-kn4eunyR.js.map +0 -1
- package/dist/esm/index-Cw77zP6g.js.map +0 -1
- package/dist/esm/index-YVlgItFD.js.map +0 -1
- package/dist/stencil/p-Cw77zP6g.js.map +0 -1
- package/dist/stencil/p-YVlgItFD.js +0 -2
- package/dist/stencil/p-YVlgItFD.js.map +0 -1
- package/dist/stencil/p-fe738990.entry.js +0 -2
- package/dist/stencil/p-fe738990.entry.js.map +0 -1
- package/dist/types/classes/commands/add-object.command.d.ts +0 -9
- package/dist/types/classes/commands/add-selection-group.command.d.ts +0 -10
- package/dist/types/classes/commands/base.command.d.ts +0 -11
- package/dist/types/classes/commands/batch.command.d.ts +0 -8
- package/dist/types/classes/commands/move-selection-group.command.d.ts +0 -13
- package/dist/types/classes/commands/remove-object.command.d.ts +0 -9
- package/dist/types/classes/commands/remove-selection-group.command.d.ts +0 -8
- package/dist/types/classes/commands/resize-selection-group.command.d.ts +0 -20
- package/dist/types/classes/commands/rotate-selection-group.command.d.ts +0 -10
- package/dist/types/classes/commands/update-object.command.d.ts +0 -11
- package/dist/types/classes/commands/update-viewport.command.d.ts +0 -21
- package/dist/types/classes/core/command-manager.class.d.ts +0 -16
- package/dist/types/classes/core/database.class.d.ts +0 -29
- package/dist/types/classes/core/history.class.d.ts +0 -12
- package/dist/types/classes/structures/circular-buffer.structure.d.ts +0 -13
- package/dist/types/interfaces/command.interface.d.ts +0 -6
- /package/dist/stencil/{p-8b831c94.entry.js.map → p-d702c5af.entry.js.map} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-
|
|
2
|
-
import {
|
|
1
|
+
import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-SGde3HXB.js';
|
|
2
|
+
import { U as KritzelDevicesHelper, G as KritzelBrushTool, L as KritzelTextTool, V as KritzelMouseButton, M as KritzelSelectionTool, S as DEFAULT_BRUSH_CONFIG, I as KritzelEraserTool, T as DEFAULT_TEXT_CONFIG, J as KritzelImageTool, R as KritzelWorkspace, W as KritzelKeyboardHelper, X as KritzelBaseHandler, Y as KritzelToolRegistry, Z as KritzelSelectionBox, _ as KritzelSelectionGroup, $ as KritzelBaseObject, F as KritzelImage, K as KritzelText, E as KritzelPath, a0 as Doc, a1 as DEFAULT_SYNC_CONFIG, a2 as UndoManager, Q as KritzelAppStateMap, a3 as ObjectHelper, a4 as KritzelEventHelper, a5 as KritzelBaseTool } from './default-text-tool.config-nXXHSTK9.js';
|
|
3
3
|
|
|
4
4
|
const kritzelColorCss = ":host{display:flex}.checkerboard-bg{background:repeating-conic-gradient(#ccc 0% 25%, #fff 0% 50%) 50% / 8px 8px;position:relative;overflow:hidden}.color-circle{width:24px;height:24px;border-radius:50%;box-sizing:border-box;display:block}.color-circle.white{border:1px solid var(--kritzel-color-palette-circle-border-color, #dddcdc)}";
|
|
5
5
|
|
|
@@ -35,13 +35,13 @@ const KritzelColor = class {
|
|
|
35
35
|
}
|
|
36
36
|
render() {
|
|
37
37
|
const isColorVeryLight = this.isLightColor(this.value);
|
|
38
|
-
return (h(Host, { key: '
|
|
38
|
+
return (h(Host, { key: '198dba41e1600d76faace18de78191d2b7a551ec' }, h("div", { key: 'ee690cffb7925e09cb2c51022eec607247a4849f', class: "checkerboard-bg", style: {
|
|
39
39
|
width: `${this.size}px`,
|
|
40
40
|
height: `${this.size}px`,
|
|
41
41
|
borderRadius: '50%',
|
|
42
42
|
display: 'inline-block',
|
|
43
43
|
position: 'relative',
|
|
44
|
-
} }, h("div", { key: '
|
|
44
|
+
} }, h("div", { key: '66cc8df8fabd008db8c00942994875e3e8d722ce', class: {
|
|
45
45
|
'color-circle': true,
|
|
46
46
|
'white': isColorVeryLight,
|
|
47
47
|
}, style: {
|
|
@@ -84,7 +84,7 @@ const KritzelColorPalette = class {
|
|
|
84
84
|
render() {
|
|
85
85
|
const displayedColors = this.isExpanded ? this.colors : this.colors.slice(0, 6);
|
|
86
86
|
const expandedHeight = this.isExpanded ? this.calculateHeight() : '32px';
|
|
87
|
-
return (h(Host, { key: '
|
|
87
|
+
return (h(Host, { key: '2ead7cd530ce181856e5f582f086a22a1fe69390' }, h("div", { key: 'fcc75b267f36e271d50615bfde42a29c28aa2536', class: {
|
|
88
88
|
'color-grid': true,
|
|
89
89
|
'expanded': this.isExpanded,
|
|
90
90
|
}, style: {
|
|
@@ -149,7 +149,7 @@ const KritzelContextMenu = class {
|
|
|
149
149
|
return defaultValue;
|
|
150
150
|
}
|
|
151
151
|
render() {
|
|
152
|
-
return (h(Host, { key: '
|
|
152
|
+
return (h(Host, { key: '908711e45cb4ea41f25c4f66a9d3b03c847f886e' }, h("div", { key: '7dcb6e5654ecafebc1fc1a2efb9fa1b8678236c4', class: "menu-container" }, this.processedItems.map(({ item, isDisabled }, index) => (h("button", { key: `${item.label}-${index}`, class: { 'menu-item': true, 'disabled': isDisabled }, onClick: () => this.handleItemClick(item, isDisabled), disabled: isDisabled }, item.icon && h("kritzel-icon", { name: item.icon, size: 16 }), h("span", { class: "label" }, item.label)))))));
|
|
153
153
|
}
|
|
154
154
|
static get watchers() { return {
|
|
155
155
|
"items": ["onItemsChanged"]
|
|
@@ -192,14 +192,14 @@ const KritzelControlBrushConfig = class {
|
|
|
192
192
|
this.toolChange.emit(this.tool);
|
|
193
193
|
}
|
|
194
194
|
render() {
|
|
195
|
-
return (h(Host, { key: '
|
|
195
|
+
return (h(Host, { key: '8fe8c0564f491121c0c44c6ff4083034f92dbb67' }, h("div", { key: '3e8a69b827785976768bfc1e809126bee7c48c62', style: {
|
|
196
196
|
display: 'flex',
|
|
197
197
|
flexDirection: 'row',
|
|
198
198
|
alignItems: this.isExpanded ? 'flex-start' : 'center',
|
|
199
199
|
justifyContent: 'flex-start',
|
|
200
200
|
width: '100%',
|
|
201
201
|
gap: '8px',
|
|
202
|
-
} }, h("kritzel-color-palette", { key: '
|
|
202
|
+
} }, h("kritzel-color-palette", { key: 'c9056f81cf47d81fef0a0f5743000dcd6633258a', colors: this.palette, selectedColor: this.tool.color, isExpanded: this.isExpanded, isOpaque: true, onColorChange: color => this.handleColorChange(color) }), h("button", { key: '2f307264b80a732d976edeb025d509bc1164606b', class: "expand-toggle", onClick: () => this.handleToggleExpand(), title: this.isExpanded ? 'Collapse' : 'Expand', style: this.palette.length > 6 ? { visibillity: 'visible' } : { visibility: 'hidden' } }, h("kritzel-icon", { key: '08133ba0a23353b2bb3f87c685a7a0798b8dd16c', name: this.isExpanded ? 'chevron-up' : 'chevron-down' }))), h("kritzel-stroke-size", { key: '3de25cc80029ffdfdc173c4c79e937a7dc329743', selectedSize: this.tool.size, onSizeChange: event => this.handleSizeChange(event) })));
|
|
203
203
|
}
|
|
204
204
|
static get watchers() { return {
|
|
205
205
|
"tool": ["handleToolChange"]
|
|
@@ -233,44 +233,18 @@ const KritzelControlTextConfig = class {
|
|
|
233
233
|
this.toolChange.emit(this.tool);
|
|
234
234
|
}
|
|
235
235
|
render() {
|
|
236
|
-
return (h(Host, { key: '
|
|
236
|
+
return (h(Host, { key: '3695b187943af25566885d63257ae3de9f405ea5' }, h("div", { key: '7bb146ae3c188478ba17f18f70fd170ce3536308', style: {
|
|
237
237
|
display: 'flex',
|
|
238
238
|
flexDirection: 'row',
|
|
239
239
|
alignItems: 'center',
|
|
240
240
|
justifyContent: 'flex-start',
|
|
241
241
|
width: '100%',
|
|
242
242
|
gap: '8px',
|
|
243
|
-
} }, h("kritzel-font-family", { key: '
|
|
243
|
+
} }, h("kritzel-font-family", { key: '87f4c5ac2e2a4cfea216b1b828faad231438b9ec', selectedFontFamily: this.tool.fontFamily, onFontFamilyChange: event => this.handleFamilyChange(event) }), h("button", { key: '2e73aaf7da659b9e069c247cc762f68394212293', class: "expand-toggle", onClick: () => this.handleToggleExpand(), title: this.isExpanded ? 'Collapse' : 'Expand' }, h("kritzel-icon", { key: '785b664697ba266432c535ea26e0665f8d8d657f', name: this.isExpanded ? 'chevron-up' : 'chevron-down' }))), h("kritzel-color-palette", { key: 'ed2517a39d254b77f45154914b3ce6a934f66c33', colors: this.tool.palette, selectedColor: this.tool.fontColor, isExpanded: this.isExpanded, onColorChange: event => this.handleColorChange(event) }), h("kritzel-font-size", { key: '9b25c9607fa69c991e769852e3e3e378e48387bd', selectedSize: this.tool.fontSize, fontFamily: this.tool.fontFamily, onSizeChange: event => this.handleSizeChange(event) })));
|
|
244
244
|
}
|
|
245
245
|
};
|
|
246
246
|
KritzelControlTextConfig.style = kritzelControlTextConfigCss;
|
|
247
247
|
|
|
248
|
-
class KritzelDevicesHelper {
|
|
249
|
-
static isTouchDevice() {
|
|
250
|
-
return window.matchMedia('(any-pointer: coarse)').matches;
|
|
251
|
-
}
|
|
252
|
-
static isAndroid() {
|
|
253
|
-
return /android/i.test(navigator.userAgent);
|
|
254
|
-
}
|
|
255
|
-
static isIOS() {
|
|
256
|
-
return /iPad|iPhone|iPod/.test(navigator.userAgent);
|
|
257
|
-
}
|
|
258
|
-
static detectOS() {
|
|
259
|
-
if (this.isIOS()) {
|
|
260
|
-
return 'iOS';
|
|
261
|
-
}
|
|
262
|
-
else if (this.isAndroid()) {
|
|
263
|
-
return 'Android';
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
return 'Other';
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
static isFirefox() {
|
|
270
|
-
return /firefox/i.test(navigator.userAgent);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
248
|
const kritzelControlsCss = ":host{display:flex;flex-direction:column;user-select:none}:host(.mobile){--kritzel-controls-control-hover-background-color:transparent;--kritzel-controls-control-active-background-color:transparent}.kritzel-controls{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:var(--kritzel-controls-gap, 8px);height:100%;padding:var(--kritzel-controls-padding, 8px);background-color:var(--kritzel-controls-background-color, #ffffff);border-radius:var(--kritzel-controls-border-radius, 16px);box-shadow:var(--kritzel-controls-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-controls-border, 1px solid #ebebeb);z-index:10000;position:relative}.kritzel-control{display:flex;justify-content:center;align-items:center;color:var(--kritzel-controls-control-color, #000000);border-radius:var(--kritzel-controls-control-border-radius, 12px);padding:var(--kritzel-controls-control-padding, 8px);border:none;outline:none;background:none;cursor:pointer;-webkit-tap-highlight-color:transparent;font-weight:bold}.kritzel-control:focus,.kritzel-control:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-control:active{background-color:var(--kritzel-controls-control-active-background-color, hsl(0, 0%, 0%, 8.6%))}.kritzel-control.selected,.kritzel-control.selected:hover,.kritzel-control.selected:active{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF) !important;color:var(--kritzel-controls-control-selected-color, #ffffff) !important}.kritzel-control.selected:focus{background-color:var(--kritzel-controls-control-selected-background-color, #007bffe3) !important}.kritzel-divider{width:var(--kritzel-controls-divider-width, 1px);height:var(--kritzel-controls-divider-height, 24px);background-color:var(--kritzel-controls-divider-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-config-container{position:relative;display:flex;justify-content:center;align-items:center;width:40px;height:40px;box-sizing:border-box;-webkit-tap-highlight-color:transparent}.kritzel-config{display:flex;justify-content:center;align-items:center;cursor:pointer;border-radius:50%}.kritzel-config:focus{outline:var(--kritzel-menu-focus-outline, 2px solid #e3e3e3)}.color-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.font-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.no-config{height:24px;width:24px;border-radius:50%;border:1px dashed gray}kritzel-tooltip{position:fixed;bottom:56px;left:50%;transform:translateX(-50%);z-index:10001}";
|
|
275
249
|
|
|
276
250
|
const KritzelControls = class {
|
|
@@ -374,13 +348,13 @@ const KritzelControls = class {
|
|
|
374
348
|
}
|
|
375
349
|
render() {
|
|
376
350
|
const hasNoConfig = this.activeControl?.config === undefined || this.activeControl?.config === null;
|
|
377
|
-
return (h(Host, { key: '
|
|
351
|
+
return (h(Host, { key: 'a463310d88265b71097f838bf775abdcabc99225', class: {
|
|
378
352
|
mobile: this.isTouchDevice,
|
|
379
|
-
} }, this.isUtilityPanelVisible && (h("kritzel-utility-panel", { key: '
|
|
353
|
+
} }, this.isUtilityPanelVisible && (h("kritzel-utility-panel", { key: '267e9c26b41a52c655209dbaa8c85cbd72323577', style: {
|
|
380
354
|
position: 'absolute',
|
|
381
355
|
bottom: '56px',
|
|
382
356
|
left: '12px',
|
|
383
|
-
}, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), h("div", { key: '
|
|
357
|
+
}, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), h("div", { key: 'c55773245c925e1b972f3e83cb4d8f1c93ebe995', class: "kritzel-controls" }, this.controls.map(control => {
|
|
384
358
|
if (control.type === 'tool') {
|
|
385
359
|
return (h("button", { class: {
|
|
386
360
|
'kritzel-control': true,
|
|
@@ -477,7 +451,7 @@ const KritzelCursorTrail = class {
|
|
|
477
451
|
}
|
|
478
452
|
}
|
|
479
453
|
render() {
|
|
480
|
-
return (h(Host, { key: '
|
|
454
|
+
return (h(Host, { key: '87003b14680b3cbca302e7b31ff57e74cc774e25' }, this.cursorTrailPoints.length > 1 && (h("svg", { key: 'aa6460089c9f3157d2dea9396405b14ab8cc1710', class: "cursor-trail-svg", xmlns: "http://www.w3.org/2000/svg", style: {
|
|
481
455
|
position: 'absolute',
|
|
482
456
|
left: '0',
|
|
483
457
|
top: '0',
|
|
@@ -723,6 +697,7 @@ const KritzelEditor = class {
|
|
|
723
697
|
customSvgIcons = {};
|
|
724
698
|
isControlsVisible = true;
|
|
725
699
|
isUtilityPanelVisible = true;
|
|
700
|
+
syncConfig;
|
|
726
701
|
isReady;
|
|
727
702
|
isEngineReady = false;
|
|
728
703
|
isControlsReady = false;
|
|
@@ -740,6 +715,14 @@ const KritzelEditor = class {
|
|
|
740
715
|
this.checkIsReady();
|
|
741
716
|
}
|
|
742
717
|
}
|
|
718
|
+
onWorkspacesChange(newWorkspaces) {
|
|
719
|
+
if (this.activeWorkspace) {
|
|
720
|
+
const updatedActiveWorkspace = newWorkspaces.find(ws => ws.id === this.activeWorkspace.id);
|
|
721
|
+
if (updatedActiveWorkspace && updatedActiveWorkspace !== this.activeWorkspace) {
|
|
722
|
+
this.activeWorkspace = updatedActiveWorkspace;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
743
726
|
handleTouchStart(event) {
|
|
744
727
|
if (event.cancelable) {
|
|
745
728
|
event.preventDefault();
|
|
@@ -848,11 +831,12 @@ const KritzelEditor = class {
|
|
|
848
831
|
}
|
|
849
832
|
}
|
|
850
833
|
render() {
|
|
851
|
-
return (h(Host, { key: '
|
|
834
|
+
return (h(Host, { key: '5e91eb780eed57131e0389969c359b9ec9a4faaf' }, h("kritzel-workspace-manager", { key: 'c212455bc5042d35963e774d918ef15f5e4fd7e1', workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-engine", { key: '214b6c42b21893172401a6918b2797c0758b3d48', ref: el => (this.engineRef = el), workspace: this.activeWorkspace, syncConfig: this.syncConfig, scaleMax: this.scaleMax, scaleMin: this.scaleMin, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => (this.workspaces = event.detail) }), h("kritzel-controls", { key: '32c6b6408e2fd2c4eaa30efc50bb75b55252a265', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => (this.controlsRef = el), controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, onIsControlsReady: () => (this.isControlsReady = true) })));
|
|
852
835
|
}
|
|
853
836
|
static get watchers() { return {
|
|
854
837
|
"isEngineReady": ["onIsEngineReady"],
|
|
855
|
-
"isControlsReady": ["onIsControlsReady"]
|
|
838
|
+
"isControlsReady": ["onIsControlsReady"],
|
|
839
|
+
"workspaces": ["onWorkspacesChange"]
|
|
856
840
|
}; }
|
|
857
841
|
};
|
|
858
842
|
KritzelEditor.style = kritzelEditorCss;
|
|
@@ -902,7 +886,10 @@ class KritzelViewport {
|
|
|
902
886
|
if (event.pointerType === 'touch') {
|
|
903
887
|
const activePointers = Array.from(this._core.store.state.pointers.values());
|
|
904
888
|
if (activePointers.length === 2) {
|
|
905
|
-
this._core.store.
|
|
889
|
+
const currentPath = this._core.store.currentPath;
|
|
890
|
+
if (currentPath) {
|
|
891
|
+
this._core.store.state.objectsMap.remove(obj => obj.id === currentPath.id);
|
|
892
|
+
}
|
|
906
893
|
this._core.store.state.isScaling = true;
|
|
907
894
|
const firstTouchX = activePointers[0].clientX - this._core.store.offsetX;
|
|
908
895
|
const firstTouchY = activePointers[0].clientY - this._core.store.offsetY;
|
|
@@ -1049,11 +1036,11 @@ class KritzelViewport {
|
|
|
1049
1036
|
class KritzelKeyHandler extends KritzelBaseHandler {
|
|
1050
1037
|
shortcuts = [
|
|
1051
1038
|
// General
|
|
1052
|
-
{ key: 'Escape', condition: c => !!c.store.
|
|
1053
|
-
{ key: 'Delete', condition: c => !!c.store.
|
|
1054
|
-
//
|
|
1055
|
-
{ key: 'z', ctrl: true, action: c => c.
|
|
1056
|
-
{ key: 'y', ctrl: true, action: c => c.
|
|
1039
|
+
{ key: 'Escape', condition: c => !!c.store.selectionGroup, action: c => c.clearSelection() },
|
|
1040
|
+
{ key: 'Delete', condition: c => !!c.store.selectionGroup, action: c => c.delete() },
|
|
1041
|
+
// Undo/Redo
|
|
1042
|
+
{ key: 'z', ctrl: true, action: c => c.undo() },
|
|
1043
|
+
{ key: 'y', ctrl: true, action: c => c.redo() },
|
|
1057
1044
|
// Tool selection
|
|
1058
1045
|
{ key: 's', ctrl: true, action: () => this.switchTool('selection') },
|
|
1059
1046
|
{ key: 'b', ctrl: true, action: () => this.switchTool('brush') },
|
|
@@ -1064,21 +1051,21 @@ class KritzelKeyHandler extends KritzelBaseHandler {
|
|
|
1064
1051
|
{
|
|
1065
1052
|
key: 'c',
|
|
1066
1053
|
ctrl: true,
|
|
1067
|
-
condition: c => !!c.store.
|
|
1054
|
+
condition: c => !!c.store.selectionGroup,
|
|
1068
1055
|
action: c => {
|
|
1069
1056
|
c.copy();
|
|
1070
1057
|
c.rerender();
|
|
1071
1058
|
},
|
|
1072
1059
|
},
|
|
1073
|
-
{ key: 'v', ctrl: true, condition: c => !!c.store.state.copiedObjects && !c.store.
|
|
1060
|
+
{ key: 'v', ctrl: true, condition: c => !!c.store.state.copiedObjects && !c.store.activeText, action: c => c.paste() },
|
|
1074
1061
|
// Text editing
|
|
1075
|
-
// { key: 'a', ctrl: true, condition: c => !!c.store.
|
|
1076
|
-
// { key: 'v', ctrl: true, condition: c => !!c.store.
|
|
1062
|
+
// { key: 'a', ctrl: true, condition: c => !!c.store.activeText, action: c => c.store.activeText.selectAll() },
|
|
1063
|
+
// { key: 'v', ctrl: true, condition: c => !!c.store.activeText, action: c => c.store.activeText.insertFromClipboard() },
|
|
1077
1064
|
// Object layering
|
|
1078
|
-
{ key: '+', ctrl: true, condition: c => !!c.store.
|
|
1079
|
-
{ key: '-', ctrl: true, condition: c => !!c.store.
|
|
1080
|
-
{ key: '*', shift: true, condition: c => !!c.store.
|
|
1081
|
-
{ key: '_', shift: true, condition: c => !!c.store.
|
|
1065
|
+
{ key: '+', ctrl: true, condition: c => !!c.store.selectionGroup, action: c => c.bringForward() },
|
|
1066
|
+
{ key: '-', ctrl: true, condition: c => !!c.store.selectionGroup, action: c => c.sendBackward() },
|
|
1067
|
+
{ key: '*', shift: true, condition: c => !!c.store.selectionGroup, action: c => c.bringToFront() },
|
|
1068
|
+
{ key: '_', shift: true, condition: c => !!c.store.selectionGroup, action: c => c.sendToBack() },
|
|
1082
1069
|
];
|
|
1083
1070
|
constructor(core) {
|
|
1084
1071
|
super(core);
|
|
@@ -1120,25 +1107,25 @@ class KritzelContextMenuHandler extends KritzelBaseHandler {
|
|
|
1120
1107
|
}
|
|
1121
1108
|
const selectionTool = this._core.store.state.activeTool;
|
|
1122
1109
|
selectionTool?.moveHandler?.cancelPendingDrag();
|
|
1123
|
-
if (this._core.store.
|
|
1124
|
-
this._core.store.state.objectsMap.remove(object => object instanceof
|
|
1125
|
-
this._core.store.state.selectionBox = null;
|
|
1110
|
+
if (this._core.store.selectionBox) {
|
|
1111
|
+
this._core.store.state.objectsMap.remove(object => object instanceof KritzelSelectionBox);
|
|
1126
1112
|
this._core.store.state.isSelecting = false;
|
|
1127
1113
|
}
|
|
1128
1114
|
const selectedObject = this._core.getObjectFromPointerEvent(event, '.object');
|
|
1129
|
-
if (selectedObject && !(selectedObject instanceof KritzelSelectionGroup) && !(selectedObject instanceof
|
|
1115
|
+
if (selectedObject && !(selectedObject instanceof KritzelSelectionGroup) && !(selectedObject instanceof KritzelSelectionBox)) {
|
|
1130
1116
|
const selectionGroup = KritzelSelectionGroup.create(this._core);
|
|
1131
1117
|
selectionGroup.addOrRemove(selectedObject);
|
|
1132
1118
|
selectionGroup.isSelected = true;
|
|
1133
1119
|
selectionGroup.rotation = selectedObject.rotation;
|
|
1134
1120
|
this._core.store.state.isSelecting = false;
|
|
1135
|
-
const
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
this._core.
|
|
1121
|
+
const currentSelectionGroup = this._core.store.selectionGroup;
|
|
1122
|
+
if (currentSelectionGroup) {
|
|
1123
|
+
this._core.removeSelectionGroup();
|
|
1124
|
+
}
|
|
1125
|
+
this._core.addSelectionGroup(selectionGroup);
|
|
1126
|
+
this._core.rerender();
|
|
1140
1127
|
}
|
|
1141
|
-
this._core.store.state.contextMenuItems = this._core.store.
|
|
1128
|
+
this._core.store.state.contextMenuItems = this._core.store.selectionGroup ? this.objectContextMenuItems : this.globalContextMenuItems;
|
|
1142
1129
|
let x = event.clientX - this._core.store.offsetX;
|
|
1143
1130
|
let y = event.clientY - this._core.store.offsetY;
|
|
1144
1131
|
const menuWidthEstimate = 150;
|
|
@@ -1166,15 +1153,11 @@ class KritzelClassHelper {
|
|
|
1166
1153
|
}
|
|
1167
1154
|
}
|
|
1168
1155
|
|
|
1169
|
-
const
|
|
1156
|
+
const DEFAULT_ENGINE_CONFIG = {
|
|
1170
1157
|
activeWorkspace: null,
|
|
1171
1158
|
activeTool: null,
|
|
1172
|
-
activeText: null,
|
|
1173
|
-
currentPath: null,
|
|
1174
1159
|
copiedObjects: null,
|
|
1175
1160
|
objectsMap: null,
|
|
1176
|
-
selectionBox: null,
|
|
1177
|
-
selectionGroup: null,
|
|
1178
1161
|
resizeHandleType: null,
|
|
1179
1162
|
hasViewportChanged: false,
|
|
1180
1163
|
hasObjectsChanged: false,
|
|
@@ -1201,7 +1184,6 @@ const DEFAULT_ENGINE_STATE = {
|
|
|
1201
1184
|
showObjectInfo: false,
|
|
1202
1185
|
showViewportInfo: false,
|
|
1203
1186
|
logCommands: false,
|
|
1204
|
-
logDatabase: false,
|
|
1205
1187
|
},
|
|
1206
1188
|
host: null,
|
|
1207
1189
|
pointerX: 0,
|
|
@@ -1220,396 +1202,314 @@ const DEFAULT_ENGINE_STATE = {
|
|
|
1220
1202
|
translateYMin: 0,
|
|
1221
1203
|
viewportWidth: 0,
|
|
1222
1204
|
viewportHeight: 0,
|
|
1223
|
-
historyBufferSize: 1000,
|
|
1224
1205
|
longTouchTimeout: null,
|
|
1225
1206
|
longTouchDelay: 300,
|
|
1226
1207
|
pointers: new Map(),
|
|
1227
1208
|
workspaces: [],
|
|
1228
1209
|
};
|
|
1229
1210
|
|
|
1230
|
-
class
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
console.error('IndexedDB error:', request.error);
|
|
1252
|
-
reject(request.error);
|
|
1253
|
-
};
|
|
1254
|
-
request.onsuccess = () => {
|
|
1255
|
-
this.db = request.result;
|
|
1256
|
-
if (this.isLoggingEnabled) {
|
|
1257
|
-
console.info(`[IndexedDB] Database opened successfully.`);
|
|
1258
|
-
}
|
|
1259
|
-
resolve();
|
|
1260
|
-
};
|
|
1261
|
-
request.onupgradeneeded = event => {
|
|
1262
|
-
if (this.isLoggingEnabled) {
|
|
1263
|
-
console.info(`[IndexedDB] Upgrade needed for database: ${this.dbName}`);
|
|
1264
|
-
}
|
|
1265
|
-
const db = event.target.result;
|
|
1266
|
-
stores.forEach(storeConfig => {
|
|
1267
|
-
if (!db.objectStoreNames.contains(storeConfig.name)) {
|
|
1268
|
-
if (this.isLoggingEnabled) {
|
|
1269
|
-
console.info(`[IndexedDB] Creating store: ${storeConfig.name}`);
|
|
1270
|
-
}
|
|
1271
|
-
const store = db.createObjectStore(storeConfig.name, storeConfig.options);
|
|
1272
|
-
if (storeConfig.indices) {
|
|
1273
|
-
storeConfig.indices.forEach(index => {
|
|
1274
|
-
if (this.isLoggingEnabled) {
|
|
1275
|
-
console.info(`[IndexedDB] Creating index: ${index.name} on store: ${storeConfig.name}`);
|
|
1276
|
-
}
|
|
1277
|
-
store.createIndex(index.name, index.keyPath, index.options);
|
|
1278
|
-
});
|
|
1279
|
-
}
|
|
1280
|
-
}
|
|
1281
|
-
});
|
|
1282
|
-
};
|
|
1283
|
-
});
|
|
1284
|
-
}
|
|
1285
|
-
close() {
|
|
1286
|
-
if (this.db) {
|
|
1287
|
-
if (this.isLoggingEnabled) {
|
|
1288
|
-
console.info(`[IndexedDB] Closing database: ${this.dbName}`);
|
|
1289
|
-
}
|
|
1290
|
-
this.db.close();
|
|
1291
|
-
this.db = null;
|
|
1292
|
-
}
|
|
1211
|
+
class KritzelCustomElement extends KritzelBaseObject {
|
|
1212
|
+
__class__ = 'KritzelCustomElement';
|
|
1213
|
+
element;
|
|
1214
|
+
isInteractive = true;
|
|
1215
|
+
constructor(config) {
|
|
1216
|
+
super();
|
|
1217
|
+
if (config) {
|
|
1218
|
+
this.translateX = config.translateX || 0;
|
|
1219
|
+
this.translateY = config.translateY || 0;
|
|
1220
|
+
this.scale = config.scale || 1;
|
|
1221
|
+
this.element = config.element;
|
|
1222
|
+
this.height = config.height || 0;
|
|
1223
|
+
this.width = config.width || 0;
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
static create(core, config) {
|
|
1227
|
+
const object = new KritzelCustomElement(config);
|
|
1228
|
+
object._core = core;
|
|
1229
|
+
object.id = object.generateId();
|
|
1230
|
+
object.workspaceId = core.store.state.activeWorkspace.id;
|
|
1231
|
+
return object;
|
|
1293
1232
|
}
|
|
1294
|
-
|
|
1295
|
-
if (
|
|
1296
|
-
|
|
1233
|
+
mount(element) {
|
|
1234
|
+
if (element === null) {
|
|
1235
|
+
return;
|
|
1297
1236
|
}
|
|
1298
|
-
|
|
1299
|
-
|
|
1237
|
+
// If already mounted to the same element and content is still attached, skip
|
|
1238
|
+
if (this.isMounted && this.elementRef === element && this.element.parentElement === element) {
|
|
1239
|
+
return;
|
|
1300
1240
|
}
|
|
1301
|
-
|
|
1302
|
-
|
|
1241
|
+
this.elementRef = element;
|
|
1242
|
+
this.isMounted = true;
|
|
1243
|
+
// Clear existing content and append the element
|
|
1244
|
+
this.elementRef.innerHTML = '';
|
|
1245
|
+
this.elementRef.appendChild(this.element);
|
|
1303
1246
|
}
|
|
1304
|
-
|
|
1305
|
-
if (
|
|
1306
|
-
|
|
1247
|
+
resize(x, y, width, height) {
|
|
1248
|
+
if (width <= 1 || height <= 1) {
|
|
1249
|
+
return;
|
|
1307
1250
|
}
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1251
|
+
this.width = width;
|
|
1252
|
+
this.height = height;
|
|
1253
|
+
this.translateX = x;
|
|
1254
|
+
this.translateY = y;
|
|
1255
|
+
if (this.element) {
|
|
1256
|
+
this.element.style.width = `${width}px`;
|
|
1257
|
+
this.element.style.height = `${height}px`;
|
|
1313
1258
|
}
|
|
1314
|
-
|
|
1259
|
+
// Update to sync changes to y.js and propagate to other tabs
|
|
1260
|
+
this._core.store.state.objectsMap.update(this);
|
|
1315
1261
|
}
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
const serializedItem = item.serialize();
|
|
1324
|
-
return this.executeTransaction(storeName, 'readwrite', store => store.put(serializedItem));
|
|
1262
|
+
copy() {
|
|
1263
|
+
const copiedObject = Object.create(Object.getPrototypeOf(this));
|
|
1264
|
+
Object.assign(copiedObject, this);
|
|
1265
|
+
copiedObject.id = this.generateId();
|
|
1266
|
+
copiedObject.isMounted = false;
|
|
1267
|
+
copiedObject.element = this.element.cloneNode(true);
|
|
1268
|
+
return copiedObject;
|
|
1325
1269
|
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
class KritzelReviver {
|
|
1273
|
+
_core;
|
|
1274
|
+
constructor(core) {
|
|
1275
|
+
this._core = core;
|
|
1331
1276
|
}
|
|
1332
|
-
|
|
1333
|
-
if (
|
|
1334
|
-
|
|
1277
|
+
revive(obj) {
|
|
1278
|
+
if (obj && typeof obj === 'object') {
|
|
1279
|
+
if (obj.__class__) {
|
|
1280
|
+
let revivedObj;
|
|
1281
|
+
switch (obj.__class__) {
|
|
1282
|
+
case 'KritzelPath':
|
|
1283
|
+
revivedObj = KritzelPath.create(this._core).deserialize(obj);
|
|
1284
|
+
break;
|
|
1285
|
+
case 'KritzelText':
|
|
1286
|
+
revivedObj = KritzelText.create(this._core, obj.fontSize, obj.fontFamily).deserialize(obj);
|
|
1287
|
+
break;
|
|
1288
|
+
case 'KritzelImage':
|
|
1289
|
+
revivedObj = KritzelImage.create(this._core).deserialize(obj);
|
|
1290
|
+
break;
|
|
1291
|
+
case 'KritzelCustomElement':
|
|
1292
|
+
revivedObj = KritzelCustomElement.create(this._core).deserialize(obj);
|
|
1293
|
+
break;
|
|
1294
|
+
case 'KritzelSelectionGroup':
|
|
1295
|
+
revivedObj = KritzelSelectionGroup.create(this._core).deserialize(obj);
|
|
1296
|
+
break;
|
|
1297
|
+
case 'KritzelWorkspace':
|
|
1298
|
+
revivedObj = KritzelWorkspace.create(this._core, obj).deserialize(obj);
|
|
1299
|
+
break;
|
|
1300
|
+
case 'KritzelBrushTool':
|
|
1301
|
+
revivedObj = new KritzelBrushTool(this._core);
|
|
1302
|
+
break;
|
|
1303
|
+
case 'KritzelEraserTool':
|
|
1304
|
+
revivedObj = new KritzelEraserTool(this._core);
|
|
1305
|
+
break;
|
|
1306
|
+
case 'KritzelImageTool':
|
|
1307
|
+
revivedObj = new KritzelImageTool(this._core);
|
|
1308
|
+
break;
|
|
1309
|
+
case 'KritzelSelectionTool':
|
|
1310
|
+
revivedObj = new KritzelSelectionTool(this._core);
|
|
1311
|
+
break;
|
|
1312
|
+
case 'KritzelTextTool':
|
|
1313
|
+
revivedObj = new KritzelTextTool(this._core);
|
|
1314
|
+
break;
|
|
1315
|
+
default:
|
|
1316
|
+
revivedObj = obj;
|
|
1317
|
+
}
|
|
1318
|
+
return revivedObj;
|
|
1319
|
+
}
|
|
1320
|
+
const newObj = Array.isArray(obj) ? [] : {};
|
|
1321
|
+
for (const key in obj) {
|
|
1322
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
1323
|
+
newObj[key] = this.revive(obj[key]);
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
return newObj;
|
|
1335
1327
|
}
|
|
1336
|
-
return
|
|
1328
|
+
return obj;
|
|
1337
1329
|
}
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
class KritzelObjectMap {
|
|
1333
|
+
map;
|
|
1334
|
+
_ydoc = null;
|
|
1335
|
+
_objectsMap = null;
|
|
1336
|
+
_providers = [];
|
|
1337
|
+
_undoManager = null;
|
|
1338
|
+
_reviver = null;
|
|
1339
|
+
_core = null;
|
|
1340
|
+
_workspaceId = null;
|
|
1341
|
+
_isReady = false;
|
|
1342
|
+
_temporaryItemsCount = 0;
|
|
1343
|
+
get isReady() {
|
|
1344
|
+
return this._isReady;
|
|
1345
|
+
}
|
|
1346
|
+
get undoManager() {
|
|
1347
|
+
return this._undoManager;
|
|
1348
|
+
}
|
|
1349
|
+
get workspaceId() {
|
|
1350
|
+
return this._workspaceId;
|
|
1345
1351
|
}
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
console.info('[IndexedDB] GetAllByIndex:', { storeName, indexName, query });
|
|
1349
|
-
}
|
|
1350
|
-
return this.executeTransaction(storeName, 'readonly', store => {
|
|
1351
|
-
const index = store.index(indexName);
|
|
1352
|
-
return index.getAll(query);
|
|
1353
|
-
});
|
|
1352
|
+
constructor() {
|
|
1353
|
+
this.map = new Map();
|
|
1354
1354
|
}
|
|
1355
|
-
async
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
}
|
|
1355
|
+
async initialize(core, workspaceId, config) {
|
|
1356
|
+
this._core = core;
|
|
1357
|
+
this._workspaceId = workspaceId;
|
|
1358
|
+
this._reviver = new KritzelReviver(core);
|
|
1359
|
+
// Create a dedicated Y.Doc for this workspace
|
|
1360
|
+
this._ydoc = new Doc();
|
|
1361
|
+
this._objectsMap = this._ydoc.getMap('objects');
|
|
1362
|
+
const docName = `kritzel-workspace-${workspaceId}`;
|
|
1363
|
+
const finalConfig = config ?? DEFAULT_SYNC_CONFIG;
|
|
1364
|
+
// Instantiate providers from configuration
|
|
1365
|
+
for (const providerConfig of finalConfig.providers) {
|
|
1366
|
+
let provider;
|
|
1367
|
+
// Check if it's a class constructor or a factory
|
|
1368
|
+
if (typeof providerConfig === 'function') {
|
|
1369
|
+
// It's a class constructor
|
|
1370
|
+
provider = new providerConfig(docName, this._ydoc);
|
|
1371
|
+
}
|
|
1372
|
+
else {
|
|
1373
|
+
// It's a factory with a create method
|
|
1374
|
+
provider = providerConfig.create(docName, this._ydoc);
|
|
1375
|
+
}
|
|
1376
|
+
this._providers.push(provider);
|
|
1377
|
+
}
|
|
1378
|
+
// Set up undo/redo manager for this workspace
|
|
1379
|
+
this._undoManager = new UndoManager([this._objectsMap], {
|
|
1380
|
+
captureTimeout: 200,
|
|
1381
|
+
trackedOrigins: new Set(['local', 'temporary']),
|
|
1382
|
+
ignoreRemoteMapChanges: true,
|
|
1376
1383
|
});
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
const storeNames = await this.extractStoreNamesFromActions(actions);
|
|
1383
|
-
if (this.isLoggingEnabled) {
|
|
1384
|
-
console.info('[IndexedDB] Starting batch transaction:', { storeNames });
|
|
1385
|
-
}
|
|
1386
|
-
return new Promise((resolve, reject) => {
|
|
1387
|
-
const transaction = this.db.transaction(storeNames, 'readwrite');
|
|
1388
|
-
const results = [];
|
|
1389
|
-
const promises = [];
|
|
1390
|
-
const tempDbInstance = {
|
|
1391
|
-
add: (storeName, item) => this.add(storeName, item),
|
|
1392
|
-
get: (storeName, key) => this.get(storeName, key),
|
|
1393
|
-
getAll: (storeName) => this.getAll(storeName),
|
|
1394
|
-
update: (storeName, item) => this.update(storeName, item),
|
|
1395
|
-
delete: (storeName, key) => this.delete(storeName, key),
|
|
1396
|
-
deleteByRange: (storeName, range) => this.deleteByRange(storeName, range),
|
|
1397
|
-
getAllByRange: (storeName, range) => this.getAllByRange(storeName, range),
|
|
1398
|
-
getAllByIndex: (storeName, indexName, query) => this.getAllByIndex(storeName, indexName, query),
|
|
1399
|
-
executeTransaction: (storeName, mode, action) => {
|
|
1400
|
-
return new Promise((resolveRequest, rejectRequest) => {
|
|
1401
|
-
if (this.isLoggingEnabled) {
|
|
1402
|
-
console.info('[IndexedDB] Executing batch action:', { storeName, mode });
|
|
1403
|
-
}
|
|
1404
|
-
const store = transaction.objectStore(storeName);
|
|
1405
|
-
const request = action(store);
|
|
1406
|
-
request.onsuccess = () => {
|
|
1407
|
-
if (this.isLoggingEnabled) {
|
|
1408
|
-
console.info('[IndexedDB] Batch action request successful:', { result: request.result });
|
|
1409
|
-
}
|
|
1410
|
-
resolveRequest(request.result);
|
|
1411
|
-
};
|
|
1412
|
-
request.onerror = () => {
|
|
1413
|
-
console.error('[IndexedDB] Batch action request error:', request.error);
|
|
1414
|
-
rejectRequest(request.error);
|
|
1415
|
-
};
|
|
1416
|
-
});
|
|
1417
|
-
},
|
|
1418
|
-
};
|
|
1419
|
-
transaction.oncomplete = () => {
|
|
1420
|
-
if (this.isLoggingEnabled) {
|
|
1421
|
-
console.info('[IndexedDB] Batch transaction complete.');
|
|
1384
|
+
this._undoManager.on('stack-item-added', event => {
|
|
1385
|
+
if (event.type === 'undo') {
|
|
1386
|
+
// Track if this was a temporary item
|
|
1387
|
+
if (event.origin === 'temporary') {
|
|
1388
|
+
this._temporaryItemsCount++;
|
|
1422
1389
|
}
|
|
1423
|
-
|
|
1424
|
-
}
|
|
1425
|
-
transaction.onabort = () => {
|
|
1426
|
-
console.error('[IndexedDB] Batch transaction aborted:', transaction.error);
|
|
1427
|
-
reject(transaction.error ?? new Error('Transaction aborted'));
|
|
1428
|
-
};
|
|
1429
|
-
transaction.onerror = () => {
|
|
1430
|
-
console.error('[IndexedDB] Batch transaction error:', transaction.error);
|
|
1431
|
-
reject(transaction.error);
|
|
1432
|
-
};
|
|
1433
|
-
actions.forEach((action, index) => {
|
|
1434
|
-
const promise = action(tempDbInstance)
|
|
1435
|
-
.then(result => {
|
|
1436
|
-
results[index] = result;
|
|
1437
|
-
})
|
|
1438
|
-
.catch(err => {
|
|
1439
|
-
if (!transaction.error) {
|
|
1440
|
-
transaction.abort();
|
|
1441
|
-
}
|
|
1442
|
-
reject(err);
|
|
1443
|
-
});
|
|
1444
|
-
promises.push(promise);
|
|
1445
|
-
});
|
|
1390
|
+
console.log('Undo performed for workspace', workspaceId, this._undoManager.undoStack.length, this._undoManager.redoStack.length);
|
|
1391
|
+
}
|
|
1446
1392
|
});
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
if (['add', 'get', 'getAll', 'update', 'delete', 'deleteByRange', 'getAllByRange', 'getAllByIndex'].includes(prop)) {
|
|
1453
|
-
return (storeName) => {
|
|
1454
|
-
storeNamesSet.add(storeName);
|
|
1455
|
-
return Promise.resolve();
|
|
1456
|
-
};
|
|
1393
|
+
this._undoManager.on('stack-item-popped', event => {
|
|
1394
|
+
if (event.type === 'undo') {
|
|
1395
|
+
// Reduce temporary count when items are undone
|
|
1396
|
+
if (event.origin === 'temporary' && this._temporaryItemsCount > 0) {
|
|
1397
|
+
this._temporaryItemsCount--;
|
|
1457
1398
|
}
|
|
1458
|
-
|
|
1459
|
-
}
|
|
1399
|
+
console.log('Redo performed for workspace', workspaceId, this._undoManager.undoStack.length, this._undoManager.redoStack.length);
|
|
1400
|
+
}
|
|
1460
1401
|
});
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
}
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
}
|
|
1478
|
-
execute() {
|
|
1479
|
-
this._core.store.state.scale = this.currentViewport.scale;
|
|
1480
|
-
this._core.store.state.translateX = this.currentViewport.translateX;
|
|
1481
|
-
this._core.store.state.translateY = this.currentViewport.translateY;
|
|
1482
|
-
}
|
|
1483
|
-
undo() {
|
|
1484
|
-
this._core.store.state.scale = this.previousViewport.scale;
|
|
1485
|
-
this._core.store.state.translateX = this.previousViewport.translateX;
|
|
1486
|
-
this._core.store.state.translateY = this.previousViewport.translateY;
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1490
|
-
class KritzelCircularBuffer {
|
|
1491
|
-
buffer;
|
|
1492
|
-
capacity;
|
|
1493
|
-
head = 0;
|
|
1494
|
-
tail = 0;
|
|
1495
|
-
size = 0;
|
|
1496
|
-
constructor(capacity) {
|
|
1497
|
-
this.capacity = capacity;
|
|
1498
|
-
this.buffer = new Array(capacity).fill(null);
|
|
1499
|
-
}
|
|
1500
|
-
add(item) {
|
|
1501
|
-
this.buffer[this.head] = item;
|
|
1502
|
-
this.head = (this.head + 1) % this.capacity;
|
|
1503
|
-
if (this.size < this.capacity) {
|
|
1504
|
-
this.size++;
|
|
1505
|
-
}
|
|
1506
|
-
else {
|
|
1507
|
-
this.tail = (this.tail + 1) % this.capacity;
|
|
1508
|
-
}
|
|
1509
|
-
}
|
|
1510
|
-
pop() {
|
|
1511
|
-
if (this.size === 0) {
|
|
1512
|
-
return null;
|
|
1402
|
+
// Observe changes to objects and sync with application state
|
|
1403
|
+
this._objectsMap.observe(event => {
|
|
1404
|
+
this.handleObjectsChange(event);
|
|
1405
|
+
});
|
|
1406
|
+
// Connect all providers in parallel
|
|
1407
|
+
await Promise.all(this._providers.map(p => p.connect()));
|
|
1408
|
+
this._isReady = true;
|
|
1409
|
+
// Load objects from Yjs
|
|
1410
|
+
this.loadFromYjs();
|
|
1411
|
+
}
|
|
1412
|
+
handleObjectsChange(event) {
|
|
1413
|
+
// Skip Map updates for local changes (already done), but still trigger re-render
|
|
1414
|
+
// 'temporary' is also a local change that shouldn't be re-deserialized
|
|
1415
|
+
if (event.transaction.origin === 'local' || event.transaction.origin === 'temporary') {
|
|
1416
|
+
this._core?.rerender();
|
|
1417
|
+
return;
|
|
1513
1418
|
}
|
|
1514
|
-
|
|
1515
|
-
const
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1419
|
+
const changedKeys = Array.from(event.keysChanged);
|
|
1420
|
+
const objectsToUpdate = [];
|
|
1421
|
+
const selectionGroupsToUpdate = [];
|
|
1422
|
+
const objectsToDelete = [];
|
|
1423
|
+
changedKeys.forEach(key => {
|
|
1424
|
+
const change = event.changes.keys.get(key);
|
|
1425
|
+
if (change && change.action === 'delete') {
|
|
1426
|
+
objectsToDelete.push(key);
|
|
1427
|
+
}
|
|
1428
|
+
else {
|
|
1429
|
+
const serialized = this._objectsMap.get(key);
|
|
1430
|
+
if (serialized) {
|
|
1431
|
+
const object = this._reviver.revive(serialized);
|
|
1432
|
+
// Separate SelectionGroups to process them after regular objects
|
|
1433
|
+
if (object instanceof KritzelSelectionGroup) {
|
|
1434
|
+
selectionGroupsToUpdate.push(object);
|
|
1435
|
+
}
|
|
1436
|
+
else {
|
|
1437
|
+
objectsToUpdate.push(object);
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
});
|
|
1442
|
+
// Delete objects from local map
|
|
1443
|
+
objectsToDelete.forEach(objectId => {
|
|
1444
|
+
this.map.delete(objectId);
|
|
1445
|
+
});
|
|
1446
|
+
// First, update or insert regular objects
|
|
1447
|
+
objectsToUpdate.forEach(object => {
|
|
1448
|
+
this.map.set(object.id, object);
|
|
1449
|
+
});
|
|
1450
|
+
// Then, update or insert SelectionGroups
|
|
1451
|
+
selectionGroupsToUpdate.forEach(object => {
|
|
1452
|
+
this.map.set(object.id, object);
|
|
1453
|
+
});
|
|
1454
|
+
this._core?.rerender();
|
|
1519
1455
|
}
|
|
1520
|
-
|
|
1521
|
-
if (this.
|
|
1522
|
-
|
|
1456
|
+
transaction(callback) {
|
|
1457
|
+
if (this._ydoc) {
|
|
1458
|
+
this._ydoc.transact(callback, 'local');
|
|
1523
1459
|
}
|
|
1524
|
-
const lastIndex = (this.head - 1 + this.capacity) % this.capacity;
|
|
1525
|
-
return this.buffer[lastIndex];
|
|
1526
|
-
}
|
|
1527
|
-
isEmpty() {
|
|
1528
|
-
return this.size === 0;
|
|
1529
|
-
}
|
|
1530
|
-
clear() {
|
|
1531
|
-
this.buffer.fill(null);
|
|
1532
|
-
this.head = 0;
|
|
1533
|
-
this.tail = 0;
|
|
1534
|
-
this.size = 0;
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1538
|
-
class KritzelHistory {
|
|
1539
|
-
_core;
|
|
1540
|
-
undoStack;
|
|
1541
|
-
redoStack;
|
|
1542
|
-
constructor(core) {
|
|
1543
|
-
this._core = core;
|
|
1544
|
-
this.undoStack = new KritzelCircularBuffer(this._core.store.state.historyBufferSize);
|
|
1545
|
-
this.redoStack = new KritzelCircularBuffer(this._core.store.state.historyBufferSize);
|
|
1546
1460
|
}
|
|
1547
|
-
|
|
1548
|
-
this.
|
|
1549
|
-
this.redoStack.clear();
|
|
1550
|
-
this._core.commandManager.previousViewport = {
|
|
1551
|
-
scale: this._core.store.state.scale,
|
|
1552
|
-
scaleStep: this._core.store.state.scaleStep,
|
|
1553
|
-
translateX: this._core.store.state.translateX,
|
|
1554
|
-
translateY: this._core.store.state.translateY
|
|
1555
|
-
};
|
|
1556
|
-
}
|
|
1557
|
-
undo() {
|
|
1558
|
-
if (this._core.store.state.hasViewportChanged) {
|
|
1559
|
-
const command = new UpdateViewportCommand(this._core, this, this._core.commandManager.previousViewport);
|
|
1560
|
-
command.undo();
|
|
1561
|
-
this._core.store.state.hasViewportChanged = false;
|
|
1562
|
-
this._core.rerender();
|
|
1461
|
+
loadFromYjs() {
|
|
1462
|
+
if (!this._objectsMap || !this._reviver) {
|
|
1563
1463
|
return;
|
|
1564
1464
|
}
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
this.redoStack.add(command);
|
|
1571
|
-
}
|
|
1572
|
-
this._core.store.state.copiedObjects = null;
|
|
1573
|
-
this._core.rerender();
|
|
1574
|
-
}
|
|
1575
|
-
redo() {
|
|
1576
|
-
const command = this.redoStack.pop();
|
|
1577
|
-
if (command) {
|
|
1578
|
-
command.execute();
|
|
1579
|
-
if (this._core.store.state.debugInfo.logCommands)
|
|
1580
|
-
console.info('redo', command);
|
|
1581
|
-
this.undoStack.add(command);
|
|
1582
|
-
}
|
|
1583
|
-
this._core.rerender();
|
|
1584
|
-
}
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
class KritzelObjectMap {
|
|
1588
|
-
map;
|
|
1589
|
-
constructor() {
|
|
1590
|
-
this.map = new Map();
|
|
1465
|
+
this.map.clear();
|
|
1466
|
+
this._objectsMap.forEach((serialized, key) => {
|
|
1467
|
+
const object = this._reviver.revive(serialized);
|
|
1468
|
+
this.map.set(key, object);
|
|
1469
|
+
});
|
|
1591
1470
|
}
|
|
1592
1471
|
reset() {
|
|
1593
1472
|
this.map.clear();
|
|
1473
|
+
this._ydoc.transact(() => {
|
|
1474
|
+
this._objectsMap.clear();
|
|
1475
|
+
}, 'local');
|
|
1594
1476
|
}
|
|
1595
1477
|
insert(object) {
|
|
1596
1478
|
if (!object.id) {
|
|
1597
1479
|
return false;
|
|
1598
1480
|
}
|
|
1599
1481
|
this.map.set(object.id, object);
|
|
1482
|
+
if (this._objectsMap && this.isPersistable(object)) {
|
|
1483
|
+
const serialized = object.serialize();
|
|
1484
|
+
this._ydoc.transact(() => {
|
|
1485
|
+
this._objectsMap.set(object.id, serialized);
|
|
1486
|
+
}, 'local');
|
|
1487
|
+
}
|
|
1600
1488
|
return true;
|
|
1601
1489
|
}
|
|
1602
|
-
update(object) {
|
|
1490
|
+
update(object, options = {}) {
|
|
1603
1491
|
if (!object.id || !this.map.has(object.id)) {
|
|
1604
1492
|
return false;
|
|
1605
1493
|
}
|
|
1606
1494
|
this.map.set(object.id, object);
|
|
1495
|
+
if (this._objectsMap && this.isPersistable(object)) {
|
|
1496
|
+
const serialized = object.serialize();
|
|
1497
|
+
const origin = options.temporary ? 'temporary' : 'local';
|
|
1498
|
+
this._ydoc.transact(() => {
|
|
1499
|
+
this._objectsMap.set(object.id, serialized);
|
|
1500
|
+
}, origin);
|
|
1501
|
+
}
|
|
1607
1502
|
return true;
|
|
1608
1503
|
}
|
|
1609
1504
|
remove(predicate) {
|
|
1610
1505
|
for (const [id, object] of this.map) {
|
|
1611
1506
|
if (predicate(object)) {
|
|
1612
1507
|
this.map.delete(id);
|
|
1508
|
+
if (this._objectsMap && this.isPersistable(object)) {
|
|
1509
|
+
this._ydoc.transact(() => {
|
|
1510
|
+
this._objectsMap.delete(id);
|
|
1511
|
+
}, 'local');
|
|
1512
|
+
}
|
|
1613
1513
|
}
|
|
1614
1514
|
}
|
|
1615
1515
|
}
|
|
@@ -1625,6 +1525,98 @@ class KritzelObjectMap {
|
|
|
1625
1525
|
allObjects() {
|
|
1626
1526
|
return Array.from(this.map.values());
|
|
1627
1527
|
}
|
|
1528
|
+
isPersistable(object) {
|
|
1529
|
+
if (object instanceof KritzelSelectionBox) {
|
|
1530
|
+
return false;
|
|
1531
|
+
}
|
|
1532
|
+
return true;
|
|
1533
|
+
}
|
|
1534
|
+
undo() {
|
|
1535
|
+
if (this._undoManager && this._undoManager.canUndo()) {
|
|
1536
|
+
this._undoManager.undo();
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
redo() {
|
|
1540
|
+
if (this._undoManager && this._undoManager.canRedo()) {
|
|
1541
|
+
this._undoManager.redo();
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
canUndo() {
|
|
1545
|
+
return this._undoManager ? this._undoManager.canUndo() : false;
|
|
1546
|
+
}
|
|
1547
|
+
canRedo() {
|
|
1548
|
+
return this._undoManager ? this._undoManager.canRedo() : false;
|
|
1549
|
+
}
|
|
1550
|
+
clearHistory() {
|
|
1551
|
+
if (this._undoManager) {
|
|
1552
|
+
this._undoManager.clear();
|
|
1553
|
+
this._temporaryItemsCount = 0;
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
/**
|
|
1557
|
+
* Consolidates all temporary items in the undo stack into a single undo item.
|
|
1558
|
+
* Call this when you want to merge multiple temporary changes (e.g., keystrokes) into one.
|
|
1559
|
+
*/
|
|
1560
|
+
consolidateTemporaryItems() {
|
|
1561
|
+
if (!this._undoManager || this._temporaryItemsCount === 0) {
|
|
1562
|
+
return;
|
|
1563
|
+
}
|
|
1564
|
+
// Get current stack length
|
|
1565
|
+
const stackLength = this._undoManager.undoStack.length;
|
|
1566
|
+
if (stackLength === 0) {
|
|
1567
|
+
this._temporaryItemsCount = 0;
|
|
1568
|
+
return;
|
|
1569
|
+
}
|
|
1570
|
+
// Stop tracking temporarily
|
|
1571
|
+
this._undoManager.stopCapturing();
|
|
1572
|
+
// The temporary items should be at the end of the stack
|
|
1573
|
+
// We'll need to undo them all, then redo as a single transaction
|
|
1574
|
+
const itemsToConsolidate = Math.min(this._temporaryItemsCount, stackLength);
|
|
1575
|
+
if (itemsToConsolidate > 1) {
|
|
1576
|
+
// Undo all temporary items
|
|
1577
|
+
for (let i = 0; i < itemsToConsolidate; i++) {
|
|
1578
|
+
if (this._undoManager.canUndo()) {
|
|
1579
|
+
this._undoManager.undo();
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
// Now redo them all as a single 'local' transaction
|
|
1583
|
+
// This will consolidate them into one undo item
|
|
1584
|
+
this._ydoc.transact(() => {
|
|
1585
|
+
for (let i = itemsToConsolidate - 1; i >= 0; i--) {
|
|
1586
|
+
if (this._undoManager.canRedo()) {
|
|
1587
|
+
this._undoManager.redo();
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
}, 'local');
|
|
1591
|
+
}
|
|
1592
|
+
this._temporaryItemsCount = 0;
|
|
1593
|
+
}
|
|
1594
|
+
/**
|
|
1595
|
+
* Removes all temporary items from the undo stack without consolidating them.
|
|
1596
|
+
* Use this to discard temporary changes completely.
|
|
1597
|
+
*/
|
|
1598
|
+
clearTemporaryItems() {
|
|
1599
|
+
if (!this._undoManager || this._temporaryItemsCount === 0) {
|
|
1600
|
+
return;
|
|
1601
|
+
}
|
|
1602
|
+
const stackLength = this._undoManager.undoStack.length;
|
|
1603
|
+
const itemsToRemove = Math.min(this._temporaryItemsCount, stackLength);
|
|
1604
|
+
// Remove items from the end of the stack
|
|
1605
|
+
for (let i = 0; i < itemsToRemove; i++) {
|
|
1606
|
+
if (this._undoManager.undoStack.length > 0) {
|
|
1607
|
+
this._undoManager.undoStack.pop();
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
this._temporaryItemsCount = 0;
|
|
1611
|
+
}
|
|
1612
|
+
destroy() {
|
|
1613
|
+
this._providers.forEach(p => p.destroy());
|
|
1614
|
+
this._providers = [];
|
|
1615
|
+
if (this._ydoc) {
|
|
1616
|
+
this._ydoc.destroy();
|
|
1617
|
+
}
|
|
1618
|
+
this.map.clear();
|
|
1619
|
+
}
|
|
1628
1620
|
}
|
|
1629
1621
|
|
|
1630
1622
|
class KritzelStore {
|
|
@@ -1634,17 +1626,33 @@ class KritzelStore {
|
|
|
1634
1626
|
return this._state;
|
|
1635
1627
|
}
|
|
1636
1628
|
get currentZIndex() {
|
|
1637
|
-
return Math.max(0, ...this._state.objectsMap.filter(o => !(o instanceof KritzelSelectionGroup) && !(o instanceof
|
|
1629
|
+
return Math.max(0, ...this._state.objectsMap.filter(o => !(o instanceof KritzelSelectionGroup) && !(o instanceof KritzelSelectionBox)).map(o => o.zIndex)) + 1;
|
|
1638
1630
|
}
|
|
1639
1631
|
get allObjects() {
|
|
1640
1632
|
return this._state.objectsMap.allObjects();
|
|
1641
1633
|
}
|
|
1642
1634
|
get allNonSelectionObjects() {
|
|
1643
|
-
return this._state.objectsMap.allObjects().filter(o => !(o instanceof KritzelSelectionGroup) && !(o instanceof
|
|
1635
|
+
return this._state.objectsMap.allObjects().filter(o => !(o instanceof KritzelSelectionGroup) && !(o instanceof KritzelSelectionBox));
|
|
1644
1636
|
}
|
|
1645
1637
|
get selectedObjects() {
|
|
1646
1638
|
return this.allObjects.filter(o => !(o instanceof KritzelSelectionGroup)).filter(o => o.isSelected);
|
|
1647
1639
|
}
|
|
1640
|
+
get selectionBox() {
|
|
1641
|
+
const selectionBoxes = this._state.objectsMap.filter(o => o instanceof KritzelSelectionBox);
|
|
1642
|
+
return selectionBoxes.length > 0 ? selectionBoxes[0] : null;
|
|
1643
|
+
}
|
|
1644
|
+
get selectionGroup() {
|
|
1645
|
+
const selectionGroups = this._state.objectsMap.filter(o => o instanceof KritzelSelectionGroup);
|
|
1646
|
+
return selectionGroups.length > 0 ? selectionGroups[0] : null;
|
|
1647
|
+
}
|
|
1648
|
+
get activeText() {
|
|
1649
|
+
const activeTexts = this._state.objectsMap.filter(o => o instanceof KritzelText && o.isEditing);
|
|
1650
|
+
return activeTexts.length > 0 ? activeTexts[0] : null;
|
|
1651
|
+
}
|
|
1652
|
+
get currentPath() {
|
|
1653
|
+
const drawingPaths = this._state.objectsMap.filter(o => o instanceof KritzelPath && o.isCompleted === false);
|
|
1654
|
+
return drawingPaths.length > 0 ? drawingPaths[0] : null;
|
|
1655
|
+
}
|
|
1648
1656
|
get offsetX() {
|
|
1649
1657
|
return this._state.host.getBoundingClientRect().left;
|
|
1650
1658
|
}
|
|
@@ -1678,203 +1686,124 @@ class KritzelStore {
|
|
|
1678
1686
|
}
|
|
1679
1687
|
}
|
|
1680
1688
|
|
|
1681
|
-
class KritzelCommandManager {
|
|
1682
|
-
_core;
|
|
1683
|
-
_history;
|
|
1684
|
-
previousViewport;
|
|
1685
|
-
constructor(core) {
|
|
1686
|
-
this._core = core;
|
|
1687
|
-
this._history = this._core.history;
|
|
1688
|
-
this.previousViewport = {
|
|
1689
|
-
scale: this._core.store.state.scale,
|
|
1690
|
-
scaleStep: this._core.store.state.scaleStep,
|
|
1691
|
-
translateX: this._core.store.state.translateX,
|
|
1692
|
-
translateY: this._core.store.state.translateY,
|
|
1693
|
-
};
|
|
1694
|
-
}
|
|
1695
|
-
executeCommand(command) {
|
|
1696
|
-
if (this._core.store.state.hasViewportChanged) {
|
|
1697
|
-
this.addUpdateViewportCommand();
|
|
1698
|
-
}
|
|
1699
|
-
command.execute();
|
|
1700
|
-
if (this.isSkipped(command) === false) {
|
|
1701
|
-
if (this._core.store.state.debugInfo.logCommands) {
|
|
1702
|
-
console.log('execute', command);
|
|
1703
|
-
}
|
|
1704
|
-
this._history.undoStack.add(command);
|
|
1705
|
-
if (this._history.redoStack.isEmpty() === false) {
|
|
1706
|
-
this._history.redoStack.clear();
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
this._core.rerender();
|
|
1710
|
-
}
|
|
1711
|
-
isSkipped(command) {
|
|
1712
|
-
return command.skipHistory === true;
|
|
1713
|
-
}
|
|
1714
|
-
addUpdateViewportCommand() {
|
|
1715
|
-
const command = new UpdateViewportCommand(this._core, this, this.previousViewport);
|
|
1716
|
-
command.execute();
|
|
1717
|
-
this._history.undoStack.add(command);
|
|
1718
|
-
if (this._history.redoStack.isEmpty() === false) {
|
|
1719
|
-
this._history.redoStack.clear();
|
|
1720
|
-
}
|
|
1721
|
-
this._core.store.state.hasViewportChanged = false;
|
|
1722
|
-
this.previousViewport = {
|
|
1723
|
-
scale: this._core.store.state.scale,
|
|
1724
|
-
scaleStep: this._core.store.state.scaleStep,
|
|
1725
|
-
translateX: this._core.store.state.translateX,
|
|
1726
|
-
translateY: this._core.store.state.translateY,
|
|
1727
|
-
};
|
|
1728
|
-
}
|
|
1729
|
-
}
|
|
1730
|
-
|
|
1731
1689
|
class KritzelCore {
|
|
1732
1690
|
_kritzelEngine;
|
|
1733
1691
|
_store;
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
_database;
|
|
1692
|
+
_syncConfig;
|
|
1693
|
+
_appStateMap;
|
|
1737
1694
|
get engine() {
|
|
1738
1695
|
return this._kritzelEngine;
|
|
1739
1696
|
}
|
|
1740
|
-
get history() {
|
|
1741
|
-
return this._history;
|
|
1742
|
-
}
|
|
1743
|
-
get commandManager() {
|
|
1744
|
-
return this._commandManager;
|
|
1745
|
-
}
|
|
1746
|
-
get database() {
|
|
1747
|
-
return this._database;
|
|
1748
|
-
}
|
|
1749
1697
|
get store() {
|
|
1750
1698
|
return this._store;
|
|
1751
1699
|
}
|
|
1700
|
+
get appStateMap() {
|
|
1701
|
+
return this._appStateMap;
|
|
1702
|
+
}
|
|
1752
1703
|
constructor(kritzelEngine) {
|
|
1753
1704
|
this._kritzelEngine = kritzelEngine;
|
|
1754
|
-
this._store = new KritzelStore(
|
|
1755
|
-
this.
|
|
1756
|
-
this._commandManager = new KritzelCommandManager(this);
|
|
1757
|
-
this._database = new KritzelDatabase('kritzelDB', 1, this._store.state.debugInfo.logDatabase);
|
|
1758
|
-
}
|
|
1759
|
-
async initializeDatabase() {
|
|
1760
|
-
await this._database.open([
|
|
1761
|
-
{
|
|
1762
|
-
name: 'objects',
|
|
1763
|
-
options: { keyPath: ['workspaceId', 'id'] },
|
|
1764
|
-
},
|
|
1765
|
-
{ name: 'workspaces', options: { keyPath: 'id' } },
|
|
1766
|
-
]);
|
|
1767
|
-
this.rerender();
|
|
1705
|
+
this._store = new KritzelStore(DEFAULT_ENGINE_CONFIG);
|
|
1706
|
+
this._appStateMap = new KritzelAppStateMap();
|
|
1768
1707
|
}
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
const mostRecentWorkspace = [...workspaces].sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())[0];
|
|
1772
|
-
const fallbackWorkspace = new KritzelWorkspace(ObjectHelper.generateUUID(), 'New Workspace');
|
|
1773
|
-
const candidateWorkspace = workspace ?? mostRecentWorkspace ?? fallbackWorkspace;
|
|
1774
|
-
const existingWorkspace = await this.getWorkspace(candidateWorkspace.id);
|
|
1775
|
-
if (existingWorkspace) {
|
|
1776
|
-
this._store.state.activeWorkspace = existingWorkspace;
|
|
1777
|
-
await this.updateWorkspace(this._store.state.activeWorkspace);
|
|
1778
|
-
}
|
|
1779
|
-
else {
|
|
1780
|
-
this._store.state.activeWorkspace = candidateWorkspace;
|
|
1781
|
-
await this.createWorkspace(this._store.state.activeWorkspace);
|
|
1782
|
-
}
|
|
1783
|
-
this._store.state.workspaces = await this.getWorkspaces();
|
|
1784
|
-
const viewport = this._store.state.activeWorkspace.viewport ?? { translateX: 0, translateY: 0, scale: 1 };
|
|
1785
|
-
this._store.state.translateX = viewport.translateX ?? 0;
|
|
1786
|
-
this._store.state.translateY = viewport.translateY ?? 0;
|
|
1787
|
-
this._store.state.scale = viewport.scale ?? 1;
|
|
1788
|
-
await this.initializeWorkspaceObjects(this._store.state.activeWorkspace.id);
|
|
1789
|
-
}
|
|
1790
|
-
async initializeWorkspaceObjects(workspaceId) {
|
|
1791
|
-
this._store.state.objectsMap.reset();
|
|
1792
|
-
this._history.reset();
|
|
1793
|
-
const objectsFromDb = await this._database.getAllByRange('objects', IDBKeyRange.bound([workspaceId], [workspaceId, '\uffff']));
|
|
1794
|
-
const reviver = new KritzelReviver(this);
|
|
1795
|
-
objectsFromDb.forEach(element => {
|
|
1796
|
-
const revivedObject = reviver.revive(element);
|
|
1797
|
-
this._store.state.objectsMap.insert(revivedObject);
|
|
1798
|
-
});
|
|
1799
|
-
this.rerender();
|
|
1708
|
+
setSyncConfig(config) {
|
|
1709
|
+
this._syncConfig = config;
|
|
1800
1710
|
}
|
|
1801
|
-
async
|
|
1802
|
-
|
|
1803
|
-
if (!activeWorkspace) {
|
|
1804
|
-
throw new Error('Workspace not initialized');
|
|
1805
|
-
}
|
|
1806
|
-
activeWorkspace.viewport = { translateX, translateY, scale };
|
|
1807
|
-
activeWorkspace.updatedAt = new Date();
|
|
1808
|
-
await this._database.update('workspaces', activeWorkspace);
|
|
1711
|
+
async initializeYjs() {
|
|
1712
|
+
await this._appStateMap.initialize(this, this._syncConfig);
|
|
1809
1713
|
}
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
if (!activeWorkspace) {
|
|
1816
|
-
throw new Error('Workspace not initialized');
|
|
1817
|
-
}
|
|
1818
|
-
activeWorkspace.updatedAt = new Date();
|
|
1819
|
-
await this._database.batch([db => db.add('objects', object), db => db.update('workspaces', activeWorkspace)]).catch(err => {
|
|
1820
|
-
console.error('Error adding object to database:', err);
|
|
1821
|
-
});
|
|
1714
|
+
/**
|
|
1715
|
+
* Load all workspaces from app state map
|
|
1716
|
+
*/
|
|
1717
|
+
loadWorkspacesFromAppState() {
|
|
1718
|
+
return this._appStateMap.allWorkspaces();
|
|
1822
1719
|
}
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1720
|
+
/**
|
|
1721
|
+
* Save a workspace to app state map
|
|
1722
|
+
*/
|
|
1723
|
+
saveWorkspaceToAppState(workspace) {
|
|
1724
|
+
if (this._appStateMap.has(workspace.id)) {
|
|
1725
|
+
this._appStateMap.update(workspace);
|
|
1826
1726
|
}
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
throw new Error('Workspace not initialized');
|
|
1727
|
+
else {
|
|
1728
|
+
this._appStateMap.insert(workspace);
|
|
1830
1729
|
}
|
|
1831
|
-
activeWorkspace.updatedAt = new Date();
|
|
1832
|
-
await this._database.batch([db => db.update('objects', object), db => db.update('workspaces', activeWorkspace)]).catch(err => {
|
|
1833
|
-
console.error('Error updating object in database:', err);
|
|
1834
|
-
});
|
|
1835
1730
|
}
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1731
|
+
/**
|
|
1732
|
+
* Delete a workspace from app state map
|
|
1733
|
+
*/
|
|
1734
|
+
deleteWorkspaceFromAppState(workspaceId) {
|
|
1735
|
+
this._appStateMap.remove(w => w.id === workspaceId);
|
|
1736
|
+
}
|
|
1737
|
+
async initializeWorkspace(workspace) {
|
|
1738
|
+
// Load all workspaces from app state map
|
|
1739
|
+
const workspaces = this.loadWorkspacesFromAppState();
|
|
1740
|
+
// Find most recently updated workspace or use provided/fallback
|
|
1741
|
+
const mostRecentWorkspace = workspaces.length > 0 ? [...workspaces].sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())[0] : null;
|
|
1742
|
+
let activeWorkspace;
|
|
1743
|
+
if (workspace) {
|
|
1744
|
+
// Use provided workspace
|
|
1745
|
+
activeWorkspace = workspace;
|
|
1746
|
+
const existing = workspaces.find(w => w.id === workspace.id);
|
|
1747
|
+
if (!existing) {
|
|
1748
|
+
// New workspace, save it
|
|
1749
|
+
activeWorkspace._core = this;
|
|
1750
|
+
this.saveWorkspaceToAppState(activeWorkspace);
|
|
1751
|
+
}
|
|
1839
1752
|
}
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1753
|
+
else if (mostRecentWorkspace) {
|
|
1754
|
+
// Use most recent workspace
|
|
1755
|
+
activeWorkspace = mostRecentWorkspace;
|
|
1843
1756
|
}
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1757
|
+
else {
|
|
1758
|
+
// Create fallback workspace
|
|
1759
|
+
activeWorkspace = new KritzelWorkspace(ObjectHelper.generateUUID(), 'New Workspace');
|
|
1760
|
+
activeWorkspace._core = this;
|
|
1761
|
+
this.saveWorkspaceToAppState(activeWorkspace);
|
|
1762
|
+
}
|
|
1763
|
+
// Destroy old ObjectMap if switching workspaces
|
|
1764
|
+
if (this._store.state.objectsMap && this._store.state.objectsMap.isReady) {
|
|
1765
|
+
this._store.state.objectsMap.destroy();
|
|
1766
|
+
}
|
|
1767
|
+
// Set active workspace
|
|
1768
|
+
this._store.state.activeWorkspace = activeWorkspace;
|
|
1769
|
+
this._store.state.workspaces = this.loadWorkspacesFromAppState();
|
|
1770
|
+
// Set viewport from workspace
|
|
1771
|
+
const viewport = activeWorkspace.viewport ?? { translateX: 0, translateY: 0, scale: 1 };
|
|
1772
|
+
this._store.state.translateX = viewport.translateX ?? 0;
|
|
1773
|
+
this._store.state.translateY = viewport.translateY ?? 0;
|
|
1774
|
+
this._store.state.scale = viewport.scale ?? 1;
|
|
1775
|
+
// Create new ObjectMap with its own Y.Doc for this workspace
|
|
1776
|
+
const objectsMap = new KritzelObjectMap();
|
|
1777
|
+
await objectsMap.initialize(this, activeWorkspace.id, this._syncConfig);
|
|
1778
|
+
this._store.state.objectsMap = objectsMap;
|
|
1779
|
+
this.rerender();
|
|
1848
1780
|
}
|
|
1849
|
-
|
|
1850
|
-
if (
|
|
1851
|
-
|
|
1781
|
+
rerender() {
|
|
1782
|
+
if (this._kritzelEngine) {
|
|
1783
|
+
this._kritzelEngine.forceUpdate++;
|
|
1852
1784
|
}
|
|
1853
|
-
const reviver = new KritzelReviver(this);
|
|
1854
|
-
return this._database.get('workspaces', id).then(rawWorkspace => (rawWorkspace ? reviver.revive(rawWorkspace) : null));
|
|
1855
1785
|
}
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1786
|
+
findObjectById(id) {
|
|
1787
|
+
for (const object of this._store.allObjects) {
|
|
1788
|
+
if (object.id === id) {
|
|
1789
|
+
return object;
|
|
1790
|
+
}
|
|
1859
1791
|
}
|
|
1860
|
-
|
|
1861
|
-
return this._database.getAll('workspaces').then(rawWorkspaces => rawWorkspaces.map(ws => reviver.revive(ws)));
|
|
1792
|
+
return null;
|
|
1862
1793
|
}
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1794
|
+
getWorkspaces() {
|
|
1795
|
+
return this.loadWorkspacesFromAppState();
|
|
1796
|
+
}
|
|
1797
|
+
createWorkspace(workspace) {
|
|
1798
|
+
workspace._core = this;
|
|
1867
1799
|
workspace.createdAt = new Date();
|
|
1868
1800
|
workspace.updatedAt = new Date();
|
|
1869
|
-
|
|
1870
|
-
this._store.state.workspaces.
|
|
1801
|
+
this.saveWorkspaceToAppState(workspace);
|
|
1802
|
+
this._store.state.workspaces = this.loadWorkspacesFromAppState();
|
|
1871
1803
|
}
|
|
1872
|
-
|
|
1873
|
-
if (!this._database) {
|
|
1874
|
-
throw new Error('Database not initialized');
|
|
1875
|
-
}
|
|
1804
|
+
updateWorkspace(workspace) {
|
|
1876
1805
|
workspace.updatedAt = new Date();
|
|
1877
|
-
|
|
1806
|
+
this.saveWorkspaceToAppState(workspace);
|
|
1878
1807
|
const workspaces = this._store.state.workspaces;
|
|
1879
1808
|
const index = workspaces.findIndex(w => w.id === workspace.id);
|
|
1880
1809
|
if (index !== -1) {
|
|
@@ -1882,126 +1811,216 @@ class KritzelCore {
|
|
|
1882
1811
|
this._store.state.workspaces = workspaces;
|
|
1883
1812
|
}
|
|
1884
1813
|
}
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1814
|
+
deleteWorkspace(workspace) {
|
|
1815
|
+
// If deleting the active workspace, need to handle ObjectMap cleanup
|
|
1816
|
+
if (this._store.state.activeWorkspace?.id === workspace.id) {
|
|
1817
|
+
this._store.state.objectsMap?.destroy();
|
|
1888
1818
|
}
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1819
|
+
this.deleteWorkspaceFromAppState(workspace.id);
|
|
1820
|
+
this._store.state.workspaces = this.loadWorkspacesFromAppState();
|
|
1821
|
+
// Also delete the workspace's IndexedDB database
|
|
1822
|
+
const dbName = `kritzel-workspace-${workspace.id}`;
|
|
1823
|
+
window.indexedDB.deleteDatabase(dbName);
|
|
1893
1824
|
}
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1825
|
+
updateWorkspaceViewport(translateX, translateY, scale) {
|
|
1826
|
+
const activeWorkspace = this._store.state.activeWorkspace;
|
|
1827
|
+
if (!activeWorkspace) {
|
|
1828
|
+
return;
|
|
1897
1829
|
}
|
|
1830
|
+
activeWorkspace.viewport = { translateX, translateY, scale };
|
|
1831
|
+
activeWorkspace.updatedAt = new Date();
|
|
1832
|
+
this.saveWorkspaceToAppState(activeWorkspace);
|
|
1898
1833
|
}
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1834
|
+
addObject(object) {
|
|
1835
|
+
this._store.state.objectsMap.insert(object);
|
|
1836
|
+
}
|
|
1837
|
+
removeObject(object) {
|
|
1838
|
+
object.isMounted = false;
|
|
1839
|
+
this._store.state.objectsMap.remove(o => o.id === object.id);
|
|
1840
|
+
}
|
|
1841
|
+
updateObject(object, updatedProperties) {
|
|
1842
|
+
for (const key in updatedProperties) {
|
|
1843
|
+
if (updatedProperties.hasOwnProperty(key)) {
|
|
1844
|
+
object[key] = updatedProperties[key];
|
|
1903
1845
|
}
|
|
1904
1846
|
}
|
|
1905
|
-
|
|
1847
|
+
this._store.state.objectsMap.update(object);
|
|
1906
1848
|
}
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1849
|
+
addSelectionGroup(selectionGroup) {
|
|
1850
|
+
this.removeSelectionGroup();
|
|
1851
|
+
this.removeSelectionBox();
|
|
1852
|
+
this._store.state.objectsMap.insert(selectionGroup);
|
|
1853
|
+
}
|
|
1854
|
+
removeSelectionGroup() {
|
|
1855
|
+
const selectionGroup = this._store.selectionGroup;
|
|
1856
|
+
if (selectionGroup) {
|
|
1857
|
+
this._store.state.objectsMap.remove(object => object.id === selectionGroup.id);
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
removeSelectionBox() {
|
|
1861
|
+
const selectionBox = this._store.selectionBox;
|
|
1862
|
+
if (selectionBox) {
|
|
1863
|
+
this._store.state.objectsMap.remove(object => object.id === selectionBox.id);
|
|
1910
1864
|
}
|
|
1911
1865
|
}
|
|
1866
|
+
deselectAllObjects() {
|
|
1867
|
+
this.removeSelectionGroup();
|
|
1868
|
+
this.rerender();
|
|
1869
|
+
}
|
|
1912
1870
|
delete() {
|
|
1913
|
-
|
|
1871
|
+
const selectionGroup = this._store.selectionGroup;
|
|
1872
|
+
if (!selectionGroup) {
|
|
1914
1873
|
return;
|
|
1915
1874
|
}
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1875
|
+
selectionGroup.objects.forEach(obj => this.removeObject(obj));
|
|
1876
|
+
this.removeSelectionGroup();
|
|
1877
|
+
this.rerender();
|
|
1878
|
+
}
|
|
1879
|
+
undo() {
|
|
1880
|
+
this._store.state.objectsMap?.undo();
|
|
1920
1881
|
}
|
|
1921
|
-
|
|
1882
|
+
redo() {
|
|
1883
|
+
this._store.state.objectsMap?.redo();
|
|
1884
|
+
}
|
|
1885
|
+
deleteObject(id) {
|
|
1922
1886
|
const object = this.findObjectById(id);
|
|
1923
1887
|
if (object) {
|
|
1924
|
-
|
|
1925
|
-
this.
|
|
1888
|
+
this.removeObject(object);
|
|
1889
|
+
this.rerender();
|
|
1926
1890
|
}
|
|
1927
1891
|
}
|
|
1928
1892
|
copy() {
|
|
1929
|
-
|
|
1893
|
+
const selectionGroup = this._store.selectionGroup;
|
|
1894
|
+
if (selectionGroup) {
|
|
1895
|
+
// Copy each object and store them in an array
|
|
1896
|
+
this._store.state.copiedObjects = selectionGroup.objects.sort((a, b) => a.zIndex - b.zIndex).map(obj => obj.copy());
|
|
1897
|
+
}
|
|
1930
1898
|
}
|
|
1931
1899
|
paste(x, y) {
|
|
1932
1900
|
const copiedObjects = this._store.state.copiedObjects;
|
|
1933
|
-
copiedObjects.
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
const adjustedY = y !== undefined ? y : this._store.state.copiedObjects.translateY + 25 / this._store.state.scale;
|
|
1937
|
-
this._store.state.copiedObjects.updatePosition(adjustedX, adjustedY);
|
|
1938
|
-
this._store.state.copiedObjects.updateZIndices(this._store.currentZIndex);
|
|
1901
|
+
if (!copiedObjects || copiedObjects.length === 0) {
|
|
1902
|
+
return;
|
|
1903
|
+
}
|
|
1939
1904
|
const activeWorkspace = this._store.state.activeWorkspace;
|
|
1940
|
-
if
|
|
1941
|
-
|
|
1905
|
+
// Check if we're pasting from a different workspace
|
|
1906
|
+
const isDifferentWorkspace = copiedObjects.some(obj => obj.workspaceId !== activeWorkspace.id);
|
|
1907
|
+
// Calculate the bounding box of all copied objects
|
|
1908
|
+
const minX = Math.min(...copiedObjects.map(obj => obj.translateX));
|
|
1909
|
+
const minY = Math.min(...copiedObjects.map(obj => obj.translateY));
|
|
1910
|
+
// Determine the paste position
|
|
1911
|
+
let pasteX;
|
|
1912
|
+
let pasteY;
|
|
1913
|
+
if (x !== undefined && y !== undefined) {
|
|
1914
|
+
// Explicit position provided (e.g., right-click paste)
|
|
1915
|
+
pasteX = x;
|
|
1916
|
+
pasteY = y;
|
|
1917
|
+
}
|
|
1918
|
+
else if (isDifferentWorkspace) {
|
|
1919
|
+
// Pasting to different workspace without explicit position
|
|
1920
|
+
// Keep original position; will be centered by centerInViewport() later
|
|
1921
|
+
pasteX = minX;
|
|
1922
|
+
pasteY = minY;
|
|
1923
|
+
}
|
|
1924
|
+
else {
|
|
1925
|
+
// Same workspace paste: offset by 25 pixels from original position
|
|
1926
|
+
pasteX = minX + 25 / this._store.state.scale;
|
|
1927
|
+
pasteY = minY + 25 / this._store.state.scale;
|
|
1928
|
+
}
|
|
1929
|
+
// Calculate the offset to apply to all objects
|
|
1930
|
+
const offsetX = pasteX - minX;
|
|
1931
|
+
const offsetY = pasteY - minY;
|
|
1932
|
+
this.removeSelectionGroup();
|
|
1933
|
+
this.removeSelectionBox();
|
|
1934
|
+
// Create a new selection group for the pasted objects
|
|
1935
|
+
const selectionGroup = KritzelSelectionGroup.create(this);
|
|
1936
|
+
// First add all copied objects to the objectsMap with updated positions
|
|
1937
|
+
copiedObjects.forEach((obj, i) => {
|
|
1938
|
+
// Update workspace if pasting to a different workspace
|
|
1939
|
+
if (obj.workspaceId !== activeWorkspace.id) {
|
|
1940
|
+
obj.workspaceId = activeWorkspace.id;
|
|
1941
|
+
}
|
|
1942
|
+
// Update position
|
|
1943
|
+
obj.updatePosition(obj.translateX + offsetX, obj.translateY + offsetY);
|
|
1944
|
+
// Update z-index
|
|
1945
|
+
obj.zIndex = this._store.currentZIndex + i;
|
|
1946
|
+
// Add to objectsMap
|
|
1947
|
+
this.addObject(obj);
|
|
1948
|
+
// Add to selection group
|
|
1949
|
+
selectionGroup.addOrRemove(obj);
|
|
1950
|
+
});
|
|
1951
|
+
// Mark selection group as selected
|
|
1952
|
+
selectionGroup.isSelected = true;
|
|
1953
|
+
// Set rotation for single object
|
|
1954
|
+
if (copiedObjects.length === 1) {
|
|
1955
|
+
selectionGroup.rotation = copiedObjects[0].rotation;
|
|
1956
|
+
}
|
|
1957
|
+
// Add the selection group
|
|
1958
|
+
this.addSelectionGroup(selectionGroup);
|
|
1959
|
+
// Handle cross-workspace paste: center objects in viewport
|
|
1960
|
+
if (isDifferentWorkspace) {
|
|
1942
1961
|
if (x !== undefined && y !== undefined) {
|
|
1943
|
-
|
|
1962
|
+
// Position was explicitly provided, use it
|
|
1963
|
+
selectionGroup.updatePosition(x, y);
|
|
1944
1964
|
}
|
|
1945
1965
|
else {
|
|
1946
|
-
|
|
1966
|
+
// Center the selection group in the viewport
|
|
1967
|
+
selectionGroup.centerInViewport();
|
|
1947
1968
|
}
|
|
1948
|
-
|
|
1969
|
+
// Fit the viewport to show the pasted objects
|
|
1970
|
+
this.engine.viewport.centerFitInViewport(selectionGroup);
|
|
1949
1971
|
}
|
|
1950
|
-
const commands = [];
|
|
1951
|
-
let previousSelectionGroup = null;
|
|
1952
|
-
if (this._store.state.selectionGroup !== null) {
|
|
1953
|
-
previousSelectionGroup = this._store.state.selectionGroup;
|
|
1954
|
-
commands.push(new RemoveSelectionGroupCommand(this, this._store.state.selectionGroup));
|
|
1955
|
-
}
|
|
1956
|
-
const addCopiedObjectsCommands = this._store.state.copiedObjects.objects.map(obj => new AddObjectCommand(this, this, obj));
|
|
1957
|
-
const addCopiedObjectsAsSelectionGroupCommand = new AddSelectionGroupCommand(this, this, this._store.state.copiedObjects, previousSelectionGroup);
|
|
1958
|
-
commands.push(...addCopiedObjectsCommands, addCopiedObjectsAsSelectionGroupCommand);
|
|
1959
|
-
this.commandManager.executeCommand(new BatchCommand(this, this, commands));
|
|
1960
1972
|
this._store.state.isSelecting = false;
|
|
1961
|
-
|
|
1973
|
+
// Update copiedObjects to the newly created objects for potential future pastes
|
|
1974
|
+
const newSelectionGroup = this._store.selectionGroup;
|
|
1975
|
+
if (newSelectionGroup) {
|
|
1976
|
+
this._store.state.copiedObjects = newSelectionGroup.objects.sort((a, b) => a.zIndex - b.zIndex).map(obj => obj.copy());
|
|
1977
|
+
}
|
|
1962
1978
|
this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
1979
|
+
this.rerender();
|
|
1963
1980
|
}
|
|
1964
1981
|
bringForward(object) {
|
|
1965
|
-
const
|
|
1982
|
+
const selectionGroup = this._store.selectionGroup;
|
|
1983
|
+
const objects = object ? [object] : selectionGroup?.objects || [];
|
|
1966
1984
|
const allNonSelectionObjectsWithoutCurrent = this._store.allNonSelectionObjects.filter(o => objects.findIndex(obj => obj.id === o.id) === -1);
|
|
1967
1985
|
const max = allNonSelectionObjectsWithoutCurrent.length > 0 ? Math.max(...allNonSelectionObjectsWithoutCurrent.map(obj => obj.zIndex)) + 1 : 0;
|
|
1968
|
-
|
|
1969
|
-
if (obj.zIndex
|
|
1970
|
-
|
|
1986
|
+
objects.forEach(obj => {
|
|
1987
|
+
if (obj.zIndex !== max) {
|
|
1988
|
+
this.updateObject(obj, { zIndex: obj.zIndex + 1 });
|
|
1971
1989
|
}
|
|
1972
|
-
return new UpdateObjectCommand(this, this, obj, { zIndex: obj.zIndex + 1 });
|
|
1973
1990
|
});
|
|
1974
|
-
this.
|
|
1991
|
+
this.rerender();
|
|
1975
1992
|
}
|
|
1976
1993
|
sendBackward(object) {
|
|
1977
|
-
const
|
|
1994
|
+
const selectionGroup = this._store.selectionGroup;
|
|
1995
|
+
const objects = object ? [object] : selectionGroup?.objects || [];
|
|
1978
1996
|
const allNonSelectionObjectsWithoutCurrent = this._store.allNonSelectionObjects.filter(o => objects.findIndex(obj => obj.id === o.id) === -1);
|
|
1979
1997
|
const min = allNonSelectionObjectsWithoutCurrent.length > 0 ? Math.min(...allNonSelectionObjectsWithoutCurrent.map(obj => obj.zIndex)) - 1 : 0;
|
|
1980
|
-
|
|
1981
|
-
if (obj.zIndex
|
|
1982
|
-
|
|
1998
|
+
objects.forEach(obj => {
|
|
1999
|
+
if (obj.zIndex !== min) {
|
|
2000
|
+
this.updateObject(obj, { zIndex: obj.zIndex - 1 });
|
|
1983
2001
|
}
|
|
1984
|
-
return new UpdateObjectCommand(this, this, obj, { zIndex: obj.zIndex - 1 });
|
|
1985
2002
|
});
|
|
1986
|
-
this.
|
|
2003
|
+
this.rerender();
|
|
1987
2004
|
}
|
|
1988
2005
|
bringToFront(object) {
|
|
1989
|
-
const
|
|
2006
|
+
const selectionGroup = this._store.selectionGroup;
|
|
2007
|
+
const objects = object ? [object] : selectionGroup?.objects || [];
|
|
1990
2008
|
const allNonSelectionObjectsWithoutCurrent = this._store.allNonSelectionObjects.filter(o => objects.findIndex(obj => obj.id === o.id) === -1);
|
|
1991
2009
|
const max = Math.max(...allNonSelectionObjectsWithoutCurrent.map(obj => obj.zIndex)) + 1;
|
|
1992
|
-
|
|
1993
|
-
|
|
2010
|
+
objects.forEach(obj => {
|
|
2011
|
+
this.updateObject(obj, { zIndex: max });
|
|
1994
2012
|
});
|
|
1995
|
-
this.
|
|
2013
|
+
this.rerender();
|
|
1996
2014
|
}
|
|
1997
2015
|
sendToBack(object) {
|
|
1998
|
-
const
|
|
2016
|
+
const selectionGroup = this._store.selectionGroup;
|
|
2017
|
+
const objects = object ? [object] : selectionGroup?.objects || [];
|
|
1999
2018
|
const allNonSelectionObjectsWithoutCurrent = this._store.allNonSelectionObjects.filter(o => objects.findIndex(obj => obj.id === o.id) === -1);
|
|
2000
2019
|
const min = Math.min(...allNonSelectionObjectsWithoutCurrent.map(obj => obj.zIndex)) - 1;
|
|
2001
|
-
|
|
2002
|
-
|
|
2020
|
+
objects.forEach(obj => {
|
|
2021
|
+
this.updateObject(obj, { zIndex: min });
|
|
2003
2022
|
});
|
|
2004
|
-
this.
|
|
2023
|
+
this.rerender();
|
|
2005
2024
|
}
|
|
2006
2025
|
selectObjects(objects) {
|
|
2007
2026
|
if (objects.length === 0) {
|
|
@@ -2013,16 +2032,16 @@ class KritzelCore {
|
|
|
2013
2032
|
selectionGroup.addOrRemove(obj);
|
|
2014
2033
|
});
|
|
2015
2034
|
selectionGroup.isSelected = true;
|
|
2016
|
-
this._store.state.selectionBox = selectionGroup;
|
|
2017
2035
|
if (objects.length === 1) {
|
|
2018
2036
|
selectionGroup.rotation = selectionGroup.objects[0].rotation;
|
|
2019
2037
|
}
|
|
2020
|
-
this.
|
|
2038
|
+
this.addSelectionGroup(selectionGroup);
|
|
2039
|
+
this.rerender();
|
|
2021
2040
|
}
|
|
2022
2041
|
selectAllObjectsInViewport() {
|
|
2023
2042
|
const objectsInViewport = this._store.state.objectsMap
|
|
2024
2043
|
.filter(o => o.isInViewport())
|
|
2025
|
-
.filter(o => !(o instanceof KritzelSelectionGroup) && !(o instanceof
|
|
2044
|
+
.filter(o => !(o instanceof KritzelSelectionGroup) && !(o instanceof KritzelSelectionBox) && !(o instanceof KritzelContextMenu));
|
|
2026
2045
|
if (objectsInViewport.length > 0) {
|
|
2027
2046
|
const selectionGroup = KritzelSelectionGroup.create(this);
|
|
2028
2047
|
objectsInViewport.forEach(obj => {
|
|
@@ -2034,30 +2053,29 @@ class KritzelCore {
|
|
|
2034
2053
|
if (objectsInViewport.length === 1) {
|
|
2035
2054
|
selectionGroup.rotation = selectionGroup.objects[0].rotation;
|
|
2036
2055
|
}
|
|
2037
|
-
this.
|
|
2056
|
+
this.addSelectionGroup(selectionGroup);
|
|
2038
2057
|
this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
2058
|
+
this.rerender();
|
|
2039
2059
|
}
|
|
2040
2060
|
}
|
|
2041
2061
|
clearSelection() {
|
|
2042
|
-
|
|
2043
|
-
this.
|
|
2044
|
-
this._store.state.selectionGroup = null;
|
|
2045
|
-
this._store.state.selectionBox = null;
|
|
2062
|
+
this.removeSelectionGroup();
|
|
2063
|
+
this._store.state.objectsMap.remove(o => o instanceof KritzelSelectionBox || o instanceof KritzelSelectionGroup);
|
|
2046
2064
|
this._store.state.isSelecting = false;
|
|
2047
2065
|
this._store.state.isResizeHandleSelected = false;
|
|
2048
2066
|
this._store.state.isRotationHandleSelected = false;
|
|
2049
2067
|
this.rerender();
|
|
2050
2068
|
}
|
|
2051
2069
|
resetActiveText() {
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2070
|
+
const activeText = this._store.activeText;
|
|
2071
|
+
if (activeText) {
|
|
2072
|
+
if (activeText.isEmpty) {
|
|
2073
|
+
this.deleteObject(activeText.id);
|
|
2055
2074
|
}
|
|
2056
2075
|
else {
|
|
2057
|
-
|
|
2076
|
+
activeText.save();
|
|
2058
2077
|
}
|
|
2059
2078
|
}
|
|
2060
|
-
this._store.state.activeText = null;
|
|
2061
2079
|
}
|
|
2062
2080
|
getObjectFromPointerEvent(event, selector = '.object') {
|
|
2063
2081
|
const shadowRoot = this._store.state.host?.shadowRoot;
|
|
@@ -2122,8 +2140,11 @@ const kritzelEngineCss = ":host{display:block;position:relative;height:100%;widt
|
|
|
2122
2140
|
const KritzelEngine = class {
|
|
2123
2141
|
get host() { return getElement(this); }
|
|
2124
2142
|
workspace;
|
|
2143
|
+
syncConfig;
|
|
2125
2144
|
onWorkspaceChange(newWorkspace) {
|
|
2126
|
-
|
|
2145
|
+
const currentWorkspaceId = this.core.store.state.activeWorkspace?.id;
|
|
2146
|
+
const newWorkspaceId = newWorkspace?.id;
|
|
2147
|
+
if (currentWorkspaceId !== newWorkspaceId) {
|
|
2127
2148
|
this.core.beforeWorkspaceChange();
|
|
2128
2149
|
this.core.initializeWorkspace(newWorkspace);
|
|
2129
2150
|
}
|
|
@@ -2286,15 +2307,15 @@ const KritzelEngine = class {
|
|
|
2286
2307
|
this.core.sendToBack(object);
|
|
2287
2308
|
}
|
|
2288
2309
|
async undo() {
|
|
2289
|
-
this.core.
|
|
2310
|
+
this.core.undo();
|
|
2290
2311
|
}
|
|
2291
2312
|
async redo() {
|
|
2292
|
-
this.core.
|
|
2313
|
+
this.core.redo();
|
|
2293
2314
|
}
|
|
2294
2315
|
async hideContextMenu() {
|
|
2295
2316
|
this.core.store.state.pointers.clear();
|
|
2296
2317
|
this.core.store.state.isContextMenuVisible = false;
|
|
2297
|
-
this.core.store.state.
|
|
2318
|
+
this.core.store.state.objectsMap.remove(o => o instanceof KritzelSelectionBox);
|
|
2298
2319
|
this.core.store.state.isSelecting = false;
|
|
2299
2320
|
this.core.store.state.isEnabled = true;
|
|
2300
2321
|
this.core.rerender();
|
|
@@ -2309,24 +2330,25 @@ const KritzelEngine = class {
|
|
|
2309
2330
|
object._core = this.core;
|
|
2310
2331
|
object.scale = object.scale ? object.scale : this.core.store.state.scale;
|
|
2311
2332
|
object.zIndex = this.core.store.currentZIndex;
|
|
2312
|
-
|
|
2313
|
-
this.core.
|
|
2333
|
+
this.core.addObject(object);
|
|
2334
|
+
this.core.rerender();
|
|
2314
2335
|
return object;
|
|
2315
2336
|
}
|
|
2316
2337
|
async updateObject(object, updatedProperties) {
|
|
2317
2338
|
this.core.deselectAllObjects();
|
|
2318
|
-
|
|
2319
|
-
this.core.
|
|
2339
|
+
this.core.updateObject(object, updatedProperties);
|
|
2340
|
+
this.core.rerender();
|
|
2320
2341
|
return object;
|
|
2321
2342
|
}
|
|
2322
2343
|
async removeObject(object) {
|
|
2323
2344
|
this.core.deselectAllObjects();
|
|
2324
|
-
|
|
2325
|
-
this.core.
|
|
2345
|
+
this.core.removeObject(object);
|
|
2346
|
+
this.core.rerender();
|
|
2326
2347
|
return object;
|
|
2327
2348
|
}
|
|
2328
2349
|
async getSelectedObjects() {
|
|
2329
|
-
|
|
2350
|
+
const selectionGroup = this.core.store.selectionGroup;
|
|
2351
|
+
return selectionGroup ? selectionGroup.objects : [];
|
|
2330
2352
|
}
|
|
2331
2353
|
async selectObjects(objects) {
|
|
2332
2354
|
this.core.store.state.activeTool?.onDeactivate();
|
|
@@ -2345,15 +2367,14 @@ const KritzelEngine = class {
|
|
|
2345
2367
|
}
|
|
2346
2368
|
async centerObjectInViewport(object) {
|
|
2347
2369
|
object.centerInViewport();
|
|
2348
|
-
|
|
2349
|
-
this.core.
|
|
2370
|
+
this.core.updateObject(object, object);
|
|
2371
|
+
this.core.rerender();
|
|
2350
2372
|
return object;
|
|
2351
2373
|
}
|
|
2352
2374
|
async getCopiedObjects() {
|
|
2353
|
-
return this.core.store.state.copiedObjects
|
|
2375
|
+
return this.core.store.state.copiedObjects || [];
|
|
2354
2376
|
}
|
|
2355
2377
|
async createWorkspace(workspace) {
|
|
2356
|
-
workspace._core = this.core;
|
|
2357
2378
|
await this.core.createWorkspace(workspace);
|
|
2358
2379
|
this.workspacesChange.emit(this.core.store.state.workspaces);
|
|
2359
2380
|
return workspace;
|
|
@@ -2367,7 +2388,7 @@ const KritzelEngine = class {
|
|
|
2367
2388
|
this.workspacesChange.emit(this.core.store.state.workspaces);
|
|
2368
2389
|
}
|
|
2369
2390
|
async getWorkspaces() {
|
|
2370
|
-
return this.core.getWorkspaces();
|
|
2391
|
+
return await this.core.getWorkspaces();
|
|
2371
2392
|
}
|
|
2372
2393
|
async getActiveWorkspace() {
|
|
2373
2394
|
return this.core.store.state.activeWorkspace;
|
|
@@ -2381,7 +2402,7 @@ const KritzelEngine = class {
|
|
|
2381
2402
|
return this.core.store.state.activeTool instanceof KritzelSelectionTool && this.core.store.state.isSelecting;
|
|
2382
2403
|
}
|
|
2383
2404
|
get isSelectionActive() {
|
|
2384
|
-
return this.core.store.state.activeTool instanceof KritzelSelectionTool && this.core.store.
|
|
2405
|
+
return this.core.store.state.activeTool instanceof KritzelSelectionTool && this.core.store.selectionGroup !== null;
|
|
2385
2406
|
}
|
|
2386
2407
|
constructor(hostRef) {
|
|
2387
2408
|
registerInstance(this, hostRef);
|
|
@@ -2399,8 +2420,18 @@ const KritzelEngine = class {
|
|
|
2399
2420
|
this.contextMenuHandler = new KritzelContextMenuHandler(this.core, this.globalContextMenuItems, this.objectContextMenuItems);
|
|
2400
2421
|
this.keyHandler = new KritzelKeyHandler(this.core);
|
|
2401
2422
|
this.viewport = new KritzelViewport(this.core, this.host);
|
|
2402
|
-
|
|
2423
|
+
// Set sync configuration if provided
|
|
2424
|
+
if (this.syncConfig) {
|
|
2425
|
+
this.core.setSyncConfig(this.syncConfig);
|
|
2426
|
+
}
|
|
2427
|
+
// Initialize Yjs document and persistence layer
|
|
2428
|
+
await this.core.initializeYjs();
|
|
2429
|
+
// Initialize workspace (will load from Yjs if available)
|
|
2403
2430
|
await this.core.initializeWorkspace(this.workspace);
|
|
2431
|
+
// Register callback for remote workspace changes
|
|
2432
|
+
this.core.appStateMap.onRemoteChange(() => {
|
|
2433
|
+
this.workspacesChange.emit(this.core.store.state.workspaces);
|
|
2434
|
+
});
|
|
2404
2435
|
this._registerStateChangeListeners();
|
|
2405
2436
|
if (this.core.store.state.isReady === false) {
|
|
2406
2437
|
this.core.store.state.isReady = true;
|
|
@@ -2413,7 +2444,7 @@ const KritzelEngine = class {
|
|
|
2413
2444
|
_handleActiveToolChange(activeTool) {
|
|
2414
2445
|
if (!(activeTool instanceof KritzelSelectionTool)) {
|
|
2415
2446
|
this.core.clearSelection();
|
|
2416
|
-
this.core.store.state.
|
|
2447
|
+
this.core.store.state.objectsMap.remove(o => o instanceof KritzelSelectionBox);
|
|
2417
2448
|
this.core.store.state.isSelecting = false;
|
|
2418
2449
|
this.core.store.state.isResizeHandleSelected = false;
|
|
2419
2450
|
this.core.store.state.isRotationHandleSelected = false;
|
|
@@ -2431,7 +2462,7 @@ const KritzelEngine = class {
|
|
|
2431
2462
|
const baseHandleTouchSize = baseHandleSize * 2 < 14 ? 14 : baseHandleSize;
|
|
2432
2463
|
const viewportCenterX = this.core.store.state.viewportWidth / 2 + this.core.store.state.translateX;
|
|
2433
2464
|
const viewportCenterY = this.core.store.state.viewportHeight / 2 + this.core.store.state.translateY;
|
|
2434
|
-
return (h(Host, { key: '
|
|
2465
|
+
return (h(Host, { key: 'b67ab4cce757661cb7b1bdc10035a3aea61cb24d' }, h("div", { key: '54160ed099438a59043ff4f5a774ee8c89a02153', class: "debug-panel", style: { display: this.core.store.state.debugInfo.showViewportInfo ? 'block' : 'none' } }, h("div", { key: '66e3a55bc530877256782073c4378b77d95ccfee' }, "ActiveWorkspaceId: ", this.core.store.state?.activeWorkspace?.id), h("div", { key: '841ea8bf317c3ef5ea35950f6bb2be9e6a8116cf' }, "ActiveWorkspaceName: ", this.core.store.state?.activeWorkspace?.name), h("div", { key: 'ec3a7797f01606308b54cf9b13bf7a3722c54287' }, "TranslateX: ", this.core.store.state?.translateX), h("div", { key: '485dbc3021940fad42bae53a825206f27c76e604' }, "TranslateY: ", this.core.store.state?.translateY), h("div", { key: '20fed3eb07d6599a175e43cd7e1708aa2a61cf31' }, "ViewportWidth: ", this.core.store.state?.viewportWidth), h("div", { key: '06522e742ac0d3d7c36b4b64307d695459b792e4' }, "ViewportHeight: ", this.core.store.state?.viewportHeight), h("div", { key: 'e745be888b5e1b36331359ca9fa1afc166333d13' }, "Scale: ", this.core.store.state?.scale), h("div", { key: 'f9074a0e3434aa0fb60d8d1fc1201815cb94fb7c' }, "ActiveTool: ", this.core.store.state?.activeTool?.name), h("div", { key: '3f96d5f90187cb0e042c4529351681b4799d9b38' }, "HasViewportChanged: ", this.core.store.state?.hasViewportChanged ? 'true' : 'false'), h("div", { key: '6ca3d01c4aa817b0ccfd8bd1c5b65588006ecb5b' }, "IsEnabled: ", this.core.store.state?.isEnabled ? 'true' : 'false'), h("div", { key: 'c2941fdce608c0a0396996aa3667f3fa18cc29a3' }, "IsScaling: ", this.core.store.state?.isScaling ? 'true' : 'false'), h("div", { key: '0a99cd2e9767e4a9cb74af735a5eff5a86a9b6c4' }, "IsPanning: ", this.core.store.state?.isPanning ? 'true' : 'false'), h("div", { key: '0e749d3d2e131ab5984acbc7d9d91023b166ed45' }, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", { key: '0f102c2e704a18271e5b322814403c1cd0938356' }, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", { key: 'd0c7eaa357268d4df97e50e85634e4be36e678ac' }, "IsResizeHandleSelected: ", this.core.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", { key: 'eb7b0d98fd3d4a13f152ded89a6649f408852575' }, "IsRotationHandleSelected: ", this.core.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", { key: 'bd9a16ff4537a9b6e73bff8d67222c4281a60fa0' }, "IsDrawing: ", this.core.store.state.isDrawing ? 'true' : 'false'), h("div", { key: 'fdeb2b546e421e9ce9d61e1527fcc79bd1cb217e' }, "IsWriting: ", this.core.store.state.isWriting ? 'true' : 'false'), h("div", { key: '9e7e93bcb5ce9c92ea9686140fc30851f6a4c66d' }, "PointerX: ", this.core.store.state?.pointerX), h("div", { key: 'aaad9771c7286e352f99e2613616e8f023044926' }, "PointerY: ", this.core.store.state?.pointerY), h("div", { key: 'fca0584ae7d2481b2ccdb71a24ad123a5efc6668' }, "SelectedObjects: ", this.core.store.selectionGroup?.objects.length || 0), h("div", { key: 'a3f870ca59feb6698f2a9d4a106a694ac9b8cb3f' }, "ViewportCenter: (", viewportCenterX.toFixed(2), ", ", viewportCenterY.toFixed(2), ")")), h("div", { key: '4616f1af54642b448806e7271b421f3d7e980dd1', id: "origin", class: "origin", style: {
|
|
2435
2466
|
transform: `matrix(${this.core.store.state?.scale}, 0, 0, ${this.core.store.state?.scale}, ${this.core.store.state?.translateX}, ${this.core.store.state?.translateY})`,
|
|
2436
2467
|
} }, this.core.store.state.objectsMap.allObjects()?.map(object => {
|
|
2437
2468
|
return (h("div", { key: object.id, style: {
|
|
@@ -2488,7 +2519,7 @@ const KritzelEngine = class {
|
|
|
2488
2519
|
} })), KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup') && (h("div", { ref: el => object.mount(el), style: {
|
|
2489
2520
|
width: '100%',
|
|
2490
2521
|
height: '100%',
|
|
2491
|
-
} })), KritzelClassHelper.isInstanceOf(object, '
|
|
2522
|
+
} })), KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionBox') && (h("div", { ref: el => object.mount(el), style: {
|
|
2492
2523
|
width: '100%',
|
|
2493
2524
|
height: '100%',
|
|
2494
2525
|
backgroundColor: KritzelDevicesHelper.isFirefox() ? object.backgroundColor : 'transparent',
|
|
@@ -2536,15 +2567,7 @@ const KritzelEngine = class {
|
|
|
2536
2567
|
fill: 'transparent',
|
|
2537
2568
|
cursor: 'grab',
|
|
2538
2569
|
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("g", { style: { display: this.core.store.state.debugInfo.showObjectInfo ? 'block' : 'none', pointerEvents: 'none' } }, h("foreignObject", { x: object.totalWidth.toString(), y: "0", width: "400px", height: "160px", style: { minHeight: '0', minWidth: '0', display: object.isDebugInfoVisible ? 'block' : 'none' } }, h("div", { style: { width: '100%', height: '100%' } }, h("div", { style: { whitespace: 'nowrap' } }, "Id: ", object.id), h("div", { style: { whiteSpace: 'nowrap' } }, "width: ", object.width), h("div", { style: { whiteSpace: 'nowrap' } }, "height: ", object.height), h("div", { style: { whiteSpace: 'nowrap' } }, "translateX: ", object.translateX), h("div", { style: { whiteSpace: 'nowrap' } }, "translateY: ", object.translateY)))))));
|
|
2539
|
-
}), h("
|
|
2540
|
-
left: '0',
|
|
2541
|
-
top: '0',
|
|
2542
|
-
zIndex: this.core.store.state.currentPath?.zIndex.toString(),
|
|
2543
|
-
position: 'absolute',
|
|
2544
|
-
transform: this.core.store.state.currentPath?.transformationMatrix,
|
|
2545
|
-
transformOrigin: 'top left',
|
|
2546
|
-
overflow: 'visible',
|
|
2547
|
-
}, viewBox: this.core.store.state.currentPath?.viewBox }, h("path", { key: 'eab427509417e6b80726436f726e6e1189b7c4fb', d: this.core.store.state.currentPath?.d, fill: this.core.store.state.currentPath?.fill, stroke: this.core.store.state.currentPath?.stroke }))), this.core.store.state.isContextMenuVisible && (h("kritzel-context-menu", { key: '335cb455cfdb3e02dbc2ead1bf182d801b58e7bc', class: "context-menu", ref: el => (this.contextMenuElement = el), items: this.core.store.state.contextMenuItems, objects: this.core.store.state.selectionGroup?.objects || [], style: {
|
|
2570
|
+
})), this.core.store.state.isContextMenuVisible && (h("kritzel-context-menu", { key: '7907e01ea585125e8377d473d8d7d764b5e35609', class: "context-menu", ref: el => (this.contextMenuElement = el), items: this.core.store.state.contextMenuItems, objects: this.core.store.selectionGroup?.objects || [], style: {
|
|
2548
2571
|
position: 'fixed',
|
|
2549
2572
|
left: `${this.core.store.state.contextMenuX}px`,
|
|
2550
2573
|
top: `${this.core.store.state.contextMenuY}px`,
|
|
@@ -2553,9 +2576,9 @@ const KritzelEngine = class {
|
|
|
2553
2576
|
event.detail.action({
|
|
2554
2577
|
x: (-this.core.store.state.translateX + this.core.store.state.contextMenuX) / this.core.store.state.scale,
|
|
2555
2578
|
y: (-this.core.store.state.translateY + this.core.store.state.contextMenuY) / this.core.store.state.scale,
|
|
2556
|
-
}, this.core.store.
|
|
2579
|
+
}, this.core.store.selectionGroup?.objects);
|
|
2557
2580
|
this.hideContextMenu();
|
|
2558
|
-
}, onClose: () => this.hideContextMenu() })), this.core.store.state?.activeTool instanceof KritzelEraserTool && !this.core.store.state.isScaling && h("kritzel-cursor-trail", { key: '
|
|
2581
|
+
}, onClose: () => this.hideContextMenu() })), this.core.store.state?.activeTool instanceof KritzelEraserTool && !this.core.store.state.isScaling && h("kritzel-cursor-trail", { key: '4cb3d1ce212b078514524e9edc7c22f6117e5160', core: this.core })));
|
|
2559
2582
|
}
|
|
2560
2583
|
static get watchers() { return {
|
|
2561
2584
|
"workspace": ["onWorkspaceChange"],
|
|
@@ -2575,7 +2598,7 @@ const KritzelFont = class {
|
|
|
2575
2598
|
size = 24;
|
|
2576
2599
|
color = '#000000';
|
|
2577
2600
|
render() {
|
|
2578
|
-
return (h(Host, { key: '
|
|
2601
|
+
return (h(Host, { key: '0d0f0f75b64f579ca236950334fafde7f0ef2a38' }, h("div", { key: 'e71524879ded9727891bdd43f1a41ae5eef49175', class: "font-preview", style: {
|
|
2579
2602
|
fontFamily: this.fontFamily,
|
|
2580
2603
|
fontSize: `${this.size}px`,
|
|
2581
2604
|
color: this.color
|
|
@@ -2622,7 +2645,7 @@ const KritzelFontFamily = class {
|
|
|
2622
2645
|
label: option.label,
|
|
2623
2646
|
style: { fontFamily: option.value },
|
|
2624
2647
|
}));
|
|
2625
|
-
return (h(Host, { key: '
|
|
2648
|
+
return (h(Host, { key: 'd05a099adf8623b8c67d68f3861c1cd401e86e2c' }, h("kritzel-dropdown", { key: 'b95af194feaaf5748bb0d584617d217e4b3b8180', options: dropdownOptions, value: this.selectedFontFamily, onValueChanged: this.handleDropdownValueChange, selectStyles: { fontFamily: this.selectedFontFamily } }, h("button", { key: '04a0a72f9297dc6c34a2a2019cae111d8725bcf4', class: "font-style-button", slot: "suffix" }, "B"), h("button", { key: 'f14b59f29bcce33f890b74c1fb8d1dad0ad6fd31', class: "font-style-button italic-text", slot: "suffix" }, "I"))));
|
|
2626
2649
|
}
|
|
2627
2650
|
};
|
|
2628
2651
|
KritzelFontFamily.style = kritzelFontFamilyCss;
|
|
@@ -2643,7 +2666,7 @@ const KritzelFontSize = class {
|
|
|
2643
2666
|
this.sizeChange.emit(size);
|
|
2644
2667
|
}
|
|
2645
2668
|
render() {
|
|
2646
|
-
return (h(Host, { key: '
|
|
2669
|
+
return (h(Host, { key: '583659340d8f3bfb2ff6f64f2cd692ac07cb32d6' }, this.sizes.map(size => (h("div", { class: {
|
|
2647
2670
|
'size-container': true,
|
|
2648
2671
|
'selected': this.selectedSize === size,
|
|
2649
2672
|
}, onClick: () => this.handleSizeClick(size) }, h("kritzel-font", { fontFamily: this.fontFamily, size: size }))))));
|
|
@@ -2738,7 +2761,7 @@ const KritzelMenu = class {
|
|
|
2738
2761
|
this.itemCloseChildMenu.emit(event.detail);
|
|
2739
2762
|
};
|
|
2740
2763
|
render() {
|
|
2741
|
-
return (h(Host, { key: '
|
|
2764
|
+
return (h(Host, { key: '211bd579000294d9edf6f85f2d7244aebe331191', tabIndex: 0, onClick: e => e.stopPropagation() }, this.openChildMenuItem && h("div", { key: 'b1c397118b1fbac934867677073661a69be1cab1', class: "has-open-child-overlay", onClick: this.onOverlayClick }), this.items.map(item => (h("kritzel-menu-item", { key: item.id, item: item, parent: this.parent, style: { pointerEvents: this.editingMenuItem && !item.isEditing ? 'none' : 'auto' }, onItemSelect: this.handleItemSelect, onItemSave: this.handleSave, onItemCancel: this.handleCancel, onItemToggleChildMenu: this.handleToggleChildMenu, onItemCloseChildMenu: this.handleCloseChildMenu })))));
|
|
2742
2765
|
}
|
|
2743
2766
|
};
|
|
2744
2767
|
KritzelMenu.style = kritzelMenuCss;
|
|
@@ -2839,12 +2862,12 @@ const KritzelMenuItem = class {
|
|
|
2839
2862
|
];
|
|
2840
2863
|
}
|
|
2841
2864
|
render() {
|
|
2842
|
-
return (h(Host, { key: '
|
|
2865
|
+
return (h(Host, { key: 'a35e1e3427568f436a36b43ba87af3710a4e83c5', tabIndex: this.item.isDisabled ? -1 : 0, class: {
|
|
2843
2866
|
'selected': this.item.isSelected,
|
|
2844
2867
|
'editing': this.item.isEditing,
|
|
2845
2868
|
'disabled': this.item.isDisabled,
|
|
2846
2869
|
'child-open': this.item.isChildMenuOpen,
|
|
2847
|
-
}, onClick: this.handleItemSelect }, h("div", { key: '
|
|
2870
|
+
}, onClick: this.handleItemSelect }, h("div", { key: '42eef5a16b9b164839c1fe133e38ecb505c07632', class: "menu-item-overlay" }), this.item.isEditing ? this.renderEditMode() : this.renderViewMode()));
|
|
2848
2871
|
}
|
|
2849
2872
|
static get watchers() { return {
|
|
2850
2873
|
"item": ["onItemChange"]
|
|
@@ -3085,7 +3108,7 @@ const KritzelPortal = class {
|
|
|
3085
3108
|
this.portal.style.left = `${left}px`;
|
|
3086
3109
|
}
|
|
3087
3110
|
render() {
|
|
3088
|
-
return (h(Host, { key: '
|
|
3111
|
+
return (h(Host, { key: 'a906e21c1257dfc6ed21257cce150db17048f04e', style: { display: this.anchor ? 'block' : 'none' } }, h("slot", { key: '972544f2258f8b6dc8c691f3762d5ba806a57c41' })));
|
|
3089
3112
|
}
|
|
3090
3113
|
static get watchers() { return {
|
|
3091
3114
|
"anchor": ["anchorChanged"]
|
|
@@ -3185,7 +3208,7 @@ const KritzelSplitButton = class {
|
|
|
3185
3208
|
this.menuScrollTop = event.target.scrollTop;
|
|
3186
3209
|
};
|
|
3187
3210
|
render() {
|
|
3188
|
-
return (h(Host, { key: '
|
|
3211
|
+
return (h(Host, { key: 'd18a70b94e3d6860dfac952b26f66e5b96cc6fa0', class: { mobile: this.isTouchDevice } }, h("button", { key: 'ee65221543fd8984f94d0a0b43beb7e1d28411f2', class: "split-main-button", tabIndex: 0, onClick: this.handleButtonClick, disabled: this.mainButtonDisabled }, this.buttonIcon && h("kritzel-icon", { key: '1dbdd1e4db4087564464e9586e91b48f80b88aae', name: this.buttonIcon })), h("div", { key: '78b5e0589e7a3dd0592fb2c1cdaae8732f57b129', class: "split-divider" }), h("button", { key: 'cfc5d53f06485a927608a99ea491e36b0e993fcc', ref: el => (this.splitMenuButtonRef = el), class: "split-menu-button", tabIndex: 0, onClick: this.toggleMenu, disabled: this.menuButtonDisabled }, h("kritzel-icon", { key: '0e141b614cbfc758f01d21908d846d16bdce586d', name: this.dropdownIcon })), h("kritzel-portal", { key: 'b5def34dcfe5cbbf9641b1218af803937d7a77b6', anchor: this.anchorElement, offsetY: 4, onClose: this.closeMenu }, h("kritzel-menu", { key: '695f6c85a8ecd44f74ecf7752bf77d0caac69e6a', ref: el => (this.menuRef = el), items: this.items, onItemSelect: this.handleItemSelect, onItemSave: this.handleItemSave, onItemCancel: this.handleItemCancel, onItemToggleChildMenu: this.handleItemToggleChildMenu, onItemCloseChildMenu: this.handleItemCloseChildMenu, onClose: this.closeMenu, onScroll: this.handleScroll }))));
|
|
3189
3212
|
}
|
|
3190
3213
|
};
|
|
3191
3214
|
KritzelSplitButton.style = kritzelSplitButtonCss;
|
|
@@ -3205,7 +3228,7 @@ const KritzelStrokeSize = class {
|
|
|
3205
3228
|
this.sizeChange.emit(size);
|
|
3206
3229
|
}
|
|
3207
3230
|
render() {
|
|
3208
|
-
return (h(Host, { key: '
|
|
3231
|
+
return (h(Host, { key: '001a0ef8408d19532b57a521929c0cba54e99c52' }, this.sizes.map(size => (h("div", { tabIndex: 0, class: {
|
|
3209
3232
|
'size-container': true,
|
|
3210
3233
|
'selected': this.selectedSize === size,
|
|
3211
3234
|
}, onClick: () => this.handleSizeClick(size) }, h("kritzel-color", { value: '#000000', size: size }))))));
|
|
@@ -3282,23 +3305,23 @@ const KritzelTooltip = class {
|
|
|
3282
3305
|
}
|
|
3283
3306
|
}
|
|
3284
3307
|
render() {
|
|
3285
|
-
return (h(Host, { key: '
|
|
3308
|
+
return (h(Host, { key: '8c3aeff60625f43f129afa70367cdb7a68a4b271', style: {
|
|
3286
3309
|
position: 'fixed',
|
|
3287
3310
|
zIndex: '9999',
|
|
3288
3311
|
transition: 'opacity 0.3s ease-in-out, transform 0.3s ease-in-out',
|
|
3289
3312
|
visibility: this.isVisible ? 'visible' : 'hidden',
|
|
3290
3313
|
left: !this.isMobileView ? `${this.positionX}px` : '50%',
|
|
3291
3314
|
marginBottom: `${this.offsetY + this.arrowSize}px`,
|
|
3292
|
-
} }, h("div", { key: '
|
|
3315
|
+
} }, h("div", { key: 'b22b606c2a836c2c9bbe21c6b470754753ccb309', class: "tooltip-content", onClick: event => event.stopPropagation() }, h("slot", { key: '783403f4b5560012c9f6bd184a8c5eb26428e148' }), h("div", { key: 'bb98400edc5c6e05fd4ed2a476a5821f93964b8e', class: "tooltip-arrow-wrapper", style: {
|
|
3293
3316
|
position: 'fixed',
|
|
3294
3317
|
left: this.arrowOffset,
|
|
3295
3318
|
bottom: `-${this.arrowSize * 2}px`,
|
|
3296
|
-
} }, h("div", { key: '
|
|
3319
|
+
} }, h("div", { key: '850a058d635113a7870f25fa288a6447394c53ed', class: "tooltip-arrow", style: {
|
|
3297
3320
|
borderLeft: `${this.arrowSize}px solid transparent`,
|
|
3298
3321
|
borderRight: `${this.arrowSize}px solid transparent`,
|
|
3299
3322
|
borderTop: `${this.arrowSize}px solid var(--kritzel-controls-tooltip-background-color, #ffffff)`,
|
|
3300
3323
|
filter: 'drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2))',
|
|
3301
|
-
} }), h("div", { key: '
|
|
3324
|
+
} }), h("div", { key: 'bbb3dc2673e2dfe4443ad80540dfc9e5a25c6c06', class: "tooltip-arrow-rect", style: {
|
|
3302
3325
|
position: 'relative',
|
|
3303
3326
|
width: `${this.arrowSize * 2}px`,
|
|
3304
3327
|
height: `${this.arrowSize}px`,
|
|
@@ -3334,7 +3357,7 @@ const KritzelUtilityPanel = class {
|
|
|
3334
3357
|
this.redo.emit();
|
|
3335
3358
|
}
|
|
3336
3359
|
render() {
|
|
3337
|
-
return (h(Host, { key: '
|
|
3360
|
+
return (h(Host, { key: '8109ccff01374c046d057021dfbcabdc632d829f' }, h("button", { key: '0d51cfb401974edf1a2a8810d2244f8a977c347f', class: "utility-button", onClick: event => this.handleUndo(event) }, h("kritzel-icon", { key: '1d13ee6bbf060402e0b1349d41b728875314e2e5', name: "undo" })), h("button", { key: 'f2fe59e7c99cb1550052088b507313cfaed72f29', class: "utility-button", onClick: event => this.handleRedo(event) }, h("kritzel-icon", { key: '74bf8c20f61144ab4abc5804dcd8f39917d2c966', name: "redo" })), h("div", { key: '0c9a942e786425b32e984fefdc97b1abb5077997', class: "utility-separator" }), h("button", { key: '44ca9340c2f73212332e9b3ed93ed93b8f7c6944', class: "utility-button" }, h("kritzel-icon", { key: '7b4c3d9a105e0c25b5bbc11ff1bc1cbed9833e03', name: "delete", onClick: () => this.delete.emit() }))));
|
|
3338
3361
|
}
|
|
3339
3362
|
};
|
|
3340
3363
|
KritzelUtilityPanel.style = kritzelUtilityPanelCss;
|