kritzel-stencil 0.0.131 → 0.0.133
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-BwINBV6L.js → index-DCHCVnOl.js} +755 -701
- package/dist/cjs/index-DCHCVnOl.js.map +1 -0
- package/dist/cjs/index-nzUNdMPh.js +6 -2
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/kritzel-brush-style.cjs.entry.js +32 -0
- package/dist/cjs/kritzel-brush-style.entry.cjs.js.map +1 -0
- package/dist/cjs/{kritzel-brush-style_23.cjs.entry.js → kritzel-color_22.cjs.entry.js} +1046 -874
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/stencil.cjs.js +1 -1
- package/dist/collection/classes/commands/add-object.command.js +6 -7
- package/dist/collection/classes/commands/add-object.command.js.map +1 -1
- package/dist/collection/classes/commands/add-selection-group.command.js +9 -9
- package/dist/collection/classes/commands/add-selection-group.command.js.map +1 -1
- package/dist/collection/classes/commands/base.command.js +3 -3
- package/dist/collection/classes/commands/base.command.js.map +1 -1
- package/dist/collection/classes/commands/batch.command.js +2 -2
- package/dist/collection/classes/commands/batch.command.js.map +1 -1
- package/dist/collection/classes/commands/move-selection-group.command.js +15 -7
- package/dist/collection/classes/commands/move-selection-group.command.js.map +1 -1
- package/dist/collection/classes/commands/remove-object.command.js +8 -9
- package/dist/collection/classes/commands/remove-object.command.js.map +1 -1
- package/dist/collection/classes/commands/remove-selection-group.command.js +7 -7
- package/dist/collection/classes/commands/remove-selection-group.command.js.map +1 -1
- package/dist/collection/classes/commands/resize-selection-group.command.js +15 -7
- package/dist/collection/classes/commands/resize-selection-group.command.js.map +1 -1
- package/dist/collection/classes/commands/rotate-selection-group.command.js +14 -12
- package/dist/collection/classes/commands/rotate-selection-group.command.js.map +1 -1
- package/dist/collection/classes/commands/update-object.command.js +6 -5
- package/dist/collection/classes/commands/update-object.command.js.map +1 -1
- package/dist/collection/classes/commands/update-viewport.command.js +11 -11
- package/dist/collection/classes/commands/update-viewport.command.js.map +1 -1
- package/dist/collection/classes/{store.class.js → core/core.class.js} +116 -145
- package/dist/collection/classes/core/core.class.js.map +1 -0
- package/dist/collection/classes/{database.class.js → core/database.class.js} +28 -20
- package/dist/collection/classes/core/database.class.js.map +1 -0
- package/dist/collection/classes/core/history.class.js +88 -0
- package/dist/collection/classes/core/history.class.js.map +1 -0
- package/dist/collection/classes/{reviver.class.js → core/reviver.class.js} +27 -23
- package/dist/collection/classes/core/reviver.class.js.map +1 -0
- package/dist/collection/classes/core/store.class.js +51 -0
- package/dist/collection/classes/core/store.class.js.map +1 -0
- package/dist/collection/classes/core/viewport.class.js +165 -0
- package/dist/collection/classes/core/viewport.class.js.map +1 -0
- package/dist/collection/classes/core/workspace.class.js +42 -0
- package/dist/collection/classes/core/workspace.class.js.map +1 -0
- package/dist/collection/classes/handlers/base.handler.js +4 -4
- package/dist/collection/classes/handlers/base.handler.js.map +1 -1
- package/dist/collection/classes/handlers/context-menu.handler.js +29 -19
- package/dist/collection/classes/handlers/context-menu.handler.js.map +1 -1
- package/dist/collection/classes/handlers/hover.handler.js +5 -5
- package/dist/collection/classes/handlers/hover.handler.js.map +1 -1
- package/dist/collection/classes/handlers/key.handler.js +38 -44
- package/dist/collection/classes/handlers/key.handler.js.map +1 -1
- package/dist/collection/classes/handlers/move.handler.js +49 -44
- package/dist/collection/classes/handlers/move.handler.js.map +1 -1
- package/dist/collection/classes/handlers/resize.handler.js +55 -60
- package/dist/collection/classes/handlers/resize.handler.js.map +1 -1
- package/dist/collection/classes/handlers/rotation.handler.js +59 -69
- package/dist/collection/classes/handlers/rotation.handler.js.map +1 -1
- package/dist/collection/classes/handlers/selection.handler.js +73 -72
- package/dist/collection/classes/handlers/selection.handler.js.map +1 -1
- package/dist/collection/classes/objects/base-object.class.js +30 -17
- package/dist/collection/classes/objects/base-object.class.js.map +1 -1
- package/dist/collection/classes/objects/custom-element.class.js +3 -3
- package/dist/collection/classes/objects/custom-element.class.js.map +1 -1
- package/dist/collection/classes/objects/image.class.js +5 -5
- package/dist/collection/classes/objects/image.class.js.map +1 -1
- package/dist/collection/classes/objects/path.class.js +7 -7
- package/dist/collection/classes/objects/path.class.js.map +1 -1
- package/dist/collection/classes/objects/selection-box.class.js +4 -4
- package/dist/collection/classes/objects/selection-box.class.js.map +1 -1
- package/dist/collection/classes/objects/selection-group.class.js +19 -20
- package/dist/collection/classes/objects/selection-group.class.js.map +1 -1
- package/dist/collection/classes/objects/text.class.js +13 -13
- package/dist/collection/classes/objects/text.class.js.map +1 -1
- package/dist/collection/classes/registries/tool.registry.js +2 -2
- package/dist/collection/classes/registries/tool.registry.js.map +1 -1
- package/dist/collection/classes/tools/base-tool.class.js +11 -5
- package/dist/collection/classes/tools/base-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/brush-tool.class.js +57 -53
- package/dist/collection/classes/tools/brush-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/eraser-tool.class.js +26 -26
- package/dist/collection/classes/tools/eraser-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/image-tool.class.js +11 -11
- package/dist/collection/classes/tools/image-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/selection-tool.class.js +39 -37
- package/dist/collection/classes/tools/selection-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/text-tool.class.js +37 -37
- package/dist/collection/classes/tools/text-tool.class.js.map +1 -1
- package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.js +28 -28
- package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.js.map +1 -1
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.css +7 -9
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +177 -7
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js.map +1 -1
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +237 -232
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -1
- package/dist/collection/components/shared/kritzel-brush-style/kritzel-brush-style.js +1 -1
- package/dist/collection/components/shared/kritzel-brush-style/kritzel-brush-style.js.map +1 -1
- package/dist/collection/components/shared/kritzel-color/kritzel-color.js +2 -2
- package/dist/collection/components/shared/kritzel-color/kritzel-color.js.map +1 -1
- package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.css +5 -0
- package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.js +3 -3
- package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.js.map +1 -1
- package/dist/collection/components/shared/kritzel-dropdown/kritzel-dropdown.js +12 -12
- package/dist/collection/components/shared/kritzel-dropdown/kritzel-dropdown.js.map +1 -1
- package/dist/collection/components/shared/kritzel-font/kritzel-font.js +1 -1
- package/dist/collection/components/shared/kritzel-font/kritzel-font.js.map +1 -1
- package/dist/collection/components/shared/kritzel-font-family/kritzel-font-family.js +1 -1
- package/dist/collection/components/shared/kritzel-font-family/kritzel-font-family.js.map +1 -1
- package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.js +1 -1
- package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.js.map +1 -1
- package/dist/collection/components/shared/kritzel-icon/kritzel-icon.css +1 -0
- package/dist/collection/components/shared/kritzel-icon/kritzel-icon.js.map +1 -1
- package/dist/collection/components/shared/kritzel-menu/kritzel-menu.css +5 -1
- package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js +2 -2
- package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js.map +1 -1
- package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.css +18 -7
- package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.js +24 -9
- package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.js.map +1 -1
- package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js +4 -42
- package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js.map +1 -1
- package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.css +0 -4
- package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.js +52 -10
- package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.js.map +1 -1
- package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.css +4 -0
- package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.js +1 -1
- package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.js.map +1 -1
- package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.js +79 -7
- package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.js.map +1 -1
- package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js +47 -15
- package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js.map +1 -1
- package/dist/collection/components/ui/kritzel-control-brush-config/kritzel-control-brush-config.css +4 -0
- package/dist/collection/components/ui/kritzel-control-brush-config/kritzel-control-brush-config.js +6 -6
- package/dist/collection/components/ui/kritzel-control-brush-config/kritzel-control-brush-config.js.map +1 -1
- package/dist/collection/components/ui/kritzel-control-text-config/kritzel-control-text-config.js +2 -2
- package/dist/collection/components/ui/kritzel-control-text-config/kritzel-control-text-config.js.map +1 -1
- package/dist/collection/components/ui/kritzel-controls/kritzel-controls.css +12 -1
- package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +23 -7
- package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js.map +1 -1
- package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.css +5 -0
- package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js +1 -1
- package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js.map +1 -1
- package/dist/collection/components/ui/kritzel-workspace-manager/kritzel-workspace-manager.js +25 -15
- package/dist/collection/components/ui/kritzel-workspace-manager/kritzel-workspace-manager.js.map +1 -1
- package/dist/collection/configs/default-engine-state.js +0 -1
- package/dist/collection/configs/default-engine-state.js.map +1 -1
- package/dist/collection/helpers/devices.helper.js +20 -0
- package/dist/collection/helpers/devices.helper.js.map +1 -1
- package/dist/collection/helpers/event.helper.js +1 -5
- package/dist/collection/helpers/event.helper.js.map +1 -1
- package/dist/collection/helpers/html.helper.js +29 -0
- package/dist/collection/helpers/html.helper.js.map +1 -1
- package/dist/collection/helpers/object.helper.js +0 -14
- package/dist/collection/helpers/object.helper.js.map +1 -1
- package/dist/collection/index.js +1 -1
- package/dist/collection/index.js.map +1 -1
- package/dist/collection/interfaces/clonable.interface.js +2 -0
- package/dist/collection/interfaces/clonable.interface.js.map +1 -0
- package/dist/collection/interfaces/engine-state.interface.js.map +1 -1
- package/dist/collection/interfaces/serializable.interface.js.map +1 -1
- package/dist/collection/types/deep-readonly.type.js +2 -0
- package/dist/collection/types/deep-readonly.type.js.map +1 -0
- package/dist/components/index.js +3 -3
- package/dist/components/kritzel-brush-style.js +59 -1
- package/dist/components/kritzel-brush-style.js.map +1 -1
- 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 +80 -37
- 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-CMJ3P0Vw.js → p-0iJh9Z6m.js} +5 -5
- package/dist/components/p-0iJh9Z6m.js.map +1 -0
- package/dist/components/p-B0kd2rUI.js +16 -0
- package/dist/components/p-B0kd2rUI.js.map +1 -0
- package/dist/components/{p-BB5R2k1o.js → p-B3LGnqFz.js} +41 -31
- package/dist/components/p-B3LGnqFz.js.map +1 -0
- package/dist/components/{p-BB0_-X42.js → p-B7kZ1_RH.js} +4 -4
- package/dist/components/{p-BB0_-X42.js.map → p-B7kZ1_RH.js.map} +1 -1
- package/dist/components/{p-t4NIsuX9.js → p-B7w19kIk.js} +15 -27
- package/dist/components/p-B7w19kIk.js.map +1 -0
- package/dist/components/{p-B1BLgWL1.js → p-BGdsAz54.js} +27 -18
- package/dist/components/p-BGdsAz54.js.map +1 -0
- package/dist/components/{p-CGmS8wnN.js → p-BKvOO7NT.js} +26 -16
- package/dist/components/p-BKvOO7NT.js.map +1 -0
- package/dist/components/{p-BhiYvSBc.js → p-BM9IjvnD.js} +3 -3
- package/dist/components/p-BM9IjvnD.js.map +1 -0
- package/dist/components/{p-BrBQUN0Q.js → p-BPsQrpzN.js} +40 -11
- package/dist/components/p-BPsQrpzN.js.map +1 -0
- package/dist/components/p-C6qB08BS.js +68 -0
- package/dist/components/p-C6qB08BS.js.map +1 -0
- package/dist/components/{p-BPz_H-EG.js → p-CM8KdFZI.js} +28 -16
- package/dist/components/p-CM8KdFZI.js.map +1 -0
- package/dist/components/{p-DHSEK3rF.js → p-CNTK3JOp.js} +174 -153
- package/dist/components/p-CNTK3JOp.js.map +1 -0
- package/dist/components/{p-DMrtdhBD.js → p-CsyM5q2M.js} +7 -7
- package/dist/components/p-CsyM5q2M.js.map +1 -0
- package/dist/components/{p-BuewJQNl.js → p-CwH-bwjb.js} +1187 -1141
- package/dist/components/p-CwH-bwjb.js.map +1 -0
- package/dist/components/{p-BgmKrd5Z.js → p-DCx3703u.js} +5 -5
- package/dist/components/p-DCx3703u.js.map +1 -0
- package/dist/components/{p-trncBp_6.js → p-DFO-6kuA.js} +15 -15
- package/dist/components/p-DFO-6kuA.js.map +1 -0
- package/dist/components/{p-BubxwvMA.js → p-Db3kxVe2.js} +24 -24
- package/dist/components/p-Db3kxVe2.js.map +1 -0
- package/dist/components/{p-BexTdWaX.js → p-Ddlbt3Bj.js} +4 -4
- package/dist/components/p-Ddlbt3Bj.js.map +1 -0
- package/dist/components/{p-CHxPWeZd.js → p-DjU7p3od.js} +11 -11
- package/dist/components/{p-CHxPWeZd.js.map → p-DjU7p3od.js.map} +1 -1
- package/dist/components/{p-BeljsQ-8.js → p-Dw4n-4zp.js} +32 -17
- package/dist/components/p-Dw4n-4zp.js.map +1 -0
- package/dist/components/{p-DxTu1aoJ.js → p-NP1Htol7.js} +7 -45
- package/dist/components/p-NP1Htol7.js.map +1 -0
- package/dist/components/p-YqK8ch2R.js +46 -0
- package/dist/components/p-YqK8ch2R.js.map +1 -0
- package/dist/components/p-l10It7Nm.js +30 -0
- package/dist/components/p-l10It7Nm.js.map +1 -0
- package/dist/components/{p-p1Jkec_q.js → p-sq9jgfX0.js} +3 -3
- package/dist/components/p-sq9jgfX0.js.map +1 -0
- package/dist/components/{p-yZ48g7-u.js → p-sreNwi0N.js} +4 -4
- package/dist/components/{p-yZ48g7-u.js.map → p-sreNwi0N.js.map} +1 -1
- package/dist/esm/{index-B-oSk-v8.js → index-DY3KqYWc.js} +756 -702
- package/dist/esm/index-DY3KqYWc.js.map +1 -0
- package/dist/esm/index-oCOlsFCN.js +6 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/kritzel-brush-style.entry.js +30 -0
- package/dist/esm/kritzel-brush-style.entry.js.map +1 -0
- package/dist/esm/{kritzel-brush-style_23.entry.js → kritzel-color_22.entry.js} +1048 -875
- package/dist/esm/loader.js +1 -1
- package/dist/esm/stencil.js +1 -1
- package/dist/stencil/index.esm.js +1 -1
- package/dist/stencil/kritzel-brush-style.entry.esm.js.map +1 -0
- package/dist/stencil/p-25d1e040.entry.js +2 -0
- package/dist/stencil/p-25d1e040.entry.js.map +1 -0
- package/dist/stencil/p-DY3KqYWc.js +2 -0
- package/dist/stencil/p-DY3KqYWc.js.map +1 -0
- package/dist/stencil/p-dc534b01.entry.js +2 -0
- package/dist/stencil/p-dc534b01.entry.js.map +1 -0
- package/dist/stencil/stencil.esm.js +1 -1
- package/dist/types/classes/commands/add-object.command.d.ts +2 -2
- package/dist/types/classes/commands/add-selection-group.command.d.ts +2 -1
- package/dist/types/classes/commands/base.command.d.ts +3 -3
- package/dist/types/classes/commands/batch.command.d.ts +2 -1
- package/dist/types/classes/commands/move-selection-group.command.d.ts +2 -1
- package/dist/types/classes/commands/remove-object.command.d.ts +2 -2
- package/dist/types/classes/commands/remove-selection-group.command.d.ts +2 -2
- package/dist/types/classes/commands/resize-selection-group.command.d.ts +2 -1
- package/dist/types/classes/commands/rotate-selection-group.command.d.ts +2 -1
- package/dist/types/classes/commands/update-object.command.d.ts +2 -2
- package/dist/types/classes/commands/update-viewport.command.d.ts +2 -1
- package/dist/types/classes/{store.class.d.ts → core/core.class.d.ts} +9 -19
- package/dist/types/classes/{database.class.d.ts → core/database.class.d.ts} +3 -2
- package/dist/types/classes/{history.class.d.ts → core/history.class.d.ts} +5 -5
- package/dist/types/classes/core/reviver.class.d.ts +6 -0
- package/dist/types/classes/core/store.class.d.ts +17 -0
- package/dist/types/classes/{viewport.class.d.ts → core/viewport.class.d.ts} +3 -3
- package/dist/types/classes/core/workspace.class.d.ts +24 -0
- package/dist/types/classes/handlers/base.handler.d.ts +3 -3
- package/dist/types/classes/handlers/context-menu.handler.d.ts +2 -2
- package/dist/types/classes/handlers/hover.handler.d.ts +2 -2
- package/dist/types/classes/handlers/key.handler.d.ts +2 -2
- package/dist/types/classes/handlers/move.handler.d.ts +4 -2
- package/dist/types/classes/handlers/resize.handler.d.ts +3 -2
- package/dist/types/classes/handlers/rotation.handler.d.ts +6 -2
- package/dist/types/classes/handlers/selection.handler.d.ts +2 -2
- package/dist/types/classes/objects/base-object.class.d.ts +8 -5
- package/dist/types/classes/objects/custom-element.class.d.ts +2 -2
- package/dist/types/classes/objects/image.class.d.ts +2 -2
- package/dist/types/classes/objects/path.class.d.ts +2 -2
- package/dist/types/classes/objects/selection-box.class.d.ts +2 -2
- package/dist/types/classes/objects/selection-group.class.d.ts +2 -2
- package/dist/types/classes/objects/text.class.d.ts +2 -2
- package/dist/types/classes/registries/tool.registry.d.ts +2 -2
- package/dist/types/classes/tools/base-tool.class.d.ts +8 -4
- package/dist/types/classes/tools/brush-tool.class.d.ts +2 -2
- package/dist/types/classes/tools/eraser-tool.class.d.ts +2 -2
- package/dist/types/classes/tools/image-tool.class.d.ts +2 -2
- package/dist/types/classes/tools/selection-tool.class.d.ts +2 -2
- package/dist/types/classes/tools/text-tool.class.d.ts +2 -2
- package/dist/types/components/core/kritzel-cursor-trail/kritzel-cursor-trail.d.ts +5 -5
- package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +13 -3
- package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +21 -22
- package/dist/types/components/shared/kritzel-dropdown/kritzel-dropdown.d.ts +2 -2
- package/dist/types/components/shared/kritzel-menu-item/kritzel-menu-item.d.ts +2 -0
- package/dist/types/components/shared/kritzel-portal/kritzel-portal.d.ts +0 -1
- package/dist/types/components/shared/kritzel-split-button/kritzel-split-button.d.ts +4 -2
- package/dist/types/components/shared/kritzel-tooltip/kritzel-tooltip.d.ts +8 -2
- package/dist/types/components/ui/kritzel-context-menu/kritzel-context-menu.d.ts +5 -3
- package/dist/types/components/ui/kritzel-control-brush-config/kritzel-control-brush-config.d.ts +1 -1
- package/dist/types/components/ui/kritzel-controls/kritzel-controls.d.ts +3 -1
- package/dist/types/components/ui/kritzel-workspace-manager/kritzel-workspace-manager.d.ts +3 -2
- package/dist/types/components.d.ts +41 -12
- package/dist/types/helpers/devices.helper.d.ts +4 -0
- package/dist/types/helpers/event.helper.d.ts +1 -1
- package/dist/types/helpers/html.helper.d.ts +1 -0
- package/dist/types/helpers/object.helper.d.ts +0 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/interfaces/clonable.interface.d.ts +3 -0
- package/dist/types/interfaces/engine-state.interface.d.ts +1 -2
- package/dist/types/interfaces/serializable.interface.d.ts +2 -1
- package/dist/types/types/deep-readonly.type.d.ts +7 -0
- package/package.json +3 -2
- package/dist/cjs/index-BwINBV6L.js.map +0 -1
- package/dist/collection/classes/database.class.js.map +0 -1
- package/dist/collection/classes/history.class.js +0 -88
- package/dist/collection/classes/history.class.js.map +0 -1
- package/dist/collection/classes/reviver.class.js.map +0 -1
- package/dist/collection/classes/store.class.js.map +0 -1
- package/dist/collection/classes/viewport.class.js +0 -153
- package/dist/collection/classes/viewport.class.js.map +0 -1
- package/dist/collection/classes/workspace.class.js +0 -15
- package/dist/collection/classes/workspace.class.js.map +0 -1
- package/dist/components/p-B1BLgWL1.js.map +0 -1
- package/dist/components/p-BB5R2k1o.js.map +0 -1
- package/dist/components/p-BPz_H-EG.js.map +0 -1
- package/dist/components/p-B_lb1FGi.js +0 -19
- package/dist/components/p-B_lb1FGi.js.map +0 -1
- package/dist/components/p-BeljsQ-8.js.map +0 -1
- package/dist/components/p-BexTdWaX.js.map +0 -1
- package/dist/components/p-BgmKrd5Z.js.map +0 -1
- package/dist/components/p-BhiYvSBc.js.map +0 -1
- package/dist/components/p-BrBQUN0Q.js.map +0 -1
- package/dist/components/p-BubxwvMA.js.map +0 -1
- package/dist/components/p-BuewJQNl.js.map +0 -1
- package/dist/components/p-CGmS8wnN.js.map +0 -1
- package/dist/components/p-CJKA5zIE.js +0 -10
- package/dist/components/p-CJKA5zIE.js.map +0 -1
- package/dist/components/p-CMJ3P0Vw.js.map +0 -1
- package/dist/components/p-DHSEK3rF.js.map +0 -1
- package/dist/components/p-DMrtdhBD.js.map +0 -1
- package/dist/components/p-DnUKql15.js +0 -30
- package/dist/components/p-DnUKql15.js.map +0 -1
- package/dist/components/p-DxTu1aoJ.js.map +0 -1
- package/dist/components/p-p1Jkec_q.js.map +0 -1
- package/dist/components/p-rIRXQdie.js +0 -64
- package/dist/components/p-rIRXQdie.js.map +0 -1
- package/dist/components/p-t4NIsuX9.js.map +0 -1
- package/dist/components/p-trncBp_6.js.map +0 -1
- package/dist/esm/index-B-oSk-v8.js.map +0 -1
- package/dist/stencil/p-3bb80782.entry.js +0 -2
- package/dist/stencil/p-3bb80782.entry.js.map +0 -1
- package/dist/stencil/p-B-oSk-v8.js +0 -2
- package/dist/stencil/p-B-oSk-v8.js.map +0 -1
- package/dist/types/classes/reviver.class.d.ts +0 -6
- package/dist/types/classes/workspace.class.d.ts +0 -16
|
@@ -1,31 +1,5 @@
|
|
|
1
|
-
import { r as registerInstance,
|
|
2
|
-
import { K as KritzelBrushTool, a as KritzelTextTool, b as KritzelMouseButton, c as KritzelSelectionTool, D as DEFAULT_BRUSH_CONFIG, d as KritzelEraserTool, e as DEFAULT_TEXT_CONFIG, f as KritzelImageTool, g as
|
|
3
|
-
|
|
4
|
-
const kritzelBrushStyleCss = ":host{display:flex;align-items:flex-start;gap:8px;padding:8px;box-sizing:border-box;width:100%}.brush-style-button{display:flex;justify-content:center;align-items:center;width:42px;height:32px;padding:0;border:none;outline:none;background:none;cursor:default;border-radius:0;color:var(--control-text-color);font-weight:bold;-webkit-tap-highlight-color:transparent}.font-style-button:not(:last-child){border-right:1px solid #333333}.font-style-button:hover{background-color:var(--control-hover-bg)}.font-style-button:active{background-color:var(--control-active-bg)}.font-style-button.selected,.font-style-button.selected:hover,.font-style-button.selected:active{background-color:var(--control-selected-bg);color:var(--control-selected-color)}";
|
|
5
|
-
|
|
6
|
-
const KritzelBrushStyle = class {
|
|
7
|
-
constructor(hostRef) {
|
|
8
|
-
registerInstance(this, hostRef);
|
|
9
|
-
this.typeChange = createEvent(this, "typeChange");
|
|
10
|
-
}
|
|
11
|
-
type = 'pen';
|
|
12
|
-
brushOptions = [
|
|
13
|
-
{ value: 'pen', label: 'Pen' },
|
|
14
|
-
{ value: 'highlighter', label: 'Highlighter' },
|
|
15
|
-
];
|
|
16
|
-
typeChange;
|
|
17
|
-
handleDropdownValueChange(event) {
|
|
18
|
-
this.typeChange.emit(event.detail);
|
|
19
|
-
}
|
|
20
|
-
render() {
|
|
21
|
-
const dropdownOptions = this.brushOptions.map(option => ({
|
|
22
|
-
value: option.value,
|
|
23
|
-
label: option.label,
|
|
24
|
-
}));
|
|
25
|
-
return (h(Host, { key: 'd7af382fe6f613aa16a5146785990ad2faa17f60' }, h("kritzel-dropdown", { key: '6d6d330d415c210058834b2968774b3db2ab7fc4', options: dropdownOptions, value: this.type, onValueChanged: event => this.handleDropdownValueChange(event) }, h("button", { key: 'c9fb33795b8e25f68c1d2ae248dc82a6de29e199', class: "brush-style-button", slot: "prefix" }, h("kritzel-icon", { key: '975c95b545a1c27ae2984405ac298592eec9743d', name: this.type, size: 16 })))));
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
KritzelBrushStyle.style = kritzelBrushStyleCss;
|
|
1
|
+
import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-oCOlsFCN.js';
|
|
2
|
+
import { K as KritzelBrushTool, a as KritzelTextTool, b as KritzelMouseButton, c as KritzelSelectionTool, D as DEFAULT_BRUSH_CONFIG, d as KritzelEraserTool, e as DEFAULT_TEXT_CONFIG, f as KritzelImageTool, g as KritzelWorkspace, h as KritzelKeyboardHelper, i as KritzelEventHelper, j as KritzelBaseHandler, k as KritzelToolRegistry, l as KritzelSelectionGroup, B as BatchCommand, R as RemoveSelectionGroupCommand, A as AddSelectionGroupCommand, m as KritzelBaseCommand, n as KrtizelSelectionBox, O as ObjectHelper, o as KritzelReviver, p as RemoveObjectCommand, q as AddObjectCommand, U as UpdateObjectCommand, r as KritzelBaseTool } from './index-DY3KqYWc.js';
|
|
29
3
|
|
|
30
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)}";
|
|
31
5
|
|
|
@@ -61,13 +35,13 @@ const KritzelColor = class {
|
|
|
61
35
|
}
|
|
62
36
|
render() {
|
|
63
37
|
const isColorVeryLight = this.isLightColor(this.value);
|
|
64
|
-
return (h(Host, { key: '
|
|
38
|
+
return (h(Host, { key: '198dba41e1600d76faace18de78191d2b7a551ec' }, h("div", { key: 'ee690cffb7925e09cb2c51022eec607247a4849f', class: "checkerboard-bg", style: {
|
|
65
39
|
width: `${this.size}px`,
|
|
66
40
|
height: `${this.size}px`,
|
|
67
41
|
borderRadius: '50%',
|
|
68
42
|
display: 'inline-block',
|
|
69
43
|
position: 'relative',
|
|
70
|
-
} }, h("div", { key: '
|
|
44
|
+
} }, h("div", { key: '66cc8df8fabd008db8c00942994875e3e8d722ce', class: {
|
|
71
45
|
'color-circle': true,
|
|
72
46
|
'white': isColorVeryLight,
|
|
73
47
|
}, style: {
|
|
@@ -84,7 +58,7 @@ const KritzelColor = class {
|
|
|
84
58
|
};
|
|
85
59
|
KritzelColor.style = kritzelColorCss;
|
|
86
60
|
|
|
87
|
-
const kritzelColorPaletteCss = ":host{display:flex;align-items:flex-start;gap:8px;padding:8px;width:100%;box-sizing:border-box}.color-grid{width:100%;display:grid;grid-template-columns:repeat(6, 32px);gap:8px;justify-items:center;overflow:hidden;height:40px;transition:height 0.1s ease-in-out}.color-grid.expanded{height:500px}.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}.color-container:hover{background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.color-container.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-color-palette-selected-background-color)}";
|
|
61
|
+
const kritzelColorPaletteCss = ":host{display:flex;align-items:flex-start;gap:8px;padding:8px;width:100%;box-sizing:border-box}.color-grid{width:100%;display:grid;grid-template-columns:repeat(6, 32px);gap:8px;justify-items:center;overflow:hidden;height:40px;transition:height 0.1s ease-in-out}.color-grid.expanded{height:500px}.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}.color-container:focus-visible{outline:var(--kritzel-color-palette-focus-outline, 2px auto #e3e3e3)}.color-container:hover{background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.color-container.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-color-palette-selected-background-color)}";
|
|
88
62
|
|
|
89
63
|
const KritzelColorPalette = class {
|
|
90
64
|
constructor(hostRef) {
|
|
@@ -110,12 +84,12 @@ const KritzelColorPalette = class {
|
|
|
110
84
|
render() {
|
|
111
85
|
const displayedColors = this.isExpanded ? this.colors : this.colors.slice(0, 6);
|
|
112
86
|
const expandedHeight = this.isExpanded ? this.calculateHeight() : '32px';
|
|
113
|
-
return (h(Host, { key: '
|
|
87
|
+
return (h(Host, { key: '2ead7cd530ce181856e5f582f086a22a1fe69390' }, h("div", { key: 'fcc75b267f36e271d50615bfde42a29c28aa2536', class: {
|
|
114
88
|
'color-grid': true,
|
|
115
89
|
'expanded': this.isExpanded,
|
|
116
90
|
}, style: {
|
|
117
|
-
height: expandedHeight
|
|
118
|
-
} }, displayedColors.map(color => (h("div", { class: {
|
|
91
|
+
height: expandedHeight,
|
|
92
|
+
} }, displayedColors.map(color => (h("div", { tabIndex: 0, class: {
|
|
119
93
|
'color-container': true,
|
|
120
94
|
'selected': this.selectedColor === color,
|
|
121
95
|
}, onClick: () => this.handleColorClick(color) }, h("kritzel-color", { value: color })))))));
|
|
@@ -129,16 +103,25 @@ const KritzelContextMenu = class {
|
|
|
129
103
|
constructor(hostRef) {
|
|
130
104
|
registerInstance(this, hostRef);
|
|
131
105
|
this.actionSelected = createEvent(this, "actionSelected");
|
|
106
|
+
this.close = createEvent(this, "close");
|
|
132
107
|
}
|
|
108
|
+
get host() { return getElement(this); }
|
|
133
109
|
items;
|
|
110
|
+
onItemsChanged() {
|
|
111
|
+
this.updateMenuItems();
|
|
112
|
+
}
|
|
134
113
|
objects;
|
|
135
114
|
actionSelected;
|
|
136
|
-
|
|
115
|
+
close;
|
|
137
116
|
processedItems = [];
|
|
138
|
-
|
|
139
|
-
|
|
117
|
+
handleOutsideClick(event) {
|
|
118
|
+
event.preventDefault();
|
|
119
|
+
const path = event.composedPath();
|
|
120
|
+
if (!path.includes(this.host)) {
|
|
121
|
+
this.close.emit();
|
|
122
|
+
}
|
|
140
123
|
}
|
|
141
|
-
|
|
124
|
+
componentWillLoad() {
|
|
142
125
|
this.updateMenuItems();
|
|
143
126
|
}
|
|
144
127
|
handleItemClick(item, isDisabled) {
|
|
@@ -146,15 +129,6 @@ const KritzelContextMenu = class {
|
|
|
146
129
|
this.actionSelected.emit(item);
|
|
147
130
|
}
|
|
148
131
|
}
|
|
149
|
-
async evaluateProperty(value, defaultValue) {
|
|
150
|
-
if (typeof value === 'boolean') {
|
|
151
|
-
return value;
|
|
152
|
-
}
|
|
153
|
-
if (typeof value === 'function') {
|
|
154
|
-
return await Promise.resolve(value(null, this.objects));
|
|
155
|
-
}
|
|
156
|
-
return defaultValue;
|
|
157
|
-
}
|
|
158
132
|
async updateMenuItems() {
|
|
159
133
|
const processed = [];
|
|
160
134
|
for (const item of this.items) {
|
|
@@ -166,8 +140,17 @@ const KritzelContextMenu = class {
|
|
|
166
140
|
}
|
|
167
141
|
this.processedItems = processed;
|
|
168
142
|
}
|
|
143
|
+
async evaluateProperty(value, defaultValue) {
|
|
144
|
+
if (typeof value === 'boolean') {
|
|
145
|
+
return value;
|
|
146
|
+
}
|
|
147
|
+
if (typeof value === 'function') {
|
|
148
|
+
return await Promise.resolve(value(null, this.objects));
|
|
149
|
+
}
|
|
150
|
+
return defaultValue;
|
|
151
|
+
}
|
|
169
152
|
render() {
|
|
170
|
-
return (h(Host, { key: '
|
|
153
|
+
return (h(Host, { key: 'ff72bd31f6c0f3193674710bccab829f14e011d3' }, h("div", { key: '80cd7a99dc9bb1fb9ec4edb09a9bacde70dde7c3', 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)))))));
|
|
171
154
|
}
|
|
172
155
|
static get watchers() { return {
|
|
173
156
|
"items": ["onItemsChanged"]
|
|
@@ -175,7 +158,7 @@ const KritzelContextMenu = class {
|
|
|
175
158
|
};
|
|
176
159
|
KritzelContextMenu.style = kritzelContextMenuCss;
|
|
177
160
|
|
|
178
|
-
const kritzelControlBrushConfigCss = ":host{display:flex;flex-direction:column;width:100%}.expand-toggle{background:none;border:none;cursor:pointer;font-size:14px;line-height:1;padding:8px;color:var(--kritzel-color-palette-expand-toggle-color, #666666)}.expand-toggle:hover{color:var(--kritzel-color-palette-expand-toggle-hover-color, #333333)}";
|
|
161
|
+
const kritzelControlBrushConfigCss = ":host{display:flex;flex-direction:column;width:100%}.expand-toggle{background:none;border:none;cursor:pointer;font-size:14px;line-height:1;padding:8px;color:var(--kritzel-color-palette-expand-toggle-color, #666666)}.expand-toggle:focus-visible{outline:var(--kritzel-color-palette-focus-outline, 2px auto #e3e3e3)}.expand-toggle:hover{color:var(--kritzel-color-palette-expand-toggle-hover-color, #333333)}";
|
|
179
162
|
|
|
180
163
|
const KritzelControlBrushConfig = class {
|
|
181
164
|
constructor(hostRef) {
|
|
@@ -183,12 +166,12 @@ const KritzelControlBrushConfig = class {
|
|
|
183
166
|
this.toolChange = createEvent(this, "toolChange");
|
|
184
167
|
}
|
|
185
168
|
tool;
|
|
186
|
-
isExpanded = false;
|
|
187
|
-
toolChange;
|
|
188
|
-
palette = [];
|
|
189
169
|
handleToolChange(newTool) {
|
|
190
170
|
this.palette = newTool.palettes[newTool.type];
|
|
191
171
|
}
|
|
172
|
+
isExpanded = false;
|
|
173
|
+
toolChange;
|
|
174
|
+
palette = [];
|
|
192
175
|
componentWillLoad() {
|
|
193
176
|
this.palette = this.tool.palettes[this.tool.type];
|
|
194
177
|
}
|
|
@@ -210,14 +193,14 @@ const KritzelControlBrushConfig = class {
|
|
|
210
193
|
this.toolChange.emit(this.tool);
|
|
211
194
|
}
|
|
212
195
|
render() {
|
|
213
|
-
return (h(Host, { key: '
|
|
196
|
+
return (h(Host, { key: '8fe8c0564f491121c0c44c6ff4083034f92dbb67' }, h("div", { key: '3e8a69b827785976768bfc1e809126bee7c48c62', style: {
|
|
214
197
|
display: 'flex',
|
|
215
198
|
flexDirection: 'row',
|
|
216
|
-
alignItems: 'center',
|
|
199
|
+
alignItems: this.isExpanded ? 'flex-start' : 'center',
|
|
217
200
|
justifyContent: 'flex-start',
|
|
218
201
|
width: '100%',
|
|
219
202
|
gap: '8px',
|
|
220
|
-
} }, h("kritzel-
|
|
203
|
+
} }, 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) })));
|
|
221
204
|
}
|
|
222
205
|
static get watchers() { return {
|
|
223
206
|
"tool": ["handleToolChange"]
|
|
@@ -251,14 +234,14 @@ const KritzelControlTextConfig = class {
|
|
|
251
234
|
this.toolChange.emit(this.tool);
|
|
252
235
|
}
|
|
253
236
|
render() {
|
|
254
|
-
return (h(Host, { key: '
|
|
237
|
+
return (h(Host, { key: '3695b187943af25566885d63257ae3de9f405ea5' }, h("div", { key: '7bb146ae3c188478ba17f18f70fd170ce3536308', style: {
|
|
255
238
|
display: 'flex',
|
|
256
239
|
flexDirection: 'row',
|
|
257
240
|
alignItems: 'center',
|
|
258
241
|
justifyContent: 'flex-start',
|
|
259
242
|
width: '100%',
|
|
260
243
|
gap: '8px',
|
|
261
|
-
} }, h("kritzel-font-family", { key: '
|
|
244
|
+
} }, 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) })));
|
|
262
245
|
}
|
|
263
246
|
};
|
|
264
247
|
KritzelControlTextConfig.style = kritzelControlTextConfigCss;
|
|
@@ -267,15 +250,36 @@ class KritzelDevicesHelper {
|
|
|
267
250
|
static isTouchDevice() {
|
|
268
251
|
return window.matchMedia('(any-pointer: coarse)').matches;
|
|
269
252
|
}
|
|
253
|
+
static isAndroid() {
|
|
254
|
+
return /android/i.test(navigator.userAgent);
|
|
255
|
+
}
|
|
256
|
+
static isIOS() {
|
|
257
|
+
return /iPad|iPhone|iPod/.test(navigator.userAgent);
|
|
258
|
+
}
|
|
259
|
+
static detectOS() {
|
|
260
|
+
if (this.isIOS()) {
|
|
261
|
+
return 'iOS';
|
|
262
|
+
}
|
|
263
|
+
else if (this.isAndroid()) {
|
|
264
|
+
return 'Android';
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
return 'Other';
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
static isFirefox() {
|
|
271
|
+
return /firefox/i.test(navigator.userAgent);
|
|
272
|
+
}
|
|
270
273
|
}
|
|
271
274
|
|
|
272
|
-
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: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-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}.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:
|
|
275
|
+
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}";
|
|
273
276
|
|
|
274
277
|
const KritzelControls = class {
|
|
275
278
|
constructor(hostRef) {
|
|
276
279
|
registerInstance(this, hostRef);
|
|
277
280
|
this.isControlsReady = createEvent(this, "isControlsReady");
|
|
278
281
|
}
|
|
282
|
+
get host() { return getElement(this); }
|
|
279
283
|
controls = [];
|
|
280
284
|
activeControl = null;
|
|
281
285
|
isUtilityPanelVisible = true;
|
|
@@ -283,7 +287,6 @@ const KritzelControls = class {
|
|
|
283
287
|
firstConfig = null;
|
|
284
288
|
isTooltipVisible = false;
|
|
285
289
|
isTouchDevice = KritzelDevicesHelper.isTouchDevice();
|
|
286
|
-
get host() { return getElement(this); }
|
|
287
290
|
handleDocumentClick(event) {
|
|
288
291
|
const element = event.target;
|
|
289
292
|
if (!this.kritzelEngine || element.closest('.kritzel-tooltip')) {
|
|
@@ -300,12 +303,12 @@ const KritzelControls = class {
|
|
|
300
303
|
}
|
|
301
304
|
async handleActiveToolChange(event) {
|
|
302
305
|
this.activeControl = this.controls.find(control => control.tool === event.detail) || null;
|
|
303
|
-
await this.kritzelEngine?.setFocus();
|
|
304
306
|
}
|
|
305
307
|
async closeTooltip() {
|
|
306
308
|
this.isTooltipVisible = false;
|
|
307
309
|
}
|
|
308
310
|
kritzelEngine = null;
|
|
311
|
+
tooltipRef = null;
|
|
309
312
|
get activeToolAsTextTool() {
|
|
310
313
|
return this.activeControl?.tool;
|
|
311
314
|
}
|
|
@@ -352,21 +355,33 @@ const KritzelControls = class {
|
|
|
352
355
|
handleConfigClick(event) {
|
|
353
356
|
event.stopPropagation();
|
|
354
357
|
this.isTooltipVisible = !this.isTooltipVisible;
|
|
355
|
-
this.
|
|
358
|
+
if (this.isTooltipVisible) {
|
|
359
|
+
this.kritzelEngine?.disable();
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
this.kritzelEngine?.enable();
|
|
363
|
+
}
|
|
364
|
+
setTimeout(() => {
|
|
365
|
+
this.tooltipRef?.focusContent();
|
|
366
|
+
}, 100);
|
|
356
367
|
}
|
|
357
368
|
async handleToolChange(event) {
|
|
358
369
|
this.activeControl = { ...this.activeControl, tool: event.detail };
|
|
359
370
|
await this.kritzelEngine.changeActiveTool(this.activeControl.tool);
|
|
360
371
|
}
|
|
372
|
+
handleTooltipClosed() {
|
|
373
|
+
this.isTooltipVisible = false;
|
|
374
|
+
this.kritzelEngine?.enable();
|
|
375
|
+
}
|
|
361
376
|
render() {
|
|
362
377
|
const hasNoConfig = this.activeControl?.config === undefined || this.activeControl?.config === null;
|
|
363
|
-
return (h(Host, { key: '
|
|
378
|
+
return (h(Host, { key: 'a463310d88265b71097f838bf775abdcabc99225', class: {
|
|
364
379
|
mobile: this.isTouchDevice,
|
|
365
|
-
} }, this.isUtilityPanelVisible && (h("kritzel-utility-panel", { key: '
|
|
380
|
+
} }, this.isUtilityPanelVisible && (h("kritzel-utility-panel", { key: '267e9c26b41a52c655209dbaa8c85cbd72323577', style: {
|
|
366
381
|
position: 'absolute',
|
|
367
382
|
bottom: '56px',
|
|
368
383
|
left: '12px',
|
|
369
|
-
}, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), h("div", { key: '
|
|
384
|
+
}, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), h("div", { key: 'c55773245c925e1b972f3e83cb4d8f1c93ebe995', class: "kritzel-controls" }, this.controls.map(control => {
|
|
370
385
|
if (control.type === 'tool') {
|
|
371
386
|
return (h("button", { class: {
|
|
372
387
|
'kritzel-control': true,
|
|
@@ -377,7 +392,11 @@ const KritzelControls = class {
|
|
|
377
392
|
return h("div", { class: "kritzel-divider", key: control.name });
|
|
378
393
|
}
|
|
379
394
|
if (control.type === 'config' && control.name === this.firstConfig?.name && this.activeControl) {
|
|
380
|
-
return (h("div", { class: "kritzel-config-container", key: control.name }, h("kritzel-tooltip", { isVisible: this.isTooltipVisible, anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container') }, h("div", { style: { width: '294px', height: '100%' } }, this.activeControl.name === 'brush' && (h("kritzel-control-brush-config", { tool: this.activeToolAsBrushTool, onToolChange: event => this.handleToolChange?.(event) })), this.activeControl.name === 'text' && (h("kritzel-control-text-config", { tool: this.activeToolAsTextTool, onToolChange: event => this.handleToolChange?.(event) })))), h("div", { class: "kritzel-config", onClick: event => this.handleConfigClick?.(event),
|
|
395
|
+
return (h("div", { class: "kritzel-config-container", key: control.name }, h("kritzel-tooltip", { ref: el => (this.tooltipRef = el), isVisible: this.isTooltipVisible, anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container'), onTooltipClosed: () => this.handleTooltipClosed() }, h("div", { style: { width: '294px', height: '100%' } }, this.activeControl.name === 'brush' && (h("kritzel-control-brush-config", { tool: this.activeToolAsBrushTool, onToolChange: event => this.handleToolChange?.(event) })), this.activeControl.name === 'text' && (h("kritzel-control-text-config", { tool: this.activeToolAsTextTool, onToolChange: event => this.handleToolChange?.(event) })))), h("div", { tabIndex: 0, class: "kritzel-config", onClick: event => this.handleConfigClick?.(event), onKeyDown: event => {
|
|
396
|
+
if (event.key === 'Enter') {
|
|
397
|
+
this.handleConfigClick?.(event);
|
|
398
|
+
}
|
|
399
|
+
}, style: {
|
|
381
400
|
cursor: this.activeControl.config ? 'pointer' : 'default',
|
|
382
401
|
pointerEvents: hasNoConfig ? 'none' : 'auto',
|
|
383
402
|
} }, this.activeControl.tool instanceof KritzelBrushTool && (h("div", { class: "color-container" }, h("kritzel-color", { value: this.activeToolAsBrushTool?.color, size: this.activeToolAsBrushTool?.size, style: {
|
|
@@ -397,26 +416,9 @@ const KritzelCursorTrail = class {
|
|
|
397
416
|
constructor(hostRef) {
|
|
398
417
|
registerInstance(this, hostRef);
|
|
399
418
|
}
|
|
400
|
-
|
|
419
|
+
core;
|
|
401
420
|
cursorTrailPoints = [];
|
|
402
421
|
isLeftButtonDown = false;
|
|
403
|
-
trailCleanupIntervalId;
|
|
404
|
-
TRAIL_DURATION_MS = 100;
|
|
405
|
-
MAX_TRAIL_POINTS = 50;
|
|
406
|
-
componentDidLoad() {
|
|
407
|
-
this.trailCleanupIntervalId = window.setInterval(() => {
|
|
408
|
-
const now = Date.now();
|
|
409
|
-
const newTrailPoints = this.cursorTrailPoints.filter(p => now - p.timestamp < this.TRAIL_DURATION_MS);
|
|
410
|
-
if (newTrailPoints.length !== this.cursorTrailPoints.length) {
|
|
411
|
-
this.cursorTrailPoints = newTrailPoints;
|
|
412
|
-
}
|
|
413
|
-
}, 50);
|
|
414
|
-
}
|
|
415
|
-
disconnectedCallback() {
|
|
416
|
-
if (this.trailCleanupIntervalId) {
|
|
417
|
-
window.clearInterval(this.trailCleanupIntervalId);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
422
|
handleMouseDown(ev) {
|
|
421
423
|
if (ev.pointerType === 'mouse') {
|
|
422
424
|
if (ev.button === KritzelMouseButton.Left) {
|
|
@@ -425,7 +427,7 @@ const KritzelCursorTrail = class {
|
|
|
425
427
|
}
|
|
426
428
|
}
|
|
427
429
|
if (ev.pointerType === 'touch') {
|
|
428
|
-
if (this.store.state.pointers.size === 1) {
|
|
430
|
+
if (this.core.store.state.pointers.size === 1) {
|
|
429
431
|
this.isLeftButtonDown = true;
|
|
430
432
|
this.cursorTrailPoints = [];
|
|
431
433
|
}
|
|
@@ -452,14 +454,31 @@ const KritzelCursorTrail = class {
|
|
|
452
454
|
}
|
|
453
455
|
}
|
|
454
456
|
if (ev.pointerType === 'touch') {
|
|
455
|
-
if (this.store.state.pointers.size === 0) {
|
|
457
|
+
if (this.core.store.state.pointers.size === 0) {
|
|
456
458
|
this.isLeftButtonDown = false;
|
|
457
459
|
this.cursorTrailPoints = [];
|
|
458
460
|
}
|
|
459
461
|
}
|
|
460
462
|
}
|
|
463
|
+
trailCleanupIntervalId;
|
|
464
|
+
TRAIL_DURATION_MS = 100;
|
|
465
|
+
MAX_TRAIL_POINTS = 50;
|
|
466
|
+
componentDidLoad() {
|
|
467
|
+
this.trailCleanupIntervalId = window.setInterval(() => {
|
|
468
|
+
const now = Date.now();
|
|
469
|
+
const newTrailPoints = this.cursorTrailPoints.filter(p => now - p.timestamp < this.TRAIL_DURATION_MS);
|
|
470
|
+
if (newTrailPoints.length !== this.cursorTrailPoints.length) {
|
|
471
|
+
this.cursorTrailPoints = newTrailPoints;
|
|
472
|
+
}
|
|
473
|
+
}, 50);
|
|
474
|
+
}
|
|
475
|
+
disconnectedCallback() {
|
|
476
|
+
if (this.trailCleanupIntervalId) {
|
|
477
|
+
window.clearInterval(this.trailCleanupIntervalId);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
461
480
|
render() {
|
|
462
|
-
return (h(Host, { key: '
|
|
481
|
+
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: {
|
|
463
482
|
position: 'absolute',
|
|
464
483
|
left: '0',
|
|
465
484
|
top: '0',
|
|
@@ -490,7 +509,15 @@ const KritzelDropdown = class {
|
|
|
490
509
|
this.valueChanged = createEvent(this, "valueChanged");
|
|
491
510
|
}
|
|
492
511
|
options = [];
|
|
512
|
+
optionsChanged() {
|
|
513
|
+
this.updateInternalValue(this.internalValue, true);
|
|
514
|
+
}
|
|
493
515
|
value;
|
|
516
|
+
externalValueChanged(newValue) {
|
|
517
|
+
if (newValue !== this.internalValue) {
|
|
518
|
+
this.updateInternalValue(newValue, false);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
494
521
|
width;
|
|
495
522
|
selectStyles = {};
|
|
496
523
|
internalValue;
|
|
@@ -504,14 +531,6 @@ const KritzelDropdown = class {
|
|
|
504
531
|
this.evaluateSuffixContent();
|
|
505
532
|
this.evaluatePrefixContent();
|
|
506
533
|
}
|
|
507
|
-
externalValueChanged(newValue) {
|
|
508
|
-
if (newValue !== this.internalValue) {
|
|
509
|
-
this.updateInternalValue(newValue, false);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
optionsChanged() {
|
|
513
|
-
this.updateInternalValue(this.internalValue, true);
|
|
514
|
-
}
|
|
515
534
|
updateInternalValue(proposedValue, emitChange) {
|
|
516
535
|
let finalValue = proposedValue;
|
|
517
536
|
if (this.options && this.options.length > 0) {
|
|
@@ -569,11 +588,11 @@ const KritzelDropdown = class {
|
|
|
569
588
|
'has-suffix-border': this.hasSuffixContent,
|
|
570
589
|
'has-prefix-border': this.hasPrefixContent,
|
|
571
590
|
};
|
|
572
|
-
return (h(Host, { key: '
|
|
591
|
+
return (h(Host, { key: 'f24911715685ced571843ba7be6631248c8519b7' }, h("div", { key: '520fdb74afdef8bd5228f76074e51981f44b910d', class: "dropdown-wrapper" }, h("slot", { key: 'cf6628437946b57ad0b27c066639e0b64b5a28f8', name: "prefix", ref: el => (this.prefixSlotElement = el), onSlotchange: this.evaluatePrefixContent }), h("select", { key: '3203ccd5b9c8b84e8f41bddfcb07786e879f0035', class: selectClasses, style: { ...this.selectStyles, width: this.width }, onInput: this.handleSelectChange }, this.options.map(option => (h("option", { value: option.value, style: option.style, selected: option.value === this.internalValue }, option.label)))), h("slot", { key: 'd0abb52e082db81860c09d2c48b7c065adb406f3', name: "suffix", ref: el => (this.suffixSlotElement = el), onSlotchange: this.evaluateSuffixContent }))));
|
|
573
592
|
}
|
|
574
593
|
static get watchers() { return {
|
|
575
|
-
"
|
|
576
|
-
"
|
|
594
|
+
"options": ["optionsChanged"],
|
|
595
|
+
"value": ["externalValueChanged"]
|
|
577
596
|
}; }
|
|
578
597
|
};
|
|
579
598
|
KritzelDropdown.style = kritzelDropdownCss;
|
|
@@ -628,13 +647,14 @@ KritzelIconRegistry.registerIcons({
|
|
|
628
647
|
const ABSOLUTE_SCALE_MAX = 1000;
|
|
629
648
|
const ABSOLUTE_SCALE_MIN = 0.0001;
|
|
630
649
|
|
|
631
|
-
const kritzelEditorCss = "kritzel-editor{display:flex;margin:0;position:relative;overflow:hidden;width:100%;height:100%;align-items:center;justify-content:center;touch-action:manipulation;user-select:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}kritzel-workspace-manager{position:absolute;top:14px;left:14px}kritzel-
|
|
650
|
+
const kritzelEditorCss = "kritzel-editor{display:flex;margin:0;position:relative;overflow:hidden;width:100%;height:100%;align-items:center;justify-content:center;touch-action:manipulation;user-select:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}kritzel-workspace-manager{position:absolute;top:var(--kritzel-editor-workspace-manager-top, 14px);left:var(--kritzel-editor-workspace-manager-left, 14px)}kritzel-controls{position:absolute;bottom:var(--kritzel-editor-controls-bottom, 14px);transition:transform var(--kritzel-editor-controls-transition-duration, 0.1s) var(--kritzel-editor-controls-transition, ease-in-out)}kritzel-controls.keyboard-open{transform:var(--kritzel-editor-controls-transform, translateY(300%))}";
|
|
632
651
|
|
|
633
652
|
const KritzelEditor = class {
|
|
634
653
|
constructor(hostRef) {
|
|
635
654
|
registerInstance(this, hostRef);
|
|
636
655
|
this.isReady = createEvent(this, "isReady");
|
|
637
656
|
}
|
|
657
|
+
get host() { return getElement(this); }
|
|
638
658
|
scaleMax = ABSOLUTE_SCALE_MAX;
|
|
639
659
|
scaleMin = ABSOLUTE_SCALE_MIN;
|
|
640
660
|
controls = [
|
|
@@ -718,7 +738,6 @@ const KritzelEditor = class {
|
|
|
718
738
|
isControlsVisible = true;
|
|
719
739
|
isUtilityPanelVisible = true;
|
|
720
740
|
isReady;
|
|
721
|
-
get host() { return getElement(this); }
|
|
722
741
|
isEngineReady = false;
|
|
723
742
|
isControlsReady = false;
|
|
724
743
|
isWorkspaceManagerReady = false;
|
|
@@ -735,6 +754,11 @@ const KritzelEditor = class {
|
|
|
735
754
|
this.checkIsReady();
|
|
736
755
|
}
|
|
737
756
|
}
|
|
757
|
+
handleTouchStart(event) {
|
|
758
|
+
if (event.cancelable) {
|
|
759
|
+
event.preventDefault();
|
|
760
|
+
}
|
|
761
|
+
}
|
|
738
762
|
async getObjectById(id) {
|
|
739
763
|
return this.engineRef.getObjectById(id);
|
|
740
764
|
}
|
|
@@ -762,10 +786,21 @@ const KritzelEditor = class {
|
|
|
762
786
|
async centerObjectInViewport(object) {
|
|
763
787
|
return this.engineRef.centerObjectInViewport(object);
|
|
764
788
|
}
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
789
|
+
async createWorkspace(name, viewport) {
|
|
790
|
+
const workspace = new KritzelWorkspace(`workspace-${Date.now()}`, name, viewport);
|
|
791
|
+
return this.engineRef.createWorkspace(workspace);
|
|
792
|
+
}
|
|
793
|
+
async updateWorkspace(workspace) {
|
|
794
|
+
return this.engineRef.updateWorkspace(workspace);
|
|
795
|
+
}
|
|
796
|
+
async deleteWorkspace(workspace) {
|
|
797
|
+
return this.engineRef.deleteWorkspace(workspace);
|
|
798
|
+
}
|
|
799
|
+
async getWorkspaces() {
|
|
800
|
+
return this.engineRef.getWorkspaces();
|
|
801
|
+
}
|
|
802
|
+
async getActiveWorkspace() {
|
|
803
|
+
return this.engineRef.getActiveWorkspace();
|
|
769
804
|
}
|
|
770
805
|
engineRef;
|
|
771
806
|
controlsRef;
|
|
@@ -773,6 +808,7 @@ const KritzelEditor = class {
|
|
|
773
808
|
componentDidLoad() {
|
|
774
809
|
this.registerCustomSvgIcons();
|
|
775
810
|
this.listenForMobileKeyboard();
|
|
811
|
+
this.setOsSpecificCssVariables();
|
|
776
812
|
}
|
|
777
813
|
async checkIsReady() {
|
|
778
814
|
await customElements.whenDefined('kritzel-editor');
|
|
@@ -796,12 +832,37 @@ const KritzelEditor = class {
|
|
|
796
832
|
}
|
|
797
833
|
listenForMobileKeyboard() {
|
|
798
834
|
KritzelKeyboardHelper.onKeyboardVisibleChanged(isOpen => {
|
|
799
|
-
console.log('Mobile keyboard visibility changed:', isOpen);
|
|
800
835
|
this.isVirtualKeyboardOpen = isOpen;
|
|
801
836
|
});
|
|
802
837
|
}
|
|
838
|
+
setOsSpecificCssVariables() {
|
|
839
|
+
const os = KritzelDevicesHelper.detectOS();
|
|
840
|
+
switch (os) {
|
|
841
|
+
case 'iOS':
|
|
842
|
+
// iOS specific adjustments
|
|
843
|
+
this.host.style.setProperty('--kritzel-editor-workspace-manager-top', '14px');
|
|
844
|
+
this.host.style.setProperty('--kritzel-editor-workspace-manager-left', '14px');
|
|
845
|
+
this.host.style.setProperty('--kritzel-editor-controls-bottom', '14px');
|
|
846
|
+
this.host.style.setProperty('--kritzel-editor-controls-transition', 'cubic-bezier(0.25, 0.1, 0.25, 1.0)');
|
|
847
|
+
this.host.style.setProperty('--kritzel-editor-controls-transform', 'translateY(200%)');
|
|
848
|
+
this.host.style.setProperty('--kritzel-editor-controls-transition-duration', '0.25s');
|
|
849
|
+
break;
|
|
850
|
+
case 'Android':
|
|
851
|
+
// Android specific adjustments
|
|
852
|
+
this.host.style.setProperty('--kritzel-editor-workspace-manager-top', '14px');
|
|
853
|
+
this.host.style.setProperty('--kritzel-editor-workspace-manager-left', '14px');
|
|
854
|
+
this.host.style.setProperty('--kritzel-editor-controls-bottom', '24px');
|
|
855
|
+
break;
|
|
856
|
+
default:
|
|
857
|
+
// Default for Windows/Linux
|
|
858
|
+
this.host.style.setProperty('--kritzel-editor-workspace-manager-top', '14px');
|
|
859
|
+
this.host.style.setProperty('--kritzel-editor-workspace-manager-left', '14px');
|
|
860
|
+
this.host.style.setProperty('--kritzel-editor-controls-bottom', '14px');
|
|
861
|
+
break;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
803
864
|
render() {
|
|
804
|
-
return (h(Host, { key: '
|
|
865
|
+
return (h(Host, { key: '17c4e1ce489a5cd359972e67105019ad64703b19' }, h("kritzel-workspace-manager", { key: '963f62afe326d33eccdabda804bc3e260aafc306', workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-engine", { key: 'f60f67d06ce73f5f86716fc0ec68408c71100d82', ref: el => (this.engineRef = el), workspace: this.activeWorkspace, 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: '1dc25c1bbb50978cfac3cdaa2d3ae0a32ca7c4f7', 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) })));
|
|
805
866
|
}
|
|
806
867
|
static get watchers() { return {
|
|
807
868
|
"isEngineReady": ["onIsEngineReady"],
|
|
@@ -811,117 +872,119 @@ const KritzelEditor = class {
|
|
|
811
872
|
KritzelEditor.style = kritzelEditorCss;
|
|
812
873
|
|
|
813
874
|
class KritzelViewport {
|
|
814
|
-
|
|
875
|
+
_core;
|
|
815
876
|
initialTouchDistance = 0;
|
|
816
877
|
startX = 0;
|
|
817
878
|
startY = 0;
|
|
818
|
-
constructor(
|
|
819
|
-
this.
|
|
820
|
-
this.
|
|
821
|
-
this.
|
|
822
|
-
this.
|
|
823
|
-
this.
|
|
824
|
-
this.
|
|
825
|
-
this.
|
|
826
|
-
this.
|
|
879
|
+
constructor(core, host) {
|
|
880
|
+
this._core = core;
|
|
881
|
+
this._core.store.setState('host', host);
|
|
882
|
+
this._core.store.setState('viewportWidth', host.clientWidth);
|
|
883
|
+
this._core.store.setState('viewportHeight', host.clientHeight);
|
|
884
|
+
this._core.store.setState('startX', 0);
|
|
885
|
+
this._core.store.setState('startY', 0);
|
|
886
|
+
this._core.store.setState('translateX', 0);
|
|
887
|
+
this._core.store.setState('translateY', 0);
|
|
827
888
|
}
|
|
828
889
|
handleResize() {
|
|
829
|
-
this.
|
|
830
|
-
this.
|
|
831
|
-
this.
|
|
832
|
-
this.
|
|
890
|
+
this._core.store.setState('viewportWidth', this._core.store.state.host.clientWidth);
|
|
891
|
+
this._core.store.setState('viewportHeight', this._core.store.state.host.clientHeight);
|
|
892
|
+
this._core.store.setState('hasViewportChanged', true);
|
|
893
|
+
this._core.rerender();
|
|
833
894
|
}
|
|
834
895
|
handlePointerDown(event) {
|
|
835
896
|
if (event.pointerType === 'mouse') {
|
|
836
|
-
const adjustedClientX = event.clientX - this.
|
|
837
|
-
const adjustedClientY = event.clientY - this.
|
|
897
|
+
const adjustedClientX = event.clientX - this._core.store.offsetX;
|
|
898
|
+
const adjustedClientY = event.clientY - this._core.store.offsetY;
|
|
838
899
|
if (event.button === KritzelMouseButton.Right) {
|
|
839
|
-
this.
|
|
840
|
-
this.
|
|
841
|
-
this.
|
|
900
|
+
this._core.store.setState('isPanning', true);
|
|
901
|
+
this._core.store.setState('startX', adjustedClientX);
|
|
902
|
+
this._core.store.setState('startY', adjustedClientY);
|
|
842
903
|
}
|
|
843
904
|
}
|
|
844
905
|
if (event.pointerType === 'touch') {
|
|
845
|
-
const activePointers = Array.from(this.
|
|
906
|
+
const activePointers = Array.from(this._core.store.state.pointers.values());
|
|
846
907
|
if (activePointers.length === 2) {
|
|
847
|
-
this.
|
|
848
|
-
this.
|
|
849
|
-
const firstTouchX = activePointers[0].clientX - this.
|
|
850
|
-
const firstTouchY = activePointers[0].clientY - this.
|
|
851
|
-
const secondTouchX = activePointers[1].clientX - this.
|
|
852
|
-
const secondTouchY = activePointers[1].clientY - this.
|
|
908
|
+
this._core.store.setState('currentPath', null);
|
|
909
|
+
this._core.store.setState('isScaling', true);
|
|
910
|
+
const firstTouchX = activePointers[0].clientX - this._core.store.offsetX;
|
|
911
|
+
const firstTouchY = activePointers[0].clientY - this._core.store.offsetY;
|
|
912
|
+
const secondTouchX = activePointers[1].clientX - this._core.store.offsetX;
|
|
913
|
+
const secondTouchY = activePointers[1].clientY - this._core.store.offsetY;
|
|
853
914
|
this.initialTouchDistance = Math.sqrt(Math.pow(firstTouchX - secondTouchX, 2) + Math.pow(firstTouchY - secondTouchY, 2));
|
|
854
915
|
this.startX = (firstTouchX + secondTouchX) / 2;
|
|
855
916
|
this.startY = (firstTouchY + secondTouchY) / 2;
|
|
856
|
-
this.
|
|
917
|
+
this._core.rerender();
|
|
857
918
|
}
|
|
858
919
|
}
|
|
859
920
|
}
|
|
860
921
|
handlePointerMove(event) {
|
|
861
922
|
if (event.pointerType === 'mouse') {
|
|
862
|
-
const hostRect = this.
|
|
923
|
+
const hostRect = this._core.store.state.host.getBoundingClientRect();
|
|
863
924
|
const xRelativeToHost = event.clientX - hostRect.left;
|
|
864
925
|
const yRelativeToHost = event.clientY - hostRect.top;
|
|
865
|
-
this.
|
|
866
|
-
this.
|
|
867
|
-
if (this.
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
this.
|
|
871
|
-
this.
|
|
872
|
-
this.
|
|
873
|
-
this.
|
|
874
|
-
this.
|
|
875
|
-
this.
|
|
926
|
+
this._core.store.setState('pointerX', (xRelativeToHost - this._core.store.state.translateX) / this._core.store.state.scale);
|
|
927
|
+
this._core.store.setState('pointerY', (yRelativeToHost - this._core.store.state.translateY) / this._core.store.state.scale);
|
|
928
|
+
if (this._core.store.state.isPanning) {
|
|
929
|
+
const dx = xRelativeToHost - this._core.store.state.startX;
|
|
930
|
+
const dy = yRelativeToHost - this._core.store.state.startY;
|
|
931
|
+
this._core.store.setState('translateX', this._core.store.state.translateX + dx);
|
|
932
|
+
this._core.store.setState('translateY', this._core.store.state.translateY + dy);
|
|
933
|
+
this._core.store.setState('startX', xRelativeToHost);
|
|
934
|
+
this._core.store.setState('startY', yRelativeToHost);
|
|
935
|
+
this._core.store.setState('hasViewportChanged', true);
|
|
936
|
+
this._core.store.setState('skipContextMenu', true);
|
|
937
|
+
this._core.rerender();
|
|
938
|
+
this._core.updateWorkspaceViewport(this._core.store.state.translateX, this._core.store.state.translateY, this._core.store.state.scale);
|
|
876
939
|
}
|
|
877
940
|
}
|
|
878
941
|
if (event.pointerType === 'touch') {
|
|
879
|
-
const hostRect = this.
|
|
942
|
+
const hostRect = this._core.store.state.host.getBoundingClientRect();
|
|
880
943
|
const xRelativeToHost = event.clientX - hostRect.left;
|
|
881
944
|
const yRelativeToHost = event.clientY - hostRect.top;
|
|
882
|
-
this.
|
|
883
|
-
this.
|
|
884
|
-
const activePointers = Array.from(this.
|
|
945
|
+
this._core.store.setState('pointerX', (xRelativeToHost - this._core.store.state.translateX) / this._core.store.state.scale);
|
|
946
|
+
this._core.store.setState('pointerY', (yRelativeToHost - this._core.store.state.translateY) / this._core.store.state.scale);
|
|
947
|
+
const activePointers = Array.from(this._core.store.state.pointers.values());
|
|
885
948
|
if (activePointers.length === 2) {
|
|
886
|
-
const firstTouchX = activePointers[0].clientX - this.
|
|
887
|
-
const firstTouchY = activePointers[0].clientY - this.
|
|
888
|
-
const secondTouchX = activePointers[1].clientX - this.
|
|
889
|
-
const secondTouchY = activePointers[1].clientY - this.
|
|
949
|
+
const firstTouchX = activePointers[0].clientX - this._core.store.offsetX;
|
|
950
|
+
const firstTouchY = activePointers[0].clientY - this._core.store.offsetY;
|
|
951
|
+
const secondTouchX = activePointers[1].clientX - this._core.store.offsetX;
|
|
952
|
+
const secondTouchY = activePointers[1].clientY - this._core.store.offsetY;
|
|
890
953
|
const currentTouchDistance = Math.sqrt(Math.pow(firstTouchX - secondTouchX, 2) + Math.pow(firstTouchY - secondTouchY, 2));
|
|
891
954
|
const midpointX = (firstTouchX + secondTouchX) / 2;
|
|
892
955
|
const midpointY = (firstTouchY + secondTouchY) / 2;
|
|
893
956
|
const scaleRatio = currentTouchDistance / this.initialTouchDistance;
|
|
894
|
-
const newScale = this.
|
|
895
|
-
if (newScale > this.
|
|
896
|
-
this.
|
|
897
|
-
this.
|
|
957
|
+
const newScale = this._core.store.state.scale * scaleRatio;
|
|
958
|
+
if (newScale > this._core.store.state.scaleMax || newScale < this._core.store.state.scaleMin) {
|
|
959
|
+
this._core.store.setState('translateX', this._core.store.state.translateX + midpointX - this.startX);
|
|
960
|
+
this._core.store.setState('translateY', this._core.store.state.translateY + midpointY - this.startY);
|
|
898
961
|
}
|
|
899
962
|
else {
|
|
900
|
-
const translateXAdjustment = (midpointX - this.
|
|
901
|
-
const translateYAdjustment = (midpointY - this.
|
|
902
|
-
this.
|
|
903
|
-
this.
|
|
904
|
-
this.
|
|
963
|
+
const translateXAdjustment = (midpointX - this._core.store.state.translateX) * (scaleRatio - 1);
|
|
964
|
+
const translateYAdjustment = (midpointY - this._core.store.state.translateY) * (scaleRatio - 1);
|
|
965
|
+
this._core.store.setState('translateX', this._core.store.state.translateX + midpointX - this.startX - translateXAdjustment);
|
|
966
|
+
this._core.store.setState('translateY', this._core.store.state.translateY + midpointY - this.startY - translateYAdjustment);
|
|
967
|
+
this._core.store.setState('scale', newScale);
|
|
905
968
|
this.initialTouchDistance = currentTouchDistance;
|
|
906
969
|
}
|
|
907
970
|
this.startX = midpointX;
|
|
908
971
|
this.startY = midpointY;
|
|
909
|
-
this.
|
|
910
|
-
this.
|
|
911
|
-
this.
|
|
972
|
+
this._core.store.setState('hasViewportChanged', true);
|
|
973
|
+
this._core.rerender();
|
|
974
|
+
this._core.updateWorkspaceViewport(this._core.store.state.translateX, this._core.store.state.translateY, this._core.store.state.scale);
|
|
912
975
|
}
|
|
913
976
|
}
|
|
914
977
|
}
|
|
915
978
|
handlePointerUp(event) {
|
|
916
979
|
if (event.pointerType === 'mouse') {
|
|
917
|
-
if (this.
|
|
918
|
-
this.
|
|
919
|
-
this.
|
|
980
|
+
if (this._core.store.state.isPanning) {
|
|
981
|
+
this._core.store.setState('isPanning', false);
|
|
982
|
+
this._core.rerender();
|
|
920
983
|
}
|
|
921
984
|
}
|
|
922
985
|
if (event.pointerType === 'touch') {
|
|
923
|
-
this.
|
|
924
|
-
this.
|
|
986
|
+
this._core.store.setState('isScaling', false);
|
|
987
|
+
this._core.rerender();
|
|
925
988
|
}
|
|
926
989
|
}
|
|
927
990
|
handleWheel(event) {
|
|
@@ -934,188 +997,169 @@ class KritzelViewport {
|
|
|
934
997
|
}
|
|
935
998
|
}
|
|
936
999
|
handleZoom(event) {
|
|
937
|
-
|
|
1000
|
+
this._core.store.setState('isScaling', true);
|
|
1001
|
+
const rect = this._core.store.state.host.getBoundingClientRect();
|
|
938
1002
|
const xRelativeToHost = event.clientX - rect.left;
|
|
939
1003
|
const yRelativeToHost = event.clientY - rect.top;
|
|
940
|
-
this.
|
|
941
|
-
this.
|
|
942
|
-
const delta = event.deltaY > 0 ? -this.
|
|
943
|
-
const newScale = Math.min(this.
|
|
944
|
-
const scaleRatio = newScale / this.
|
|
945
|
-
const translateXAdjustment = (xRelativeToHost - this.
|
|
946
|
-
const translateYAdjustment = (yRelativeToHost - this.
|
|
947
|
-
this.
|
|
948
|
-
this.
|
|
949
|
-
this.
|
|
950
|
-
this.
|
|
951
|
-
this.
|
|
952
|
-
this.
|
|
1004
|
+
this._core.store.setState('pointerX', (xRelativeToHost - this._core.store.state.translateX) / this._core.store.state.scale);
|
|
1005
|
+
this._core.store.setState('pointerY', (yRelativeToHost - this._core.store.state.translateY) / this._core.store.state.scale);
|
|
1006
|
+
const delta = event.deltaY > 0 ? -this._core.store.state.scaleStep * this._core.store.state.scale : this._core.store.state.scaleStep * this._core.store.state.scale;
|
|
1007
|
+
const newScale = Math.min(this._core.store.state.scaleMax, Math.max(this._core.store.state.scaleMin, this._core.store.state.scale + delta));
|
|
1008
|
+
const scaleRatio = newScale / this._core.store.state.scale;
|
|
1009
|
+
const translateXAdjustment = (xRelativeToHost - this._core.store.state.translateX) * (scaleRatio - 1);
|
|
1010
|
+
const translateYAdjustment = (yRelativeToHost - this._core.store.state.translateY) * (scaleRatio - 1);
|
|
1011
|
+
this._core.store.setState('scale', newScale);
|
|
1012
|
+
this._core.store.setState('translateX', this._core.store.state.translateX - translateXAdjustment);
|
|
1013
|
+
this._core.store.setState('translateY', this._core.store.state.translateY - translateYAdjustment);
|
|
1014
|
+
this._core.store.setState('hasViewportChanged', true);
|
|
1015
|
+
this._core.rerender();
|
|
1016
|
+
this._core.updateWorkspaceViewport(this._core.store.state.translateX, this._core.store.state.translateY, this._core.store.state.scale);
|
|
1017
|
+
setTimeout(() => {
|
|
1018
|
+
this._core.store.setState('isScaling', false);
|
|
1019
|
+
this._core.rerender();
|
|
1020
|
+
}, 300);
|
|
953
1021
|
}
|
|
954
1022
|
handlePan(event) {
|
|
1023
|
+
this._core.store.setState('isPanning', true);
|
|
955
1024
|
const panSpeed = 0.8;
|
|
956
|
-
this.
|
|
957
|
-
this.
|
|
958
|
-
this.
|
|
959
|
-
this.
|
|
960
|
-
this.
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
currentViewport;
|
|
966
|
-
previousViewport;
|
|
967
|
-
constructor(store, initiator, previousViewport, skipHistory = false) {
|
|
968
|
-
super(store, initiator, skipHistory);
|
|
969
|
-
this.previousViewport = previousViewport;
|
|
970
|
-
this.currentViewport = {
|
|
971
|
-
scale: this._store.state.scale,
|
|
972
|
-
translateX: this._store.state.translateX,
|
|
973
|
-
translateY: this._store.state.translateY,
|
|
974
|
-
};
|
|
975
|
-
}
|
|
976
|
-
execute() {
|
|
977
|
-
this._store.state.scale = this.currentViewport.scale;
|
|
978
|
-
this._store.state.translateX = this.currentViewport.translateX;
|
|
979
|
-
this._store.state.translateY = this.currentViewport.translateY;
|
|
980
|
-
}
|
|
981
|
-
undo() {
|
|
982
|
-
this._store.state.scale = this.previousViewport.scale;
|
|
983
|
-
this._store.state.translateX = this.previousViewport.translateX;
|
|
984
|
-
this._store.state.translateY = this.previousViewport.translateY;
|
|
1025
|
+
this._core.store.setState('translateX', this._core.store.state.translateX - event.deltaX * panSpeed);
|
|
1026
|
+
this._core.store.setState('translateY', this._core.store.state.translateY - event.deltaY * panSpeed);
|
|
1027
|
+
this._core.store.setState('hasViewportChanged', true);
|
|
1028
|
+
this._core.rerender();
|
|
1029
|
+
this._core.updateWorkspaceViewport(this._core.store.state.translateX, this._core.store.state.translateY, this._core.store.state.scale);
|
|
1030
|
+
setTimeout(() => {
|
|
1031
|
+
this._core.store.setState('isPanning', false);
|
|
1032
|
+
this._core.rerender();
|
|
1033
|
+
}, 300);
|
|
985
1034
|
}
|
|
986
1035
|
}
|
|
987
1036
|
|
|
988
|
-
class
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
head = 0;
|
|
992
|
-
tail = 0;
|
|
993
|
-
size = 0;
|
|
994
|
-
constructor(capacity) {
|
|
995
|
-
this.capacity = capacity;
|
|
996
|
-
this.buffer = new Array(capacity).fill(null);
|
|
1037
|
+
class KritzelKeyHandler extends KritzelBaseHandler {
|
|
1038
|
+
constructor(core) {
|
|
1039
|
+
super(core);
|
|
997
1040
|
}
|
|
998
|
-
|
|
999
|
-
this.
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
this.size++;
|
|
1041
|
+
handleKeyDown(event) {
|
|
1042
|
+
this._core.store.setState('isCtrlKeyPressed', event.ctrlKey);
|
|
1043
|
+
if (this._core.store.state.isCtrlKeyPressed) {
|
|
1044
|
+
event.preventDefault();
|
|
1003
1045
|
}
|
|
1004
|
-
|
|
1005
|
-
this.
|
|
1046
|
+
if (event.key === 'Escape' && this._core.store.state.selectionGroup) {
|
|
1047
|
+
this._core.clearSelection();
|
|
1006
1048
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
if (this.size === 0) {
|
|
1010
|
-
return null;
|
|
1049
|
+
if (event.key === 'Delete' && this._core.store.state.selectionGroup) {
|
|
1050
|
+
this._core.delete();
|
|
1011
1051
|
}
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1052
|
+
if (event.key === 'z' && event.ctrlKey) {
|
|
1053
|
+
this._core.history.undo();
|
|
1054
|
+
}
|
|
1055
|
+
if (event.key === 'y' && event.ctrlKey) {
|
|
1056
|
+
this._core.history.redo();
|
|
1057
|
+
}
|
|
1058
|
+
if (event.key === 's' && event.ctrlKey) {
|
|
1059
|
+
this._core.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
1060
|
+
this._core.deselectAllObjects();
|
|
1061
|
+
}
|
|
1062
|
+
if (event.key === 'b' && event.ctrlKey) {
|
|
1063
|
+
this._core.store.setState('activeTool', KritzelToolRegistry.getTool('brush'));
|
|
1064
|
+
this._core.deselectAllObjects();
|
|
1065
|
+
}
|
|
1066
|
+
if (event.key === 'e' && event.ctrlKey) {
|
|
1067
|
+
this._core.store.setState('activeTool', KritzelToolRegistry.getTool('eraser'));
|
|
1068
|
+
this._core.deselectAllObjects();
|
|
1069
|
+
}
|
|
1070
|
+
if (event.key === 'i' && event.ctrlKey) {
|
|
1071
|
+
this._core.store.setState('activeTool', KritzelToolRegistry.getTool('image'));
|
|
1072
|
+
this._core.deselectAllObjects();
|
|
1073
|
+
}
|
|
1074
|
+
if (event.key === 'x' && event.ctrlKey) {
|
|
1075
|
+
this._core.store.setState('activeTool', KritzelToolRegistry.getTool('text'));
|
|
1076
|
+
this._core.deselectAllObjects();
|
|
1077
|
+
}
|
|
1078
|
+
if (event.key === 'c' && event.ctrlKey && this._core.store.state.selectionGroup) {
|
|
1079
|
+
this._core.copy();
|
|
1080
|
+
this._core.rerender();
|
|
1081
|
+
}
|
|
1082
|
+
if (event.key === 'v' && event.ctrlKey && this._core.store.state.copiedObjects) {
|
|
1083
|
+
this._core.paste();
|
|
1084
|
+
}
|
|
1085
|
+
if (event.key === '+' && event.ctrlKey && this._core.store.state.selectionGroup) {
|
|
1086
|
+
this._core.bringForward();
|
|
1087
|
+
}
|
|
1088
|
+
if (event.key === '-' && event.ctrlKey && this._core.store.state.selectionGroup) {
|
|
1089
|
+
this._core.sendBackward();
|
|
1090
|
+
}
|
|
1091
|
+
if (event.key === '*' && event.shiftKey && this._core.store.state.selectionGroup) {
|
|
1092
|
+
this._core.bringToFront();
|
|
1093
|
+
}
|
|
1094
|
+
if (event.key === '_' && event.shiftKey && this._core.store.state.selectionGroup) {
|
|
1095
|
+
this._core.sendToBack();
|
|
1096
|
+
}
|
|
1097
|
+
if (event.key === 'a' && event.ctrlKey && this._core.store.state.activeText) {
|
|
1098
|
+
this._core.store.state.activeText.selectAll();
|
|
1099
|
+
}
|
|
1100
|
+
if (event.key === 'v' && event.ctrlKey && this._core.store.state.activeText) {
|
|
1101
|
+
this._core.store.state.activeText.insertFromClipboard();
|
|
1021
1102
|
}
|
|
1022
|
-
const lastIndex = (this.head - 1 + this.capacity) % this.capacity;
|
|
1023
|
-
return this.buffer[lastIndex];
|
|
1024
|
-
}
|
|
1025
|
-
isEmpty() {
|
|
1026
|
-
return this.size === 0;
|
|
1027
1103
|
}
|
|
1028
|
-
|
|
1029
|
-
this.
|
|
1030
|
-
this.head = 0;
|
|
1031
|
-
this.tail = 0;
|
|
1032
|
-
this.size = 0;
|
|
1104
|
+
handleKeyUp(event) {
|
|
1105
|
+
this._core.store.setState('isCtrlKeyPressed', event.ctrlKey);
|
|
1033
1106
|
}
|
|
1034
1107
|
}
|
|
1035
1108
|
|
|
1036
|
-
class
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
this.
|
|
1043
|
-
this.undoStack = new KritzelCircularBuffer(this._store.state.historyBufferSize);
|
|
1044
|
-
this.redoStack = new KritzelCircularBuffer(this._store.state.historyBufferSize);
|
|
1045
|
-
this.previousViewport = {
|
|
1046
|
-
scale: this._store.state.scale,
|
|
1047
|
-
scaleStep: this._store.state.scaleStep,
|
|
1048
|
-
translateX: this._store.state.translateX,
|
|
1049
|
-
translateY: this._store.state.translateY,
|
|
1050
|
-
};
|
|
1051
|
-
}
|
|
1052
|
-
reset() {
|
|
1053
|
-
this.undoStack.clear();
|
|
1054
|
-
this.redoStack.clear();
|
|
1055
|
-
this.previousViewport = {
|
|
1056
|
-
scale: this._store.state.scale,
|
|
1057
|
-
scaleStep: this._store.state.scaleStep,
|
|
1058
|
-
translateX: this._store.state.translateX,
|
|
1059
|
-
translateY: this._store.state.translateY
|
|
1060
|
-
};
|
|
1109
|
+
class KritzelContextMenuHandler extends KritzelBaseHandler {
|
|
1110
|
+
globalContextMenuItems = [];
|
|
1111
|
+
objectContextMenuItems = [];
|
|
1112
|
+
constructor(core, globalContextMenuItems, objectContextMenuItems) {
|
|
1113
|
+
super(core);
|
|
1114
|
+
this.globalContextMenuItems = globalContextMenuItems;
|
|
1115
|
+
this.objectContextMenuItems = objectContextMenuItems;
|
|
1061
1116
|
}
|
|
1062
|
-
|
|
1063
|
-
if (this.
|
|
1064
|
-
|
|
1065
|
-
}
|
|
1066
|
-
command.execute();
|
|
1067
|
-
if (command.skipHistory === false) {
|
|
1068
|
-
if (this._store.state.debugInfo.logCommands) {
|
|
1069
|
-
console.info('add', command);
|
|
1070
|
-
}
|
|
1071
|
-
this.undoStack.add(command);
|
|
1072
|
-
if (this.redoStack.isEmpty() === false) {
|
|
1073
|
-
this.redoStack.clear();
|
|
1074
|
-
}
|
|
1117
|
+
handleContextMenu(event) {
|
|
1118
|
+
if (!(this._core.store.state.activeTool instanceof KritzelSelectionTool)) {
|
|
1119
|
+
return;
|
|
1075
1120
|
}
|
|
1076
|
-
this.
|
|
1077
|
-
|
|
1078
|
-
undo() {
|
|
1079
|
-
if (this._store.state.hasViewportChanged) {
|
|
1080
|
-
const command = new UpdateViewportCommand(this._store, this, this.previousViewport);
|
|
1081
|
-
command.undo();
|
|
1082
|
-
this._store.state.hasViewportChanged = false;
|
|
1083
|
-
this._store.rerender();
|
|
1121
|
+
if (this._core.store.state.skipContextMenu) {
|
|
1122
|
+
this._core.store.setState('skipContextMenu', false);
|
|
1084
1123
|
return;
|
|
1085
1124
|
}
|
|
1086
|
-
const
|
|
1087
|
-
if (
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1125
|
+
const selectedObject = this._core.getObjectFromPointerEvent(event, '.object');
|
|
1126
|
+
if (selectedObject && !(selectedObject instanceof KritzelSelectionGroup)) {
|
|
1127
|
+
const selectionGroup = KritzelSelectionGroup.create(this._core);
|
|
1128
|
+
selectionGroup.addOrRemove(selectedObject);
|
|
1129
|
+
selectionGroup.isSelected = true;
|
|
1130
|
+
selectionGroup.rotation = selectedObject.rotation;
|
|
1131
|
+
this._core.store.setState('isSelecting', false);
|
|
1132
|
+
const batch = new BatchCommand(this._core, this, [
|
|
1133
|
+
new RemoveSelectionGroupCommand(this._core, this._core.store.state.selectionGroup),
|
|
1134
|
+
new AddSelectionGroupCommand(this._core, this, selectionGroup),
|
|
1135
|
+
]);
|
|
1136
|
+
this._core.history.executeCommand(batch);
|
|
1137
|
+
}
|
|
1138
|
+
this._core.store.setState('contextMenuItems', this._core.store.state.selectionGroup ? this.objectContextMenuItems : this.globalContextMenuItems);
|
|
1139
|
+
let x = event.clientX - this._core.store.offsetX;
|
|
1140
|
+
let y = event.clientY - this._core.store.offsetY;
|
|
1141
|
+
const menuWidthEstimate = 150;
|
|
1142
|
+
const menuHeightEstimate = 200;
|
|
1143
|
+
const margin = 10;
|
|
1144
|
+
if (x + menuWidthEstimate > window.innerWidth - margin) {
|
|
1145
|
+
x = window.innerWidth - menuWidthEstimate - margin;
|
|
1092
1146
|
}
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
redo() {
|
|
1096
|
-
const command = this.redoStack.pop();
|
|
1097
|
-
if (command) {
|
|
1098
|
-
command.execute();
|
|
1099
|
-
if (this._store.state.debugInfo.logCommands)
|
|
1100
|
-
console.info('redo', command);
|
|
1101
|
-
this.undoStack.add(command);
|
|
1147
|
+
if (y + menuHeightEstimate > window.innerHeight - margin) {
|
|
1148
|
+
y = window.innerHeight - menuHeightEstimate - margin;
|
|
1102
1149
|
}
|
|
1103
|
-
|
|
1150
|
+
x = Math.max(margin, x);
|
|
1151
|
+
y = Math.max(margin, y);
|
|
1152
|
+
this._core.store.setState('contextMenuX', x);
|
|
1153
|
+
this._core.store.setState('contextMenuY', y);
|
|
1154
|
+
this._core.store.setState('isContextMenuVisible', true);
|
|
1155
|
+
this._core.store.setState('isEnabled', false);
|
|
1156
|
+
this._core.rerender();
|
|
1104
1157
|
}
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
this.redoStack.clear();
|
|
1111
|
-
}
|
|
1112
|
-
this._store.state.hasViewportChanged = false;
|
|
1113
|
-
this.previousViewport = {
|
|
1114
|
-
scale: this._store.state.scale,
|
|
1115
|
-
scaleStep: this._store.state.scaleStep,
|
|
1116
|
-
translateX: this._store.state.translateX,
|
|
1117
|
-
translateY: this._store.state.translateY,
|
|
1118
|
-
};
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
class KritzelClassHelper {
|
|
1161
|
+
static isInstanceOf(object, className) {
|
|
1162
|
+
return !!object && object.__class__ === className;
|
|
1119
1163
|
}
|
|
1120
1164
|
}
|
|
1121
1165
|
|
|
@@ -1134,7 +1178,6 @@ const DEFAULT_ENGINE_STATE = {
|
|
|
1134
1178
|
isEnabled: true,
|
|
1135
1179
|
isScaling: false,
|
|
1136
1180
|
isPanning: false,
|
|
1137
|
-
isFocused: false,
|
|
1138
1181
|
isSelecting: false,
|
|
1139
1182
|
isResizing: false,
|
|
1140
1183
|
isResizeHandleSelected: false,
|
|
@@ -1197,7 +1240,7 @@ class KritzelDatabase {
|
|
|
1197
1240
|
return;
|
|
1198
1241
|
}
|
|
1199
1242
|
if (this.isLoggingEnabled) {
|
|
1200
|
-
console.
|
|
1243
|
+
console.info(`[IndexedDB] Opening database: ${this.dbName}, version: ${this.dbVersion}`);
|
|
1201
1244
|
}
|
|
1202
1245
|
const request = indexedDB.open(this.dbName, this.dbVersion);
|
|
1203
1246
|
request.onerror = () => {
|
|
@@ -1207,25 +1250,25 @@ class KritzelDatabase {
|
|
|
1207
1250
|
request.onsuccess = () => {
|
|
1208
1251
|
this.db = request.result;
|
|
1209
1252
|
if (this.isLoggingEnabled) {
|
|
1210
|
-
console.
|
|
1253
|
+
console.info(`[IndexedDB] Database opened successfully.`);
|
|
1211
1254
|
}
|
|
1212
1255
|
resolve();
|
|
1213
1256
|
};
|
|
1214
1257
|
request.onupgradeneeded = event => {
|
|
1215
1258
|
if (this.isLoggingEnabled) {
|
|
1216
|
-
console.
|
|
1259
|
+
console.info(`[IndexedDB] Upgrade needed for database: ${this.dbName}`);
|
|
1217
1260
|
}
|
|
1218
1261
|
const db = event.target.result;
|
|
1219
1262
|
stores.forEach(storeConfig => {
|
|
1220
1263
|
if (!db.objectStoreNames.contains(storeConfig.name)) {
|
|
1221
1264
|
if (this.isLoggingEnabled) {
|
|
1222
|
-
console.
|
|
1265
|
+
console.info(`[IndexedDB] Creating store: ${storeConfig.name}`);
|
|
1223
1266
|
}
|
|
1224
1267
|
const store = db.createObjectStore(storeConfig.name, storeConfig.options);
|
|
1225
1268
|
if (storeConfig.indices) {
|
|
1226
1269
|
storeConfig.indices.forEach(index => {
|
|
1227
1270
|
if (this.isLoggingEnabled) {
|
|
1228
|
-
console.
|
|
1271
|
+
console.info(`[IndexedDB] Creating index: ${index.name} on store: ${storeConfig.name}`);
|
|
1229
1272
|
}
|
|
1230
1273
|
store.createIndex(index.name, index.keyPath, index.options);
|
|
1231
1274
|
});
|
|
@@ -1238,7 +1281,7 @@ class KritzelDatabase {
|
|
|
1238
1281
|
close() {
|
|
1239
1282
|
if (this.db) {
|
|
1240
1283
|
if (this.isLoggingEnabled) {
|
|
1241
|
-
console.
|
|
1284
|
+
console.info(`[IndexedDB] Closing database: ${this.dbName}`);
|
|
1242
1285
|
}
|
|
1243
1286
|
this.db.close();
|
|
1244
1287
|
this.db = null;
|
|
@@ -1246,43 +1289,51 @@ class KritzelDatabase {
|
|
|
1246
1289
|
}
|
|
1247
1290
|
async add(storeName, item) {
|
|
1248
1291
|
if (this.isLoggingEnabled) {
|
|
1249
|
-
console.
|
|
1292
|
+
console.info('[IndexedDB] Add:', { storeName, item });
|
|
1293
|
+
}
|
|
1294
|
+
if (item.serialize === undefined) {
|
|
1295
|
+
throw new Error('Item does not implement KritzelSerializable interface.');
|
|
1250
1296
|
}
|
|
1251
|
-
|
|
1297
|
+
const serializedItem = item.serialize();
|
|
1298
|
+
return this.executeTransaction(storeName, 'readwrite', store => store.add(serializedItem));
|
|
1252
1299
|
}
|
|
1253
1300
|
async get(storeName, key) {
|
|
1254
1301
|
if (this.isLoggingEnabled) {
|
|
1255
|
-
console.
|
|
1302
|
+
console.info('[IndexedDB] Get:', { storeName, key });
|
|
1256
1303
|
}
|
|
1257
1304
|
return this.executeTransaction(storeName, 'readonly', store => store.get(key));
|
|
1258
1305
|
}
|
|
1259
1306
|
async getAll(storeName) {
|
|
1260
1307
|
if (this.isLoggingEnabled) {
|
|
1261
|
-
console.
|
|
1308
|
+
console.info('[IndexedDB] GetAll:', { storeName });
|
|
1262
1309
|
}
|
|
1263
1310
|
return this.executeTransaction(storeName, 'readonly', store => store.getAll());
|
|
1264
1311
|
}
|
|
1265
1312
|
async update(storeName, item) {
|
|
1266
1313
|
if (this.isLoggingEnabled) {
|
|
1267
|
-
console.
|
|
1314
|
+
console.info('[IndexedDB] Update:', { storeName, item });
|
|
1268
1315
|
}
|
|
1269
|
-
|
|
1316
|
+
if (item.serialize === undefined) {
|
|
1317
|
+
throw new Error('Item does not implement KritzelSerializable interface.');
|
|
1318
|
+
}
|
|
1319
|
+
const serializedItem = item.serialize();
|
|
1320
|
+
return this.executeTransaction(storeName, 'readwrite', store => store.put(serializedItem));
|
|
1270
1321
|
}
|
|
1271
1322
|
async delete(storeName, key) {
|
|
1272
1323
|
if (this.isLoggingEnabled) {
|
|
1273
|
-
console.
|
|
1324
|
+
console.info('[IndexedDB] Delete:', { storeName, key });
|
|
1274
1325
|
}
|
|
1275
1326
|
return this.executeTransaction(storeName, 'readwrite', store => store.delete(key));
|
|
1276
1327
|
}
|
|
1277
1328
|
async deleteByRange(storeName, range) {
|
|
1278
1329
|
if (this.isLoggingEnabled) {
|
|
1279
|
-
console.
|
|
1330
|
+
console.info('[IndexedDB] DeleteByRange:', { storeName, range });
|
|
1280
1331
|
}
|
|
1281
1332
|
return this.executeTransaction(storeName, 'readwrite', store => store.delete(range));
|
|
1282
1333
|
}
|
|
1283
1334
|
async getAllByRange(storeName, range) {
|
|
1284
1335
|
if (this.isLoggingEnabled) {
|
|
1285
|
-
console.
|
|
1336
|
+
console.info('[IndexedDB] GetAllByRange:', { storeName, range });
|
|
1286
1337
|
}
|
|
1287
1338
|
return this.executeTransaction(storeName, 'readonly', store => {
|
|
1288
1339
|
return store.getAll(range);
|
|
@@ -1290,7 +1341,7 @@ class KritzelDatabase {
|
|
|
1290
1341
|
}
|
|
1291
1342
|
async getAllByIndex(storeName, indexName, query) {
|
|
1292
1343
|
if (this.isLoggingEnabled) {
|
|
1293
|
-
console.
|
|
1344
|
+
console.info('[IndexedDB] GetAllByIndex:', { storeName, indexName, query });
|
|
1294
1345
|
}
|
|
1295
1346
|
return this.executeTransaction(storeName, 'readonly', store => {
|
|
1296
1347
|
const index = store.index(indexName);
|
|
@@ -1326,7 +1377,7 @@ class KritzelDatabase {
|
|
|
1326
1377
|
}
|
|
1327
1378
|
const storeNames = await this.extractStoreNamesFromActions(actions);
|
|
1328
1379
|
if (this.isLoggingEnabled) {
|
|
1329
|
-
console.
|
|
1380
|
+
console.info('[IndexedDB] Starting batch transaction:', { storeNames });
|
|
1330
1381
|
}
|
|
1331
1382
|
return new Promise((resolve, reject) => {
|
|
1332
1383
|
const transaction = this.db.transaction(storeNames, 'readwrite');
|
|
@@ -1344,13 +1395,13 @@ class KritzelDatabase {
|
|
|
1344
1395
|
executeTransaction: (storeName, mode, action) => {
|
|
1345
1396
|
return new Promise((resolveRequest, rejectRequest) => {
|
|
1346
1397
|
if (this.isLoggingEnabled) {
|
|
1347
|
-
console.
|
|
1398
|
+
console.info('[IndexedDB] Executing batch action:', { storeName, mode });
|
|
1348
1399
|
}
|
|
1349
1400
|
const store = transaction.objectStore(storeName);
|
|
1350
1401
|
const request = action(store);
|
|
1351
1402
|
request.onsuccess = () => {
|
|
1352
1403
|
if (this.isLoggingEnabled) {
|
|
1353
|
-
console.
|
|
1404
|
+
console.info('[IndexedDB] Batch action request successful:', { result: request.result });
|
|
1354
1405
|
}
|
|
1355
1406
|
resolveRequest(request.result);
|
|
1356
1407
|
};
|
|
@@ -1363,7 +1414,7 @@ class KritzelDatabase {
|
|
|
1363
1414
|
};
|
|
1364
1415
|
transaction.oncomplete = () => {
|
|
1365
1416
|
if (this.isLoggingEnabled) {
|
|
1366
|
-
console.
|
|
1417
|
+
console.info('[IndexedDB] Batch transaction complete.');
|
|
1367
1418
|
}
|
|
1368
1419
|
Promise.all(promises).then(() => resolve(results));
|
|
1369
1420
|
};
|
|
@@ -1408,6 +1459,164 @@ class KritzelDatabase {
|
|
|
1408
1459
|
}
|
|
1409
1460
|
}
|
|
1410
1461
|
|
|
1462
|
+
class UpdateViewportCommand extends KritzelBaseCommand {
|
|
1463
|
+
currentViewport;
|
|
1464
|
+
previousViewport;
|
|
1465
|
+
constructor(core, initiator, previousViewport, skipHistory = false) {
|
|
1466
|
+
super(core, initiator, skipHistory);
|
|
1467
|
+
this.previousViewport = previousViewport;
|
|
1468
|
+
this.currentViewport = {
|
|
1469
|
+
scale: this._core.store.state.scale,
|
|
1470
|
+
translateX: this._core.store.state.translateX,
|
|
1471
|
+
translateY: this._core.store.state.translateY,
|
|
1472
|
+
};
|
|
1473
|
+
}
|
|
1474
|
+
execute() {
|
|
1475
|
+
this._core.store.setState('scale', this.currentViewport.scale);
|
|
1476
|
+
this._core.store.setState('translateX', this.currentViewport.translateX);
|
|
1477
|
+
this._core.store.setState('translateY', this.currentViewport.translateY);
|
|
1478
|
+
}
|
|
1479
|
+
undo() {
|
|
1480
|
+
this._core.store.setState('scale', this.previousViewport.scale);
|
|
1481
|
+
this._core.store.setState('translateX', this.previousViewport.translateX);
|
|
1482
|
+
this._core.store.setState('translateY', this.previousViewport.translateY);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
class KritzelCircularBuffer {
|
|
1487
|
+
buffer;
|
|
1488
|
+
capacity;
|
|
1489
|
+
head = 0;
|
|
1490
|
+
tail = 0;
|
|
1491
|
+
size = 0;
|
|
1492
|
+
constructor(capacity) {
|
|
1493
|
+
this.capacity = capacity;
|
|
1494
|
+
this.buffer = new Array(capacity).fill(null);
|
|
1495
|
+
}
|
|
1496
|
+
add(item) {
|
|
1497
|
+
this.buffer[this.head] = item;
|
|
1498
|
+
this.head = (this.head + 1) % this.capacity;
|
|
1499
|
+
if (this.size < this.capacity) {
|
|
1500
|
+
this.size++;
|
|
1501
|
+
}
|
|
1502
|
+
else {
|
|
1503
|
+
this.tail = (this.tail + 1) % this.capacity;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
pop() {
|
|
1507
|
+
if (this.size === 0) {
|
|
1508
|
+
return null;
|
|
1509
|
+
}
|
|
1510
|
+
this.head = (this.head - 1 + this.capacity) % this.capacity;
|
|
1511
|
+
const item = this.buffer[this.head];
|
|
1512
|
+
this.buffer[this.head] = null;
|
|
1513
|
+
this.size--;
|
|
1514
|
+
return item;
|
|
1515
|
+
}
|
|
1516
|
+
peek() {
|
|
1517
|
+
if (this.size === 0) {
|
|
1518
|
+
return null;
|
|
1519
|
+
}
|
|
1520
|
+
const lastIndex = (this.head - 1 + this.capacity) % this.capacity;
|
|
1521
|
+
return this.buffer[lastIndex];
|
|
1522
|
+
}
|
|
1523
|
+
isEmpty() {
|
|
1524
|
+
return this.size === 0;
|
|
1525
|
+
}
|
|
1526
|
+
clear() {
|
|
1527
|
+
this.buffer.fill(null);
|
|
1528
|
+
this.head = 0;
|
|
1529
|
+
this.tail = 0;
|
|
1530
|
+
this.size = 0;
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
class KritzelHistory {
|
|
1535
|
+
_core;
|
|
1536
|
+
undoStack;
|
|
1537
|
+
redoStack;
|
|
1538
|
+
previousViewport;
|
|
1539
|
+
constructor(core) {
|
|
1540
|
+
this._core = core;
|
|
1541
|
+
this.undoStack = new KritzelCircularBuffer(this._core.store.state.historyBufferSize);
|
|
1542
|
+
this.redoStack = new KritzelCircularBuffer(this._core.store.state.historyBufferSize);
|
|
1543
|
+
this.previousViewport = {
|
|
1544
|
+
scale: this._core.store.state.scale,
|
|
1545
|
+
scaleStep: this._core.store.state.scaleStep,
|
|
1546
|
+
translateX: this._core.store.state.translateX,
|
|
1547
|
+
translateY: this._core.store.state.translateY,
|
|
1548
|
+
};
|
|
1549
|
+
}
|
|
1550
|
+
reset() {
|
|
1551
|
+
this.undoStack.clear();
|
|
1552
|
+
this.redoStack.clear();
|
|
1553
|
+
this.previousViewport = {
|
|
1554
|
+
scale: this._core.store.state.scale,
|
|
1555
|
+
scaleStep: this._core.store.state.scaleStep,
|
|
1556
|
+
translateX: this._core.store.state.translateX,
|
|
1557
|
+
translateY: this._core.store.state.translateY
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
executeCommand(command) {
|
|
1561
|
+
if (this._core.store.state.hasViewportChanged) {
|
|
1562
|
+
this.addUpdateViewportCommand();
|
|
1563
|
+
}
|
|
1564
|
+
command.execute();
|
|
1565
|
+
if (command.skipHistory === false) {
|
|
1566
|
+
if (this._core.store.state.debugInfo.logCommands) {
|
|
1567
|
+
console.info('add', command);
|
|
1568
|
+
}
|
|
1569
|
+
this.undoStack.add(command);
|
|
1570
|
+
if (this.redoStack.isEmpty() === false) {
|
|
1571
|
+
this.redoStack.clear();
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
this._core.rerender();
|
|
1575
|
+
}
|
|
1576
|
+
undo() {
|
|
1577
|
+
if (this._core.store.state.hasViewportChanged) {
|
|
1578
|
+
const command = new UpdateViewportCommand(this._core, this, this.previousViewport);
|
|
1579
|
+
command.undo();
|
|
1580
|
+
this._core.store.setState('hasViewportChanged', false);
|
|
1581
|
+
this._core.rerender();
|
|
1582
|
+
return;
|
|
1583
|
+
}
|
|
1584
|
+
const command = this.undoStack.pop();
|
|
1585
|
+
if (command) {
|
|
1586
|
+
command.undo();
|
|
1587
|
+
if (this._core.store.state.debugInfo.logCommands)
|
|
1588
|
+
console.info('undo', command);
|
|
1589
|
+
this.redoStack.add(command);
|
|
1590
|
+
}
|
|
1591
|
+
this._core.rerender();
|
|
1592
|
+
}
|
|
1593
|
+
redo() {
|
|
1594
|
+
const command = this.redoStack.pop();
|
|
1595
|
+
if (command) {
|
|
1596
|
+
command.execute();
|
|
1597
|
+
if (this._core.store.state.debugInfo.logCommands)
|
|
1598
|
+
console.info('redo', command);
|
|
1599
|
+
this.undoStack.add(command);
|
|
1600
|
+
}
|
|
1601
|
+
this._core.rerender();
|
|
1602
|
+
}
|
|
1603
|
+
addUpdateViewportCommand() {
|
|
1604
|
+
const command = new UpdateViewportCommand(this._core, this, this.previousViewport);
|
|
1605
|
+
command.execute();
|
|
1606
|
+
this.undoStack.add(command);
|
|
1607
|
+
if (this.redoStack.isEmpty() === false) {
|
|
1608
|
+
this.redoStack.clear();
|
|
1609
|
+
}
|
|
1610
|
+
this._core.store.setState('hasViewportChanged', false);
|
|
1611
|
+
this.previousViewport = {
|
|
1612
|
+
scale: this._core.store.state.scale,
|
|
1613
|
+
scaleStep: this._core.store.state.scaleStep,
|
|
1614
|
+
translateX: this._core.store.state.translateX,
|
|
1615
|
+
translateY: this._core.store.state.translateY,
|
|
1616
|
+
};
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1411
1620
|
class KritzelObjectMap {
|
|
1412
1621
|
map;
|
|
1413
1622
|
constructor() {
|
|
@@ -1452,18 +1661,8 @@ class KritzelObjectMap {
|
|
|
1452
1661
|
}
|
|
1453
1662
|
|
|
1454
1663
|
class KritzelStore {
|
|
1455
|
-
_kritzelEngine;
|
|
1456
1664
|
_state;
|
|
1457
|
-
_history;
|
|
1458
|
-
_database;
|
|
1459
1665
|
_listeners = new Map();
|
|
1460
|
-
objects = [];
|
|
1461
|
-
get history() {
|
|
1462
|
-
return this._history;
|
|
1463
|
-
}
|
|
1464
|
-
get database() {
|
|
1465
|
-
return this._database;
|
|
1466
|
-
}
|
|
1467
1666
|
get state() {
|
|
1468
1667
|
return this._state;
|
|
1469
1668
|
}
|
|
@@ -1479,18 +1678,58 @@ class KritzelStore {
|
|
|
1479
1678
|
get offsetX() {
|
|
1480
1679
|
return this._state.host.getBoundingClientRect().left;
|
|
1481
1680
|
}
|
|
1482
|
-
get offsetY() {
|
|
1483
|
-
return this._state.host.getBoundingClientRect().top;
|
|
1681
|
+
get offsetY() {
|
|
1682
|
+
return this._state.host.getBoundingClientRect().top;
|
|
1683
|
+
}
|
|
1684
|
+
get isDisabled() {
|
|
1685
|
+
return this._state.isEnabled === false || this._state.isReady === false || this._state.activeWorkspace === null;
|
|
1686
|
+
}
|
|
1687
|
+
constructor(state) {
|
|
1688
|
+
this._state = state;
|
|
1689
|
+
this._state.objectsMap = new KritzelObjectMap();
|
|
1690
|
+
}
|
|
1691
|
+
onStateChange(property, listener) {
|
|
1692
|
+
if (!this._listeners.has(property)) {
|
|
1693
|
+
this._listeners.set(property, new Set());
|
|
1694
|
+
}
|
|
1695
|
+
this._listeners.get(property).add(listener);
|
|
1696
|
+
}
|
|
1697
|
+
getState(property) {
|
|
1698
|
+
return this._state[property];
|
|
1699
|
+
}
|
|
1700
|
+
setState(property, value) {
|
|
1701
|
+
const oldValue = this._state[property];
|
|
1702
|
+
if (oldValue !== value) {
|
|
1703
|
+
this._state[property] = value;
|
|
1704
|
+
if (this._listeners.has(property)) {
|
|
1705
|
+
this._listeners.get(property).forEach(listener => listener(value, oldValue, String(property)));
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
class KritzelCore {
|
|
1712
|
+
_kritzelEngine;
|
|
1713
|
+
_store;
|
|
1714
|
+
_history;
|
|
1715
|
+
_database;
|
|
1716
|
+
get engine() {
|
|
1717
|
+
return this._kritzelEngine;
|
|
1718
|
+
}
|
|
1719
|
+
get history() {
|
|
1720
|
+
return this._history;
|
|
1721
|
+
}
|
|
1722
|
+
get database() {
|
|
1723
|
+
return this._database;
|
|
1484
1724
|
}
|
|
1485
|
-
get
|
|
1486
|
-
return this.
|
|
1725
|
+
get store() {
|
|
1726
|
+
return this._store;
|
|
1487
1727
|
}
|
|
1488
1728
|
constructor(kritzelEngine) {
|
|
1489
|
-
this._state = DEFAULT_ENGINE_STATE;
|
|
1490
1729
|
this._kritzelEngine = kritzelEngine;
|
|
1730
|
+
this._store = new KritzelStore(DEFAULT_ENGINE_STATE);
|
|
1491
1731
|
this._history = new KritzelHistory(this);
|
|
1492
|
-
this._database = new KritzelDatabase('kritzelDB', 1, this.
|
|
1493
|
-
this._state.objectsMap = new KritzelObjectMap();
|
|
1732
|
+
this._database = new KritzelDatabase('kritzelDB', 1, this._store.state.debugInfo.logDatabase);
|
|
1494
1733
|
}
|
|
1495
1734
|
async initializeDatabase() {
|
|
1496
1735
|
await this._database.open([
|
|
@@ -1506,52 +1745,50 @@ class KritzelStore {
|
|
|
1506
1745
|
const workspaces = await this.getWorkspaces();
|
|
1507
1746
|
const mostRecentWorkspace = [...workspaces].sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())[0];
|
|
1508
1747
|
const fallbackWorkspace = new KritzelWorkspace(ObjectHelper.generateUUID(), 'New Workspace');
|
|
1509
|
-
this.
|
|
1510
|
-
const isExistingWorkspace = await this.getWorkspace(this.
|
|
1748
|
+
this._store.setState('activeWorkspace', workspace ?? mostRecentWorkspace ?? fallbackWorkspace);
|
|
1749
|
+
const isExistingWorkspace = await this.getWorkspace(this._store.state.activeWorkspace.id);
|
|
1511
1750
|
if (isExistingWorkspace) {
|
|
1512
|
-
await this.updateWorkspace(this.
|
|
1751
|
+
await this.updateWorkspace(this._store.state.activeWorkspace);
|
|
1513
1752
|
}
|
|
1514
1753
|
else {
|
|
1515
|
-
await this.createWorkspace(this.
|
|
1754
|
+
await this.createWorkspace(this._store.state.activeWorkspace);
|
|
1516
1755
|
}
|
|
1517
|
-
this.
|
|
1518
|
-
this.
|
|
1519
|
-
this.
|
|
1520
|
-
this.
|
|
1521
|
-
await this.initializeWorkspaceObjects(this.
|
|
1756
|
+
this._store.setState('workspaces', await this.getWorkspaces());
|
|
1757
|
+
this._store.setState('translateX', this._store.state.activeWorkspace.viewport.translateX);
|
|
1758
|
+
this._store.setState('translateY', this._store.state.activeWorkspace.viewport.translateY);
|
|
1759
|
+
this._store.setState('scale', this._store.state.activeWorkspace.viewport.scale);
|
|
1760
|
+
await this.initializeWorkspaceObjects(this._store.state.activeWorkspace.id);
|
|
1522
1761
|
}
|
|
1523
1762
|
async initializeWorkspaceObjects(workspaceId) {
|
|
1524
|
-
this.
|
|
1763
|
+
this._store.state.objectsMap.reset();
|
|
1525
1764
|
this._history.reset();
|
|
1526
1765
|
const objectsFromDb = await this._database.getAllByRange('objects', IDBKeyRange.bound([workspaceId], [workspaceId, '\uffff']));
|
|
1527
1766
|
const reviver = new KritzelReviver(this);
|
|
1528
1767
|
objectsFromDb.forEach(element => {
|
|
1529
1768
|
const revivedObject = reviver.revive(element);
|
|
1530
|
-
this.
|
|
1769
|
+
this._store.state.objectsMap.insert(revivedObject);
|
|
1531
1770
|
});
|
|
1532
1771
|
this.rerender();
|
|
1533
1772
|
}
|
|
1534
1773
|
async updateWorkspaceViewport(translateX, translateY, scale) {
|
|
1535
|
-
|
|
1774
|
+
const activeWorkspace = this._store.state.activeWorkspace;
|
|
1775
|
+
if (!activeWorkspace) {
|
|
1536
1776
|
throw new Error('Workspace not initialized');
|
|
1537
1777
|
}
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
scale,
|
|
1542
|
-
};
|
|
1543
|
-
this.state.activeWorkspace.updatedAt = new Date();
|
|
1544
|
-
await this._database.update('workspaces', this.state.activeWorkspace);
|
|
1778
|
+
activeWorkspace.viewport = { translateX, translateY, scale };
|
|
1779
|
+
activeWorkspace.updatedAt = new Date();
|
|
1780
|
+
await this._database.update('workspaces', activeWorkspace);
|
|
1545
1781
|
}
|
|
1546
1782
|
async addObjectToDatabase(object) {
|
|
1547
1783
|
if (!this._database) {
|
|
1548
1784
|
throw new Error('Database not initialized');
|
|
1549
1785
|
}
|
|
1550
|
-
|
|
1786
|
+
const activeWorkspace = this._store.state.activeWorkspace;
|
|
1787
|
+
if (!activeWorkspace) {
|
|
1551
1788
|
throw new Error('Workspace not initialized');
|
|
1552
1789
|
}
|
|
1553
|
-
|
|
1554
|
-
await this._database.batch([db => db.add('objects', object), db => db.update('workspaces',
|
|
1790
|
+
activeWorkspace.updatedAt = new Date();
|
|
1791
|
+
await this._database.batch([db => db.add('objects', object), db => db.update('workspaces', activeWorkspace)]).catch(err => {
|
|
1555
1792
|
console.error('Error adding object to database:', err);
|
|
1556
1793
|
});
|
|
1557
1794
|
}
|
|
@@ -1559,11 +1796,12 @@ class KritzelStore {
|
|
|
1559
1796
|
if (!this._database) {
|
|
1560
1797
|
throw new Error('Database not initialized');
|
|
1561
1798
|
}
|
|
1562
|
-
|
|
1799
|
+
const activeWorkspace = this._store.state.activeWorkspace;
|
|
1800
|
+
if (!activeWorkspace) {
|
|
1563
1801
|
throw new Error('Workspace not initialized');
|
|
1564
1802
|
}
|
|
1565
|
-
|
|
1566
|
-
await this._database.batch([db => db.update('objects', object), db => db.update('workspaces',
|
|
1803
|
+
activeWorkspace.updatedAt = new Date();
|
|
1804
|
+
await this._database.batch([db => db.update('objects', object), db => db.update('workspaces', activeWorkspace)]).catch(err => {
|
|
1567
1805
|
console.error('Error updating object in database:', err);
|
|
1568
1806
|
});
|
|
1569
1807
|
}
|
|
@@ -1571,25 +1809,28 @@ class KritzelStore {
|
|
|
1571
1809
|
if (!this._database) {
|
|
1572
1810
|
throw new Error('Database not initialized');
|
|
1573
1811
|
}
|
|
1574
|
-
|
|
1812
|
+
const activeWorkspace = this._store.state.activeWorkspace;
|
|
1813
|
+
if (!activeWorkspace) {
|
|
1575
1814
|
throw new Error('Workspace not initialized');
|
|
1576
1815
|
}
|
|
1577
|
-
|
|
1578
|
-
await this._database.batch([db => db.delete('objects', [
|
|
1816
|
+
activeWorkspace.updatedAt = new Date();
|
|
1817
|
+
await this._database.batch([db => db.delete('objects', [activeWorkspace.id, objectId]), db => db.update('workspaces', activeWorkspace)]).catch(err => {
|
|
1579
1818
|
console.error('Error deleting object from database:', err);
|
|
1580
1819
|
});
|
|
1581
1820
|
}
|
|
1582
|
-
getWorkspace(id) {
|
|
1821
|
+
async getWorkspace(id) {
|
|
1583
1822
|
if (!this._database) {
|
|
1584
1823
|
throw new Error('Database not initialized');
|
|
1585
1824
|
}
|
|
1586
|
-
|
|
1825
|
+
const reviver = new KritzelReviver(this);
|
|
1826
|
+
return this._database.get('workspaces', id).then(rawWorkspace => (rawWorkspace ? reviver.revive(rawWorkspace) : null));
|
|
1587
1827
|
}
|
|
1588
|
-
getWorkspaces() {
|
|
1828
|
+
async getWorkspaces() {
|
|
1589
1829
|
if (!this._database) {
|
|
1590
1830
|
throw new Error('Database not initialized');
|
|
1591
1831
|
}
|
|
1592
|
-
|
|
1832
|
+
const reviver = new KritzelReviver(this);
|
|
1833
|
+
return this._database.getAll('workspaces').then(rawWorkspaces => rawWorkspaces.map(ws => reviver.revive(ws)));
|
|
1593
1834
|
}
|
|
1594
1835
|
async createWorkspace(workspace) {
|
|
1595
1836
|
if (!this._database) {
|
|
@@ -1598,7 +1839,7 @@ class KritzelStore {
|
|
|
1598
1839
|
workspace.createdAt = new Date();
|
|
1599
1840
|
workspace.updatedAt = new Date();
|
|
1600
1841
|
await this._database.add('workspaces', workspace);
|
|
1601
|
-
this.state.workspaces.push(workspace);
|
|
1842
|
+
this._store.state.workspaces.push(workspace);
|
|
1602
1843
|
}
|
|
1603
1844
|
async updateWorkspace(workspace) {
|
|
1604
1845
|
if (!this._database) {
|
|
@@ -1606,9 +1847,11 @@ class KritzelStore {
|
|
|
1606
1847
|
}
|
|
1607
1848
|
workspace.updatedAt = new Date();
|
|
1608
1849
|
await this._database.update('workspaces', workspace);
|
|
1609
|
-
const
|
|
1850
|
+
const workspaces = this._store.state.workspaces;
|
|
1851
|
+
const index = workspaces.findIndex(w => w.id === workspace.id);
|
|
1610
1852
|
if (index !== -1) {
|
|
1611
|
-
|
|
1853
|
+
workspaces[index] = workspace;
|
|
1854
|
+
this._store.setState('workspaces', workspaces);
|
|
1612
1855
|
}
|
|
1613
1856
|
}
|
|
1614
1857
|
async deleteWorkspace(workspace) {
|
|
@@ -1618,7 +1861,7 @@ class KritzelStore {
|
|
|
1618
1861
|
const objectRange = IDBKeyRange.bound([workspace.id], [workspace.id, '\uffff']);
|
|
1619
1862
|
await this._database.deleteByRange('objects', objectRange);
|
|
1620
1863
|
await this._database.delete('workspaces', workspace.id);
|
|
1621
|
-
this.
|
|
1864
|
+
this._store.setState('workspaces', this._store.state.workspaces.filter(ws => ws.id !== workspace.id));
|
|
1622
1865
|
}
|
|
1623
1866
|
rerender() {
|
|
1624
1867
|
if (this._kritzelEngine) {
|
|
@@ -1626,7 +1869,7 @@ class KritzelStore {
|
|
|
1626
1869
|
}
|
|
1627
1870
|
}
|
|
1628
1871
|
findObjectById(id) {
|
|
1629
|
-
for (const object of this.allObjects) {
|
|
1872
|
+
for (const object of this._store.allObjects) {
|
|
1630
1873
|
if (object.id === id) {
|
|
1631
1874
|
return object;
|
|
1632
1875
|
}
|
|
@@ -1634,33 +1877,18 @@ class KritzelStore {
|
|
|
1634
1877
|
return null;
|
|
1635
1878
|
}
|
|
1636
1879
|
deselectAllObjects() {
|
|
1637
|
-
if (this.
|
|
1880
|
+
if (this._store.state.selectionGroup) {
|
|
1638
1881
|
this._history.executeCommand(new RemoveSelectionGroupCommand(this, this));
|
|
1639
1882
|
}
|
|
1640
1883
|
}
|
|
1641
|
-
onStateChange(property, listener) {
|
|
1642
|
-
if (!this._listeners.has(property)) {
|
|
1643
|
-
this._listeners.set(property, new Set());
|
|
1644
|
-
}
|
|
1645
|
-
this._listeners.get(property).add(listener);
|
|
1646
|
-
}
|
|
1647
|
-
setState(property, value) {
|
|
1648
|
-
const oldValue = this._state[property];
|
|
1649
|
-
if (oldValue !== value) {
|
|
1650
|
-
this._state[property] = value;
|
|
1651
|
-
if (this._listeners.has(property)) {
|
|
1652
|
-
this._listeners.get(property).forEach(listener => listener(value, oldValue, String(property)));
|
|
1653
|
-
}
|
|
1654
|
-
}
|
|
1655
|
-
}
|
|
1656
1884
|
delete() {
|
|
1657
|
-
if (!this.state.selectionGroup) {
|
|
1885
|
+
if (!this._store.state.selectionGroup) {
|
|
1658
1886
|
return;
|
|
1659
1887
|
}
|
|
1660
|
-
const deleteSelectedObjectsCommand = this.state.selectionGroup.objects.map(obj => new RemoveObjectCommand(this, this.state.selectionGroup, obj));
|
|
1661
|
-
const removeSelectionGroupCommand = new RemoveSelectionGroupCommand(this, this.state.selectionGroup);
|
|
1888
|
+
const deleteSelectedObjectsCommand = this._store.state.selectionGroup.objects.map(obj => new RemoveObjectCommand(this, this._store.state.selectionGroup, obj));
|
|
1889
|
+
const removeSelectionGroupCommand = new RemoveSelectionGroupCommand(this, this._store.state.selectionGroup);
|
|
1662
1890
|
const commands = [...deleteSelectedObjectsCommand, removeSelectionGroupCommand];
|
|
1663
|
-
this.history.executeCommand(new BatchCommand(this, this.state.selectionGroup, commands));
|
|
1891
|
+
this.history.executeCommand(new BatchCommand(this, this._store.state.selectionGroup, commands));
|
|
1664
1892
|
}
|
|
1665
1893
|
deleteObject(id, skipHistory = false) {
|
|
1666
1894
|
const object = this.findObjectById(id);
|
|
@@ -1670,28 +1898,30 @@ class KritzelStore {
|
|
|
1670
1898
|
}
|
|
1671
1899
|
}
|
|
1672
1900
|
copy() {
|
|
1673
|
-
this.
|
|
1901
|
+
this._store.setState('copiedObjects', this._store.state.selectionGroup.copy());
|
|
1674
1902
|
}
|
|
1675
1903
|
paste(x, y) {
|
|
1676
|
-
this.state.copiedObjects
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
this.state.copiedObjects.
|
|
1904
|
+
const copiedObjects = this._store.state.copiedObjects;
|
|
1905
|
+
copiedObjects.isSelected = true;
|
|
1906
|
+
this._store.setState('copiedObjects', copiedObjects);
|
|
1907
|
+
const adjustedX = x !== undefined ? x : this._store.state.copiedObjects.translateX + 25 / this._store.state.scale;
|
|
1908
|
+
const adjustedY = y !== undefined ? y : this._store.state.copiedObjects.translateY + 25 / this._store.state.scale;
|
|
1909
|
+
this._store.state.copiedObjects.updatePosition(adjustedX, adjustedY);
|
|
1680
1910
|
const commands = [];
|
|
1681
|
-
if (this.state.selectionGroup !== null) {
|
|
1682
|
-
commands.push(new RemoveSelectionGroupCommand(this, this.state.selectionGroup));
|
|
1911
|
+
if (this._store.state.selectionGroup !== null) {
|
|
1912
|
+
commands.push(new RemoveSelectionGroupCommand(this, this._store.state.selectionGroup));
|
|
1683
1913
|
}
|
|
1684
|
-
const addCopiedObjectsCommands = this.state.copiedObjects.objects.map(obj => new AddObjectCommand(this, this, obj));
|
|
1685
|
-
const addCopiedObjectsAsSelectionGroupCommand = new AddSelectionGroupCommand(this, this, this.state.copiedObjects);
|
|
1914
|
+
const addCopiedObjectsCommands = this._store.state.copiedObjects.objects.map(obj => new AddObjectCommand(this, this, obj));
|
|
1915
|
+
const addCopiedObjectsAsSelectionGroupCommand = new AddSelectionGroupCommand(this, this, this._store.state.copiedObjects);
|
|
1686
1916
|
commands.push(...addCopiedObjectsCommands, addCopiedObjectsAsSelectionGroupCommand);
|
|
1687
1917
|
this.history.executeCommand(new BatchCommand(this, this, commands));
|
|
1688
|
-
this.
|
|
1689
|
-
this.
|
|
1690
|
-
this.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
1918
|
+
this._store.setState('isSelecting', false);
|
|
1919
|
+
this._store.setState('copiedObjects', this._store.state.selectionGroup.copy());
|
|
1920
|
+
this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
1691
1921
|
}
|
|
1692
1922
|
bringForward(object) {
|
|
1693
|
-
const max = this.allObjects.length + 1;
|
|
1694
|
-
const objects = object ? [object] : this.state.selectionGroup.objects;
|
|
1923
|
+
const max = this._store.allObjects.length + 1;
|
|
1924
|
+
const objects = object ? [object] : this._store.state.selectionGroup.objects;
|
|
1695
1925
|
const increaseZIndexCommands = objects.map(obj => {
|
|
1696
1926
|
if (obj.zIndex === max) {
|
|
1697
1927
|
return;
|
|
@@ -1702,7 +1932,7 @@ class KritzelStore {
|
|
|
1702
1932
|
}
|
|
1703
1933
|
sendBackward(object) {
|
|
1704
1934
|
const min = 0;
|
|
1705
|
-
const objects = object ? [object] : this.state.selectionGroup.objects;
|
|
1935
|
+
const objects = object ? [object] : this._store.state.selectionGroup.objects;
|
|
1706
1936
|
const decreaseZIndexCommands = objects.map(obj => {
|
|
1707
1937
|
if (obj.zIndex === min) {
|
|
1708
1938
|
return;
|
|
@@ -1712,16 +1942,16 @@ class KritzelStore {
|
|
|
1712
1942
|
this.history.executeCommand(new BatchCommand(this, this, decreaseZIndexCommands));
|
|
1713
1943
|
}
|
|
1714
1944
|
bringToFront(object) {
|
|
1715
|
-
const max = Math.max(...this.allObjects.map(obj => obj.zIndex)) + 1;
|
|
1716
|
-
const objects = object ? [object] : this.state.selectionGroup.objects;
|
|
1945
|
+
const max = Math.max(...this._store.allObjects.map(obj => obj.zIndex)) + 1;
|
|
1946
|
+
const objects = object ? [object] : this._store.state.selectionGroup.objects;
|
|
1717
1947
|
const increaseZIndexCommands = objects.map(obj => {
|
|
1718
1948
|
return new UpdateObjectCommand(this, this, obj, { zIndex: max });
|
|
1719
1949
|
});
|
|
1720
1950
|
this.history.executeCommand(new BatchCommand(this, this, increaseZIndexCommands));
|
|
1721
1951
|
}
|
|
1722
1952
|
sendToBack(object) {
|
|
1723
|
-
const min = Math.min(...this.allObjects.map(obj => obj.zIndex)) - 1;
|
|
1724
|
-
const objects = object ? [object] : this.state.selectionGroup.objects;
|
|
1953
|
+
const min = Math.min(...this._store.allObjects.map(obj => obj.zIndex)) - 1;
|
|
1954
|
+
const objects = object ? [object] : this._store.state.selectionGroup.objects;
|
|
1725
1955
|
const decreaseZIndexCommands = objects.map(obj => {
|
|
1726
1956
|
return new UpdateObjectCommand(this, this, obj, { zIndex: min });
|
|
1727
1957
|
});
|
|
@@ -1737,14 +1967,14 @@ class KritzelStore {
|
|
|
1737
1967
|
selectionGroup.addOrRemove(obj);
|
|
1738
1968
|
});
|
|
1739
1969
|
selectionGroup.isSelected = true;
|
|
1740
|
-
this.
|
|
1970
|
+
this._store.setState('selectionGroup', selectionGroup);
|
|
1741
1971
|
if (objects.length === 1) {
|
|
1742
1972
|
selectionGroup.rotation = selectionGroup.objects[0].rotation;
|
|
1743
1973
|
}
|
|
1744
1974
|
this.history.executeCommand(new AddSelectionGroupCommand(this, this, selectionGroup));
|
|
1745
1975
|
}
|
|
1746
1976
|
selectAllObjectsInViewport() {
|
|
1747
|
-
const objectsInViewport = this.
|
|
1977
|
+
const objectsInViewport = this._store.state.objectsMap
|
|
1748
1978
|
.filter(o => o.isInViewport())
|
|
1749
1979
|
.filter(o => !(o instanceof KritzelSelectionGroup) && !(o instanceof KrtizelSelectionBox) && !(o instanceof KritzelContextMenu));
|
|
1750
1980
|
if (objectsInViewport.length > 0) {
|
|
@@ -1754,31 +1984,31 @@ class KritzelStore {
|
|
|
1754
1984
|
selectionGroup.addOrRemove(obj);
|
|
1755
1985
|
});
|
|
1756
1986
|
selectionGroup.isSelected = true;
|
|
1757
|
-
this.
|
|
1987
|
+
this._store.setState('isSelecting', false);
|
|
1758
1988
|
if (objectsInViewport.length === 1) {
|
|
1759
1989
|
selectionGroup.rotation = selectionGroup.objects[0].rotation;
|
|
1760
1990
|
}
|
|
1761
1991
|
this.history.executeCommand(new AddSelectionGroupCommand(this, this, selectionGroup));
|
|
1762
|
-
this.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
1992
|
+
this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
1763
1993
|
}
|
|
1764
1994
|
}
|
|
1765
1995
|
clearSelection() {
|
|
1766
|
-
const command = new RemoveSelectionGroupCommand(this, this.state.selectionGroup);
|
|
1996
|
+
const command = new RemoveSelectionGroupCommand(this, this._store.state.selectionGroup);
|
|
1767
1997
|
this.history.executeCommand(command);
|
|
1768
|
-
this.
|
|
1769
|
-
this.
|
|
1770
|
-
this.
|
|
1771
|
-
this.
|
|
1772
|
-
this.
|
|
1998
|
+
this._store.setState('selectionGroup', null);
|
|
1999
|
+
this._store.setState('selectionBox', null);
|
|
2000
|
+
this._store.setState('isSelecting', false);
|
|
2001
|
+
this._store.setState('isResizeHandleSelected', false);
|
|
2002
|
+
this._store.setState('isRotationHandleSelected', false);
|
|
1773
2003
|
}
|
|
1774
2004
|
resetActiveText() {
|
|
1775
|
-
if (this.state.activeText && this.state.activeText.value === ' ') {
|
|
1776
|
-
this.deleteObject(this.state.activeText.id, true);
|
|
2005
|
+
if (this._store.state.activeText && this._store.state.activeText.value === ' ') {
|
|
2006
|
+
this.deleteObject(this._store.state.activeText.id, true);
|
|
1777
2007
|
}
|
|
1778
|
-
this.
|
|
2008
|
+
this._store.setState('activeText', null);
|
|
1779
2009
|
}
|
|
1780
2010
|
getObjectFromPointerEvent(event, selector = '.object') {
|
|
1781
|
-
const shadowRoot = this.state.host?.shadowRoot;
|
|
2011
|
+
const shadowRoot = this._store.state.host?.shadowRoot;
|
|
1782
2012
|
if (!shadowRoot)
|
|
1783
2013
|
return null;
|
|
1784
2014
|
const clientX = event.clientX;
|
|
@@ -1788,12 +2018,14 @@ class KritzelStore {
|
|
|
1788
2018
|
return null;
|
|
1789
2019
|
const selectedObject = elementAtPoint.closest(selector);
|
|
1790
2020
|
if (selectedObject) {
|
|
1791
|
-
|
|
2021
|
+
const foundObject = this._store.allObjects.find(object => selectedObject.id === object.id);
|
|
2022
|
+
const isHit = foundObject?.hitTest(clientX, clientY);
|
|
2023
|
+
return isHit ? foundObject : null;
|
|
1792
2024
|
}
|
|
1793
2025
|
return null;
|
|
1794
2026
|
}
|
|
1795
2027
|
getObjectsFromPointerEvent(event, selector = '.object') {
|
|
1796
|
-
const shadowRoot = this.state.host?.shadowRoot;
|
|
2028
|
+
const shadowRoot = this._store.state.host?.shadowRoot;
|
|
1797
2029
|
if (!shadowRoot)
|
|
1798
2030
|
return [];
|
|
1799
2031
|
const clientX = event.clientX;
|
|
@@ -1809,288 +2041,119 @@ class KritzelStore {
|
|
|
1809
2041
|
}
|
|
1810
2042
|
});
|
|
1811
2043
|
if (objectIds.size > 0) {
|
|
1812
|
-
return this.allObjects.filter(object => objectIds.has(object.id)).sort((a, b) => b.zIndex - a.zIndex);
|
|
2044
|
+
return this._store.allObjects.filter(object => objectIds.has(object.id)).sort((a, b) => b.zIndex - a.zIndex);
|
|
1813
2045
|
}
|
|
1814
2046
|
return [];
|
|
1815
2047
|
}
|
|
1816
2048
|
getCanvasPoint(event) {
|
|
1817
|
-
if (!this.state.host) {
|
|
2049
|
+
if (!this._store.state.host) {
|
|
1818
2050
|
return { x: 0, y: 0 };
|
|
1819
2051
|
}
|
|
1820
|
-
|
|
1821
|
-
const hostRect = this.state.host.getBoundingClientRect();
|
|
1822
|
-
// 1. Make the pointer coordinates relative to the host element
|
|
2052
|
+
const hostRect = this._store.state.host.getBoundingClientRect();
|
|
1823
2053
|
const xRelativeToHost = event.clientX - hostRect.left;
|
|
1824
2054
|
const yRelativeToHost = event.clientY - hostRect.top;
|
|
1825
|
-
|
|
1826
|
-
const
|
|
1827
|
-
const
|
|
1828
|
-
|
|
1829
|
-
const worldX = xWithoutTranslate / this.state.scale;
|
|
1830
|
-
const worldY = yWithoutTranslate / this.state.scale;
|
|
2055
|
+
const xWithoutTranslate = xRelativeToHost - this._store.state.translateX;
|
|
2056
|
+
const yWithoutTranslate = yRelativeToHost - this._store.state.translateY;
|
|
2057
|
+
const worldX = xWithoutTranslate / this._store.state.scale;
|
|
2058
|
+
const worldY = yWithoutTranslate / this._store.state.scale;
|
|
1831
2059
|
return { x: worldX, y: worldY };
|
|
1832
2060
|
}
|
|
1833
2061
|
}
|
|
1834
2062
|
|
|
1835
|
-
class KritzelKeyHandler extends KritzelBaseHandler {
|
|
1836
|
-
constructor(store) {
|
|
1837
|
-
super(store);
|
|
1838
|
-
}
|
|
1839
|
-
handleKeyDown(event) {
|
|
1840
|
-
if (this._store.state.isFocused === false) {
|
|
1841
|
-
return;
|
|
1842
|
-
}
|
|
1843
|
-
this._store.state.isCtrlKeyPressed = event.ctrlKey;
|
|
1844
|
-
if (this._store.state.isCtrlKeyPressed) {
|
|
1845
|
-
event.preventDefault();
|
|
1846
|
-
}
|
|
1847
|
-
if (event.key === 'Escape' && this._store.state.selectionGroup) {
|
|
1848
|
-
this._store.clearSelection();
|
|
1849
|
-
}
|
|
1850
|
-
if (event.key === 'Delete' && this._store.state.selectionGroup) {
|
|
1851
|
-
this._store.delete();
|
|
1852
|
-
}
|
|
1853
|
-
if (event.key === 'z' && event.ctrlKey) {
|
|
1854
|
-
this._store.history.undo();
|
|
1855
|
-
}
|
|
1856
|
-
if (event.key === 'y' && event.ctrlKey) {
|
|
1857
|
-
this._store.history.redo();
|
|
1858
|
-
}
|
|
1859
|
-
if (event.key === 's' && event.ctrlKey) {
|
|
1860
|
-
this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
1861
|
-
this._store.deselectAllObjects();
|
|
1862
|
-
}
|
|
1863
|
-
if (event.key === 'b' && event.ctrlKey) {
|
|
1864
|
-
this._store.setState('activeTool', KritzelToolRegistry.getTool('brush'));
|
|
1865
|
-
this._store.deselectAllObjects();
|
|
1866
|
-
}
|
|
1867
|
-
if (event.key === 'e' && event.ctrlKey) {
|
|
1868
|
-
this._store.setState('activeTool', KritzelToolRegistry.getTool('eraser'));
|
|
1869
|
-
this._store.deselectAllObjects();
|
|
1870
|
-
}
|
|
1871
|
-
if (event.key === 'i' && event.ctrlKey) {
|
|
1872
|
-
this._store.setState('activeTool', KritzelToolRegistry.getTool('image'));
|
|
1873
|
-
this._store.deselectAllObjects();
|
|
1874
|
-
}
|
|
1875
|
-
if (event.key === 'x' && event.ctrlKey) {
|
|
1876
|
-
this._store.setState('activeTool', KritzelToolRegistry.getTool('text'));
|
|
1877
|
-
this._store.deselectAllObjects();
|
|
1878
|
-
}
|
|
1879
|
-
if (event.key === 'c' && event.ctrlKey && this._store.state.selectionGroup) {
|
|
1880
|
-
this._store.copy();
|
|
1881
|
-
this._store.rerender();
|
|
1882
|
-
}
|
|
1883
|
-
if (event.key === 'v' && event.ctrlKey && this._store.state.copiedObjects) {
|
|
1884
|
-
this._store.paste();
|
|
1885
|
-
}
|
|
1886
|
-
if (event.key === '+' && event.ctrlKey && this._store.state.selectionGroup) {
|
|
1887
|
-
this._store.bringForward();
|
|
1888
|
-
}
|
|
1889
|
-
if (event.key === '-' && event.ctrlKey && this._store.state.selectionGroup) {
|
|
1890
|
-
this._store.sendBackward();
|
|
1891
|
-
}
|
|
1892
|
-
if (event.key === '*' && event.shiftKey && this._store.state.selectionGroup) {
|
|
1893
|
-
this._store.bringToFront();
|
|
1894
|
-
}
|
|
1895
|
-
if (event.key === '_' && event.shiftKey && this._store.state.selectionGroup) {
|
|
1896
|
-
this._store.sendToBack();
|
|
1897
|
-
}
|
|
1898
|
-
if (event.key === 'a' && event.ctrlKey && this._store.state.activeText) {
|
|
1899
|
-
this._store.state.activeText.selectAll();
|
|
1900
|
-
}
|
|
1901
|
-
if (event.key === 'v' && event.ctrlKey && this._store.state.activeText) {
|
|
1902
|
-
this._store.state.activeText.insertFromClipboard();
|
|
1903
|
-
}
|
|
1904
|
-
}
|
|
1905
|
-
handleKeyUp(event) {
|
|
1906
|
-
if (this._store.state.isFocused === false) {
|
|
1907
|
-
return;
|
|
1908
|
-
}
|
|
1909
|
-
this._store.state.isCtrlKeyPressed = event.ctrlKey;
|
|
1910
|
-
}
|
|
1911
|
-
}
|
|
1912
|
-
|
|
1913
|
-
class KritzelContextMenuHandler extends KritzelBaseHandler {
|
|
1914
|
-
globalContextMenuItems = [];
|
|
1915
|
-
objectContextMenuItems = [];
|
|
1916
|
-
constructor(store, globalContextMenuItems, objectContextMenuItems) {
|
|
1917
|
-
super(store);
|
|
1918
|
-
this.globalContextMenuItems = globalContextMenuItems;
|
|
1919
|
-
this.objectContextMenuItems = objectContextMenuItems;
|
|
1920
|
-
}
|
|
1921
|
-
handleContextMenu(event) {
|
|
1922
|
-
if (this._store.state.skipContextMenu) {
|
|
1923
|
-
this._store.state.skipContextMenu = false;
|
|
1924
|
-
return;
|
|
1925
|
-
}
|
|
1926
|
-
const selectedObject = this._store.getObjectFromPointerEvent(event, '.object');
|
|
1927
|
-
if (selectedObject && !(selectedObject instanceof KritzelSelectionGroup)) {
|
|
1928
|
-
this._store.state.selectionGroup = KritzelSelectionGroup.create(this._store);
|
|
1929
|
-
this._store.state.selectionGroup.addOrRemove(selectedObject);
|
|
1930
|
-
this._store.state.selectionGroup.isSelected = true;
|
|
1931
|
-
this._store.state.selectionGroup.rotation = selectedObject.rotation;
|
|
1932
|
-
this._store.state.isSelecting = false;
|
|
1933
|
-
this._store.history.executeCommand(new AddSelectionGroupCommand(this._store, this, this._store.state.selectionGroup));
|
|
1934
|
-
}
|
|
1935
|
-
this._store.state.contextMenuItems = this._store.state.selectionGroup ? this.objectContextMenuItems : this.globalContextMenuItems;
|
|
1936
|
-
let x = event.clientX - this._store.offsetX;
|
|
1937
|
-
let y = event.clientY - this._store.offsetY;
|
|
1938
|
-
const menuWidthEstimate = 150;
|
|
1939
|
-
const menuHeightEstimate = 200;
|
|
1940
|
-
const margin = 10;
|
|
1941
|
-
if (x + menuWidthEstimate > window.innerWidth - margin) {
|
|
1942
|
-
x = window.innerWidth - menuWidthEstimate - margin;
|
|
1943
|
-
}
|
|
1944
|
-
if (y + menuHeightEstimate > window.innerHeight - margin) {
|
|
1945
|
-
y = window.innerHeight - menuHeightEstimate - margin;
|
|
1946
|
-
}
|
|
1947
|
-
x = Math.max(margin, x);
|
|
1948
|
-
y = Math.max(margin, y);
|
|
1949
|
-
this._store.state.contextMenuX = x;
|
|
1950
|
-
this._store.state.contextMenuY = y;
|
|
1951
|
-
this._store.state.isContextMenuVisible = true;
|
|
1952
|
-
this._store.state.isEnabled = false;
|
|
1953
|
-
this._store.rerender();
|
|
1954
|
-
}
|
|
1955
|
-
}
|
|
1956
|
-
|
|
1957
|
-
class KritzelClassHelper {
|
|
1958
|
-
static isInstanceOf(object, className) {
|
|
1959
|
-
return !!object && object.__class__ === className;
|
|
1960
|
-
}
|
|
1961
|
-
}
|
|
1962
|
-
|
|
1963
2063
|
const kritzelEngineCss = ":host{display:block;position:relative;height:100%;width:100%;overflow:hidden;background-color:var(--kritzel-engine-background-color, #ffffff)}:host,:host *{touch-action:none;user-select:none}.debug-panel{position:absolute;pointer-events:none;top:0;right:0}.origin{position:relative;top:0;left:0;height:0;width:0;pointer-events:none;-webkit-transform-origin:top left;-moz-transform-origin:top left;transform-origin:top left;overflow:visible}.object{overflow:visible}textarea{all:unset;box-sizing:border-box;outline:none !important;border:none !important;overflow:visible}.resize-handle-overlay.top-left,.resize-handle-overlay.bottom-right{cursor:nwse-resize}.resize-handle-overlay.top-right,.resize-handle-overlay.bottom-left{cursor:nesw-resize}.rotation-handle-overlay{cursor:grab}";
|
|
1964
2064
|
|
|
1965
2065
|
const KritzelEngine = class {
|
|
2066
|
+
get host() { return getElement(this); }
|
|
1966
2067
|
workspace;
|
|
2068
|
+
onWorkspaceChange(newWorkspace) {
|
|
2069
|
+
if (this.core.store.state.activeWorkspace !== newWorkspace) {
|
|
2070
|
+
this.core.initializeWorkspace(newWorkspace);
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
1967
2073
|
activeTool;
|
|
1968
2074
|
globalContextMenuItems;
|
|
1969
2075
|
objectContextMenuItems;
|
|
1970
2076
|
scaleMax = ABSOLUTE_SCALE_MAX;
|
|
1971
|
-
scaleMin = ABSOLUTE_SCALE_MIN;
|
|
1972
|
-
isEngineReady;
|
|
1973
|
-
activeToolChange;
|
|
1974
|
-
workspacesChange;
|
|
1975
|
-
get host() { return getElement(this); }
|
|
1976
|
-
forceUpdate = 0;
|
|
1977
|
-
onWorkspaceChange(newWorkspace) {
|
|
1978
|
-
if (newWorkspace) {
|
|
1979
|
-
this.store.initializeWorkspace(newWorkspace);
|
|
1980
|
-
}
|
|
1981
|
-
}
|
|
1982
2077
|
validateScaleMax(newValue) {
|
|
1983
2078
|
if (newValue > ABSOLUTE_SCALE_MAX) {
|
|
1984
2079
|
console.warn(`scaleMax cannot be greater than ${ABSOLUTE_SCALE_MAX}.`);
|
|
1985
2080
|
this.scaleMax = ABSOLUTE_SCALE_MAX;
|
|
1986
|
-
this.store.
|
|
2081
|
+
this.core.store.setState('scaleMax', this.scaleMax);
|
|
1987
2082
|
}
|
|
1988
2083
|
else {
|
|
1989
|
-
this.store.
|
|
2084
|
+
this.core.store.setState('scaleMax', newValue);
|
|
1990
2085
|
}
|
|
1991
2086
|
}
|
|
2087
|
+
scaleMin = ABSOLUTE_SCALE_MIN;
|
|
1992
2088
|
validateScaleMin(newValue) {
|
|
1993
2089
|
if (newValue < ABSOLUTE_SCALE_MIN) {
|
|
1994
2090
|
console.warn(`scaleMin cannot be less than ${ABSOLUTE_SCALE_MIN}.`);
|
|
1995
2091
|
this.scaleMin = ABSOLUTE_SCALE_MIN;
|
|
1996
|
-
this.store.
|
|
2092
|
+
this.core.store.setState('scaleMin', this.scaleMin);
|
|
1997
2093
|
}
|
|
1998
2094
|
else {
|
|
1999
|
-
this.store.
|
|
2000
|
-
}
|
|
2001
|
-
}
|
|
2002
|
-
store;
|
|
2003
|
-
viewport;
|
|
2004
|
-
contextMenuHandler;
|
|
2005
|
-
keyHandler;
|
|
2006
|
-
contextMenuElement = null;
|
|
2007
|
-
get isSelecting() {
|
|
2008
|
-
return this.store.state.activeTool instanceof KritzelSelectionTool && this.store.state.isSelecting;
|
|
2009
|
-
}
|
|
2010
|
-
get isSelectionActive() {
|
|
2011
|
-
return this.store.state.activeTool instanceof KritzelSelectionTool && this.store.state.selectionGroup !== null;
|
|
2012
|
-
}
|
|
2013
|
-
constructor(hostRef) {
|
|
2014
|
-
registerInstance(this, hostRef);
|
|
2015
|
-
this.isEngineReady = createEvent(this, "isEngineReady");
|
|
2016
|
-
this.activeToolChange = createEvent(this, "activeToolChange");
|
|
2017
|
-
this.workspacesChange = createEvent(this, "workspacesChange");
|
|
2018
|
-
this.store = new KritzelStore(this);
|
|
2019
|
-
}
|
|
2020
|
-
componentWillLoad() {
|
|
2021
|
-
this.validateScaleMax(this.scaleMax);
|
|
2022
|
-
this.validateScaleMin(this.scaleMin);
|
|
2023
|
-
}
|
|
2024
|
-
async componentDidLoad() {
|
|
2025
|
-
this.contextMenuHandler = new KritzelContextMenuHandler(this.store, this.globalContextMenuItems, this.objectContextMenuItems);
|
|
2026
|
-
this.keyHandler = new KritzelKeyHandler(this.store);
|
|
2027
|
-
this.viewport = new KritzelViewport(this.store, this.host);
|
|
2028
|
-
this._registerStateChangeListeners();
|
|
2029
|
-
await this.store.initializeDatabase();
|
|
2030
|
-
await this.store.initializeWorkspace(this.workspace);
|
|
2031
|
-
if (this.store.state.isReady === false) {
|
|
2032
|
-
this.store.state.isReady = true;
|
|
2033
|
-
this.isEngineReady.emit(this.store.state);
|
|
2095
|
+
this.core.store.setState('scaleMin', newValue);
|
|
2034
2096
|
}
|
|
2035
2097
|
}
|
|
2098
|
+
isEngineReady;
|
|
2099
|
+
activeToolChange;
|
|
2100
|
+
workspacesChange;
|
|
2101
|
+
longpress;
|
|
2102
|
+
forceUpdate = 0;
|
|
2036
2103
|
handleWheel(ev) {
|
|
2037
|
-
if (this.store.isDisabled) {
|
|
2104
|
+
if (this.core.store.isDisabled) {
|
|
2038
2105
|
return;
|
|
2039
2106
|
}
|
|
2040
|
-
if (this.store.state.isContextMenuVisible) {
|
|
2107
|
+
if (this.core.store.state.isContextMenuVisible) {
|
|
2041
2108
|
this.hideContextMenu();
|
|
2042
2109
|
}
|
|
2043
2110
|
this.viewport.handleWheel(ev);
|
|
2044
|
-
this.store.state?.activeTool?.handleWheel(ev);
|
|
2111
|
+
this.core.store.state?.activeTool?.handleWheel(ev);
|
|
2045
2112
|
}
|
|
2046
2113
|
handlePointerDown(ev) {
|
|
2047
|
-
if (this.store.isDisabled) {
|
|
2114
|
+
if (this.core.store.isDisabled) {
|
|
2048
2115
|
return;
|
|
2049
2116
|
}
|
|
2050
|
-
if (
|
|
2051
|
-
this.
|
|
2052
|
-
return;
|
|
2117
|
+
if (KritzelDevicesHelper.isTouchDevice()) {
|
|
2118
|
+
KritzelEventHelper.onLongPress(ev, (event) => this.longpress.emit(event));
|
|
2053
2119
|
}
|
|
2054
|
-
KritzelEventHelper.onLongTouchPress(ev, (event) => {
|
|
2055
|
-
if (!(this.store.state.activeTool instanceof KritzelSelectionTool)) {
|
|
2056
|
-
return;
|
|
2057
|
-
}
|
|
2058
|
-
this.contextMenuHandler.handleContextMenu(event);
|
|
2059
|
-
});
|
|
2060
2120
|
this.host.setPointerCapture(ev.pointerId);
|
|
2061
|
-
this.store.state.pointers.set(ev.pointerId, ev);
|
|
2121
|
+
this.core.store.state.pointers.set(ev.pointerId, ev);
|
|
2062
2122
|
this.viewport.handlePointerDown(ev);
|
|
2063
|
-
this.store.state?.activeTool?.handlePointerDown(ev);
|
|
2123
|
+
this.core.store.state?.activeTool?.handlePointerDown(ev);
|
|
2064
2124
|
}
|
|
2065
2125
|
handlePointerMove(ev) {
|
|
2066
|
-
if (this.store.isDisabled) {
|
|
2126
|
+
if (this.core.store.isDisabled) {
|
|
2067
2127
|
return;
|
|
2068
2128
|
}
|
|
2069
|
-
this.store.state.pointers.set(ev.pointerId, ev);
|
|
2129
|
+
this.core.store.state.pointers.set(ev.pointerId, ev);
|
|
2070
2130
|
this.viewport.handlePointerMove(ev);
|
|
2071
|
-
this.store.state?.activeTool?.handlePointerMove(ev);
|
|
2131
|
+
this.core.store.state?.activeTool?.handlePointerMove(ev);
|
|
2072
2132
|
}
|
|
2073
2133
|
handlePointerUp(ev) {
|
|
2074
|
-
if (this.store.isDisabled) {
|
|
2134
|
+
if (this.core.store.isDisabled) {
|
|
2075
2135
|
return;
|
|
2076
2136
|
}
|
|
2077
|
-
this.store.state.pointers.delete(ev.pointerId);
|
|
2137
|
+
this.core.store.state.pointers.delete(ev.pointerId);
|
|
2078
2138
|
this.host.releasePointerCapture(ev.pointerId);
|
|
2079
2139
|
this.viewport.handlePointerUp(ev);
|
|
2080
|
-
this.store.state?.activeTool?.handlePointerUp(ev);
|
|
2140
|
+
this.core.store.state?.activeTool?.handlePointerUp(ev);
|
|
2081
2141
|
}
|
|
2082
2142
|
handlePointerCancel(ev) {
|
|
2083
|
-
if (this.store.isDisabled) {
|
|
2143
|
+
if (this.core.store.isDisabled) {
|
|
2084
2144
|
return;
|
|
2085
2145
|
}
|
|
2086
2146
|
this.host.releasePointerCapture(ev.pointerId);
|
|
2087
|
-
this.store.state.pointers.delete(ev.pointerId);
|
|
2147
|
+
this.core.store.state.pointers.delete(ev.pointerId);
|
|
2088
2148
|
this.viewport.handlePointerUp(ev);
|
|
2089
|
-
this.store.state?.activeTool?.handlePointerUp(ev);
|
|
2149
|
+
this.core.store.state?.activeTool?.handlePointerUp(ev);
|
|
2150
|
+
}
|
|
2151
|
+
handleLongPress(ev) {
|
|
2152
|
+
this.contextMenuHandler.handleContextMenu(ev.detail);
|
|
2090
2153
|
}
|
|
2091
2154
|
handleContextMenu(ev) {
|
|
2092
2155
|
ev.preventDefault();
|
|
2093
|
-
if (this.store.isDisabled) {
|
|
2156
|
+
if (this.core.store.isDisabled) {
|
|
2094
2157
|
return;
|
|
2095
2158
|
}
|
|
2096
2159
|
if (ev.pointerType === 'touch') {
|
|
@@ -2107,26 +2170,12 @@ const KritzelEngine = class {
|
|
|
2107
2170
|
handleKeyUp(ev) {
|
|
2108
2171
|
this.keyHandler.handleKeyUp(ev);
|
|
2109
2172
|
}
|
|
2110
|
-
updateFocus(ev) {
|
|
2111
|
-
if (this.store.isDisabled) {
|
|
2112
|
-
return;
|
|
2113
|
-
}
|
|
2114
|
-
const rect = this.store.state.host.getBoundingClientRect();
|
|
2115
|
-
const isInside = ev.clientX >= rect.left && ev.clientX <= rect.right && ev.clientY >= rect.top && ev.clientY <= rect.bottom;
|
|
2116
|
-
const path = ev.composedPath();
|
|
2117
|
-
const kritzelEngineElement = this.host.closest('kritzel-engine');
|
|
2118
|
-
const isInKritzelEngine = path.includes(kritzelEngineElement || this.host);
|
|
2119
|
-
this.store.setState('isFocused', isInside && isInKritzelEngine);
|
|
2120
|
-
}
|
|
2121
|
-
handleClick() {
|
|
2122
|
-
this.enable();
|
|
2123
|
-
}
|
|
2124
2173
|
async registerTool(toolName, toolClass, toolConfig) {
|
|
2125
2174
|
if (typeof toolClass !== 'function' || !(toolClass.prototype instanceof KritzelBaseTool)) {
|
|
2126
2175
|
console.error(`Failed to register tool "${toolName}": Tool class must be a constructor function`);
|
|
2127
2176
|
return null;
|
|
2128
2177
|
}
|
|
2129
|
-
const registeredTool = KritzelToolRegistry.registerTool(toolName, toolClass, this.
|
|
2178
|
+
const registeredTool = KritzelToolRegistry.registerTool(toolName, toolClass, this.core);
|
|
2130
2179
|
if (toolConfig) {
|
|
2131
2180
|
Object.entries(toolConfig).forEach(([key, value]) => {
|
|
2132
2181
|
registeredTool[key] = value;
|
|
@@ -2135,153 +2184,188 @@ const KritzelEngine = class {
|
|
|
2135
2184
|
return Promise.resolve(registeredTool);
|
|
2136
2185
|
}
|
|
2137
2186
|
async changeActiveTool(tool) {
|
|
2138
|
-
this.store.state.activeTool?.onDeactivate();
|
|
2139
|
-
this.store.setState('activeTool', tool);
|
|
2140
|
-
this.
|
|
2187
|
+
this.core.store.state.activeTool?.onDeactivate();
|
|
2188
|
+
this.core.store.setState('activeTool', tool);
|
|
2189
|
+
this.core.deselectAllObjects();
|
|
2141
2190
|
tool?.onActivate();
|
|
2142
2191
|
}
|
|
2143
|
-
async setFocus() {
|
|
2144
|
-
this.host.focus();
|
|
2145
|
-
this.store.state.isFocused = true;
|
|
2146
|
-
}
|
|
2147
2192
|
async disable() {
|
|
2148
|
-
this.store.
|
|
2149
|
-
this.
|
|
2193
|
+
this.core.store.setState('isEnabled', false);
|
|
2194
|
+
this.core.rerender();
|
|
2150
2195
|
}
|
|
2151
2196
|
async enable() {
|
|
2152
|
-
this.store.
|
|
2153
|
-
this.
|
|
2197
|
+
this.core.store.setState('isEnabled', true);
|
|
2198
|
+
this.core.rerender();
|
|
2154
2199
|
}
|
|
2155
2200
|
async delete() {
|
|
2156
|
-
this.
|
|
2201
|
+
this.core.delete();
|
|
2157
2202
|
}
|
|
2158
2203
|
async copy() {
|
|
2159
|
-
this.
|
|
2204
|
+
this.core.copy();
|
|
2160
2205
|
}
|
|
2161
2206
|
async paste(x, y) {
|
|
2162
|
-
this.
|
|
2207
|
+
this.core.paste(x, y);
|
|
2163
2208
|
}
|
|
2164
2209
|
async bringForward(object) {
|
|
2165
|
-
this.
|
|
2210
|
+
this.core.bringForward(object);
|
|
2166
2211
|
}
|
|
2167
2212
|
async sendBackward(object) {
|
|
2168
|
-
this.
|
|
2213
|
+
this.core.sendBackward(object);
|
|
2169
2214
|
}
|
|
2170
2215
|
async bringToFront(object) {
|
|
2171
|
-
this.
|
|
2216
|
+
this.core.bringToFront(object);
|
|
2172
2217
|
}
|
|
2173
2218
|
async sendToBack(object) {
|
|
2174
|
-
this.
|
|
2219
|
+
this.core.sendToBack(object);
|
|
2175
2220
|
}
|
|
2176
2221
|
async undo() {
|
|
2177
|
-
this.
|
|
2222
|
+
this.core.history.undo();
|
|
2178
2223
|
}
|
|
2179
2224
|
async redo() {
|
|
2180
|
-
this.
|
|
2225
|
+
this.core.history.redo();
|
|
2181
2226
|
}
|
|
2182
2227
|
async hideContextMenu() {
|
|
2183
|
-
this.store.state.pointers.clear();
|
|
2184
|
-
this.store.
|
|
2185
|
-
this.store.
|
|
2186
|
-
this.store.
|
|
2228
|
+
this.core.store.state.pointers.clear();
|
|
2229
|
+
this.core.store.setState('isContextMenuVisible', false);
|
|
2230
|
+
this.core.store.setState('selectionBox', null);
|
|
2231
|
+
this.core.store.setState('isSelecting', false);
|
|
2232
|
+
this.core.store.setState('isEnabled', true);
|
|
2233
|
+
this.core.rerender();
|
|
2187
2234
|
}
|
|
2188
2235
|
async getObjectById(id) {
|
|
2189
|
-
const object = this.store.
|
|
2236
|
+
const object = this.core.store.allObjects.find(obj => obj.id === id);
|
|
2190
2237
|
return object || null;
|
|
2191
2238
|
}
|
|
2192
2239
|
async addObject(object) {
|
|
2193
|
-
this.
|
|
2240
|
+
this.core.deselectAllObjects();
|
|
2194
2241
|
object.id = object.generateId();
|
|
2195
|
-
object.
|
|
2196
|
-
object.scale = object.scale ? object.scale : this.store.state.scale;
|
|
2197
|
-
object.zIndex = this.store.currentZIndex;
|
|
2198
|
-
const command = new AddObjectCommand(this.
|
|
2199
|
-
this.
|
|
2242
|
+
object._core = this.core;
|
|
2243
|
+
object.scale = object.scale ? object.scale : this.core.store.state.scale;
|
|
2244
|
+
object.zIndex = this.core.store.currentZIndex;
|
|
2245
|
+
const command = new AddObjectCommand(this.core, this, object);
|
|
2246
|
+
this.core.history.executeCommand(command);
|
|
2200
2247
|
return object;
|
|
2201
2248
|
}
|
|
2202
2249
|
async updateObject(object, updatedProperties) {
|
|
2203
|
-
this.
|
|
2204
|
-
const command = new UpdateObjectCommand(this.
|
|
2205
|
-
this.
|
|
2250
|
+
this.core.deselectAllObjects();
|
|
2251
|
+
const command = new UpdateObjectCommand(this.core, this, object, updatedProperties);
|
|
2252
|
+
this.core.history.executeCommand(command);
|
|
2206
2253
|
return object;
|
|
2207
2254
|
}
|
|
2208
2255
|
async removeObject(object) {
|
|
2209
|
-
this.
|
|
2210
|
-
const command = new RemoveObjectCommand(this.
|
|
2211
|
-
this.
|
|
2256
|
+
this.core.deselectAllObjects();
|
|
2257
|
+
const command = new RemoveObjectCommand(this.core, this, object);
|
|
2258
|
+
this.core.history.executeCommand(command);
|
|
2212
2259
|
return object;
|
|
2213
2260
|
}
|
|
2214
2261
|
async getSelectedObjects() {
|
|
2215
|
-
return this.store.state.selectionGroup ? this.store.state.selectionGroup.objects : [];
|
|
2262
|
+
return this.core.store.state.selectionGroup ? this.core.store.state.selectionGroup.objects : [];
|
|
2216
2263
|
}
|
|
2217
2264
|
async selectObjects(objects) {
|
|
2218
|
-
this.store.state.activeTool?.onDeactivate();
|
|
2219
|
-
this.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
2220
|
-
this.
|
|
2221
|
-
this.
|
|
2265
|
+
this.core.store.state.activeTool?.onDeactivate();
|
|
2266
|
+
this.core.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
2267
|
+
this.core.deselectAllObjects();
|
|
2268
|
+
this.core.selectObjects(objects);
|
|
2222
2269
|
}
|
|
2223
2270
|
async selectAllObjectsInViewport() {
|
|
2224
|
-
this.store.state.activeTool?.onDeactivate();
|
|
2225
|
-
this.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
2226
|
-
this.
|
|
2227
|
-
this.
|
|
2271
|
+
this.core.store.state.activeTool?.onDeactivate();
|
|
2272
|
+
this.core.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
2273
|
+
this.core.deselectAllObjects();
|
|
2274
|
+
this.core.selectAllObjectsInViewport();
|
|
2228
2275
|
}
|
|
2229
2276
|
async clearSelection() {
|
|
2230
|
-
this.
|
|
2277
|
+
this.core.clearSelection();
|
|
2231
2278
|
}
|
|
2232
2279
|
async centerObjectInViewport(object) {
|
|
2233
2280
|
object.centerInViewport();
|
|
2234
|
-
const command = new UpdateObjectCommand(this.
|
|
2235
|
-
this.
|
|
2281
|
+
const command = new UpdateObjectCommand(this.core, this, object, object);
|
|
2282
|
+
this.core.history.executeCommand(command);
|
|
2236
2283
|
return object;
|
|
2237
2284
|
}
|
|
2238
2285
|
async getCopiedObjects() {
|
|
2239
|
-
return this.store.state.copiedObjects?.objects || [];
|
|
2286
|
+
return this.core.store.state.copiedObjects?.objects || [];
|
|
2240
2287
|
}
|
|
2241
2288
|
async createWorkspace(workspace) {
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2289
|
+
workspace._core = this.core;
|
|
2290
|
+
await this.core.createWorkspace(workspace);
|
|
2291
|
+
this.workspacesChange.emit(this.core.store.state.workspaces);
|
|
2292
|
+
return workspace;
|
|
2245
2293
|
}
|
|
2246
2294
|
async updateWorkspace(workspace) {
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
});
|
|
2295
|
+
await this.core.updateWorkspace(workspace);
|
|
2296
|
+
this.workspacesChange.emit(this.core.store.state.workspaces);
|
|
2250
2297
|
}
|
|
2251
2298
|
async deleteWorkspace(workspace) {
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
});
|
|
2299
|
+
await this.core.deleteWorkspace(workspace);
|
|
2300
|
+
this.workspacesChange.emit(this.core.store.state.workspaces);
|
|
2255
2301
|
}
|
|
2256
2302
|
async getWorkspaces() {
|
|
2257
|
-
return this.
|
|
2303
|
+
return this.core.getWorkspaces();
|
|
2304
|
+
}
|
|
2305
|
+
async getActiveWorkspace() {
|
|
2306
|
+
return this.core.store.state.activeWorkspace;
|
|
2307
|
+
}
|
|
2308
|
+
core;
|
|
2309
|
+
viewport;
|
|
2310
|
+
contextMenuHandler;
|
|
2311
|
+
keyHandler;
|
|
2312
|
+
contextMenuElement = null;
|
|
2313
|
+
get isSelecting() {
|
|
2314
|
+
return this.core.store.state.activeTool instanceof KritzelSelectionTool && this.core.store.state.isSelecting;
|
|
2315
|
+
}
|
|
2316
|
+
get isSelectionActive() {
|
|
2317
|
+
return this.core.store.state.activeTool instanceof KritzelSelectionTool && this.core.store.state.selectionGroup !== null;
|
|
2318
|
+
}
|
|
2319
|
+
constructor(hostRef) {
|
|
2320
|
+
registerInstance(this, hostRef);
|
|
2321
|
+
this.isEngineReady = createEvent(this, "isEngineReady");
|
|
2322
|
+
this.activeToolChange = createEvent(this, "activeToolChange");
|
|
2323
|
+
this.workspacesChange = createEvent(this, "workspacesChange");
|
|
2324
|
+
this.longpress = createEvent(this, "longpress");
|
|
2325
|
+
this.core = new KritzelCore(this);
|
|
2326
|
+
}
|
|
2327
|
+
componentWillLoad() {
|
|
2328
|
+
this.validateScaleMax(this.scaleMax);
|
|
2329
|
+
this.validateScaleMin(this.scaleMin);
|
|
2330
|
+
}
|
|
2331
|
+
async componentDidLoad() {
|
|
2332
|
+
this.contextMenuHandler = new KritzelContextMenuHandler(this.core, this.globalContextMenuItems, this.objectContextMenuItems);
|
|
2333
|
+
this.keyHandler = new KritzelKeyHandler(this.core);
|
|
2334
|
+
this.viewport = new KritzelViewport(this.core, this.host);
|
|
2335
|
+
await this.core.initializeDatabase();
|
|
2336
|
+
await this.core.initializeWorkspace(this.workspace);
|
|
2337
|
+
this._registerStateChangeListeners();
|
|
2338
|
+
if (this.core.store.state.isReady === false) {
|
|
2339
|
+
this.core.store.setState('isReady', true);
|
|
2340
|
+
this.isEngineReady.emit(this.core.store.state);
|
|
2341
|
+
}
|
|
2258
2342
|
}
|
|
2259
2343
|
_registerStateChangeListeners() {
|
|
2260
|
-
this.store.onStateChange('activeTool', this._handleActiveToolChange.bind(this));
|
|
2261
|
-
this.store.onStateChange('isFocused', this._handleIsFocusedChange.bind(this));
|
|
2344
|
+
this.core.store.onStateChange('activeTool', this._handleActiveToolChange.bind(this));
|
|
2262
2345
|
}
|
|
2263
2346
|
_handleActiveToolChange(activeTool) {
|
|
2264
2347
|
if (!(activeTool instanceof KritzelSelectionTool)) {
|
|
2265
|
-
this.
|
|
2348
|
+
this.core.clearSelection();
|
|
2266
2349
|
}
|
|
2267
|
-
this.store.
|
|
2350
|
+
this.core.store.setState('skipContextMenu', false);
|
|
2268
2351
|
this.activeToolChange.emit(activeTool);
|
|
2269
2352
|
KritzelKeyboardHelper.forceHideKeyboard();
|
|
2270
2353
|
}
|
|
2271
|
-
_handleIsFocusedChange(isFocused) {
|
|
2272
|
-
if (!isFocused) {
|
|
2273
|
-
this.store.resetActiveText();
|
|
2274
|
-
}
|
|
2275
|
-
}
|
|
2276
2354
|
render() {
|
|
2277
2355
|
const computedStyle = window.getComputedStyle(this.host);
|
|
2278
2356
|
const baseHandleSizePx = computedStyle.getPropertyValue('--kritzel-selection-handle-size').trim() || '6px';
|
|
2279
2357
|
const baseHandleSize = parseFloat(baseHandleSizePx);
|
|
2280
2358
|
const baseHandleTouchSize = baseHandleSize * 2 < 14 ? 14 : baseHandleSize;
|
|
2281
|
-
return (h(Host, { key: '
|
|
2282
|
-
transform: `matrix(${this.store.state?.scale}, 0, 0, ${this.store.state?.scale}, ${this.store.state?.translateX}, ${this.store.state?.translateY})`,
|
|
2283
|
-
} }, this.store.state.objectsMap.allObjects()?.map(object => {
|
|
2284
|
-
return (h("div", { key: object.id, style: {
|
|
2359
|
+
return (h(Host, { key: 'da47553aad7abf8b5daab177c6933a9177b91089' }, h("div", { key: '4e64b43bfb85a61154d36ca8ecd3518d61445d50', class: "debug-panel", style: { display: this.core.store.state.debugInfo.showViewportInfo ? 'block' : 'none' } }, h("div", { key: '21742da9258a2b929b81c0ca6c8f37f41b228ad4' }, "ActiveWorkspaceId: ", this.core.store.state?.activeWorkspace?.id), h("div", { key: 'de31fcf57b0faf8fad2bb39336eeea35dbec35ca' }, "ActiveWorkspaceName: ", this.core.store.state?.activeWorkspace?.name), h("div", { key: 'a2cb298a867f92349b5e1fb556ee5f9c6110f1c7' }, "TranslateX: ", this.core.store.state?.translateX), h("div", { key: '28697bfcecf9f8b4b1972a90cd02855767433047' }, "TranslateY: ", this.core.store.state?.translateY), h("div", { key: '7fb25f6e9c9b8dea11832dbd311d2cc0b981cbeb' }, "ViewportWidth: ", this.core.store.state?.viewportWidth), h("div", { key: '92aeade312b3d28e4c9b0e1c7ca55f6932fd23d9' }, "ViewportHeight: ", this.core.store.state?.viewportHeight), h("div", { key: 'a4fd8090acaf094e44fdc2e72fcc388695b412c4' }, "Scale: ", this.core.store.state?.scale), h("div", { key: '6ff28100b64bafdffcb8fe9d49cd041a6a374817' }, "ActiveTool: ", this.core.store.state?.activeTool?.name), h("div", { key: '12a61ad3d070563eb721d0d4068143962914b2bc' }, "HasViewportChanged: ", this.core.store.state?.hasViewportChanged ? 'true' : 'false'), h("div", { key: '437309daa2af1a64c9b9d3548fe12e075dd4a8bd' }, "IsEnabled: ", this.core.store.state?.isEnabled ? 'true' : 'false'), h("div", { key: 'e6841095c220ebf081604c548729f085ec9d17bd' }, "IsScaling: ", this.core.store.state?.isScaling ? 'true' : 'false'), h("div", { key: 'b07316a528782f7560c2e42f7bd9edd473cc256c' }, "IsPanning: ", this.core.store.state?.isPanning ? 'true' : 'false'), h("div", { key: '7160a5aa21c4cdbf2b523f620c819ad541a2e466' }, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", { key: '9ad29a686bc76b47d4c5040121b468428ade437a' }, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", { key: '68f240aa7d7188996647afd0df73d63a253e18a1' }, "IsResizeHandleSelected: ", this.core.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", { key: '260010c089bdf0e8fd8c2406c39394ef79a85262' }, "IsRotationHandleSelected: ", this.core.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", { key: '6b07975c781801b0a7d7727d0666a6765aa9e889' }, "IsDrawing: ", this.core.store.state.isDrawing ? 'true' : 'false'), h("div", { key: '83c949c9ed26c3d445421ba1f965a742f5fc149f' }, "IsWriting: ", this.core.store.state.isWriting ? 'true' : 'false'), h("div", { key: '1687122785d3370da5d91a975dd56f11aebc81c1' }, "PointerX: ", this.core.store.state?.pointerX), h("div", { key: 'a28e152a0510c9e3eef5624de1b5512baf45b37c' }, "PointerY: ", this.core.store.state?.pointerY), h("div", { key: '09e5a0157002fe95a46415d32a3eb17be8d959a9' }, "SelectedObjects: ", this.core.store.state.selectionGroup?.objects.length || 0)), h("div", { key: '5228fbae773f30d91b129c257ef08adca10a6a70', id: "origin", class: "origin", style: {
|
|
2360
|
+
transform: `matrix(${this.core.store.state?.scale}, 0, 0, ${this.core.store.state?.scale}, ${this.core.store.state?.translateX}, ${this.core.store.state?.translateY})`,
|
|
2361
|
+
} }, this.core.store.state.objectsMap.allObjects()?.map(object => {
|
|
2362
|
+
return (h("div", { key: object.id, style: {
|
|
2363
|
+
display: object.isInViewport() ? 'block' : 'none',
|
|
2364
|
+
transform: object?.transformationMatrix,
|
|
2365
|
+
transformOrigin: 'top left',
|
|
2366
|
+
zIndex: object.zIndex.toString(),
|
|
2367
|
+
position: 'absolute',
|
|
2368
|
+
} }, h("svg", { xmlns: "http://www.w3.org/2000/svg", id: object.id, class: "object", style: {
|
|
2285
2369
|
height: object?.totalHeight.toString(),
|
|
2286
2370
|
width: object?.totalWidth.toString(),
|
|
2287
2371
|
left: '0',
|
|
@@ -2338,69 +2422,71 @@ const KritzelEngine = class {
|
|
|
2338
2422
|
} })), KritzelClassHelper.isInstanceOf(object, 'KrtizelSelectionBox') && (h("div", { ref: el => (el ? object.mount(el) : object.unmount()), style: {
|
|
2339
2423
|
width: '100%',
|
|
2340
2424
|
height: '100%',
|
|
2425
|
+
backgroundColor: KritzelDevicesHelper.isFirefox() ? object.backgroundColor : 'transparent',
|
|
2426
|
+
borderWidth: KritzelDevicesHelper.isFirefox() ? object.borderWidth + 'px' : '0',
|
|
2427
|
+
borderStyle: KritzelDevicesHelper.isFirefox() ? 'solid' : 'none',
|
|
2428
|
+
borderColor: KritzelDevicesHelper.isFirefox() ? object.borderColor : 'transparent',
|
|
2341
2429
|
} }))), h("line", { x1: "0", y1: "0", x2: object.totalWidth, y2: "0", style: {
|
|
2342
2430
|
stroke: 'var(--kritzel-selection-border-color, #007AFF)',
|
|
2343
|
-
strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.store.state?.scale})`,
|
|
2431
|
+
strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.core.store.state?.scale})`,
|
|
2344
2432
|
strokeLinecap: 'square',
|
|
2345
2433
|
}, visibility: object.isSelected ? 'visible' : 'hidden' }), h("line", { x1: "0", y1: "0", x2: "0", y2: object.totalHeight, style: {
|
|
2346
2434
|
stroke: 'var(--kritzel-selection-border-color, #007AFF)',
|
|
2347
|
-
strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.store.state?.scale})`,
|
|
2435
|
+
strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.core.store.state?.scale})`,
|
|
2348
2436
|
strokeLinecap: 'square',
|
|
2349
2437
|
}, visibility: object.isSelected ? 'visible' : 'hidden' }), h("line", { x1: "0", y1: object.totalHeight, x2: object.totalWidth, y2: object.totalHeight, style: {
|
|
2350
2438
|
stroke: 'var(--kritzel-selection-border-color, #007AFF)',
|
|
2351
|
-
strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.store.state?.scale})`,
|
|
2439
|
+
strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.core.store.state?.scale})`,
|
|
2352
2440
|
strokeLinecap: 'square',
|
|
2353
2441
|
}, visibility: object.isSelected ? 'visible' : 'hidden' }), h("line", { x1: object.totalWidth, y1: "0", x2: object.totalWidth, y2: object.totalHeight, style: {
|
|
2354
2442
|
stroke: 'var(--kritzel-selection-border-color, #007AFF)',
|
|
2355
|
-
strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.store.state?.scale})`,
|
|
2443
|
+
strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.core.store.state?.scale})`,
|
|
2356
2444
|
strokeLinecap: 'square',
|
|
2357
|
-
}, visibility: object.isSelected ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle top-left", cx: "0", cy: "0", r: `${(baseHandleSize * object.scale) / this.store.state?.scale}`, style: {
|
|
2445
|
+
}, visibility: object.isSelected ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle top-left", cx: "0", cy: "0", r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
|
|
2358
2446
|
fill: 'var(--kritzel-selection-handle-color, #000000)',
|
|
2359
|
-
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle-overlay top-left", cx: "0", cy: "0", r: `${(baseHandleTouchSize * object.scale) / this.store.state?.scale}`, style: {
|
|
2447
|
+
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle-overlay top-left", cx: "0", cy: "0", r: `${(baseHandleTouchSize * object.scale) / this.core.store.state?.scale}`, style: {
|
|
2360
2448
|
fill: 'transparent',
|
|
2361
|
-
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle top-right", cx: object.totalWidth, cy: "0", r: `${(baseHandleSize * object.scale) / this.store.state?.scale}`, style: {
|
|
2449
|
+
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle top-right", cx: object.totalWidth, cy: "0", r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
|
|
2362
2450
|
fill: 'var(--kritzel-selection-handle-color, #000000)',
|
|
2363
|
-
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle-overlay top-right", cx: object.totalWidth, cy: "0", r: `${(baseHandleTouchSize * object.scale) / this.store.state?.scale}`, style: {
|
|
2451
|
+
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle-overlay top-right", cx: object.totalWidth, cy: "0", r: `${(baseHandleTouchSize * object.scale) / this.core.store.state?.scale}`, style: {
|
|
2364
2452
|
fill: 'transparent',
|
|
2365
|
-
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle bottom-left", cx: "0", cy: object.totalHeight, r: `${(baseHandleSize * object.scale) / this.store.state?.scale}`, style: {
|
|
2453
|
+
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle bottom-left", cx: "0", cy: object.totalHeight, r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
|
|
2366
2454
|
fill: 'var(--kritzel-selection-handle-color, #000000)',
|
|
2367
|
-
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle-overlay bottom-left", cx: "0", cy: object.totalHeight, r: `${(baseHandleTouchSize * object.scale) / this.store.state?.scale}`, style: {
|
|
2455
|
+
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle-overlay bottom-left", cx: "0", cy: object.totalHeight, r: `${(baseHandleTouchSize * object.scale) / this.core.store.state?.scale}`, style: {
|
|
2368
2456
|
fill: 'transparent',
|
|
2369
|
-
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle bottom-right", cx: object.totalWidth, cy: object.totalHeight, r: `${(baseHandleSize * object.scale) / this.store.state?.scale}`, style: {
|
|
2457
|
+
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle bottom-right", cx: object.totalWidth, cy: object.totalHeight, r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
|
|
2370
2458
|
fill: 'var(--kritzel-selection-handle-color, #000000)',
|
|
2371
|
-
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle-overlay bottom-right", cx: object.totalWidth, cy: object.totalHeight, r: `${(baseHandleTouchSize * object.scale) / this.store.state?.scale}`, style: {
|
|
2459
|
+
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "resize-handle-overlay bottom-right", cx: object.totalWidth, cy: object.totalHeight, r: `${(baseHandleTouchSize * object.scale) / this.core.store.state?.scale}`, style: {
|
|
2372
2460
|
fill: 'transparent',
|
|
2373
|
-
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("line", { x1: object.totalWidth / 2, y1: "0", x2: object.totalWidth / 2, y2: -((15 * object.scale) / this.store.state?.scale), style: {
|
|
2461
|
+
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("line", { x1: object.totalWidth / 2, y1: "0", x2: object.totalWidth / 2, y2: -((15 * object.scale) / this.core.store.state?.scale), style: {
|
|
2374
2462
|
stroke: 'var(--kritzel-selection-border-color, #007AFF)',
|
|
2375
|
-
strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.store.state?.scale})`,
|
|
2376
|
-
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "rotation-handle", cx: object.totalWidth / 2, cy: -((15 * object.scale) / this.store.state?.scale), r: `${(baseHandleSize * object.scale) / this.store.state?.scale}`, style: {
|
|
2463
|
+
strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.core.store.state?.scale})`,
|
|
2464
|
+
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "rotation-handle", cx: object.totalWidth / 2, cy: -((15 * object.scale) / this.core.store.state?.scale), r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
|
|
2377
2465
|
fill: 'var(--kritzel-selection-handle-color, #000000)',
|
|
2378
|
-
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "rotation-handle-overlay", cx: object.totalWidth / 2, cy: -((15 * object.scale) / this.store.state?.scale), r: `${(baseHandleTouchSize * object.scale) / this.store.state?.scale}`, style: {
|
|
2466
|
+
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("circle", { class: "rotation-handle-overlay", cx: object.totalWidth / 2, cy: -((15 * object.scale) / this.core.store.state?.scale), r: `${(baseHandleTouchSize * object.scale) / this.core.store.state?.scale}`, style: {
|
|
2379
2467
|
fill: 'transparent',
|
|
2380
2468
|
cursor: 'grab',
|
|
2381
|
-
}, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), h("g", { style: { display: this.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' } }, "zIndex: ", object.zIndex), h("div", { style: { whiteSpace: 'nowrap' } }, "translateX: ", object.translateX), h("div", { style: { whiteSpace: 'nowrap' } }, "translateY: ", object.translateY), h("div", { style: { whiteSpace: 'nowrap' } }, "width: ", object.width), h("div", { style: { whiteSpace: 'nowrap' } }, "height: ", object.height), h("div", { style: { whiteSpace: 'nowrap' } }, "scale: ", object.scale), h("div", { style: { whiteSpace: 'nowrap' } }, "rotation: ", object.rotation), h("div", { style: { whiteSpace: 'nowrap' } }, "x: ", object.x), h("div", { style: { whiteSpace: 'nowrap' } }, "y: ", object.y)))))));
|
|
2382
|
-
}), h("svg", { key:
|
|
2383
|
-
height: this.store.state.currentPath?.height.toString(),
|
|
2384
|
-
width: this.store.state.currentPath?.width.toString(),
|
|
2469
|
+
}, 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' } }, "zIndex: ", object.zIndex), h("div", { style: { whiteSpace: 'nowrap' } }, "translateX: ", object.translateX), h("div", { style: { whiteSpace: 'nowrap' } }, "translateY: ", object.translateY), h("div", { style: { whiteSpace: 'nowrap' } }, "width: ", object.width), h("div", { style: { whiteSpace: 'nowrap' } }, "height: ", object.height), h("div", { style: { whiteSpace: 'nowrap' } }, "scale: ", object.scale), h("div", { style: { whiteSpace: 'nowrap' } }, "rotation: ", object.rotation), h("div", { style: { whiteSpace: 'nowrap' } }, "x: ", object.x), h("div", { style: { whiteSpace: 'nowrap' } }, "y: ", object.y)))))));
|
|
2470
|
+
}), h("svg", { key: "current-path", class: "object", xmlns: "http://www.w3.org/2000/svg", width: this.core.store.state.currentPath?.width, height: this.core.store.state.currentPath?.height, style: {
|
|
2385
2471
|
left: '0',
|
|
2386
2472
|
top: '0',
|
|
2387
|
-
zIndex: this.store.state.currentPath?.zIndex.toString(),
|
|
2473
|
+
zIndex: this.core.store.state.currentPath?.zIndex.toString(),
|
|
2388
2474
|
position: 'absolute',
|
|
2389
|
-
transform: this.store.state.currentPath?.transformationMatrix,
|
|
2475
|
+
transform: this.core.store.state.currentPath?.transformationMatrix,
|
|
2390
2476
|
transformOrigin: 'top left',
|
|
2391
2477
|
overflow: 'visible',
|
|
2392
|
-
}, viewBox: this.store.state.currentPath?.viewBox }, h("path", { key: '
|
|
2478
|
+
}, viewBox: this.core.store.state.currentPath?.viewBox }, h("path", { key: '6dedb398968d275166e042660c4718635b57da84', 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: '09ae0d7842918bcb4ae9fd16d416badc19942264', class: "context-menu", ref: el => (this.contextMenuElement = el), items: this.core.store.state.contextMenuItems, objects: this.core.store.state.selectionGroup?.objects || [], style: {
|
|
2393
2479
|
position: 'fixed',
|
|
2394
|
-
left: `${this.store.state.contextMenuX}px`,
|
|
2395
|
-
top: `${this.store.state.contextMenuY}px`,
|
|
2480
|
+
left: `${this.core.store.state.contextMenuX}px`,
|
|
2481
|
+
top: `${this.core.store.state.contextMenuY}px`,
|
|
2396
2482
|
zIndex: '10000',
|
|
2397
2483
|
}, onActionSelected: event => {
|
|
2398
2484
|
event.detail.action({
|
|
2399
|
-
x: (-this.store.state.translateX + this.store.state.contextMenuX) / this.store.state.scale,
|
|
2400
|
-
y: (-this.store.state.translateY + this.store.state.contextMenuY) / this.store.state.scale,
|
|
2401
|
-
}, this.store.state.selectionGroup?.objects);
|
|
2485
|
+
x: (-this.core.store.state.translateX + this.core.store.state.contextMenuX) / this.core.store.state.scale,
|
|
2486
|
+
y: (-this.core.store.state.translateY + this.core.store.state.contextMenuY) / this.core.store.state.scale,
|
|
2487
|
+
}, this.core.store.state.selectionGroup?.objects);
|
|
2402
2488
|
this.hideContextMenu();
|
|
2403
|
-
} })), this.store.state?.activeTool instanceof KritzelEraserTool && !this.store.state.isScaling && h("kritzel-cursor-trail", { key: '
|
|
2489
|
+
}, onClose: () => this.hideContextMenu() })), this.core.store.state?.activeTool instanceof KritzelEraserTool && !this.core.store.state.isScaling && h("kritzel-cursor-trail", { key: 'e0863ccf8c52ebef822827d8eeac62d3619134ca', core: this.core })));
|
|
2404
2490
|
}
|
|
2405
2491
|
static get watchers() { return {
|
|
2406
2492
|
"workspace": ["onWorkspaceChange"],
|
|
@@ -2420,7 +2506,7 @@ const KritzelFont = class {
|
|
|
2420
2506
|
size = 24;
|
|
2421
2507
|
color = '#000000';
|
|
2422
2508
|
render() {
|
|
2423
|
-
return (h(Host, { key: '
|
|
2509
|
+
return (h(Host, { key: '0d0f0f75b64f579ca236950334fafde7f0ef2a38' }, h("div", { key: 'e71524879ded9727891bdd43f1a41ae5eef49175', class: "font-preview", style: {
|
|
2424
2510
|
fontFamily: this.fontFamily,
|
|
2425
2511
|
fontSize: `${this.size}px`,
|
|
2426
2512
|
color: this.color
|
|
@@ -2467,7 +2553,7 @@ const KritzelFontFamily = class {
|
|
|
2467
2553
|
label: option.label,
|
|
2468
2554
|
style: { fontFamily: option.value },
|
|
2469
2555
|
}));
|
|
2470
|
-
return (h(Host, { key: '
|
|
2556
|
+
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"))));
|
|
2471
2557
|
}
|
|
2472
2558
|
};
|
|
2473
2559
|
KritzelFontFamily.style = kritzelFontFamilyCss;
|
|
@@ -2488,7 +2574,7 @@ const KritzelFontSize = class {
|
|
|
2488
2574
|
this.sizeChange.emit(size);
|
|
2489
2575
|
}
|
|
2490
2576
|
render() {
|
|
2491
|
-
return (h(Host, { key: '
|
|
2577
|
+
return (h(Host, { key: '583659340d8f3bfb2ff6f64f2cd692ac07cb32d6' }, this.sizes.map(size => (h("div", { class: {
|
|
2492
2578
|
'size-container': true,
|
|
2493
2579
|
'selected': this.selectedSize === size,
|
|
2494
2580
|
}, onClick: () => this.handleSizeClick(size) }, h("kritzel-font", { fontFamily: this.fontFamily, size: size }))))));
|
|
@@ -2496,7 +2582,7 @@ const KritzelFontSize = class {
|
|
|
2496
2582
|
};
|
|
2497
2583
|
KritzelFontSize.style = kritzelFontSizeCss;
|
|
2498
2584
|
|
|
2499
|
-
const kritzelIconCss = ":host{display:inline-flex;justify-content:center;align-items:center;}span{display:flex;align-items:center;width:100%;height:100%;}span>svg{width:100%;height:100%}";
|
|
2585
|
+
const kritzelIconCss = ":host{display:inline-flex;justify-content:center;align-items:center;color:var(--kritzel-icon-color, inherited)}span{display:flex;align-items:center;width:100%;height:100%;}span>svg{width:100%;height:100%}";
|
|
2500
2586
|
|
|
2501
2587
|
const KritzelIcon = class {
|
|
2502
2588
|
constructor(hostRef) {
|
|
@@ -2520,7 +2606,7 @@ const KritzelIcon = class {
|
|
|
2520
2606
|
};
|
|
2521
2607
|
KritzelIcon.style = kritzelIconCss;
|
|
2522
2608
|
|
|
2523
|
-
const kritzelMenuCss = ":host{position:relative;display:flex;flex-direction:column;background-color:var(--kritzel-menu-background-color, #ffffff);width:var(--kritzel-menu-width,
|
|
2609
|
+
const kritzelMenuCss = ":host{position:relative;display:flex;flex-direction:column;background-color:var(--kritzel-menu-background-color, #ffffff);width:var(--kritzel-menu-width, 200px);padding:var(--kritzel-menu-padding, 8px);border-radius:var(--kritzel-menu-border-radius, 12px);box-shadow:var(--kritzel-menu-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-menu-border, 1px solid #ebebeb);z-index:2;gap:var(--kritzel-menu-gap, 4px);overflow-y:auto;scrollbar-color:#ebebeb transparent;scrollbar-width:thin;max-height:300px}:host(:focus-visible){outline:var(--kritzel-menu-focus-outline, 2px solid #e3e3e3)}.has-open-child-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:3}";
|
|
2524
2610
|
|
|
2525
2611
|
const KritzelMenu = class {
|
|
2526
2612
|
constructor(hostRef) {
|
|
@@ -2543,7 +2629,7 @@ const KritzelMenu = class {
|
|
|
2543
2629
|
close;
|
|
2544
2630
|
selectedIndex = null;
|
|
2545
2631
|
async setFocus() {
|
|
2546
|
-
const firstItem = this.host.querySelector('kritzel-menu-item');
|
|
2632
|
+
const firstItem = this.host.shadowRoot.querySelector('kritzel-menu-item');
|
|
2547
2633
|
if (firstItem) {
|
|
2548
2634
|
firstItem.focus();
|
|
2549
2635
|
}
|
|
@@ -2579,12 +2665,12 @@ const KritzelMenu = class {
|
|
|
2579
2665
|
this.itemCloseChildMenu.emit(event.detail);
|
|
2580
2666
|
};
|
|
2581
2667
|
render() {
|
|
2582
|
-
return (h(Host, { key: '
|
|
2668
|
+
return (h(Host, { key: 'd971df2bd948b07f7bf2abc589c226d57891d05e', tabIndex: 0, onClick: e => e.stopPropagation() }, this.openChildMenuItem && h("div", { key: 'dfa6846429aac15a5912b87acd45610663200a3e', 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 })))));
|
|
2583
2669
|
}
|
|
2584
2670
|
};
|
|
2585
2671
|
KritzelMenu.style = kritzelMenuCss;
|
|
2586
2672
|
|
|
2587
|
-
const kritzelMenuItemCss = ":host{position:relative;display:flex;align-items:center;justify-content:space-between;width:100%;padding:var(--kritzel-menu-item-padding, 8px);box-sizing:border-box;gap:16px;height:var(--kritzel-menu-item-height, 40px);min-height:var(--kritzel-menu-item-min-height, 40px);font-family:sans-serif;font-size:var(--kritzel-menu-item-font-size, 14px);border-radius:var(--kritzel-menu-item-border-radius, 12px);outline:none;cursor:default}:host(:hover) .menu-item-overlay,:host(:focus-within) .menu-item-overlay{background-color:var(--kritzel-menu-item-
|
|
2673
|
+
const kritzelMenuItemCss = ":host{position:relative;display:flex;align-items:center;justify-content:space-between;width:100%;padding:var(--kritzel-menu-item-padding, 8px);box-sizing:border-box;gap:16px;height:var(--kritzel-menu-item-height, 40px);min-height:var(--kritzel-menu-item-min-height, 40px);font-family:sans-serif;font-size:var(--kritzel-menu-item-font-size, 14px);color:var(--kritzel-menu-item-color, #333333);border-radius:var(--kritzel-menu-item-border-radius, 12px);outline:none;cursor:default}:host(:hover) .menu-item-overlay,:host(:focus-within) .menu-item-overlay{background-color:var(--kritzel-menu-item-overlay-background-color, hsl(0, 0%, 0%, 4.3%))}:host(.selected){background-color:var(--kritzel-menu-item-selected-bg, #007aff);color:var(--kritzel-menu-item-selected-color, #ffffff)}:host(.selected) .action-button{color:var(--kritzel-menu-item-selected-color, #ffffff)}:host(.selected.editing){background-color:var(--kritzel-menu-item-selected-bg, #007aff)}:host(.selected) .edit-input{color:var(--kritzel-menu-item-selected-color, #ffffff)}:host(.selected) .action-button kritzel-icon{--kritzel-icon-color:var(--kritzel-menu-item-selected-color, #ffffff)}kritzel-icon{--kritzel-icon-color:var(--kritzel-menu-item-color, #333333)}:host(.selected) .edit-input::selection{background-color:var(--kritzel-menu-item-input-selection-color, rgba(255, 255, 255, 0.16))}:host(.editing){background-color:var(--kritzel-menu-item-editing-background-color, hsl(0, 0%, 0%, 4.3%))}:host(.disabled){opacity:0.5;pointer-events:none !important}:host(.child-open){background-color:var(--kritzel-menu-item-child-open-background-color, hsl(0, 0%, 0%, 4.3%))}:host(.child-open.selected){background-color:var(--kritzel-menu-item-selected-bg, #007aff)}.menu-item-overlay{position:absolute;inset:0;background-color:transparent;z-index:0;pointer-events:none;border-radius:var(--kritzel-menu-item-border-radius, 12px)}.menu-item-content{display:flex;align-items:center;gap:8px;position:relative;z-index:1;height:100%}.left{justify-content:flex-start;flex:1;min-width:0}.left>div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.right{justify-content:flex-end}.edit-input{flex:1;height:var(--kritzel-menu-item-input-height, 24px);padding:0;background-color:transparent;border-radius:0;border:none;border-bottom:1px solid var(--kritzel-menu-item-input-border, #ccc);font-size:var(--kritzel-context-menu-item-font-size, 14px);width:100%;min-width:0;box-sizing:border-box;outline:none}.edit-input::selection{background-color:var(--kritzel-menu-item-input-selection-color, #007bff);color:var(--kritzel-menu-item-input-selection-text-color, #ffffff)}.action-button{padding:4px;border-radius:8px;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;background-color:transparent;background:transparent;outline:none;-webkit-tap-highlight-color:transparent}.action-button:hover,.action-button:focus{background-color:var(--kritzel-menu-item-button-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.action-button.disabled{pointer-events:none;opacity:0.5}";
|
|
2588
2674
|
|
|
2589
2675
|
const KritzelMenuItem = class {
|
|
2590
2676
|
constructor(hostRef) {
|
|
@@ -2610,18 +2696,32 @@ const KritzelMenuItem = class {
|
|
|
2610
2696
|
itemCloseChildMenu;
|
|
2611
2697
|
isDirty = false;
|
|
2612
2698
|
inputRef;
|
|
2613
|
-
|
|
2699
|
+
focusInput() {
|
|
2614
2700
|
if (this.item.isEditing && this.inputRef && !this.isDirty) {
|
|
2615
2701
|
this.inputRef.focus();
|
|
2616
|
-
|
|
2702
|
+
if (KritzelDevicesHelper.isIOS()) {
|
|
2703
|
+
const length = this.inputRef.value.length;
|
|
2704
|
+
this.inputRef.setSelectionRange(length, length);
|
|
2705
|
+
}
|
|
2706
|
+
else {
|
|
2707
|
+
this.inputRef.select();
|
|
2708
|
+
}
|
|
2617
2709
|
}
|
|
2618
2710
|
}
|
|
2711
|
+
componentDidLoad() {
|
|
2712
|
+
this.setDeviceSpecificStyles();
|
|
2713
|
+
this.focusInput();
|
|
2714
|
+
}
|
|
2619
2715
|
componentDidUpdate() {
|
|
2620
|
-
|
|
2621
|
-
this.inputRef.focus();
|
|
2622
|
-
this.inputRef.select();
|
|
2623
|
-
}
|
|
2716
|
+
this.focusInput();
|
|
2624
2717
|
}
|
|
2718
|
+
setDeviceSpecificStyles = () => {
|
|
2719
|
+
const isTouchDevice = KritzelDevicesHelper.isTouchDevice();
|
|
2720
|
+
if (isTouchDevice) {
|
|
2721
|
+
this.host.style.setProperty('--kritzel-menu-item-overlay-background-color', 'transparent');
|
|
2722
|
+
this.host.style.setProperty('--kritzel-menu-item-button-hover-background-color', 'transparent');
|
|
2723
|
+
}
|
|
2724
|
+
};
|
|
2625
2725
|
handleItemSelect = (event) => {
|
|
2626
2726
|
event.stopPropagation();
|
|
2627
2727
|
this.itemSelect.emit({ item: this.item, parent: this.parent });
|
|
@@ -2662,16 +2762,16 @@ const KritzelMenuItem = class {
|
|
|
2662
2762
|
renderEditMode() {
|
|
2663
2763
|
return [
|
|
2664
2764
|
h("div", { class: "menu-item-content left" }, h("input", { ref: el => (this.inputRef = el), type: "text", class: "edit-input", value: this.item.label, onInput: this.handleInputChange })),
|
|
2665
|
-
h("div", { class: "menu-item-content right" }, h("div", { tabIndex:
|
|
2765
|
+
h("div", { class: "menu-item-content right" }, h("div", { tabIndex: 0, class: "action-button", onClick: this.handleCancel }, h("kritzel-icon", { name: "x", size: 16 })), h("div", { tabIndex: !this.isDirty && !this.item.isNewItem ? -1 : 0, class: { 'action-button': true, 'disabled': !this.isDirty && !this.item.isNewItem }, onClick: this.handleSave }, h("kritzel-icon", { name: "check", size: 16 }))),
|
|
2666
2766
|
];
|
|
2667
2767
|
}
|
|
2668
2768
|
render() {
|
|
2669
|
-
return (h(Host, { key: '
|
|
2769
|
+
return (h(Host, { key: 'a35e1e3427568f436a36b43ba87af3710a4e83c5', tabIndex: this.item.isDisabled ? -1 : 0, class: {
|
|
2670
2770
|
'selected': this.item.isSelected,
|
|
2671
2771
|
'editing': this.item.isEditing,
|
|
2672
2772
|
'disabled': this.item.isDisabled,
|
|
2673
2773
|
'child-open': this.item.isChildMenuOpen,
|
|
2674
|
-
}, onClick: this.handleItemSelect }, h("div", { key: '
|
|
2774
|
+
}, onClick: this.handleItemSelect }, h("div", { key: '42eef5a16b9b164839c1fe133e38ecb505c07632', class: "menu-item-overlay" }), this.item.isEditing ? this.renderEditMode() : this.renderViewMode()));
|
|
2675
2775
|
}
|
|
2676
2776
|
static get watchers() { return {
|
|
2677
2777
|
"item": ["onItemChange"]
|
|
@@ -2679,6 +2779,70 @@ const KritzelMenuItem = class {
|
|
|
2679
2779
|
};
|
|
2680
2780
|
KritzelMenuItem.style = kritzelMenuItemCss;
|
|
2681
2781
|
|
|
2782
|
+
class KritzelHTMLHelper {
|
|
2783
|
+
static getNumericValueFromStyle(element, property) {
|
|
2784
|
+
const value = window.getComputedStyle(element).getPropertyValue(property);
|
|
2785
|
+
return parseFloat(value) || 0;
|
|
2786
|
+
}
|
|
2787
|
+
static getScrollableParent(element) {
|
|
2788
|
+
if (!element) {
|
|
2789
|
+
return window;
|
|
2790
|
+
}
|
|
2791
|
+
const parent = element.parentNode?.host ?? element.parentElement;
|
|
2792
|
+
if (!parent || parent.tagName === 'BODY') {
|
|
2793
|
+
return window;
|
|
2794
|
+
}
|
|
2795
|
+
const style = window.getComputedStyle(parent);
|
|
2796
|
+
if (style.overflow === 'auto' || style.overflowY === 'auto' || style.overflow === 'scroll' || style.overflowY === 'scroll') {
|
|
2797
|
+
return parent;
|
|
2798
|
+
}
|
|
2799
|
+
return this.getScrollableParent(parent);
|
|
2800
|
+
}
|
|
2801
|
+
static isElementInViewport(element) {
|
|
2802
|
+
if (!element) {
|
|
2803
|
+
return false;
|
|
2804
|
+
}
|
|
2805
|
+
const scrollableParent = this.getScrollableParent(element);
|
|
2806
|
+
const rect = element.getBoundingClientRect();
|
|
2807
|
+
if (scrollableParent === window) {
|
|
2808
|
+
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
2809
|
+
const viewportWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
2810
|
+
return rect.top >= 0 && rect.left >= 0 && rect.bottom <= viewportHeight && rect.right <= viewportWidth;
|
|
2811
|
+
}
|
|
2812
|
+
const parentRect = scrollableParent.getBoundingClientRect();
|
|
2813
|
+
return rect.top >= parentRect.top && rect.left >= parentRect.left && rect.bottom <= parentRect.bottom && rect.right <= parentRect.right;
|
|
2814
|
+
}
|
|
2815
|
+
static getFocusableElements(root) {
|
|
2816
|
+
if (!root)
|
|
2817
|
+
return [];
|
|
2818
|
+
const focusableElements = [];
|
|
2819
|
+
const focusableSelector = 'a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), details, [tabindex]:not([tabindex="-1"])';
|
|
2820
|
+
const isVisible = (el) => {
|
|
2821
|
+
return el.offsetParent !== null;
|
|
2822
|
+
};
|
|
2823
|
+
const find = (element) => {
|
|
2824
|
+
// Check if the element itself is focusable
|
|
2825
|
+
if (element instanceof HTMLElement && element.matches(focusableSelector) && !element.hasAttribute('disabled') && isVisible(element)) {
|
|
2826
|
+
focusableElements.push(element);
|
|
2827
|
+
}
|
|
2828
|
+
// Traverse shadow DOM
|
|
2829
|
+
if (element.shadowRoot) {
|
|
2830
|
+
Array.from(element.shadowRoot.children).forEach(find);
|
|
2831
|
+
}
|
|
2832
|
+
// Traverse slotted content
|
|
2833
|
+
if (element.tagName === 'SLOT') {
|
|
2834
|
+
element.assignedElements({ flatten: true }).forEach(find);
|
|
2835
|
+
}
|
|
2836
|
+
// Traverse light DOM children if there is no shadow root
|
|
2837
|
+
if (!element.shadowRoot) {
|
|
2838
|
+
Array.from(element.children).forEach(find);
|
|
2839
|
+
}
|
|
2840
|
+
};
|
|
2841
|
+
find(root);
|
|
2842
|
+
return focusableElements;
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
|
|
2682
2846
|
const KritzelPortal = class {
|
|
2683
2847
|
constructor(hostRef) {
|
|
2684
2848
|
registerInstance(this, hostRef);
|
|
@@ -2754,7 +2918,7 @@ const KritzelPortal = class {
|
|
|
2754
2918
|
return activeEl;
|
|
2755
2919
|
}
|
|
2756
2920
|
trapFocus(event) {
|
|
2757
|
-
const focusableElements =
|
|
2921
|
+
const focusableElements = KritzelHTMLHelper.getFocusableElements(this.host);
|
|
2758
2922
|
if (focusableElements.length === 0)
|
|
2759
2923
|
return;
|
|
2760
2924
|
const firstFocusable = focusableElements[0];
|
|
@@ -2775,51 +2939,12 @@ const KritzelPortal = class {
|
|
|
2775
2939
|
}
|
|
2776
2940
|
}
|
|
2777
2941
|
}
|
|
2778
|
-
getFocusableElements(root) {
|
|
2779
|
-
if (!root)
|
|
2780
|
-
return [];
|
|
2781
|
-
const focusableElements = [];
|
|
2782
|
-
const focusableSelector = 'a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), details, [tabindex]:not([tabindex="-1"])';
|
|
2783
|
-
const isVisible = (el) => {
|
|
2784
|
-
return el.offsetParent !== null;
|
|
2785
|
-
};
|
|
2786
|
-
// Check if the root element itself is focusable
|
|
2787
|
-
if (root.matches(focusableSelector) && !root.hasAttribute('disabled') && isVisible(root)) {
|
|
2788
|
-
focusableElements.push(root);
|
|
2789
|
-
}
|
|
2790
|
-
// Function to recursively find focusable elements
|
|
2791
|
-
const findFocusable = (element) => {
|
|
2792
|
-
// Search in shadow root
|
|
2793
|
-
if (element.shadowRoot) {
|
|
2794
|
-
Array.from(element.shadowRoot.querySelectorAll(focusableSelector)).forEach(el => {
|
|
2795
|
-
if (isVisible(el)) {
|
|
2796
|
-
focusableElements.push(el);
|
|
2797
|
-
}
|
|
2798
|
-
});
|
|
2799
|
-
Array.from(element.shadowRoot.children).forEach(findFocusable);
|
|
2800
|
-
}
|
|
2801
|
-
// Search in light DOM
|
|
2802
|
-
Array.from(element.querySelectorAll(focusableSelector)).forEach(el => {
|
|
2803
|
-
if (!focusableElements.includes(el) && isVisible(el)) {
|
|
2804
|
-
focusableElements.push(el);
|
|
2805
|
-
}
|
|
2806
|
-
});
|
|
2807
|
-
// Handle slotted content
|
|
2808
|
-
if (element.tagName === 'SLOT') {
|
|
2809
|
-
element.assignedElements({ flatten: true }).forEach(el => findFocusable(el));
|
|
2810
|
-
}
|
|
2811
|
-
Array.from(element.children).forEach(findFocusable);
|
|
2812
|
-
};
|
|
2813
|
-
findFocusable(root);
|
|
2814
|
-
// Return unique elements in document order
|
|
2815
|
-
return [...new Set(focusableElements)];
|
|
2816
|
-
}
|
|
2817
2942
|
get firstFocusableElement() {
|
|
2818
2943
|
const slotEl = this.host.shadowRoot?.querySelector('slot');
|
|
2819
2944
|
const firstAssigned = slotEl?.assignedElements({ flatten: true })[0];
|
|
2820
2945
|
if (!firstAssigned)
|
|
2821
2946
|
return null;
|
|
2822
|
-
const focusable =
|
|
2947
|
+
const focusable = KritzelHTMLHelper.getFocusableElements(firstAssigned);
|
|
2823
2948
|
return focusable[0] ?? firstAssigned;
|
|
2824
2949
|
}
|
|
2825
2950
|
get lastAddedPortal() {
|
|
@@ -2878,25 +3003,26 @@ const KritzelPortal = class {
|
|
|
2878
3003
|
this.portal.style.left = `${left}px`;
|
|
2879
3004
|
}
|
|
2880
3005
|
render() {
|
|
2881
|
-
return (h(Host, { key: '
|
|
3006
|
+
return (h(Host, { key: 'a994d8ab8c758bc92836693f35f8d9415913cfff', style: { display: this.anchor ? 'block' : 'none' } }, h("slot", { key: 'a9b9a71d82e9b57de24e5ecfa90197a27ed691c4' })));
|
|
2882
3007
|
}
|
|
2883
3008
|
static get watchers() { return {
|
|
2884
3009
|
"anchor": ["anchorChanged"]
|
|
2885
3010
|
}; }
|
|
2886
3011
|
};
|
|
2887
3012
|
|
|
2888
|
-
const kritzelSplitButtonCss = ":host{position:relative;display:flex;align-items:center;font-family:sans-serif;z-index:1;padding:var(--kritzel-split-button-padding, 4px);background-color:var(--kritzel-split-button-background-color, #ffffff);border-radius:var(--kritzel-split-button-border-radius, 12px);box-shadow:var(--kritzel-split-button-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-split-button-border, 1px solid #ebebeb);gap:var(--kritzel-split-button-gap, 4px)}:host(
|
|
3013
|
+
const kritzelSplitButtonCss = ":host{position:relative;display:flex;align-items:center;font-family:sans-serif;z-index:1;padding:var(--kritzel-split-button-padding, 4px);background-color:var(--kritzel-split-button-background-color, #ffffff);border-radius:var(--kritzel-split-button-border-radius, 12px);box-shadow:var(--kritzel-split-button-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-split-button-border, 1px solid #ebebeb);gap:var(--kritzel-split-button-gap, 4px)}:host(.mobile){--kritzel-split-button-hover-background-color:transparent}button{border:none;background-color:transparent;padding:0;margin:0;font-family:inherit;font-size:inherit;color:inherit;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;text-align:center;display:flex;align-items:center;justify-content:center;pointer-events:all;-webkit-tap-highlight-color:transparent}.split-main-button,.split-menu-button{height:auto;display:flex;align-items:center;padding:var(--kritzel-split-button-padding, 8px);background-color:var(--kritzel-split-button-background-color, #ffffff);border-radius:var(--kritzel-split-button-border-radius, 12px);font-size:var(--kritzel-split-button-font-size, 14px)}.split-main-button:hover,.split-menu-button:hover{background-color:var(--kritzel-split-button-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.split-main-button:focus,.split-menu-button:focus{outline:none;background-color:var(--kritzel-split-button-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.split-main-button{gap:var(--kritzel-split-button-gap, 4px)}.split-menu-button{border-left:none;justify-content:center}.split-divider{width:var(--kritzel-split-button-divider-width, 1px);height:24px;background-color:var(--kritzel-split-button-divider-background-color, hsl(0, 0%, 0%, 4.3%))}:disabled{pointer-events:none;opacity:0.5}";
|
|
2889
3014
|
|
|
2890
3015
|
const KritzelSplitButton = class {
|
|
2891
3016
|
constructor(hostRef) {
|
|
2892
3017
|
registerInstance(this, hostRef);
|
|
2893
|
-
this.
|
|
3018
|
+
this.mainButtonClick = createEvent(this, "mainButtonClick");
|
|
2894
3019
|
this.itemSelect = createEvent(this, "itemSelect");
|
|
2895
3020
|
this.itemSave = createEvent(this, "itemSave");
|
|
2896
3021
|
this.itemCancel = createEvent(this, "itemCancel");
|
|
2897
3022
|
this.itemToggleChildMenu = createEvent(this, "itemToggleChildMenu");
|
|
2898
3023
|
this.itemCloseChildMenu = createEvent(this, "itemCloseChildMenu");
|
|
2899
|
-
this.
|
|
3024
|
+
this.menuOpen = createEvent(this, "menuOpen");
|
|
3025
|
+
this.menuClose = createEvent(this, "menuClose");
|
|
2900
3026
|
}
|
|
2901
3027
|
get host() { return getElement(this); }
|
|
2902
3028
|
buttonIcon = 'plus';
|
|
@@ -2904,13 +3030,14 @@ const KritzelSplitButton = class {
|
|
|
2904
3030
|
items = [];
|
|
2905
3031
|
mainButtonDisabled = false;
|
|
2906
3032
|
menuButtonDisabled = false;
|
|
2907
|
-
|
|
3033
|
+
mainButtonClick;
|
|
2908
3034
|
itemSelect;
|
|
2909
3035
|
itemSave;
|
|
2910
3036
|
itemCancel;
|
|
2911
3037
|
itemToggleChildMenu;
|
|
2912
3038
|
itemCloseChildMenu;
|
|
2913
|
-
|
|
3039
|
+
menuOpen;
|
|
3040
|
+
menuClose;
|
|
2914
3041
|
isMenuOpen = false;
|
|
2915
3042
|
isTouchDevice = KritzelDevicesHelper.isTouchDevice();
|
|
2916
3043
|
anchorElement;
|
|
@@ -2919,11 +3046,18 @@ const KritzelSplitButton = class {
|
|
|
2919
3046
|
async open() {
|
|
2920
3047
|
if (this.isMenuOpen)
|
|
2921
3048
|
return;
|
|
2922
|
-
this.
|
|
3049
|
+
this.isMenuOpen = true;
|
|
3050
|
+
this.anchorElement = this.host;
|
|
3051
|
+
this.menuOpen.emit();
|
|
3052
|
+
}
|
|
3053
|
+
async focusMenu() {
|
|
3054
|
+
if (this.menuRef) {
|
|
3055
|
+
await this.menuRef.setFocus();
|
|
3056
|
+
}
|
|
2923
3057
|
}
|
|
2924
3058
|
handleButtonClick = (event) => {
|
|
2925
3059
|
event.stopPropagation();
|
|
2926
|
-
this.
|
|
3060
|
+
this.mainButtonClick.emit();
|
|
2927
3061
|
};
|
|
2928
3062
|
toggleMenu = (event) => {
|
|
2929
3063
|
event.stopPropagation();
|
|
@@ -2938,11 +3072,13 @@ const KritzelSplitButton = class {
|
|
|
2938
3072
|
event.stopPropagation();
|
|
2939
3073
|
this.isMenuOpen = true;
|
|
2940
3074
|
this.anchorElement = this.host;
|
|
3075
|
+
this.menuOpen.emit();
|
|
2941
3076
|
};
|
|
2942
3077
|
closeMenu = () => {
|
|
2943
3078
|
this.isMenuOpen = false;
|
|
2944
3079
|
this.anchorElement = null;
|
|
2945
|
-
this.
|
|
3080
|
+
this.splitMenuButtonRef?.blur();
|
|
3081
|
+
this.menuClose.emit();
|
|
2946
3082
|
};
|
|
2947
3083
|
handleItemSelect = event => {
|
|
2948
3084
|
this.itemSelect.emit(event.detail);
|
|
@@ -2960,12 +3096,12 @@ const KritzelSplitButton = class {
|
|
|
2960
3096
|
this.itemCloseChildMenu.emit(event.detail);
|
|
2961
3097
|
};
|
|
2962
3098
|
render() {
|
|
2963
|
-
return (h(Host, { key: '
|
|
3099
|
+
return (h(Host, { key: '2521559224e78ed1984446320a1601e77ccf2843', class: { mobile: this.isTouchDevice } }, h("button", { key: 'a924ad4590506cb5209ef9fa1babca5312ec0513', class: "split-main-button", tabIndex: 0, onClick: this.handleButtonClick, disabled: this.mainButtonDisabled }, this.buttonIcon && h("kritzel-icon", { key: '214565d158d4d3c06ad883559aa7bac2827a593f', name: this.buttonIcon })), h("div", { key: '2f7d189c46c08227c3006d226a0ee3065f241bf4', class: "split-divider" }), h("button", { key: '4d6e2e224e3719fe3685ee289af94680c120abf6', ref: el => (this.splitMenuButtonRef = el), class: "split-menu-button", tabIndex: 0, onClick: this.toggleMenu, disabled: this.menuButtonDisabled }, h("kritzel-icon", { key: 'bc8176681dfedde9d13b9af561d8bdff8613098f', name: this.dropdownIcon })), h("kritzel-portal", { key: 'afb44cd208f52350cbc82e050d6dee0ba734391d', anchor: this.anchorElement, offsetY: 4, onClose: this.closeMenu }, h("kritzel-menu", { key: 'b28f04138daa8777e6c9b2aa7fa3b5f2f62fd914', 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 }))));
|
|
2964
3100
|
}
|
|
2965
3101
|
};
|
|
2966
3102
|
KritzelSplitButton.style = kritzelSplitButtonCss;
|
|
2967
3103
|
|
|
2968
|
-
const kritzelStrokeSizeCss = ":host{display:flex;align-items:flex-start;gap:8px;padding:8px;box-sizing:border-box}.size-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}.size-container:hover{background-color:var(--kritzel-stroke-size-hover-background-color, #ebebeb)}.size-container.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-stroke-size-selected-background-color, #ebebeb)}";
|
|
3104
|
+
const kritzelStrokeSizeCss = ":host{display:flex;align-items:flex-start;gap:8px;padding:8px;box-sizing:border-box}.size-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}.size-container:focus-visible{outline:var(--kritzel-stroke-size-focus-outline, 2px auto #e3e3e3)}.size-container:hover{background-color:var(--kritzel-stroke-size-hover-background-color, #ebebeb)}.size-container.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-stroke-size-selected-background-color, #ebebeb)}";
|
|
2969
3105
|
|
|
2970
3106
|
const KritzelStrokeSize = class {
|
|
2971
3107
|
constructor(hostRef) {
|
|
@@ -2980,7 +3116,7 @@ const KritzelStrokeSize = class {
|
|
|
2980
3116
|
this.sizeChange.emit(size);
|
|
2981
3117
|
}
|
|
2982
3118
|
render() {
|
|
2983
|
-
return (h(Host, { key: '
|
|
3119
|
+
return (h(Host, { key: '001a0ef8408d19532b57a521929c0cba54e99c52' }, this.sizes.map(size => (h("div", { tabIndex: 0, class: {
|
|
2984
3120
|
'size-container': true,
|
|
2985
3121
|
'selected': this.selectedSize === size,
|
|
2986
3122
|
}, onClick: () => this.handleSizeClick(size) }, h("kritzel-color", { value: '#000000', size: size }))))));
|
|
@@ -2994,19 +3130,38 @@ const MOBILE_BREAKPOINT = 768;
|
|
|
2994
3130
|
const KritzelTooltip = class {
|
|
2995
3131
|
constructor(hostRef) {
|
|
2996
3132
|
registerInstance(this, hostRef);
|
|
3133
|
+
this.tooltipClosed = createEvent(this, "tooltipClosed");
|
|
2997
3134
|
}
|
|
3135
|
+
get host() { return getElement(this); }
|
|
2998
3136
|
isVisible = false;
|
|
2999
3137
|
anchorElement;
|
|
3000
3138
|
arrowSize = 8;
|
|
3001
3139
|
offsetY = 24;
|
|
3002
|
-
|
|
3140
|
+
tooltipClosed;
|
|
3003
3141
|
positionX = 0;
|
|
3004
3142
|
arrowOffset = '0px';
|
|
3005
3143
|
isMobileView = window.innerWidth < MOBILE_BREAKPOINT;
|
|
3144
|
+
handleOutsideClick(event) {
|
|
3145
|
+
if (!this.isVisible)
|
|
3146
|
+
return;
|
|
3147
|
+
const target = event.target;
|
|
3148
|
+
if (!this.host.contains(target)) {
|
|
3149
|
+
this.tooltipClosed.emit();
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3006
3152
|
handleWindowResize() {
|
|
3007
3153
|
this.isMobileView = window.innerWidth < MOBILE_BREAKPOINT;
|
|
3008
3154
|
this.calculateAdjustedPosition();
|
|
3009
3155
|
}
|
|
3156
|
+
async focusContent() {
|
|
3157
|
+
const focusableElements = KritzelHTMLHelper.getFocusableElements(this.host);
|
|
3158
|
+
if (focusableElements.length > 0) {
|
|
3159
|
+
focusableElements[0].focus();
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
componentDidLoad() {
|
|
3163
|
+
this.focusSlottedContent();
|
|
3164
|
+
}
|
|
3010
3165
|
componentWillLoad() {
|
|
3011
3166
|
this.isMobileView = window.innerWidth < MOBILE_BREAKPOINT;
|
|
3012
3167
|
this.calculateAdjustedPosition();
|
|
@@ -3014,10 +3169,18 @@ const KritzelTooltip = class {
|
|
|
3014
3169
|
componentWillUpdate() {
|
|
3015
3170
|
this.calculateAdjustedPosition();
|
|
3016
3171
|
}
|
|
3172
|
+
focusSlottedContent() {
|
|
3173
|
+
const slot = this.host.shadowRoot?.querySelector('slot');
|
|
3174
|
+
const assignedElements = slot?.assignedElements() || [];
|
|
3175
|
+
if (assignedElements.length > 0) {
|
|
3176
|
+
const firstElement = assignedElements[0];
|
|
3177
|
+
firstElement.focus();
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3017
3180
|
calculateAdjustedPosition() {
|
|
3018
3181
|
if (this.isVisible && this.anchorElement) {
|
|
3019
3182
|
const anchorRect = this.anchorElement.getBoundingClientRect();
|
|
3020
|
-
const tooltipContent = this.
|
|
3183
|
+
const tooltipContent = this.host.shadowRoot?.querySelector('.tooltip-content');
|
|
3021
3184
|
if (!this.isMobileView) {
|
|
3022
3185
|
this.positionX = anchorRect.left + anchorRect.width / 2;
|
|
3023
3186
|
this.arrowOffset = `calc(${50}% - ${this.arrowSize}px)`;
|
|
@@ -3030,23 +3193,23 @@ const KritzelTooltip = class {
|
|
|
3030
3193
|
}
|
|
3031
3194
|
}
|
|
3032
3195
|
render() {
|
|
3033
|
-
return (h(Host, { key: '
|
|
3196
|
+
return (h(Host, { key: '8c3aeff60625f43f129afa70367cdb7a68a4b271', style: {
|
|
3034
3197
|
position: 'fixed',
|
|
3035
3198
|
zIndex: '9999',
|
|
3036
3199
|
transition: 'opacity 0.3s ease-in-out, transform 0.3s ease-in-out',
|
|
3037
3200
|
visibility: this.isVisible ? 'visible' : 'hidden',
|
|
3038
3201
|
left: !this.isMobileView ? `${this.positionX}px` : '50%',
|
|
3039
3202
|
marginBottom: `${this.offsetY + this.arrowSize}px`,
|
|
3040
|
-
} }, h("div", { key: '
|
|
3203
|
+
} }, h("div", { key: 'b22b606c2a836c2c9bbe21c6b470754753ccb309', class: "tooltip-content", onClick: event => event.stopPropagation() }, h("slot", { key: '783403f4b5560012c9f6bd184a8c5eb26428e148' }), h("div", { key: 'bb98400edc5c6e05fd4ed2a476a5821f93964b8e', class: "tooltip-arrow-wrapper", style: {
|
|
3041
3204
|
position: 'fixed',
|
|
3042
3205
|
left: this.arrowOffset,
|
|
3043
3206
|
bottom: `-${this.arrowSize * 2}px`,
|
|
3044
|
-
} }, h("div", { key: '
|
|
3207
|
+
} }, h("div", { key: '850a058d635113a7870f25fa288a6447394c53ed', class: "tooltip-arrow", style: {
|
|
3045
3208
|
borderLeft: `${this.arrowSize}px solid transparent`,
|
|
3046
3209
|
borderRight: `${this.arrowSize}px solid transparent`,
|
|
3047
3210
|
borderTop: `${this.arrowSize}px solid var(--kritzel-controls-tooltip-background-color, #ffffff)`,
|
|
3048
3211
|
filter: 'drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2))',
|
|
3049
|
-
} }), h("div", { key: '
|
|
3212
|
+
} }), h("div", { key: 'bbb3dc2673e2dfe4443ad80540dfc9e5a25c6c06', class: "tooltip-arrow-rect", style: {
|
|
3050
3213
|
position: 'relative',
|
|
3051
3214
|
width: `${this.arrowSize * 2}px`,
|
|
3052
3215
|
height: `${this.arrowSize}px`,
|
|
@@ -3057,7 +3220,7 @@ const KritzelTooltip = class {
|
|
|
3057
3220
|
};
|
|
3058
3221
|
KritzelTooltip.style = kritzelTooltipCss;
|
|
3059
3222
|
|
|
3060
|
-
const kritzelUtilityPanelCss = ":host{display:flex;flex-direction:row;align-items:center;padding:4px;gap:8px;border-top-left-radius:12px;border-top-right-radius:12px;background-color:rgb(226, 226, 226);width:fit-content;user-select:none}.utility-button{display:flex;justify-content:center;align-items:center;width:28px;height:28px;padding:8px 4px;border:none;outline:none;background:none;cursor:pointer;color:#333333;-webkit-tap-highlight-color:transparent}.utility-separator{width:1px;height:16px;background-color:hsl(0, 0%, 0%, 4.3%)}";
|
|
3223
|
+
const kritzelUtilityPanelCss = ":host{display:flex;flex-direction:row;align-items:center;padding:4px;gap:8px;border-top-left-radius:12px;border-top-right-radius:12px;background-color:rgb(226, 226, 226);width:fit-content;user-select:none}.utility-button{display:flex;justify-content:center;align-items:center;width:28px;height:28px;padding:8px 4px;border:none;outline:none;background:none;cursor:pointer;color:#333333;-webkit-tap-highlight-color:transparent;border-radius:var(--kritzel-utility-panel-button-border-radius, 8px)}.utility-button:focus{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.utility-separator{width:1px;height:16px;background-color:hsl(0, 0%, 0%, 4.3%)}";
|
|
3061
3224
|
|
|
3062
3225
|
const KritzelUtilityPanel = class {
|
|
3063
3226
|
constructor(hostRef) {
|
|
@@ -3082,7 +3245,7 @@ const KritzelUtilityPanel = class {
|
|
|
3082
3245
|
this.redo.emit();
|
|
3083
3246
|
}
|
|
3084
3247
|
render() {
|
|
3085
|
-
return (h(Host, { key: '
|
|
3248
|
+
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() }))));
|
|
3086
3249
|
}
|
|
3087
3250
|
};
|
|
3088
3251
|
KritzelUtilityPanel.style = kritzelUtilityPanelCss;
|
|
@@ -3131,9 +3294,9 @@ const KritzelWorkspaceManager = class {
|
|
|
3131
3294
|
this.workspaceChange.emit(item.value);
|
|
3132
3295
|
}
|
|
3133
3296
|
async add() {
|
|
3297
|
+
await this.splitButtonRef.open();
|
|
3134
3298
|
this.newWorkspace = new KritzelWorkspace(ObjectHelper.generateUUID(), 'New Workspace');
|
|
3135
3299
|
this.editingItemId = this.newWorkspace.id;
|
|
3136
|
-
await this.splitButtonRef.open();
|
|
3137
3300
|
}
|
|
3138
3301
|
edit(item) {
|
|
3139
3302
|
this.openChildMenuItem = null;
|
|
@@ -3144,11 +3307,14 @@ const KritzelWorkspaceManager = class {
|
|
|
3144
3307
|
}
|
|
3145
3308
|
async save(item) {
|
|
3146
3309
|
if (this.newWorkspace) {
|
|
3147
|
-
|
|
3310
|
+
this.newWorkspace.name = item.label;
|
|
3311
|
+
await this.kritzelEngineRef.createWorkspace(this.newWorkspace);
|
|
3148
3312
|
this.workspaceChange.emit(this.newWorkspace);
|
|
3149
3313
|
}
|
|
3150
3314
|
else {
|
|
3151
|
-
|
|
3315
|
+
const workspace = item.value;
|
|
3316
|
+
workspace.name = item.label;
|
|
3317
|
+
await this.kritzelEngineRef.updateWorkspace(workspace);
|
|
3152
3318
|
}
|
|
3153
3319
|
this.editingItemId = null;
|
|
3154
3320
|
this.newWorkspace = null;
|
|
@@ -3161,6 +3327,11 @@ const KritzelWorkspaceManager = class {
|
|
|
3161
3327
|
this.openChildMenuItem = null;
|
|
3162
3328
|
this.childMenuAnchor = null;
|
|
3163
3329
|
await this.kritzelEngineRef.deleteWorkspace(item.value);
|
|
3330
|
+
if (item.value.id === this.activeWorkspace?.id) {
|
|
3331
|
+
this.activeWorkspace = this.sortedWorkspaces.find(ws => ws.id !== item.value.id) || null;
|
|
3332
|
+
this.workspaceChange.emit(this.activeWorkspace);
|
|
3333
|
+
}
|
|
3334
|
+
await this.splitButtonRef.focusMenu();
|
|
3164
3335
|
}
|
|
3165
3336
|
toggleChildMenu(item, anchor) {
|
|
3166
3337
|
this.openChildMenuItem = item;
|
|
@@ -3170,12 +3341,15 @@ const KritzelWorkspaceManager = class {
|
|
|
3170
3341
|
this.openChildMenuItem = null;
|
|
3171
3342
|
this.childMenuAnchor = null;
|
|
3172
3343
|
}
|
|
3173
|
-
|
|
3344
|
+
handleMenuOpen() {
|
|
3345
|
+
this.kritzelEngineRef.disable();
|
|
3346
|
+
}
|
|
3347
|
+
handleMenuClose() {
|
|
3174
3348
|
this.cancel();
|
|
3175
3349
|
this.closeChildMenu();
|
|
3350
|
+
this.kritzelEngineRef.enable();
|
|
3176
3351
|
}
|
|
3177
3352
|
render() {
|
|
3178
|
-
console.log('render workspace manager');
|
|
3179
3353
|
const menuItems = this.sortedWorkspaces
|
|
3180
3354
|
.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())
|
|
3181
3355
|
.filter(ws => ws !== null)
|
|
@@ -3200,17 +3374,16 @@ const KritzelWorkspaceManager = class {
|
|
|
3200
3374
|
id: `${ws.id}-delete`,
|
|
3201
3375
|
label: 'Delete',
|
|
3202
3376
|
value: 'delete',
|
|
3377
|
+
isDisabled: this.sortedWorkspaces.length <= 1,
|
|
3203
3378
|
action: (_item, parent) => this.delete(parent),
|
|
3204
3379
|
},
|
|
3205
3380
|
],
|
|
3206
3381
|
};
|
|
3207
3382
|
});
|
|
3208
|
-
return (h(Host, null, h("kritzel-split-button", { ref: el => (this.splitButtonRef = el), items: menuItems, mainButtonDisabled: this.editingItemId != null,
|
|
3209
|
-
this.closeMenu();
|
|
3210
|
-
} })));
|
|
3383
|
+
return (h(Host, null, h("kritzel-split-button", { ref: el => (this.splitButtonRef = el), items: menuItems, mainButtonDisabled: this.editingItemId != null, onMainButtonClick: () => this.add(), onItemSelect: event => this.select(event.detail.item, event.detail.parent), onItemToggleChildMenu: event => this.toggleChildMenu(event.detail.item, event.detail.childMenuAnchor), onItemSave: event => this.save(event.detail), onItemCancel: () => this.cancel(), onItemCloseChildMenu: () => this.closeChildMenu(), onMenuOpen: () => this.handleMenuOpen(), onMenuClose: () => this.handleMenuClose() })));
|
|
3211
3384
|
}
|
|
3212
3385
|
};
|
|
3213
3386
|
KritzelWorkspaceManager.style = kritzelWorkspaceManagerCss;
|
|
3214
3387
|
|
|
3215
|
-
export {
|
|
3216
|
-
//# sourceMappingURL=kritzel-
|
|
3388
|
+
export { KritzelColor as kritzel_color, KritzelColorPalette as kritzel_color_palette, KritzelContextMenu as kritzel_context_menu, KritzelControlBrushConfig as kritzel_control_brush_config, KritzelControlTextConfig as kritzel_control_text_config, KritzelControls as kritzel_controls, KritzelCursorTrail as kritzel_cursor_trail, KritzelDropdown as kritzel_dropdown, KritzelEditor as kritzel_editor, KritzelEngine as kritzel_engine, KritzelFont as kritzel_font, KritzelFontFamily as kritzel_font_family, KritzelFontSize as kritzel_font_size, KritzelIcon as kritzel_icon, KritzelMenu as kritzel_menu, KritzelMenuItem as kritzel_menu_item, KritzelPortal as kritzel_portal, KritzelSplitButton as kritzel_split_button, KritzelStrokeSize as kritzel_stroke_size, KritzelTooltip as kritzel_tooltip, KritzelUtilityPanel as kritzel_utility_panel, KritzelWorkspaceManager as kritzel_workspace_manager };
|
|
3389
|
+
//# sourceMappingURL=kritzel-color.kritzel-color-palette.kritzel-context-menu.kritzel-control-brush-config.kritzel-control-text-config.kritzel-controls.kritzel-cursor-trail.kritzel-dropdown.kritzel-editor.kritzel-engine.kritzel-font.kritzel-font-family.kritzel-font-size.kritzel-icon.kritzel-menu.kritzel-menu-item.kritzel-portal.kritzel-split-button.kritzel-stroke-size.kritzel-tooltip.kritzel-utility-panel.kritzel-workspace-manager.entry.js.map
|