kritzel-stencil 0.0.107 → 0.0.109

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.
Files changed (117) hide show
  1. package/dist/cjs/kritzel-brush-style_18.cjs.entry.js +858 -820
  2. package/dist/cjs/kritzel-brush-style_18.cjs.entry.js.map +1 -1
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/stencil.cjs.js +1 -1
  5. package/dist/collection/classes/handlers/context-menu.handler.js +2 -47
  6. package/dist/collection/classes/handlers/context-menu.handler.js.map +1 -1
  7. package/dist/collection/classes/handlers/key.handler.js +1 -1
  8. package/dist/collection/classes/handlers/key.handler.js.map +1 -1
  9. package/dist/collection/classes/handlers/move.handler.js +62 -55
  10. package/dist/collection/classes/handlers/move.handler.js.map +1 -1
  11. package/dist/collection/classes/handlers/resize.handler.js +122 -113
  12. package/dist/collection/classes/handlers/resize.handler.js.map +1 -1
  13. package/dist/collection/classes/handlers/rotation.handler.js +74 -66
  14. package/dist/collection/classes/handlers/rotation.handler.js.map +1 -1
  15. package/dist/collection/classes/handlers/selection.handler.js +59 -50
  16. package/dist/collection/classes/handlers/selection.handler.js.map +1 -1
  17. package/dist/collection/classes/objects/base-object.class.js +3 -0
  18. package/dist/collection/classes/objects/base-object.class.js.map +1 -1
  19. package/dist/collection/classes/objects/text.class.js +11 -1
  20. package/dist/collection/classes/objects/text.class.js.map +1 -1
  21. package/dist/collection/classes/registries/icon-registry.class.js.map +1 -0
  22. package/dist/collection/classes/registries/tool.registry.js.map +1 -0
  23. package/dist/collection/classes/store.class.js +3 -54
  24. package/dist/collection/classes/store.class.js.map +1 -1
  25. package/dist/collection/classes/tools/base-tool.class.js +3 -18
  26. package/dist/collection/classes/tools/base-tool.class.js.map +1 -1
  27. package/dist/collection/classes/tools/brush-tool.class.js +79 -71
  28. package/dist/collection/classes/tools/brush-tool.class.js.map +1 -1
  29. package/dist/collection/classes/tools/eraser-tool.class.js +61 -56
  30. package/dist/collection/classes/tools/eraser-tool.class.js.map +1 -1
  31. package/dist/collection/classes/tools/image-tool.class.js +1 -1
  32. package/dist/collection/classes/tools/image-tool.class.js.map +1 -1
  33. package/dist/collection/classes/tools/selection-tool.class.js +94 -74
  34. package/dist/collection/classes/tools/selection-tool.class.js.map +1 -1
  35. package/dist/collection/classes/tools/text-tool.class.js +73 -70
  36. package/dist/collection/classes/tools/text-tool.class.js.map +1 -1
  37. package/dist/collection/classes/viewport.class.js +76 -69
  38. package/dist/collection/classes/viewport.class.js.map +1 -1
  39. package/dist/collection/components/core/kritzel-editor/kritzel-editor.css +6 -0
  40. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +2 -2
  41. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js.map +1 -1
  42. package/dist/collection/components/core/kritzel-engine/kritzel-engine.css +6 -0
  43. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +69 -121
  44. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -1
  45. package/dist/collection/components/shared/kritzel-icon/kritzel-icon.js +1 -1
  46. package/dist/collection/components/shared/kritzel-icon/kritzel-icon.js.map +1 -1
  47. package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js +1 -16
  48. package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js.map +1 -1
  49. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.css +10 -2
  50. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +9 -4
  51. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js.map +1 -1
  52. package/dist/collection/configs/default-engine-state.js +53 -0
  53. package/dist/collection/configs/default-engine-state.js.map +1 -0
  54. package/dist/collection/helpers/devices.helper.js +6 -0
  55. package/dist/collection/helpers/devices.helper.js.map +1 -0
  56. package/dist/collection/helpers/event.helper.js +43 -20
  57. package/dist/collection/helpers/event.helper.js.map +1 -1
  58. package/dist/collection/interfaces/engine-state.interface.js.map +1 -1
  59. package/dist/collection/interfaces/object.interface.js.map +1 -1
  60. package/dist/collection/interfaces/tool.interface.js.map +1 -1
  61. package/dist/components/kritzel-context-menu.js +1 -1
  62. package/dist/components/kritzel-controls.js +1 -1
  63. package/dist/components/kritzel-editor.js +6 -6
  64. package/dist/components/kritzel-editor.js.map +1 -1
  65. package/dist/components/kritzel-engine.js +1 -1
  66. package/dist/components/{p-CesjDLvT.js → p-7Ns73-wN.js} +237 -206
  67. package/dist/components/p-7Ns73-wN.js.map +1 -0
  68. package/dist/components/{p-Cbu5RSmC.js → p-BmAloSfd.js} +3 -4
  69. package/dist/components/p-BmAloSfd.js.map +1 -0
  70. package/dist/components/{p-_3gCPfqz.js → p-BmrZipyu.js} +621 -622
  71. package/dist/components/p-BmrZipyu.js.map +1 -0
  72. package/dist/components/p-CZkSABuJ.js.map +1 -1
  73. package/dist/components/{p-DTcfnx4-.js → p-Ch6TgHX3.js} +18 -8
  74. package/dist/components/p-Ch6TgHX3.js.map +1 -0
  75. package/dist/esm/kritzel-brush-style_18.entry.js +858 -820
  76. package/dist/esm/kritzel-brush-style_18.entry.js.map +1 -1
  77. package/dist/esm/loader.js +1 -1
  78. package/dist/esm/stencil.js +1 -1
  79. package/dist/stencil/p-c976660c.entry.js +2 -0
  80. package/dist/stencil/p-c976660c.entry.js.map +1 -0
  81. package/dist/stencil/stencil.esm.js +1 -1
  82. package/dist/types/classes/handlers/context-menu.handler.d.ts +1 -2
  83. package/dist/types/classes/handlers/move.handler.d.ts +3 -6
  84. package/dist/types/classes/handlers/resize.handler.d.ts +3 -6
  85. package/dist/types/classes/handlers/rotation.handler.d.ts +3 -6
  86. package/dist/types/classes/handlers/selection.handler.d.ts +3 -6
  87. package/dist/types/classes/objects/base-object.class.d.ts +1 -0
  88. package/dist/types/classes/objects/text.class.d.ts +1 -0
  89. package/dist/types/classes/{tool.registry.d.ts → registries/tool.registry.d.ts} +2 -2
  90. package/dist/types/classes/tools/base-tool.class.d.ts +3 -8
  91. package/dist/types/classes/tools/brush-tool.class.d.ts +3 -6
  92. package/dist/types/classes/tools/eraser-tool.class.d.ts +3 -6
  93. package/dist/types/classes/tools/selection-tool.class.d.ts +4 -7
  94. package/dist/types/classes/tools/text-tool.class.d.ts +2 -4
  95. package/dist/types/classes/viewport.class.d.ts +3 -6
  96. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +5 -10
  97. package/dist/types/components/ui/kritzel-context-menu/kritzel-context-menu.d.ts +0 -1
  98. package/dist/types/components/ui/kritzel-controls/kritzel-controls.d.ts +1 -0
  99. package/dist/types/components.d.ts +0 -2
  100. package/dist/types/configs/default-engine-state.d.ts +2 -0
  101. package/dist/types/helpers/devices.helper.d.ts +3 -0
  102. package/dist/types/helpers/event.helper.d.ts +2 -4
  103. package/dist/types/interfaces/engine-state.interface.d.ts +1 -1
  104. package/dist/types/interfaces/object.interface.d.ts +1 -0
  105. package/dist/types/interfaces/tool.interface.d.ts +3 -8
  106. package/package.json +1 -1
  107. package/dist/collection/classes/icon-registry.class.js.map +0 -1
  108. package/dist/collection/classes/tool.registry.js.map +0 -1
  109. package/dist/components/p-Cbu5RSmC.js.map +0 -1
  110. package/dist/components/p-CesjDLvT.js.map +0 -1
  111. package/dist/components/p-DTcfnx4-.js.map +0 -1
  112. package/dist/components/p-_3gCPfqz.js.map +0 -1
  113. package/dist/stencil/p-e596d004.entry.js +0 -2
  114. package/dist/stencil/p-e596d004.entry.js.map +0 -1
  115. /package/dist/collection/classes/{icon-registry.class.js → registries/icon-registry.class.js} +0 -0
  116. /package/dist/collection/classes/{tool.registry.js → registries/tool.registry.js} +0 -0
  117. /package/dist/types/classes/{icon-registry.class.d.ts → registries/icon-registry.class.d.ts} +0 -0
@@ -127,7 +127,6 @@ const KritzelContextMenu = class {
127
127
  constructor(hostRef) {
128
128
  index.registerInstance(this, hostRef);
129
129
  this.actionSelected = index.createEvent(this, "actionSelected");
130
- this.close = index.createEvent(this, "close");
131
130
  }
132
131
  handleItemClick(item) {
133
132
  const isDisabled = typeof item.disabled === 'function' ? item.disabled() : item.disabled;
@@ -136,7 +135,7 @@ const KritzelContextMenu = class {
136
135
  }
137
136
  }
138
137
  render() {
139
- return (index.h(index.Host, { key: 'db318a0936f89f202ef5101447b723c0ba7aa139' }, index.h("div", { key: '53da01021464f605e08c5f910997bb8f21d481a1', class: "menu-container" }, this.items.map(item => (index.h("button", { key: `${item.label}-${this.items.indexOf(item)}`, class: { 'menu-item': true, 'disabled': typeof item.disabled === 'function' ? item.disabled() : item.disabled }, onClick: () => this.handleItemClick(item), onTouchStart: () => this.handleItemClick(item), disabled: typeof item.disabled === 'function' ? item.disabled() : item.disabled }, item.icon && index.h("kritzel-icon", { name: item.icon, size: 16 }), index.h("span", { class: "label" }, item.label)))))));
138
+ return (index.h(index.Host, { key: '92cf80d71faae3e33bc29d9e9b3a81b4b6ee6c87' }, index.h("div", { key: '838734ed3f1e3af86a5db7312c2206e90835a8f0', class: "menu-container" }, this.items.map(item => (index.h("button", { key: `${item.label}-${this.items.indexOf(item)}`, class: { 'menu-item': true, 'disabled': typeof item.disabled === 'function' ? item.disabled() : item.disabled }, onClick: () => this.handleItemClick(item), onTouchStart: () => this.handleItemClick(item), disabled: typeof item.disabled === 'function' ? item.disabled() : item.disabled }, item.icon && index.h("kritzel-icon", { name: item.icon, size: 16 }), index.h("span", { class: "label" }, item.label)))))));
140
139
  }
141
140
  get hostElement() { return index.getElement(this); }
142
141
  };
@@ -243,29 +242,52 @@ class KritzelEventHelper {
243
242
  static isMainMouseWheel(event) {
244
243
  return Math.abs(event.deltaY) > 0 && Math.abs(event.deltaX) === 0 && Number.isInteger(event.deltaY);
245
244
  }
246
- static detectDoubleTap() {
247
- const currentTime = Date.now();
248
- const tapLength = currentTime - KritzelEventHelper.lastTapTimestamp;
249
- if (KritzelEventHelper.tapTimeoutId) {
250
- clearTimeout(KritzelEventHelper.tapTimeoutId);
251
- KritzelEventHelper.tapTimeoutId = null;
252
- }
253
- if (tapLength < KritzelEventHelper.doubleTapTimeout && tapLength > 0) {
254
- KritzelEventHelper.lastTapTimestamp = 0;
255
- return true;
256
- }
257
- else {
258
- KritzelEventHelper.lastTapTimestamp = currentTime;
259
- KritzelEventHelper.tapTimeoutId = setTimeout(() => {
260
- KritzelEventHelper.tapTimeoutId = null;
261
- }, KritzelEventHelper.doubleTapTimeout);
262
- return false;
263
- }
245
+ static isPointerEventOnContextMenu(event) {
246
+ const path = event.composedPath();
247
+ const contextMenu = path.find(element => element.classList && element.classList.contains('context-menu'));
248
+ return !!contextMenu;
249
+ }
250
+ static onLongTouchPress(event, onSuccess, onCancel) {
251
+ if (event.pointerType !== 'touch') {
252
+ onCancel === null || onCancel === void 0 ? void 0 : onCancel();
253
+ return () => { };
254
+ }
255
+ const longPressTimeout = 400;
256
+ const moveThreshold = 10;
257
+ const startX = event.clientX;
258
+ const startY = event.clientY;
259
+ const target = event.target;
260
+ const timer = setTimeout(() => {
261
+ removeListeners();
262
+ onSuccess(event);
263
+ }, longPressTimeout);
264
+ const cancel = () => {
265
+ clearTimeout(timer);
266
+ removeListeners();
267
+ onCancel === null || onCancel === void 0 ? void 0 : onCancel();
268
+ };
269
+ const onPointerMove = (e) => {
270
+ if (Math.abs(e.clientX - startX) > moveThreshold || Math.abs(e.clientY - startY) > moveThreshold) {
271
+ cancel();
272
+ }
273
+ };
274
+ const onPointerUp = () => {
275
+ cancel();
276
+ };
277
+ const onPointerCancel = () => {
278
+ cancel();
279
+ };
280
+ const removeListeners = () => {
281
+ target.removeEventListener('pointermove', onPointerMove);
282
+ target.removeEventListener('pointerup', onPointerUp);
283
+ target.removeEventListener('pointercancel', onPointerCancel);
284
+ };
285
+ target.addEventListener('pointermove', onPointerMove, { passive: true });
286
+ target.addEventListener('pointerup', onPointerUp, { once: true });
287
+ target.addEventListener('pointercancel', onPointerCancel, { once: true });
288
+ return cancel;
264
289
  }
265
290
  }
266
- KritzelEventHelper.lastTapTimestamp = 0;
267
- KritzelEventHelper.tapTimeoutId = null;
268
- KritzelEventHelper.doubleTapTimeout = 300;
269
291
 
270
292
  class KritzelBaseCommand {
271
293
  constructor(store, initiator) {
@@ -526,6 +548,9 @@ class KritzelBaseObject {
526
548
  copiedObject.isMounted = false;
527
549
  return copiedObject;
528
550
  }
551
+ onSelectedClick() {
552
+ // This method can be overridden by subclasses to handle click events when the object is selected.
553
+ }
529
554
  revive(object) {
530
555
  Object.assign(this, object);
531
556
  return this;
@@ -662,28 +687,13 @@ class KritzelBaseTool {
662
687
  onDeactivate() {
663
688
  // default implementation
664
689
  }
665
- handleMouseDown(_event) {
666
- // default implementation
667
- }
668
- handleMouseMove(_event) {
669
- // default implementation
670
- }
671
- handleMouseUp(_event) {
672
- // default implementation
673
- }
674
- handleDoubleClick(_event) {
690
+ handlePointerDown(_event) {
675
691
  // default implementation
676
692
  }
677
- handleDoubleTap(_event) {
693
+ handlePointerMove(_event) {
678
694
  // default implementation
679
695
  }
680
- handleTouchStart(_event) {
681
- // default implementation
682
- }
683
- handleTouchMove(_event) {
684
- // default implementation
685
- }
686
- handleTouchEnd(_event) {
696
+ handlePointerUp(_event) {
687
697
  // default implementation
688
698
  }
689
699
  handleWheel(_event) {
@@ -706,90 +716,116 @@ class KritzelBrushTool extends KritzelBaseTool {
706
716
  highlighter: ['#ffff00', '#ffb347', '#b4ffb4'],
707
717
  };
708
718
  }
709
- handleMouseDown(event) {
710
- if (KritzelEventHelper.isLeftClick(event)) {
711
- this._store.state.isDrawing = true;
712
- const x = event.clientX - this._store.offsetX;
713
- const y = event.clientY - this._store.offsetY;
714
- this._store.state.currentPath = KritzelPath.create(this._store, {
715
- points: [[x, y]],
716
- translateX: -this._store.state.translateX,
717
- translateY: -this._store.state.translateY,
718
- scale: this._store.state.scale,
719
- fill: this.color,
720
- strokeWidth: this.size,
721
- });
719
+ handlePointerDown(event) {
720
+ if (event.pointerType === 'mouse') {
721
+ if (KritzelEventHelper.isLeftClick(event)) {
722
+ this._store.state.isDrawing = true;
723
+ const x = event.clientX - this._store.offsetX;
724
+ const y = event.clientY - this._store.offsetY;
725
+ this._store.state.currentPath = KritzelPath.create(this._store, {
726
+ points: [[x, y]],
727
+ translateX: -this._store.state.translateX,
728
+ translateY: -this._store.state.translateY,
729
+ scale: this._store.state.scale,
730
+ fill: this.color,
731
+ strokeWidth: this.size,
732
+ });
733
+ }
722
734
  }
723
- }
724
- handleMouseMove(event) {
725
- if (this._store.state.isDrawing) {
726
- const x = event.clientX - this._store.offsetX;
727
- const y = event.clientY - this._store.offsetY;
728
- this._store.state.currentPath = KritzelPath.create(this._store, {
729
- points: [...this._store.state.currentPath.points, [x, y]],
730
- translateX: -this._store.state.translateX,
731
- translateY: -this._store.state.translateY,
732
- scale: this._store.state.scale,
733
- fill: this.color,
734
- strokeWidth: this.size,
735
- });
736
- this._store.rerender();
735
+ if (event.pointerType === 'touch') {
736
+ const activePointers = Array.from(this._store.state.pointers.values());
737
+ if (activePointers.length === 1) {
738
+ const x = Math.round(activePointers[0].clientX - this._store.offsetX);
739
+ const y = Math.round(activePointers[0].clientY - this._store.offsetY);
740
+ this._store.state.isDrawing = true;
741
+ this._store.state.currentPath = KritzelPath.create(this._store, {
742
+ points: [[x, y]],
743
+ translateX: -this._store.state.translateX,
744
+ translateY: -this._store.state.translateY,
745
+ scale: this._store.state.scale,
746
+ fill: this.color,
747
+ strokeWidth: this.size,
748
+ });
749
+ this._store.rerender();
750
+ }
737
751
  }
738
752
  }
739
- handleMouseUp(_event) {
740
- if (this._store.state.isDrawing) {
741
- this._store.state.isDrawing = false;
742
- if (this._store.state.currentPath) {
743
- this._store.state.currentPath.zIndex = this._store.currentZIndex;
744
- this._store.history.executeCommand(new AddObjectCommand(this._store, this, this._store.state.currentPath));
753
+ handlePointerMove(event) {
754
+ if (event.pointerType === 'mouse') {
755
+ if (this._store.state.isDrawing) {
756
+ const x = event.clientX - this._store.offsetX;
757
+ const y = event.clientY - this._store.offsetY;
758
+ this._store.state.currentPath = KritzelPath.create(this._store, {
759
+ points: [...this._store.state.currentPath.points, [x, y]],
760
+ translateX: -this._store.state.translateX,
761
+ translateY: -this._store.state.translateY,
762
+ scale: this._store.state.scale,
763
+ fill: this.color,
764
+ strokeWidth: this.size,
765
+ });
766
+ this._store.rerender();
745
767
  }
746
- this._store.state.currentPath = undefined;
747
768
  }
748
- }
749
- handleTouchStart(event) {
750
- if (this._store.state.touchCount === 1) {
751
- const x = Math.round(event.touches[0].clientX - this._store.offsetX);
752
- const y = Math.round(event.touches[0].clientY - this._store.offsetY);
753
- this._store.state.isDrawing = true;
754
- this._store.state.currentPath = KritzelPath.create(this._store, {
755
- points: [[x, y]],
756
- translateX: -this._store.state.translateX,
757
- translateY: -this._store.state.translateY,
758
- scale: this._store.state.scale,
759
- fill: this.color,
760
- strokeWidth: this.size,
761
- });
762
- this._store.rerender();
769
+ if (event.pointerType === 'touch') {
770
+ const activePointers = Array.from(this._store.state.pointers.values());
771
+ if (activePointers.length === 1) {
772
+ const x = Math.round(activePointers[0].clientX - this._store.offsetX);
773
+ const y = Math.round(activePointers[0].clientY - this._store.offsetY);
774
+ this._store.state.currentPath = KritzelPath.create(this._store, {
775
+ points: [...this._store.state.currentPath.points, [x, y]],
776
+ translateX: -this._store.state.translateX,
777
+ translateY: -this._store.state.translateY,
778
+ scale: this._store.state.scale,
779
+ fill: this.color,
780
+ strokeWidth: this.size,
781
+ });
782
+ this._store.rerender();
783
+ }
763
784
  }
764
785
  }
765
- handleTouchMove(event) {
766
- if (this._store.state.touchCount === 1) {
767
- const x = Math.round(event.touches[0].clientX - this._store.offsetX);
768
- const y = Math.round(event.touches[0].clientY - this._store.offsetY);
769
- this._store.state.currentPath = KritzelPath.create(this._store, {
770
- points: [...this._store.state.currentPath.points, [x, y]],
771
- translateX: -this._store.state.translateX,
772
- translateY: -this._store.state.translateY,
773
- scale: this._store.state.scale,
774
- fill: this.color,
775
- strokeWidth: this.size,
776
- });
777
- this._store.rerender();
786
+ handlePointerUp(event) {
787
+ if (event.pointerType === 'mouse') {
788
+ if (this._store.state.isDrawing) {
789
+ this._store.state.isDrawing = false;
790
+ if (this._store.state.currentPath) {
791
+ this._store.state.currentPath.zIndex = this._store.currentZIndex;
792
+ this._store.history.executeCommand(new AddObjectCommand(this._store, this, this._store.state.currentPath));
793
+ }
794
+ this._store.state.currentPath = undefined;
795
+ }
778
796
  }
779
- }
780
- handleTouchEnd(_event) {
781
- if (this._store.state.isDrawing) {
782
- this._store.state.isDrawing = false;
783
- if (this._store.state.currentPath) {
784
- this._store.state.currentPath.zIndex = this._store.currentZIndex;
785
- this._store.history.executeCommand(new AddObjectCommand(this._store, this, this._store.state.currentPath));
797
+ if (event.pointerType === 'touch') {
798
+ if (this._store.state.isDrawing) {
799
+ this._store.state.isDrawing = false;
800
+ if (this._store.state.currentPath) {
801
+ this._store.state.currentPath.zIndex = this._store.currentZIndex;
802
+ this._store.history.executeCommand(new AddObjectCommand(this._store, this, this._store.state.currentPath));
803
+ }
804
+ this._store.state.currentPath = undefined;
805
+ this._store.rerender();
786
806
  }
787
- this._store.state.currentPath = undefined;
788
- this._store.rerender();
789
807
  }
790
808
  }
791
809
  }
792
810
 
811
+ class KritzelToolRegistry {
812
+ static registerTool(toolName, constructor, store) {
813
+ const toolInstance = new constructor(store);
814
+ toolInstance.name = toolName;
815
+ this.registry[toolName] = toolInstance;
816
+ return toolInstance;
817
+ }
818
+ static getTool(toolName) {
819
+ const toolInstance = this.registry[toolName];
820
+ if (!toolInstance) {
821
+ console.warn(`Unknown tool: ${toolName}`);
822
+ return null;
823
+ }
824
+ return toolInstance;
825
+ }
826
+ }
827
+ KritzelToolRegistry.registry = {};
828
+
793
829
  class KritzelText extends KritzelBaseObject {
794
830
  get isReadonly() {
795
831
  return !(this._store.state.activeTool instanceof KritzelTextTool);
@@ -812,7 +848,7 @@ class KritzelText extends KritzelBaseObject {
812
848
  this.fontSize = config.fontSize || 8;
813
849
  this.fontFamily = config.fontFamily || 'Arial';
814
850
  this.fontColor = config.fontColor || '#000000';
815
- this.height = config.height || (this.fontSize * 1.2);
851
+ this.height = config.height || this.fontSize * 1.2;
816
852
  this.width = config.width || 0;
817
853
  this.scale = config.scale || 1;
818
854
  }
@@ -916,25 +952,16 @@ class KritzelText extends KritzelBaseObject {
916
952
  }
917
953
  }
918
954
  }
919
- }
920
-
921
- class KritzelToolRegistry {
922
- static registerTool(toolName, constructor, store) {
923
- const toolInstance = new constructor(store);
924
- toolInstance.name = toolName;
925
- this.registry[toolName] = toolInstance;
926
- return toolInstance;
927
- }
928
- static getTool(toolName) {
929
- const toolInstance = this.registry[toolName];
930
- if (!toolInstance) {
931
- console.warn(`Unknown tool: ${toolName}`);
932
- return null;
933
- }
934
- return toolInstance;
955
+ onSelectedClick() {
956
+ this._store.setState('activeTool', KritzelToolRegistry.getTool('text'));
957
+ this._store.state.selectionGroup = null;
958
+ this._store.state.selectionBox = null;
959
+ this._store.state.activeText = this;
960
+ setTimeout(() => {
961
+ this.focus();
962
+ }, 300);
935
963
  }
936
964
  }
937
- KritzelToolRegistry.registry = {};
938
965
 
939
966
  class KritzelKeyboardHelper {
940
967
  static forceHideKeyboard() {
@@ -991,84 +1018,93 @@ class KritzelTextTool extends KritzelBaseTool {
991
1018
  '#800080',
992
1019
  ];
993
1020
  }
994
- handleMouseDown(event) {
995
- const path = event.composedPath().slice(1);
996
- const objectElement = path.find(element => element.classList && element.classList.contains('object'));
997
- const object = this._store.findObjectById(objectElement === null || objectElement === void 0 ? void 0 : objectElement.id);
998
- if (this._store.state.activeText === null && object && object instanceof KritzelText) {
999
- this._store.state.activeText = object;
1000
- object.focus();
1001
- return;
1002
- }
1003
- if (this._store.state.activeText !== null && object instanceof KritzelText) {
1004
- object.focus();
1005
- return;
1006
- }
1007
- if (this._store.state.activeText !== null) {
1008
- this._store.resetActiveText();
1009
- this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
1010
- return;
1011
- }
1012
- if (KritzelEventHelper.isLeftClick(event) === false) {
1013
- return;
1021
+ handlePointerDown(event) {
1022
+ if (event.pointerType === 'mouse') {
1023
+ const path = event.composedPath().slice(1);
1024
+ const objectElement = path.find(element => element.classList && element.classList.contains('object'));
1025
+ const object = this._store.findObjectById(objectElement === null || objectElement === void 0 ? void 0 : objectElement.id);
1026
+ if (this._store.state.activeText === null && object && object instanceof KritzelText) {
1027
+ this._store.state.activeText = object;
1028
+ object.focus();
1029
+ return;
1030
+ }
1031
+ if (this._store.state.activeText !== null && object instanceof KritzelText) {
1032
+ object.focus();
1033
+ return;
1034
+ }
1035
+ if (this._store.state.activeText !== null) {
1036
+ this._store.resetActiveText();
1037
+ this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
1038
+ return;
1039
+ }
1040
+ if (KritzelEventHelper.isLeftClick(event) === false) {
1041
+ return;
1042
+ }
1043
+ const clientX = event.clientX - this._store.offsetX;
1044
+ const clientY = event.clientY - this._store.offsetY;
1045
+ const text = KritzelText.create(this._store, this.fontSize, this.fontFamily);
1046
+ text.fontColor = this.fontColor;
1047
+ text.translateX = (clientX - this._store.state.translateX) / this._store.state.scale;
1048
+ text.translateY = (clientY - this._store.state.translateY) / this._store.state.scale;
1049
+ text.zIndex = this._store.currentZIndex;
1050
+ this._store.state.activeText = text;
1051
+ this._store.history.executeCommand(new AddObjectCommand(this._store, this, text));
1052
+ }
1053
+ if (event.pointerType === 'touch') {
1054
+ const activePointers = Array.from(this._store.state.pointers.values());
1055
+ const path = event.composedPath().slice(1);
1056
+ const objectElement = path.find(element => element.classList && element.classList.contains('object'));
1057
+ const object = this._store.findObjectById(objectElement === null || objectElement === void 0 ? void 0 : objectElement.id);
1058
+ if (this._store.state.activeText === null && object && object instanceof KritzelText) {
1059
+ this._store.state.activeText = object;
1060
+ object.focus();
1061
+ return;
1062
+ }
1063
+ if (this._store.state.activeText !== null && object instanceof KritzelText) {
1064
+ object.focus();
1065
+ return;
1066
+ }
1067
+ if (this._store.state.activeText !== null) {
1068
+ this._store.resetActiveText();
1069
+ this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
1070
+ return;
1071
+ }
1072
+ if (activePointers.length > 1) {
1073
+ return;
1074
+ }
1075
+ KritzelKeyboardHelper.disableInteractiveWidget();
1076
+ const clientX = Math.round(activePointers[0].clientX - this._store.offsetX);
1077
+ const clientY = Math.round(activePointers[0].clientY - this._store.offsetY);
1078
+ const text = KritzelText.create(this._store, this.fontSize, this.fontFamily);
1079
+ text.fontColor = this.fontColor;
1080
+ text.translateX = (clientX - this._store.state.translateX) / this._store.state.scale;
1081
+ text.translateY = (clientY - this._store.state.translateY) / this._store.state.scale;
1082
+ text.zIndex = this._store.currentZIndex;
1083
+ this._store.state.activeText = text;
1084
+ this._store.history.executeCommand(new AddObjectCommand(this._store, this, text));
1085
+ }
1086
+ }
1087
+ handlePointerUp(event) {
1088
+ var _a, _b, _c, _d;
1089
+ if (event.pointerType === 'mouse') {
1090
+ (_a = this._store.state.activeText) === null || _a === void 0 ? void 0 : _a.adjustTextareaSize();
1091
+ (_b = this._store.state.activeText) === null || _b === void 0 ? void 0 : _b.focus();
1092
+ }
1093
+ if (event.pointerType === 'touch') {
1094
+ (_c = this._store.state.activeText) === null || _c === void 0 ? void 0 : _c.adjustTextareaSize();
1095
+ (_d = this._store.state.activeText) === null || _d === void 0 ? void 0 : _d.focus();
1096
+ KritzelKeyboardHelper.enableInteractiveWidget();
1014
1097
  }
1015
- const clientX = event.clientX - this._store.offsetX;
1016
- const clientY = event.clientY - this._store.offsetY;
1017
- const text = KritzelText.create(this._store, this.fontSize, this.fontFamily);
1018
- text.fontColor = this.fontColor;
1019
- text.translateX = (clientX - this._store.state.translateX) / this._store.state.scale;
1020
- text.translateY = (clientY - this._store.state.translateY) / this._store.state.scale;
1021
- text.zIndex = this._store.currentZIndex;
1022
- text.adjustTextareaSize();
1023
- this._store.state.activeText = text;
1024
- this._store.history.executeCommand(new AddObjectCommand(this._store, this, text));
1025
- }
1026
- handleMouseUp(_event) {
1027
- var _a, _b;
1028
- (_a = this._store.state.activeText) === null || _a === void 0 ? void 0 : _a.focus();
1029
- (_b = this._store.state.activeText) === null || _b === void 0 ? void 0 : _b.adjustTextareaSize();
1030
1098
  }
1031
- handleTouchStart(event) {
1032
- const path = event.composedPath().slice(1);
1033
- const objectElement = path.find(element => element.classList && element.classList.contains('object'));
1034
- const object = this._store.findObjectById(objectElement === null || objectElement === void 0 ? void 0 : objectElement.id);
1035
- if (this._store.state.activeText === null && object && object instanceof KritzelText) {
1036
- this._store.state.activeText = object;
1037
- object.focus();
1038
- return;
1039
- }
1040
- if (this._store.state.activeText !== null && object instanceof KritzelText) {
1041
- object.focus();
1042
- return;
1043
- }
1044
- if (this._store.state.activeText !== null) {
1045
- this._store.resetActiveText();
1046
- this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
1047
- return;
1048
- }
1049
- if (this._store.state.touchCount > 1) {
1050
- return;
1051
- }
1052
- KritzelKeyboardHelper.disableInteractiveWidget();
1053
- const clientX = Math.round(event.touches[0].clientX - this._store.offsetX);
1054
- const clientY = Math.round(event.touches[0].clientY - this._store.offsetY);
1055
- const text = KritzelText.create(this._store, this.fontSize, this.fontFamily);
1056
- text.fontColor = this.fontColor;
1057
- text.translateX = (clientX - this._store.state.translateX) / this._store.state.scale;
1058
- text.translateY = (clientY - this._store.state.translateY) / this._store.state.scale;
1059
- text.zIndex = this._store.currentZIndex;
1060
- this._store.state.activeText = text;
1061
- this._store.history.executeCommand(new AddObjectCommand(this._store, this, text));
1062
- }
1063
- handleTouchEnd(_event) {
1064
- var _a, _b;
1065
- (_a = this._store.state.activeText) === null || _a === void 0 ? void 0 : _a.focus();
1066
- (_b = this._store.state.activeText) === null || _b === void 0 ? void 0 : _b.adjustTextareaSize();
1067
- KritzelKeyboardHelper.enableInteractiveWidget();
1099
+ }
1100
+
1101
+ class KritzelDevicesHelper {
1102
+ static isTouchDevice() {
1103
+ return window.matchMedia('(any-pointer: coarse)').matches;
1068
1104
  }
1069
1105
  }
1070
1106
 
1071
- const kritzelControlsCss = ":host{display:flex;flex-direction:column;user-select:none}.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, 8px);box-shadow:var(--kritzel-controls-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-controls-border, 1px solid hsl(0, 0%, 0%, 4.3%));border-radius:var(--kritzel-controls-border-radius, 8px);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, 8px);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, #0E1111);color:var(--kritzel-controls-control-selected-color, #ffffff)}.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, #f0f0f0)}.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, #f0f0f0)}.no-config{height:24px;width:24px;border-radius:50%;border:1px dashed gray}kritzel-tooltip{position:fixed;bottom:66px;left:50%;transform:translateX(-50%);z-index:10001}";
1107
+ const kritzelControlsCss = ":host{display:flex;flex-direction:column;user-select:none}.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, 8px);box-shadow:var(--kritzel-controls-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-controls-border, 1px solid hsl(0, 0%, 0%, 4.3%));border-radius:var(--kritzel-controls-border-radius, 8px);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, 8px);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%))}:host(.mobile) .kritzel-control:hover{background-color:unset}.kritzel-control:active{background-color:var(--kritzel-controls-control-active-background-color, hsl(0, 0%, 0%, 8.6%))}:host(.mobile) .kritzel-control:active{background-color:unset}.kritzel-control.selected,.kritzel-control.selected:hover,.kritzel-control.selected:active{background-color:var(--kritzel-controls-control-selected-background-color, #0E1111) !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, #f0f0f0)}.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, #f0f0f0)}.no-config{height:24px;width:24px;border-radius:50%;border:1px dashed gray}kritzel-tooltip{position:fixed;bottom:66px;left:50%;transform:translateX(-50%);z-index:10001}";
1072
1108
 
1073
1109
  const KritzelControls = class {
1074
1110
  constructor(hostRef) {
@@ -1078,6 +1114,7 @@ const KritzelControls = class {
1078
1114
  this.activeControl = null;
1079
1115
  this.firstConfig = null;
1080
1116
  this.tooltipVisible = false;
1117
+ this.isTouchDevice = KritzelDevicesHelper.isTouchDevice();
1081
1118
  this.kritzelEngine = null;
1082
1119
  }
1083
1120
  get activeToolAsTextTool() {
@@ -1158,16 +1195,18 @@ const KritzelControls = class {
1158
1195
  render() {
1159
1196
  var _a, _b;
1160
1197
  const hasNoConfig = ((_a = this.activeControl) === null || _a === void 0 ? void 0 : _a.config) === undefined || ((_b = this.activeControl) === null || _b === void 0 ? void 0 : _b.config) === null;
1161
- return (index.h(index.Host, { key: '2b13783ef0f1638ad76bfcef22c17c3eeb849d67' }, index.h("kritzel-utility-panel", { key: '1babeb88133cebc9057c85723b812b99152316c6', style: {
1198
+ return (index.h(index.Host, { key: 'e5bfc1952235cb3524849733015d14e629f36f9d', class: {
1199
+ mobile: this.isTouchDevice,
1200
+ } }, index.h("kritzel-utility-panel", { key: '8b89423a1d1d4d93945f774f0867b2fd8bd4b0bf', style: {
1162
1201
  position: 'absolute',
1163
1202
  bottom: '56px',
1164
1203
  left: '12px',
1165
- }, onUndo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.undo(); }, onRedo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.redo(); }, onDelete: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.delete(); } }), index.h("div", { key: '8fafebdf6726dd2bffe85cb2b3ada5f4885a2bf8', class: "kritzel-controls" }, this.controls.map(control => {
1204
+ }, onUndo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.undo(); }, onRedo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.redo(); }, onDelete: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.delete(); } }), index.h("div", { key: '8b58a76ff194663f312cfe55fd3e29e78b8067d1', class: "kritzel-controls" }, this.controls.map(control => {
1166
1205
  var _a, _b, _c, _d, _e, _f, _g, _h;
1167
1206
  if (control.type === 'tool') {
1168
1207
  return (index.h("button", { class: {
1169
1208
  'kritzel-control': true,
1170
- 'selected': ((_a = this.activeControl) === null || _a === void 0 ? void 0 : _a.name) === (control === null || control === void 0 ? void 0 : control.name),
1209
+ selected: ((_a = this.activeControl) === null || _a === void 0 ? void 0 : _a.name) === (control === null || control === void 0 ? void 0 : control.name),
1171
1210
  }, key: control.name, onClick: _event => { var _a; return (_a = this.handleControlClick) === null || _a === void 0 ? void 0 : _a.call(this, control); } }, index.h("kritzel-icon", { name: control.icon })));
1172
1211
  }
1173
1212
  if (control.type === 'divider') {
@@ -1452,71 +1491,76 @@ class KritzelEraserTool extends KritzelBaseTool {
1452
1491
  super(store);
1453
1492
  this.touchStartTimeout = null;
1454
1493
  }
1455
- handleMouseDown(event) {
1456
- if (KritzelEventHelper.isLeftClick(event)) {
1457
- this._store.state.isErasing = true;
1494
+ handlePointerDown(event) {
1495
+ if (event.pointerType === 'mouse') {
1496
+ if (KritzelEventHelper.isLeftClick(event)) {
1497
+ this._store.state.isErasing = true;
1498
+ }
1458
1499
  }
1459
- }
1460
- handleMouseMove(event) {
1461
- var _a;
1462
- if (this._store.state.isErasing) {
1463
- const shadowRoot = (_a = this._store.state.host) === null || _a === void 0 ? void 0 : _a.shadowRoot;
1464
- if (!shadowRoot)
1465
- return;
1466
- const selectedObject = this._store.getObjectFromPointerEvent(event, '.object');
1467
- if (!selectedObject)
1468
- return;
1469
- selectedObject.markedForRemoval = true;
1470
- this._store.rerender();
1500
+ if (event.pointerType === 'touch') {
1501
+ this.touchStartTimeout = setTimeout(() => {
1502
+ if (this._store.state.pointers.size === 1 && !this._store.state.isScaling) {
1503
+ this._store.state.isErasing = true;
1504
+ }
1505
+ }, 80);
1471
1506
  }
1472
1507
  }
1473
- handleMouseUp(_event) {
1474
- if (this._store.state.isErasing) {
1475
- const removeCommands = this._store.allObjects
1476
- .filter(object => object.markedForRemoval)
1477
- .map(object => {
1478
- object.markedForRemoval = false;
1479
- return new RemoveObjectCommand(this._store, this, object);
1480
- });
1481
- if (removeCommands.length > 0) {
1482
- this._store.history.executeCommand(new BatchCommand(this._store, this, removeCommands));
1508
+ handlePointerMove(event) {
1509
+ var _a, _b;
1510
+ if (event.pointerType === 'mouse') {
1511
+ if (this._store.state.isErasing) {
1512
+ const shadowRoot = (_a = this._store.state.host) === null || _a === void 0 ? void 0 : _a.shadowRoot;
1513
+ if (!shadowRoot)
1514
+ return;
1515
+ const selectedObject = this._store.getObjectFromPointerEvent(event, '.object');
1516
+ if (!selectedObject)
1517
+ return;
1518
+ selectedObject.markedForRemoval = true;
1519
+ this._store.rerender();
1483
1520
  }
1484
- this._store.state.isErasing = false;
1485
1521
  }
1486
- }
1487
- handleTouchStart(_event) {
1488
- this.touchStartTimeout = setTimeout(() => {
1489
- if (this._store.state.touchCount === 1 && !this._store.state.isScaling) {
1490
- this._store.state.isErasing = true;
1522
+ if (event.pointerType === 'touch') {
1523
+ if (this._store.state.pointers.size === 1 && this._store.state.isErasing) {
1524
+ const shadowRoot = (_b = this._store.state.host) === null || _b === void 0 ? void 0 : _b.shadowRoot;
1525
+ if (!shadowRoot)
1526
+ return;
1527
+ const selectedObject = this._store.getObjectFromPointerEvent(event, '.object');
1528
+ if (!selectedObject)
1529
+ return;
1530
+ selectedObject.markedForRemoval = true;
1531
+ this._store.rerender();
1491
1532
  }
1492
- }, 80);
1493
- }
1494
- handleTouchMove(event) {
1495
- var _a;
1496
- if (this._store.state.touchCount === 1 && this._store.state.isErasing) {
1497
- const shadowRoot = (_a = this._store.state.host) === null || _a === void 0 ? void 0 : _a.shadowRoot;
1498
- if (!shadowRoot)
1499
- return;
1500
- const selectedObject = this._store.getObjectFromPointerEvent(event, '.object');
1501
- if (!selectedObject)
1502
- return;
1503
- selectedObject.markedForRemoval = true;
1504
- this._store.rerender();
1505
1533
  }
1506
1534
  }
1507
- handleTouchEnd(_event) {
1508
- clearTimeout(this.touchStartTimeout);
1509
- if (this._store.state.isErasing) {
1510
- const removeCommands = this._store.allObjects
1511
- .filter(object => object.markedForRemoval)
1512
- .map(object => {
1513
- object.markedForRemoval = false;
1514
- return new RemoveObjectCommand(this._store, this, object);
1515
- });
1516
- if (removeCommands.length > 0) {
1517
- this._store.history.executeCommand(new BatchCommand(this._store, this, removeCommands));
1535
+ handlePointerUp(event) {
1536
+ if (event.pointerType === 'mouse') {
1537
+ if (this._store.state.isErasing) {
1538
+ const removeCommands = this._store.allObjects
1539
+ .filter(object => object.markedForRemoval)
1540
+ .map(object => {
1541
+ object.markedForRemoval = false;
1542
+ return new RemoveObjectCommand(this._store, this, object);
1543
+ });
1544
+ if (removeCommands.length > 0) {
1545
+ this._store.history.executeCommand(new BatchCommand(this._store, this, removeCommands));
1546
+ }
1547
+ this._store.state.isErasing = false;
1548
+ }
1549
+ }
1550
+ if (event.pointerType === 'touch') {
1551
+ clearTimeout(this.touchStartTimeout);
1552
+ if (this._store.state.isErasing) {
1553
+ const removeCommands = this._store.allObjects
1554
+ .filter(object => object.markedForRemoval)
1555
+ .map(object => {
1556
+ object.markedForRemoval = false;
1557
+ return new RemoveObjectCommand(this._store, this, object);
1558
+ });
1559
+ if (removeCommands.length > 0) {
1560
+ this._store.history.executeCommand(new BatchCommand(this._store, this, removeCommands));
1561
+ }
1562
+ this._store.state.isErasing = false;
1518
1563
  }
1519
- this._store.state.isErasing = false;
1520
1564
  }
1521
1565
  }
1522
1566
  }
@@ -1603,72 +1647,79 @@ class KritzelMoveHandler extends KritzelBaseHandler {
1603
1647
  constructor(store) {
1604
1648
  super(store);
1605
1649
  }
1606
- handleMouseDown(event) {
1607
- var _a;
1608
- if (KritzelEventHelper.isLeftClick(event)) {
1609
- if (((_a = this._store.state.selectionGroup) === null || _a === void 0 ? void 0 : _a.selected) && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
1650
+ handlePointerDown(event) {
1651
+ var _a, _b;
1652
+ if (event.pointerType === 'mouse') {
1653
+ if (KritzelEventHelper.isLeftClick(event)) {
1654
+ if (((_a = this._store.state.selectionGroup) === null || _a === void 0 ? void 0 : _a.selected) && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
1655
+ const clientX = event.clientX - this._store.offsetX;
1656
+ const clientY = event.clientY - this._store.offsetY;
1657
+ this._store.state.isDragging = true;
1658
+ this.dragStartX = clientX;
1659
+ this.dragStartY = clientY;
1660
+ this.startX = this.dragStartX;
1661
+ this.startY = this.dragStartY;
1662
+ }
1663
+ }
1664
+ }
1665
+ if (event.pointerType === 'touch') {
1666
+ const activePointers = Array.from(this._store.state.pointers.values());
1667
+ if (this._store.state.pointers.size === 1) {
1668
+ if (((_b = this._store.state.selectionGroup) === null || _b === void 0 ? void 0 : _b.selected) && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
1669
+ const x = Math.round(activePointers[0].clientX - this._store.offsetX);
1670
+ const y = Math.round(activePointers[0].clientY - this._store.offsetY);
1671
+ this.dragStartX = x;
1672
+ this.dragStartY = y;
1673
+ this.startX = x;
1674
+ this.startY = y;
1675
+ }
1676
+ }
1677
+ }
1678
+ }
1679
+ handlePointerMove(event) {
1680
+ if (event.pointerType === 'mouse') {
1681
+ if (this._store.state.isDragging && this._store.state.selectionGroup) {
1610
1682
  const clientX = event.clientX - this._store.offsetX;
1611
1683
  const clientY = event.clientY - this._store.offsetY;
1612
- this._store.state.isDragging = true;
1684
+ this.endX = clientX;
1685
+ this.endY = clientY;
1686
+ this._store.state.selectionGroup.move(clientX, clientY, this.dragStartX, this.dragStartY);
1613
1687
  this.dragStartX = clientX;
1614
1688
  this.dragStartY = clientY;
1615
- this.startX = this.dragStartX;
1616
- this.startY = this.dragStartY;
1617
1689
  }
1618
1690
  }
1619
- }
1620
- handleMouseMove(event) {
1621
- if (this._store.state.isDragging && this._store.state.selectionGroup) {
1622
- const clientX = event.clientX - this._store.offsetX;
1623
- const clientY = event.clientY - this._store.offsetY;
1624
- this.endX = clientX;
1625
- this.endY = clientY;
1626
- this._store.state.selectionGroup.move(clientX, clientY, this.dragStartX, this.dragStartY);
1627
- this.dragStartX = clientX;
1628
- this.dragStartY = clientY;
1629
- }
1630
- }
1631
- handleMouseUp(_event) {
1632
- if (this._store.state.isDragging) {
1633
- this._store.state.isDragging = false;
1634
- this._store.history.executeCommand(new MoveSelectionGroupCommand(this._store, this, this.endX, this.endY, this.startX, this.startY, true));
1635
- }
1636
- }
1637
- handleTouchStart(event) {
1638
- var _a;
1639
- if (this._store.state.touchCount === 1) {
1640
- if (((_a = this._store.state.selectionGroup) === null || _a === void 0 ? void 0 : _a.selected) && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
1641
- const x = Math.round(event.touches[0].clientX - this._store.offsetX);
1642
- const y = Math.round(event.touches[0].clientY - this._store.offsetY);
1643
- this.dragStartX = x;
1644
- this.dragStartY = y;
1645
- this.startX = x;
1646
- this.startY = y;
1691
+ if (event.pointerType === 'touch') {
1692
+ const activePointers = Array.from(this._store.state.pointers.values());
1693
+ if (this._store.state.pointers.size === 1 && this._store.state.selectionGroup && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
1694
+ const x = Math.round(activePointers[0].clientX - this._store.offsetX);
1695
+ const y = Math.round(activePointers[0].clientY - this._store.offsetY);
1696
+ this._store.state.isDragging = true;
1697
+ this.endX = x;
1698
+ this.endY = y;
1699
+ const moveDeltaX = Math.abs(x - this.startX);
1700
+ const moveDeltaY = Math.abs(y - this.startY);
1701
+ const moveThreshold = 5;
1702
+ if (moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
1703
+ clearTimeout(this._store.state.longTouchTimeout);
1704
+ this._store.state.selectionGroup.move(x, y, this.dragStartX, this.dragStartY);
1705
+ this.dragStartX = x;
1706
+ this.dragStartY = y;
1707
+ }
1647
1708
  }
1648
1709
  }
1649
1710
  }
1650
- handleTouchMove(event) {
1651
- if (this._store.state.touchCount === 1 && this._store.state.selectionGroup && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
1652
- const x = Math.round(event.touches[0].clientX - this._store.offsetX);
1653
- const y = Math.round(event.touches[0].clientY - this._store.offsetY);
1654
- this._store.state.isDragging = true;
1655
- this.endX = x;
1656
- this.endY = y;
1657
- const moveDeltaX = Math.abs(x - this.startX);
1658
- const moveDeltaY = Math.abs(y - this.startY);
1659
- const moveThreshold = 5;
1660
- if (moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
1661
- clearTimeout(this._store.state.longTouchTimeout);
1662
- this._store.state.selectionGroup.move(x, y, this.dragStartX, this.dragStartY);
1663
- this.dragStartX = x;
1664
- this.dragStartY = y;
1711
+ handlePointerUp(event) {
1712
+ if (event.pointerType === 'mouse') {
1713
+ if (this._store.state.isDragging) {
1714
+ this._store.state.isDragging = false;
1715
+ this._store.history.executeCommand(new MoveSelectionGroupCommand(this._store, this, this.endX, this.endY, this.startX, this.startY, true));
1665
1716
  }
1666
1717
  }
1667
- }
1668
- handleTouchEnd(_event) {
1669
- if (this._store.state.isDragging) {
1670
- this._store.state.isDragging = false;
1671
- this._store.history.executeCommand(new MoveSelectionGroupCommand(this._store, this, this.endX, this.endY, this.startX, this.startY, true));
1718
+ if (event.pointerType === 'touch') {
1719
+ if (this._store.state.isDragging) {
1720
+ this._store.state.isDragging = false;
1721
+ this._store.history.executeCommand(new MoveSelectionGroupCommand(this._store, this, this.endX, this.endY, this.startX, this.startY, true));
1722
+ }
1672
1723
  }
1673
1724
  }
1674
1725
  }
@@ -1706,131 +1757,140 @@ class KritzelResizeHandler extends KritzelBaseHandler {
1706
1757
  this.initialSize = { x: 0, y: 0, width: 0, height: 0 };
1707
1758
  this.newSize = { x: 0, y: 0, width: 0, height: 0 };
1708
1759
  }
1709
- handleMouseDown(event) {
1710
- if (KritzelEventHelper.isLeftClick(event)) {
1711
- if (this._store.state.selectionGroup && this._store.state.isResizeHandleSelected) {
1712
- const clientX = event.clientX - this._store.offsetX;
1713
- const clientY = event.clientY - this._store.offsetY;
1714
- this._store.state.isResizing = true;
1715
- this.initialMouseX = clientX;
1716
- this.initialMouseY = clientY;
1717
- this.initialSize.width = this._store.state.selectionGroup.width;
1718
- this.initialSize.height = this._store.state.selectionGroup.height;
1719
- this.initialSize.x = this._store.state.selectionGroup.translateX;
1720
- this.initialSize.y = this._store.state.selectionGroup.translateY;
1760
+ handlePointerDown(event) {
1761
+ if (event.pointerType === 'mouse') {
1762
+ if (KritzelEventHelper.isLeftClick(event)) {
1763
+ if (this._store.state.selectionGroup && this._store.state.isResizeHandleSelected) {
1764
+ const clientX = event.clientX - this._store.offsetX;
1765
+ const clientY = event.clientY - this._store.offsetY;
1766
+ this._store.state.isResizing = true;
1767
+ this.initialMouseX = clientX;
1768
+ this.initialMouseY = clientY;
1769
+ this.initialSize.width = this._store.state.selectionGroup.width;
1770
+ this.initialSize.height = this._store.state.selectionGroup.height;
1771
+ this.initialSize.x = this._store.state.selectionGroup.translateX;
1772
+ this.initialSize.y = this._store.state.selectionGroup.translateY;
1773
+ }
1721
1774
  }
1722
1775
  }
1723
- }
1724
- handleMouseMove(event) {
1725
- if (this._store.state.isResizing && this._store.state.selectionGroup) {
1726
- const clientX = event.clientX - this._store.offsetX;
1727
- const clientY = event.clientY - this._store.offsetY;
1728
- const dx = clientX - this.initialMouseX;
1729
- const dy = clientY - this.initialMouseY;
1730
- switch (this._store.state.resizeHandleType) {
1731
- case KritzelHandleType.TopLeft:
1732
- this.newSize.width = this.initialSize.width - dx;
1733
- this.newSize.height = this.initialSize.height - dy;
1734
- this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
1735
- this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
1736
- break;
1737
- case KritzelHandleType.TopRight:
1738
- this.newSize.width = this.initialSize.width + dx;
1739
- this.newSize.height = this.initialSize.height - dy;
1740
- this.newSize.x = this.initialSize.x;
1741
- this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
1742
- break;
1743
- case KritzelHandleType.BottomLeft:
1744
- this.newSize.width = this.initialSize.width - dx;
1745
- this.newSize.height = this.initialSize.height + dy;
1746
- this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
1747
- this.newSize.y = this.initialSize.y;
1748
- break;
1749
- case KritzelHandleType.BottomRight:
1750
- this.newSize.width = this.initialSize.width + dx;
1751
- this.newSize.height = this.initialSize.height + dy;
1752
- this.newSize.x = this.initialSize.x;
1753
- this.newSize.y = this.initialSize.y;
1754
- break;
1776
+ if (event.pointerType === 'touch') {
1777
+ const activePointers = Array.from(this._store.state.pointers.values());
1778
+ const firstTouch = activePointers[0];
1779
+ if (!firstTouch) {
1780
+ return;
1781
+ }
1782
+ if (activePointers.length === 1) {
1783
+ if (this._store.state.selectionGroup && this._store.state.isResizeHandleSelected) {
1784
+ const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
1785
+ const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
1786
+ this._store.state.isResizing = true;
1787
+ this.initialMouseX = clientX;
1788
+ this.initialMouseY = clientY;
1789
+ this.initialSize.width = this._store.state.selectionGroup.width;
1790
+ this.initialSize.height = this._store.state.selectionGroup.height;
1791
+ this.initialSize.x = this._store.state.selectionGroup.translateX;
1792
+ this.initialSize.y = this._store.state.selectionGroup.translateY;
1793
+ clearTimeout(this._store.state.longTouchTimeout);
1794
+ }
1755
1795
  }
1756
- this._store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
1757
- this._store.rerender();
1758
- }
1759
- }
1760
- handleMouseUp(_event) {
1761
- if (this._store.state.isResizing) {
1762
- const resizeSelectionGroupCommand = new ResizeSelectionGroupCommand(this._store, this, structuredClone(this.initialSize), structuredClone(this.newSize));
1763
- this._store.history.executeCommand(resizeSelectionGroupCommand);
1764
- this._store.state.isResizing = false;
1765
- this._store.rerender();
1766
1796
  }
1767
1797
  }
1768
- handleTouchStart(event) {
1769
- const firstTouch = event.touches[0];
1770
- if (!firstTouch) {
1771
- return;
1798
+ handlePointerMove(event) {
1799
+ if (event.pointerType === 'mouse') {
1800
+ if (this._store.state.isResizing && this._store.state.selectionGroup) {
1801
+ const clientX = event.clientX - this._store.offsetX;
1802
+ const clientY = event.clientY - this._store.offsetY;
1803
+ const dx = clientX - this.initialMouseX;
1804
+ const dy = clientY - this.initialMouseY;
1805
+ switch (this._store.state.resizeHandleType) {
1806
+ case KritzelHandleType.TopLeft:
1807
+ this.newSize.width = this.initialSize.width - dx;
1808
+ this.newSize.height = this.initialSize.height - dy;
1809
+ this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
1810
+ this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
1811
+ break;
1812
+ case KritzelHandleType.TopRight:
1813
+ this.newSize.width = this.initialSize.width + dx;
1814
+ this.newSize.height = this.initialSize.height - dy;
1815
+ this.newSize.x = this.initialSize.x;
1816
+ this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
1817
+ break;
1818
+ case KritzelHandleType.BottomLeft:
1819
+ this.newSize.width = this.initialSize.width - dx;
1820
+ this.newSize.height = this.initialSize.height + dy;
1821
+ this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
1822
+ this.newSize.y = this.initialSize.y;
1823
+ break;
1824
+ case KritzelHandleType.BottomRight:
1825
+ this.newSize.width = this.initialSize.width + dx;
1826
+ this.newSize.height = this.initialSize.height + dy;
1827
+ this.newSize.x = this.initialSize.x;
1828
+ this.newSize.y = this.initialSize.y;
1829
+ break;
1830
+ }
1831
+ this._store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
1832
+ this._store.rerender();
1833
+ }
1772
1834
  }
1773
- if (this._store.state.touchCount === 1) {
1774
- if (this._store.state.selectionGroup && this._store.state.isResizeHandleSelected) {
1775
- const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
1776
- const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
1777
- this._store.state.isResizing = true;
1778
- this.initialMouseX = clientX;
1779
- this.initialMouseY = clientY;
1780
- this.initialSize.width = this._store.state.selectionGroup.width;
1781
- this.initialSize.height = this._store.state.selectionGroup.height;
1782
- this.initialSize.x = this._store.state.selectionGroup.translateX;
1783
- this.initialSize.y = this._store.state.selectionGroup.translateY;
1835
+ if (event.pointerType === 'touch') {
1836
+ const activePointers = Array.from(this._store.state.pointers.values());
1837
+ const oneFingerTouch = activePointers[0];
1838
+ if (!oneFingerTouch) {
1839
+ return;
1840
+ }
1841
+ if (this._store.state.isResizing && this._store.state.selectionGroup) {
1842
+ const clientX = Math.round(oneFingerTouch.clientX - this._store.offsetX);
1843
+ const clientY = Math.round(oneFingerTouch.clientY - this._store.offsetY);
1844
+ const dx = clientX - this.initialMouseX;
1845
+ const dy = clientY - this.initialMouseY;
1846
+ switch (this._store.state.resizeHandleType) {
1847
+ case KritzelHandleType.TopLeft:
1848
+ this.newSize.width = this.initialSize.width - dx;
1849
+ this.newSize.height = this.initialSize.height - dy;
1850
+ this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
1851
+ this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
1852
+ break;
1853
+ case KritzelHandleType.TopRight:
1854
+ this.newSize.width = this.initialSize.width + dx;
1855
+ this.newSize.height = this.initialSize.height - dy;
1856
+ this.newSize.x = this.initialSize.x;
1857
+ this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
1858
+ break;
1859
+ case KritzelHandleType.BottomLeft:
1860
+ this.newSize.width = this.initialSize.width - dx;
1861
+ this.newSize.height = this.initialSize.height + dy;
1862
+ this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
1863
+ this.newSize.y = this.initialSize.y;
1864
+ break;
1865
+ case KritzelHandleType.BottomRight:
1866
+ this.newSize.width = this.initialSize.width + dx;
1867
+ this.newSize.height = this.initialSize.height + dy;
1868
+ this.newSize.x = this.initialSize.x;
1869
+ this.newSize.y = this.initialSize.y;
1870
+ break;
1871
+ }
1872
+ this._store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
1784
1873
  clearTimeout(this._store.state.longTouchTimeout);
1785
1874
  }
1786
1875
  }
1787
1876
  }
1788
- handleTouchMove(event) {
1789
- const oneFingerTouch = event.touches[0];
1790
- if (!oneFingerTouch) {
1791
- return;
1792
- }
1793
- if (this._store.state.isResizing && this._store.state.selectionGroup) {
1794
- const clientX = Math.round(oneFingerTouch.clientX - this._store.offsetX);
1795
- const clientY = Math.round(oneFingerTouch.clientY - this._store.offsetY);
1796
- const dx = clientX - this.initialMouseX;
1797
- const dy = clientY - this.initialMouseY;
1798
- switch (this._store.state.resizeHandleType) {
1799
- case KritzelHandleType.TopLeft:
1800
- this.newSize.width = this.initialSize.width - dx;
1801
- this.newSize.height = this.initialSize.height - dy;
1802
- this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
1803
- this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
1804
- break;
1805
- case KritzelHandleType.TopRight:
1806
- this.newSize.width = this.initialSize.width + dx;
1807
- this.newSize.height = this.initialSize.height - dy;
1808
- this.newSize.x = this.initialSize.x;
1809
- this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
1810
- break;
1811
- case KritzelHandleType.BottomLeft:
1812
- this.newSize.width = this.initialSize.width - dx;
1813
- this.newSize.height = this.initialSize.height + dy;
1814
- this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
1815
- this.newSize.y = this.initialSize.y;
1816
- break;
1817
- case KritzelHandleType.BottomRight:
1818
- this.newSize.width = this.initialSize.width + dx;
1819
- this.newSize.height = this.initialSize.height + dy;
1820
- this.newSize.x = this.initialSize.x;
1821
- this.newSize.y = this.initialSize.y;
1822
- break;
1877
+ handlePointerUp(event) {
1878
+ if (event.pointerType === 'mouse') {
1879
+ if (this._store.state.isResizing) {
1880
+ const resizeSelectionGroupCommand = new ResizeSelectionGroupCommand(this._store, this, structuredClone(this.initialSize), structuredClone(this.newSize));
1881
+ this._store.history.executeCommand(resizeSelectionGroupCommand);
1882
+ this._store.state.isResizing = false;
1883
+ this._store.rerender();
1823
1884
  }
1824
- this._store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
1825
- clearTimeout(this._store.state.longTouchTimeout);
1826
1885
  }
1827
- }
1828
- handleTouchEnd(_event) {
1829
- if (this._store.state.isResizing) {
1830
- const resizeSelectionGroupCommand = new ResizeSelectionGroupCommand(this._store, this, structuredClone(this.initialSize), structuredClone(this.newSize));
1831
- this._store.history.executeCommand(resizeSelectionGroupCommand);
1832
- this._store.state.isResizing = false;
1833
- clearTimeout(this._store.state.longTouchTimeout);
1886
+ if (event.pointerType === 'touch') {
1887
+ if (this._store.state.isResizing) {
1888
+ const resizeSelectionGroupCommand = new ResizeSelectionGroupCommand(this._store, this, structuredClone(this.initialSize), structuredClone(this.newSize));
1889
+ this._store.history.executeCommand(resizeSelectionGroupCommand);
1890
+ this._store.state.isResizing = false;
1891
+ this._store.rerender();
1892
+ clearTimeout(this._store.state.longTouchTimeout);
1893
+ }
1834
1894
  }
1835
1895
  }
1836
1896
  }
@@ -1864,87 +1924,95 @@ class KritzelRotationHandler extends KritzelBaseHandler {
1864
1924
  this.initialRotation = 0;
1865
1925
  this.rotation = 0;
1866
1926
  }
1867
- handleMouseDown(event) {
1868
- if (KritzelEventHelper.isLeftClick(event)) {
1869
- if (this._store.state.selectionGroup && this._store.state.isRotationHandleSelected) {
1927
+ handlePointerDown(event) {
1928
+ if (event.pointerType === 'mouse') {
1929
+ if (KritzelEventHelper.isLeftClick(event)) {
1930
+ if (this._store.state.selectionGroup && this._store.state.isRotationHandleSelected) {
1931
+ const clientX = event.clientX - this._store.offsetX;
1932
+ const clientY = event.clientY - this._store.offsetY;
1933
+ this._store.state.isRotating = true;
1934
+ const centerX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
1935
+ const centerY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
1936
+ const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
1937
+ const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
1938
+ this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - this._store.state.selectionGroup.rotation;
1939
+ }
1940
+ }
1941
+ }
1942
+ if (event.pointerType === 'touch') {
1943
+ const activePointers = Array.from(this._store.state.pointers.values());
1944
+ const firstTouch = activePointers[0];
1945
+ if (!firstTouch) {
1946
+ return;
1947
+ }
1948
+ if (activePointers.length === 1) {
1949
+ if (this._store.state.selectionGroup && this._store.state.isRotationHandleSelected) {
1950
+ const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
1951
+ const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
1952
+ this._store.state.isRotating = true;
1953
+ const centerX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
1954
+ const centerY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
1955
+ const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
1956
+ const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
1957
+ this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - this._store.state.selectionGroup.rotation;
1958
+ clearTimeout(this._store.state.longTouchTimeout);
1959
+ }
1960
+ }
1961
+ }
1962
+ }
1963
+ handlePointerMove(event) {
1964
+ if (event.pointerType === 'mouse') {
1965
+ if (this._store.state.isRotating && this._store.state.selectionGroup) {
1870
1966
  const clientX = event.clientX - this._store.offsetX;
1871
1967
  const clientY = event.clientY - this._store.offsetY;
1872
- this._store.state.isRotating = true;
1873
- const centerX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
1874
- const centerY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
1968
+ const groupCenterX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
1969
+ const groupCenterY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
1875
1970
  const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
1876
1971
  const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
1877
- this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - this._store.state.selectionGroup.rotation;
1972
+ const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);
1973
+ this.rotation = currentRotation - this.initialRotation;
1974
+ this._store.state.selectionGroup.rotate(this.rotation);
1975
+ this._store.rerender();
1878
1976
  }
1879
1977
  }
1880
- }
1881
- handleMouseMove(event) {
1882
- if (this._store.state.isRotating && this._store.state.selectionGroup) {
1883
- const clientX = event.clientX - this._store.offsetX;
1884
- const clientY = event.clientY - this._store.offsetY;
1885
- const groupCenterX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
1886
- const groupCenterY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
1887
- const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
1888
- const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
1889
- const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);
1890
- this.rotation = currentRotation - this.initialRotation;
1891
- this._store.state.selectionGroup.rotate(this.rotation);
1892
- this._store.rerender();
1893
- }
1894
- }
1895
- handleMouseUp(_event) {
1896
- if (this._store.state.isRotating) {
1897
- this._store.history.executeCommand(new RotateSelectionGroupCommand(this._store, this, this.rotation));
1898
- this._store.state.isRotating = false;
1899
- this.initialRotation = 0;
1900
- this.rotation = 0;
1901
- }
1902
- }
1903
- handleTouchStart(event) {
1904
- const firstTouch = event.touches[0];
1905
- if (!firstTouch) {
1906
- return;
1907
- }
1908
- if (this._store.state.touchCount === 1) {
1909
- if (this._store.state.selectionGroup && this._store.state.isRotationHandleSelected) {
1978
+ if (event.pointerType === 'touch') {
1979
+ const activePointers = Array.from(this._store.state.pointers.values());
1980
+ const firstTouch = activePointers[0];
1981
+ if (!firstTouch) {
1982
+ return;
1983
+ }
1984
+ if (this._store.state.isRotating && this._store.state.selectionGroup) {
1910
1985
  const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
1911
1986
  const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
1912
- this._store.state.isRotating = true;
1913
- const centerX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
1914
- const centerY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
1987
+ const groupCenterX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
1988
+ const groupCenterY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
1915
1989
  const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
1916
1990
  const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
1917
- this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - this._store.state.selectionGroup.rotation;
1991
+ const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);
1992
+ this.rotation = currentRotation - this.initialRotation;
1993
+ this._store.state.selectionGroup.rotate(this.rotation);
1994
+ this._store.rerender();
1918
1995
  clearTimeout(this._store.state.longTouchTimeout);
1919
1996
  }
1920
1997
  }
1921
1998
  }
1922
- handleTouchMove(event) {
1923
- const firstTouch = event.touches[0];
1924
- if (!firstTouch) {
1925
- return;
1926
- }
1927
- if (this._store.state.isRotating && this._store.state.selectionGroup) {
1928
- const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
1929
- const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
1930
- const groupCenterX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
1931
- const groupCenterY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
1932
- const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
1933
- const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
1934
- const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);
1935
- this.rotation = currentRotation - this.initialRotation;
1936
- this._store.state.selectionGroup.rotate(this.rotation);
1937
- this._store.rerender();
1938
- clearTimeout(this._store.state.longTouchTimeout);
1999
+ handlePointerUp(event) {
2000
+ if (event.pointerType === 'mouse') {
2001
+ if (this._store.state.isRotating) {
2002
+ this._store.history.executeCommand(new RotateSelectionGroupCommand(this._store, this, this.rotation));
2003
+ this._store.state.isRotating = false;
2004
+ this.initialRotation = 0;
2005
+ this.rotation = 0;
2006
+ }
1939
2007
  }
1940
- }
1941
- handleTouchEnd(_event) {
1942
- if (this._store.state.isRotating) {
1943
- this._store.history.executeCommand(new RotateSelectionGroupCommand(this._store, this, this.rotation));
1944
- this._store.state.isRotating = false;
1945
- this.initialRotation = 0;
1946
- this.rotation = 0;
1947
- clearTimeout(this._store.state.longTouchTimeout);
2008
+ if (event.pointerType === 'touch') {
2009
+ if (this._store.state.isRotating) {
2010
+ this._store.history.executeCommand(new RotateSelectionGroupCommand(this._store, this, this.rotation));
2011
+ this._store.state.isRotating = false;
2012
+ this.initialRotation = 0;
2013
+ this.rotation = 0;
2014
+ clearTimeout(this._store.state.longTouchTimeout);
2015
+ }
1948
2016
  }
1949
2017
  }
1950
2018
  }
@@ -2052,63 +2120,70 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
2052
2120
  this.touchStartY = 0;
2053
2121
  this.touchStartTimeout = null;
2054
2122
  }
2055
- handleMouseDown(event) {
2056
- if (KritzelEventHelper.isLeftClick(event) && !this._store.state.selectionGroup) {
2057
- this.startMouseSelection(event);
2123
+ handlePointerDown(event) {
2124
+ if (event.pointerType === 'mouse') {
2125
+ if (KritzelEventHelper.isLeftClick(event) && !this._store.state.selectionGroup) {
2126
+ this.startMouseSelection(event);
2127
+ }
2058
2128
  }
2059
- }
2060
- handleMouseMove(event) {
2061
- if (this._store.state.isSelecting) {
2062
- this.updateMouseSelection(event);
2129
+ if (event.pointerType === 'touch') {
2130
+ this.touchStartTimeout = setTimeout(() => {
2131
+ if (this._store.state.pointers.size === 1 && !this._store.state.isScaling && !this._store.state.selectionGroup) {
2132
+ this.startTouchSelection();
2133
+ this.updateTouchSelection();
2134
+ }
2135
+ }, 80);
2063
2136
  }
2064
2137
  }
2065
- handleMouseUp(event) {
2066
- if (KritzelEventHelper.isLeftClick(event) && this._store.state.isSelecting) {
2067
- if (this.isSelectionClick) {
2138
+ handlePointerMove(event) {
2139
+ if (event.pointerType === 'mouse') {
2140
+ if (this._store.state.isSelecting) {
2068
2141
  this.updateMouseSelection(event);
2069
- this.addSelectedObjectAtIndexToSelectionGroup(0);
2070
- this.removeSelectionBox();
2071
2142
  }
2072
- if (this.isSelectionDrag) {
2073
- this.updateMouseSelection(event);
2074
- this.addSelectedObjectsToSelectionGroup();
2075
- this.removeSelectionBox();
2143
+ }
2144
+ if (event.pointerType === 'touch') {
2145
+ const activePointers = Array.from(this._store.state.pointers.values());
2146
+ const x = Math.round(activePointers[0].clientX - this._store.offsetX);
2147
+ const y = Math.round(activePointers[0].clientY - this._store.offsetY);
2148
+ const moveDeltaX = Math.abs(x - this.touchStartX);
2149
+ const moveDeltaY = Math.abs(y - this.touchStartY);
2150
+ const moveThreshold = 5;
2151
+ if ((moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) && this._store.state.isSelecting) {
2152
+ this.updateTouchSelection();
2153
+ clearTimeout(this._store.state.longTouchTimeout);
2076
2154
  }
2077
2155
  }
2078
2156
  }
2079
- handleTouchStart(event) {
2080
- this.touchStartTimeout = setTimeout(() => {
2081
- if (this._store.state.touchCount === 1 && !this._store.state.isScaling && !this._store.state.selectionGroup) {
2082
- this.startTouchSelection(event);
2083
- this.updateTouchSelection(event);
2084
- }
2085
- }, 80);
2086
- }
2087
- handleTouchMove(event) {
2088
- const x = Math.round(event.touches[0].clientX - this._store.offsetX);
2089
- const y = Math.round(event.touches[0].clientY - this._store.offsetY);
2090
- const moveDeltaX = Math.abs(x - this.touchStartX);
2091
- const moveDeltaY = Math.abs(y - this.touchStartY);
2092
- const moveThreshold = 5;
2093
- if ((moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) && this._store.state.isSelecting) {
2094
- this.updateTouchSelection(event);
2095
- clearTimeout(this._store.state.longTouchTimeout);
2096
- }
2097
- }
2098
- handleTouchEnd(event) {
2099
- clearTimeout(this.touchStartTimeout);
2100
- if (this._store.state.isSelecting) {
2101
- if (this.isSelectionClick) {
2102
- this.updateTouchSelection(event);
2103
- this.addSelectedObjectAtIndexToSelectionGroup(0);
2104
- this.removeSelectionBox();
2157
+ handlePointerUp(event) {
2158
+ if (event.pointerType === 'mouse') {
2159
+ if (KritzelEventHelper.isLeftClick(event) && this._store.state.isSelecting) {
2160
+ if (this.isSelectionClick) {
2161
+ this.updateMouseSelection(event);
2162
+ this.addSelectedObjectAtIndexToSelectionGroup(0);
2163
+ this.removeSelectionBox();
2164
+ }
2165
+ if (this.isSelectionDrag) {
2166
+ this.updateMouseSelection(event);
2167
+ this.addSelectedObjectsToSelectionGroup();
2168
+ this.removeSelectionBox();
2169
+ }
2105
2170
  }
2106
- if (this.isSelectionDrag) {
2107
- this.updateTouchSelection(event);
2108
- this.addSelectedObjectsToSelectionGroup();
2109
- this.removeSelectionBox();
2171
+ }
2172
+ if (event.pointerType === 'touch') {
2173
+ clearTimeout(this.touchStartTimeout);
2174
+ if (this._store.state.isSelecting) {
2175
+ if (this.isSelectionClick) {
2176
+ this.updateTouchSelection();
2177
+ this.addSelectedObjectAtIndexToSelectionGroup(0);
2178
+ this.removeSelectionBox();
2179
+ }
2180
+ if (this.isSelectionDrag) {
2181
+ this.updateTouchSelection();
2182
+ this.addSelectedObjectsToSelectionGroup();
2183
+ this.removeSelectionBox();
2184
+ }
2185
+ this._store.state.skipContextMenu = false;
2110
2186
  }
2111
- this._store.state.skipContextMenu = false;
2112
2187
  }
2113
2188
  }
2114
2189
  removeSelectionBox() {
@@ -2132,8 +2207,9 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
2132
2207
  this._store.state.objectsOctree.remove(o => o instanceof KrtizelSelectionBox || o instanceof KritzelSelectionGroup);
2133
2208
  this._store.state.objectsOctree.insert(selectionBox);
2134
2209
  }
2135
- startTouchSelection(event) {
2136
- const firstTouch = event.touches[0];
2210
+ startTouchSelection() {
2211
+ const activePointers = Array.from(this._store.state.pointers.values());
2212
+ const firstTouch = activePointers[0];
2137
2213
  if (!firstTouch) {
2138
2214
  return;
2139
2215
  }
@@ -2169,8 +2245,9 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
2169
2245
  this._store.rerender();
2170
2246
  }
2171
2247
  }
2172
- updateTouchSelection(event) {
2173
- const firstTouch = event.touches[0];
2248
+ updateTouchSelection() {
2249
+ const activePointers = Array.from(this._store.state.pointers.values());
2250
+ const firstTouch = activePointers[0];
2174
2251
  if (!firstTouch) {
2175
2252
  return;
2176
2253
  }
@@ -2236,39 +2313,103 @@ class KritzelSelectionTool extends KritzelBaseTool {
2236
2313
  this.resizeHandler = new KritzelResizeHandler(this._store);
2237
2314
  this.rotationHandler = new KritzelRotationHandler(this._store);
2238
2315
  }
2239
- handleMouseDown(event) {
2240
- if (KritzelEventHelper.isLeftClick(event)) {
2241
- this._store.state.isResizeHandleSelected = this.isHandleSelected(event);
2242
- this._store.state.isRotationHandleSelected = this.isRotationHandleSelected(event);
2243
- this._store.state.resizeHandleType = this.getHandleType(event);
2244
- const selectedObject = this.getSelectedObject(event);
2245
- const isDifferentObject = selectedObject && this._store.state.selectionGroup && selectedObject.id !== this._store.state.selectionGroup.id;
2246
- if ((selectedObject === null || isDifferentObject) &&
2247
- this._store.state.selectionGroup &&
2248
- !this._store.state.isResizeHandleSelected &&
2249
- !this._store.state.isRotationHandleSelected) {
2250
- this._store.history.executeCommand(new RemoveSelectionGroupCommand(this._store, this._store.state.selectionGroup));
2316
+ handlePointerDown(event) {
2317
+ if (event.pointerType === 'mouse') {
2318
+ if (KritzelEventHelper.isLeftClick(event)) {
2319
+ this._store.state.isResizeHandleSelected = this.isHandleSelected(event);
2320
+ this._store.state.isRotationHandleSelected = this.isRotationHandleSelected(event);
2321
+ this._store.state.resizeHandleType = this.getHandleType(event);
2322
+ const selectedObject = this.getSelectedObject(event);
2323
+ const isDifferentObject = selectedObject && this._store.state.selectionGroup && selectedObject.id !== this._store.state.selectionGroup.id;
2324
+ if ((selectedObject === null || isDifferentObject) &&
2325
+ this._store.state.selectionGroup &&
2326
+ !this._store.state.isResizeHandleSelected &&
2327
+ !this._store.state.isRotationHandleSelected) {
2328
+ this._store.history.executeCommand(new RemoveSelectionGroupCommand(this._store, this._store.state.selectionGroup));
2329
+ }
2330
+ if (selectedObject && selectedObject.selected && selectedObject.objects.length === 1) {
2331
+ setTimeout(() => {
2332
+ if (this._store.state.isDragging === false && this._store.state.isResizing === false && this._store.state.isRotating === false) {
2333
+ selectedObject.objects[0].onSelectedClick();
2334
+ }
2335
+ }, 100);
2336
+ }
2251
2337
  }
2338
+ this.moveHandler.handlePointerDown(event);
2339
+ this.selectionHandler.handlePointerDown(event);
2340
+ this.resizeHandler.handlePointerDown(event);
2341
+ this.rotationHandler.handlePointerDown(event);
2342
+ this._store.rerender();
2343
+ }
2344
+ if (event.pointerType === 'touch') {
2345
+ if (this._store.state.isScaling === true) {
2346
+ return;
2347
+ }
2348
+ if (this._store.state.pointers.size === 1) {
2349
+ this._store.state.isResizeHandleSelected = this.isHandleSelected(event);
2350
+ this._store.state.isRotationHandleSelected = this.isRotationHandleSelected(event);
2351
+ this._store.state.resizeHandleType = this.getHandleType(event);
2352
+ const selectedObject = this.getSelectedObject(event);
2353
+ const isDifferentObject = selectedObject && this._store.state.selectionGroup && selectedObject.id !== this._store.state.selectionGroup.id;
2354
+ if (!this._store.state.selectionGroup && selectedObject) {
2355
+ this._store.state.skipContextMenu = true;
2356
+ }
2357
+ if ((selectedObject === null || isDifferentObject) &&
2358
+ this._store.state.selectionGroup &&
2359
+ !this._store.state.isResizeHandleSelected &&
2360
+ !this._store.state.isRotationHandleSelected) {
2361
+ this._store.history.executeCommand(new RemoveSelectionGroupCommand(this._store, this._store.state.selectionGroup));
2362
+ }
2363
+ if (selectedObject && selectedObject.selected && selectedObject.objects.length === 1) {
2364
+ setTimeout(() => {
2365
+ if (this._store.state.isDragging === false && this._store.state.isResizing === false && this._store.state.isRotating === false) {
2366
+ selectedObject.objects[0].onSelectedClick();
2367
+ }
2368
+ }, 100);
2369
+ }
2370
+ }
2371
+ this.rotationHandler.handlePointerDown(event);
2372
+ this.resizeHandler.handlePointerDown(event);
2373
+ this.moveHandler.handlePointerDown(event);
2374
+ this.selectionHandler.handlePointerDown(event);
2375
+ }
2376
+ }
2377
+ handlePointerMove(event) {
2378
+ if (event.pointerType === 'mouse') {
2379
+ this.moveHandler.handlePointerMove(event);
2380
+ this.selectionHandler.handlePointerMove(event);
2381
+ this.resizeHandler.handlePointerMove(event);
2382
+ this.rotationHandler.handlePointerMove(event);
2383
+ this._store.rerender();
2384
+ }
2385
+ if (event.pointerType === 'touch') {
2386
+ if (this._store.state.isScaling === true) {
2387
+ return;
2388
+ }
2389
+ this.rotationHandler.handlePointerMove(event);
2390
+ this.resizeHandler.handlePointerMove(event);
2391
+ this.moveHandler.handlePointerMove(event);
2392
+ this.selectionHandler.handlePointerMove(event);
2393
+ this._store.rerender();
2252
2394
  }
2253
- this.moveHandler.handleMouseDown(event);
2254
- this.selectionHandler.handleMouseDown(event);
2255
- this.resizeHandler.handleMouseDown(event);
2256
- this.rotationHandler.handleMouseDown(event);
2257
- this._store.rerender();
2258
- }
2259
- handleMouseMove(event) {
2260
- this.moveHandler.handleMouseMove(event);
2261
- this.selectionHandler.handleMouseMove(event);
2262
- this.resizeHandler.handleMouseMove(event);
2263
- this.rotationHandler.handleMouseMove(event);
2264
- this._store.rerender();
2265
2395
  }
2266
- handleMouseUp(event) {
2267
- this.moveHandler.handleMouseUp(event);
2268
- this.selectionHandler.handleMouseUp(event);
2269
- this.resizeHandler.handleMouseUp(event);
2270
- this.rotationHandler.handleMouseUp(event);
2271
- this._store.rerender();
2396
+ handlePointerUp(event) {
2397
+ if (event.pointerType === 'mouse') {
2398
+ this.moveHandler.handlePointerUp(event);
2399
+ this.selectionHandler.handlePointerUp(event);
2400
+ this.resizeHandler.handlePointerUp(event);
2401
+ this.rotationHandler.handlePointerUp(event);
2402
+ this._store.rerender();
2403
+ }
2404
+ if (event.pointerType === 'touch') {
2405
+ if (this._store.state.isScaling === true) {
2406
+ return;
2407
+ }
2408
+ this.rotationHandler.handlePointerUp(event);
2409
+ this.resizeHandler.handlePointerUp(event);
2410
+ this.moveHandler.handlePointerUp(event);
2411
+ this.selectionHandler.handlePointerUp(event);
2412
+ }
2272
2413
  }
2273
2414
  handleDoubleClick(event) {
2274
2415
  var _a;
@@ -2300,50 +2441,6 @@ class KritzelSelectionTool extends KritzelBaseTool {
2300
2441
  }, 300);
2301
2442
  }
2302
2443
  }
2303
- handleTouchStart(event) {
2304
- if (this._store.state.isScaling === true) {
2305
- return;
2306
- }
2307
- if (this._store.state.touchCount === 1) {
2308
- this._store.state.isResizeHandleSelected = this.isHandleSelected(event);
2309
- this._store.state.isRotationHandleSelected = this.isRotationHandleSelected(event);
2310
- this._store.state.resizeHandleType = this.getHandleType(event);
2311
- const selectedObject = this.getSelectedObject(event);
2312
- const isDifferentObject = selectedObject && this._store.state.selectionGroup && selectedObject.id !== this._store.state.selectionGroup.id;
2313
- if (!this._store.state.selectionGroup && selectedObject) {
2314
- this._store.state.skipContextMenu = true;
2315
- }
2316
- if ((selectedObject === null || isDifferentObject) &&
2317
- this._store.state.selectionGroup &&
2318
- !this._store.state.isResizeHandleSelected &&
2319
- !this._store.state.isRotationHandleSelected) {
2320
- this._store.history.executeCommand(new RemoveSelectionGroupCommand(this._store, this._store.state.selectionGroup));
2321
- }
2322
- }
2323
- this.rotationHandler.handleTouchStart(event);
2324
- this.resizeHandler.handleTouchStart(event);
2325
- this.moveHandler.handleTouchStart(event);
2326
- this.selectionHandler.handleTouchStart(event);
2327
- }
2328
- handleTouchMove(event) {
2329
- if (this._store.state.isScaling === true) {
2330
- return;
2331
- }
2332
- this.rotationHandler.handleTouchMove(event);
2333
- this.resizeHandler.handleTouchMove(event);
2334
- this.moveHandler.handleTouchMove(event);
2335
- this.selectionHandler.handleTouchMove(event);
2336
- this._store.rerender();
2337
- }
2338
- handleTouchEnd(event) {
2339
- if (this._store.state.isScaling === true) {
2340
- return;
2341
- }
2342
- this.rotationHandler.handleTouchEnd(event);
2343
- this.resizeHandler.handleTouchEnd(event);
2344
- this.moveHandler.handleTouchEnd(event);
2345
- this.selectionHandler.handleTouchEnd(event);
2346
- }
2347
2444
  getSelectedObject(event) {
2348
2445
  const path = event.composedPath().slice(1);
2349
2446
  const objectElement = path.find(element => element.classList && element.classList.contains('object'));
@@ -2837,7 +2934,7 @@ const DEFAULT_KRITZEL_CONTROLS = [
2837
2934
  },
2838
2935
  ];
2839
2936
 
2840
- 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}kritzel-controls{position:absolute;bottom:28px}";
2937
+ 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-controls{position:absolute;bottom:28px}";
2841
2938
 
2842
2939
  const KritzelEditor = class {
2843
2940
  constructor(hostRef) {
@@ -2860,7 +2957,7 @@ const KritzelEditor = class {
2860
2957
  }
2861
2958
  }
2862
2959
  render() {
2863
- return (index.h(index.Host, { key: 'f86e43f5b908d682ba2e20e55466dcdf9f128140' }, index.h("kritzel-engine", { key: '11d72009fd277ea4379b596d57aa2a1b19b9d6bd', ref: el => (this.engineRef = el) }), index.h("kritzel-controls", { key: '4a575354c9bf117b12db7deaafaffcdcb9461bc6', ref: el => (this.controlsRef = el), controls: this.controls, style: this.hideControls ? { display: 'none' } : { display: 'flex' } })));
2960
+ return (index.h(index.Host, { key: '74206218105a7675872539955729e9329573b83b' }, index.h("kritzel-engine", { key: '596be73738bdfcbd04472a3ffef2e7ace393c94e', ref: el => (this.engineRef = el) }), index.h("kritzel-controls", { key: '95701130a74395c27c07c56eb74294074261a8be', ref: el => (this.controlsRef = el), controls: this.controls, style: this.hideControls ? { display: 'none' } : { display: 'flex' } })));
2864
2961
  }
2865
2962
  get host() { return index.getElement(this); }
2866
2963
  };
@@ -2886,85 +2983,91 @@ class KritzelViewport {
2886
2983
  this._store.state.hasViewportChanged = true;
2887
2984
  this._store.rerender();
2888
2985
  }
2889
- handleMouseDown(event) {
2890
- const adjustedClientX = event.clientX - this._store.offsetX;
2891
- const adjustedClientY = event.clientY - this._store.offsetY;
2892
- if (KritzelEventHelper.isRightClick(event)) {
2893
- this._store.state.isPanning = true;
2894
- this._store.state.startX = adjustedClientX;
2895
- this._store.state.startY = adjustedClientY;
2896
- }
2897
- }
2898
- handleMouseMove(event) {
2899
- const adjustedClientX = event.clientX - this._store.offsetX;
2900
- const adjustedClientY = event.clientY - this._store.offsetY;
2901
- this._store.state.cursorX = adjustedClientX;
2902
- this._store.state.cursorY = adjustedClientY;
2903
- if (this._store.state.isPanning) {
2904
- this._store.state.translateX -= this._store.state.startX - adjustedClientX;
2905
- this._store.state.translateY -= this._store.state.startY - adjustedClientY;
2906
- this._store.state.startX = adjustedClientX;
2907
- this._store.state.startY = adjustedClientY;
2908
- this._store.state.hasViewportChanged = true;
2909
- this._store.state.skipContextMenu = true;
2910
- this._store.rerender();
2986
+ handlePointerDown(event) {
2987
+ if (event.pointerType === 'mouse') {
2988
+ const adjustedClientX = event.clientX - this._store.offsetX;
2989
+ const adjustedClientY = event.clientY - this._store.offsetY;
2990
+ if (event.button === KritzelMouseButton.Right) {
2991
+ this._store.state.isPanning = true;
2992
+ this._store.state.startX = adjustedClientX;
2993
+ this._store.state.startY = adjustedClientY;
2994
+ }
2911
2995
  }
2912
- }
2913
- handleMouseUp(_event) {
2914
- if (this._store.state.isPanning) {
2915
- this._store.state.isPanning = false;
2916
- this._store.rerender();
2996
+ if (event.pointerType === 'touch') {
2997
+ const activePointers = Array.from(this._store.state.pointers.values());
2998
+ if (activePointers.length === 2) {
2999
+ this._store.state.currentPath = null;
3000
+ this._store.state.isScaling = true;
3001
+ const firstTouchX = activePointers[0].clientX - this._store.offsetX;
3002
+ const firstTouchY = activePointers[0].clientY - this._store.offsetY;
3003
+ const secondTouchX = activePointers[1].clientX - this._store.offsetX;
3004
+ const secondTouchY = activePointers[1].clientY - this._store.offsetY;
3005
+ this.initialTouchDistance = Math.sqrt(Math.pow(firstTouchX - secondTouchX, 2) + Math.pow(firstTouchY - secondTouchY, 2));
3006
+ this.startX = (firstTouchX + secondTouchX) / 2;
3007
+ this.startY = (firstTouchY + secondTouchY) / 2;
3008
+ this._store.rerender();
3009
+ }
2917
3010
  }
2918
3011
  }
2919
- handleTouchStart(event) {
2920
- this._store.state.touchCount = event.touches.length;
2921
- if (this._store.state.touchCount === 2) {
2922
- this._store.state.currentPath = null;
2923
- this._store.state.isScaling = true;
2924
- const firstTouchX = event.touches[0].clientX - this._store.offsetX;
2925
- const firstTouchY = event.touches[0].clientY - this._store.offsetY;
2926
- const secondTouchX = event.touches[1].clientX - this._store.offsetX;
2927
- const secondTouchY = event.touches[1].clientY - this._store.offsetY;
2928
- this.initialTouchDistance = Math.sqrt(Math.pow(firstTouchX - secondTouchX, 2) + Math.pow(firstTouchY - secondTouchY, 2));
2929
- this.startX = (firstTouchX + secondTouchX) / 2;
2930
- this.startY = (firstTouchY + secondTouchY) / 2;
2931
- this._store.rerender();
3012
+ handlePointerMove(event) {
3013
+ if (event.pointerType === 'mouse') {
3014
+ const adjustedClientX = event.clientX - this._store.offsetX;
3015
+ const adjustedClientY = event.clientY - this._store.offsetY;
3016
+ this._store.state.cursorX = adjustedClientX;
3017
+ this._store.state.cursorY = adjustedClientY;
3018
+ if (this._store.state.isPanning) {
3019
+ this._store.state.translateX -= this._store.state.startX - adjustedClientX;
3020
+ this._store.state.translateY -= this._store.state.startY - adjustedClientY;
3021
+ this._store.state.startX = adjustedClientX;
3022
+ this._store.state.startY = adjustedClientY;
3023
+ this._store.state.hasViewportChanged = true;
3024
+ this._store.state.skipContextMenu = true;
3025
+ this._store.rerender();
3026
+ }
2932
3027
  }
2933
- }
2934
- handleTouchMove(event) {
2935
- if (this._store.state.touchCount === 2) {
2936
- const firstTouchX = event.touches[0].clientX - this._store.offsetX;
2937
- const firstTouchY = event.touches[0].clientY - this._store.offsetY;
2938
- const secondTouchX = event.touches[1].clientX - this._store.offsetX;
2939
- const secondTouchY = event.touches[1].clientY - this._store.offsetY;
2940
- const currentTouchDistance = Math.sqrt(Math.pow(firstTouchX - secondTouchX, 2) + Math.pow(firstTouchY - secondTouchY, 2));
2941
- const midpointX = (firstTouchX + secondTouchX) / 2;
2942
- const midpointY = (firstTouchY + secondTouchY) / 2;
2943
- const scaleRatio = currentTouchDistance / this.initialTouchDistance;
2944
- const newScale = this._store.state.scale * scaleRatio;
2945
- if (newScale > this._store.state.scaleMax || newScale < this._store.state.scaleMin) {
2946
- this._store.state.translateX += midpointX - this.startX;
2947
- this._store.state.translateY += midpointY - this.startY;
3028
+ if (event.pointerType === 'touch') {
3029
+ const activePointers = Array.from(this._store.state.pointers.values());
3030
+ if (activePointers.length === 2) {
3031
+ const firstTouchX = activePointers[0].clientX - this._store.offsetX;
3032
+ const firstTouchY = activePointers[0].clientY - this._store.offsetY;
3033
+ const secondTouchX = activePointers[1].clientX - this._store.offsetX;
3034
+ const secondTouchY = activePointers[1].clientY - this._store.offsetY;
3035
+ const currentTouchDistance = Math.sqrt(Math.pow(firstTouchX - secondTouchX, 2) + Math.pow(firstTouchY - secondTouchY, 2));
3036
+ const midpointX = (firstTouchX + secondTouchX) / 2;
3037
+ const midpointY = (firstTouchY + secondTouchY) / 2;
3038
+ const scaleRatio = currentTouchDistance / this.initialTouchDistance;
3039
+ const newScale = this._store.state.scale * scaleRatio;
3040
+ if (newScale > this._store.state.scaleMax || newScale < this._store.state.scaleMin) {
3041
+ this._store.state.translateX += midpointX - this.startX;
3042
+ this._store.state.translateY += midpointY - this.startY;
3043
+ }
3044
+ else {
3045
+ const translateXAdjustment = (midpointX - this._store.state.translateX) * (scaleRatio - 1);
3046
+ const translateYAdjustment = (midpointY - this._store.state.translateY) * (scaleRatio - 1);
3047
+ this._store.state.translateX += midpointX - this.startX - translateXAdjustment;
3048
+ this._store.state.translateY += midpointY - this.startY - translateYAdjustment;
3049
+ this._store.state.scale = newScale;
3050
+ this.initialTouchDistance = currentTouchDistance;
3051
+ }
3052
+ this.startX = midpointX;
3053
+ this.startY = midpointY;
3054
+ this._store.state.hasViewportChanged = true;
3055
+ this._store.rerender();
2948
3056
  }
2949
- else {
2950
- const translateXAdjustment = (midpointX - this._store.state.translateX) * (scaleRatio - 1);
2951
- const translateYAdjustment = (midpointY - this._store.state.translateY) * (scaleRatio - 1);
2952
- this._store.state.translateX += midpointX - this.startX - translateXAdjustment;
2953
- this._store.state.translateY += midpointY - this.startY - translateYAdjustment;
2954
- this._store.state.scale = newScale;
2955
- this.initialTouchDistance = currentTouchDistance;
3057
+ }
3058
+ }
3059
+ handlePointerUp(event) {
3060
+ if (event.pointerType === 'mouse') {
3061
+ if (this._store.state.isPanning) {
3062
+ this._store.state.isPanning = false;
3063
+ this._store.rerender();
2956
3064
  }
2957
- this.startX = midpointX;
2958
- this.startY = midpointY;
2959
- this._store.state.hasViewportChanged = true;
3065
+ }
3066
+ if (event.pointerType === 'touch') {
3067
+ this._store.state.isScaling = false;
2960
3068
  this._store.rerender();
2961
3069
  }
2962
3070
  }
2963
- handleTouchEnd(_event) {
2964
- this._store.state.touchCount = 0;
2965
- this._store.state.isScaling = false;
2966
- this._store.rerender();
2967
- }
2968
3071
  handleWheel(event) {
2969
3072
  event.preventDefault();
2970
3073
  if (event.ctrlKey === true && KritzelEventHelper.isMainMouseWheel(event)) {
@@ -3271,7 +3374,7 @@ class UpdateObjectCommand extends KritzelBaseCommand {
3271
3374
  }
3272
3375
  }
3273
3376
 
3274
- const initialState = {
3377
+ const DEFAULT_ENGINE_STATE = {
3275
3378
  activeTool: null,
3276
3379
  activeText: null,
3277
3380
  currentPath: null,
@@ -3319,10 +3422,11 @@ const initialState = {
3319
3422
  viewportWidth: 0,
3320
3423
  viewportHeight: 0,
3321
3424
  historyBufferSize: 1000,
3322
- touchCount: 0,
3323
3425
  longTouchTimeout: null,
3324
3426
  longTouchDelay: 300,
3427
+ pointers: new Map()
3325
3428
  };
3429
+
3326
3430
  class KritzelStore {
3327
3431
  get history() {
3328
3432
  return this._history;
@@ -3348,7 +3452,7 @@ class KritzelStore {
3348
3452
  constructor(kritzelEngine) {
3349
3453
  this._listeners = new Map();
3350
3454
  this.objects = [];
3351
- this._state = initialState;
3455
+ this._state = DEFAULT_ENGINE_STATE;
3352
3456
  this._kritzelEngine = kritzelEngine;
3353
3457
  this._history = new KritzelHistory(this);
3354
3458
  this._state.objectsOctree = new KritzelOctree({
@@ -3652,46 +3756,6 @@ class KritzelContextMenuHandler extends KritzelBaseHandler {
3652
3756
  this.objectContextMenuItems = objectContextMenuItems;
3653
3757
  }
3654
3758
  handleContextMenu(event) {
3655
- if (event.cancelable) {
3656
- event.preventDefault();
3657
- }
3658
- if (!(this._store.state.activeTool instanceof KritzelSelectionTool)) {
3659
- return;
3660
- }
3661
- if (this._store.state.skipContextMenu) {
3662
- this._store.state.skipContextMenu = false;
3663
- return;
3664
- }
3665
- this._store.state.contextMenuItems = this._store.state.selectionGroup ? this.objectContextMenuItems : this.globalContextMenuItems;
3666
- let x = event.clientX - this._store.offsetX;
3667
- let y = event.clientY - this._store.offsetY;
3668
- const menuWidthEstimate = 150;
3669
- const menuHeightEstimate = 200;
3670
- const margin = 10;
3671
- if (x + menuWidthEstimate > window.innerWidth - margin) {
3672
- x = window.innerWidth - menuWidthEstimate - margin;
3673
- }
3674
- if (y + menuHeightEstimate > window.innerHeight - margin) {
3675
- y = window.innerHeight - menuHeightEstimate - margin;
3676
- }
3677
- x = Math.max(margin, x);
3678
- y = Math.max(margin, y);
3679
- this._store.state.contextMenuX = x;
3680
- this._store.state.contextMenuY = y;
3681
- this._store.state.isContextMenuVisible = true;
3682
- this._store.state.isEnabled = false;
3683
- this._store.rerender();
3684
- }
3685
- handleContextMenuTouch(event) {
3686
- if (event.cancelable) {
3687
- event.preventDefault();
3688
- }
3689
- if (this._store.state.touchCount > 1 || !(this._store.state.activeTool instanceof KritzelSelectionTool)) {
3690
- return;
3691
- }
3692
- if ('vibrate' in navigator) {
3693
- navigator.vibrate(25);
3694
- }
3695
3759
  const selectedObject = this._store.getObjectFromPointerEvent(event, '.object');
3696
3760
  if (selectedObject && !(selectedObject instanceof KritzelSelectionGroup)) {
3697
3761
  this._store.state.selectionGroup = KritzelSelectionGroup.create(this._store);
@@ -3702,12 +3766,8 @@ class KritzelContextMenuHandler extends KritzelBaseHandler {
3702
3766
  this._store.history.executeCommand(new AddSelectionGroupCommand(this._store, this, this._store.state.selectionGroup));
3703
3767
  }
3704
3768
  this._store.state.contextMenuItems = this._store.state.selectionGroup ? this.objectContextMenuItems : this.globalContextMenuItems;
3705
- const firstTouch = event.touches[0];
3706
- if (!firstTouch) {
3707
- return;
3708
- }
3709
- let x = Math.round(firstTouch.clientX - this._store.offsetX);
3710
- let y = Math.round(firstTouch.clientY - this._store.offsetY);
3769
+ let x = event.clientX - this._store.offsetX;
3770
+ let y = event.clientY - this._store.offsetY;
3711
3771
  const menuWidthEstimate = 150;
3712
3772
  const menuHeightEstimate = 200;
3713
3773
  const margin = 10;
@@ -3727,7 +3787,7 @@ class KritzelContextMenuHandler extends KritzelBaseHandler {
3727
3787
  }
3728
3788
  }
3729
3789
 
3730
- const kritzelEngineCss = ":host{display:block;position:relative;height:100%;width:100%;overflow:hidden;background-color:var(--kritzel-engine-background-color, #ffffff)}.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}";
3790
+ 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}";
3731
3791
 
3732
3792
  const KritzelEngine = class {
3733
3793
  get isSelecting() {
@@ -3792,75 +3852,50 @@ const KritzelEngine = class {
3792
3852
  this.viewport = new KritzelViewport(this.store, this.host);
3793
3853
  this.engineReady.emit();
3794
3854
  }
3795
- handleContextMenu(ev) {
3796
- if (this.store.state.isEnabled === false) {
3797
- return;
3798
- }
3799
- this.contextMenuHandler.handleContextMenu(ev);
3800
- }
3801
- handleMouseDown(ev) {
3855
+ handleWheel(ev) {
3802
3856
  var _a, _b;
3803
3857
  if (this.store.state.isContextMenuVisible) {
3804
3858
  this.hideContextMenu();
3805
- return;
3806
3859
  }
3807
- if (this.store.state.isEnabled === false) {
3808
- return;
3809
- }
3810
- this.viewport.handleMouseDown(ev);
3811
- (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handleMouseDown(ev);
3812
- }
3813
- handleMouseMove(ev) {
3814
- var _a, _b;
3815
- if (this.store.state.isEnabled === false) {
3816
- return;
3817
- }
3818
- this.viewport.handleMouseMove(ev);
3819
- (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handleMouseMove(ev);
3860
+ this.viewport.handleWheel(ev);
3861
+ (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handleWheel(ev);
3820
3862
  }
3821
- handleMouseUp(ev) {
3863
+ handlePointerDown(ev) {
3822
3864
  var _a, _b;
3823
- if (this.store.state.isEnabled === false) {
3865
+ if (KritzelEventHelper.isPointerEventOnContextMenu(ev) === false && this.store.state.isContextMenuVisible) {
3866
+ this.hideContextMenu();
3824
3867
  return;
3825
3868
  }
3826
- this.viewport.handleMouseUp(ev);
3827
- (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handleMouseUp(ev);
3828
- }
3829
- handleDoubleClick(ev) {
3830
- var _a, _b;
3831
3869
  if (this.store.state.isEnabled === false) {
3832
3870
  return;
3833
3871
  }
3834
- (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handleDoubleClick(ev);
3835
- }
3836
- handleDoubleTap(ev) {
3837
- var _a, _b;
3838
- if (this.store.state.isEnabled === false) {
3839
- return;
3872
+ if (ev.cancelable) {
3873
+ ev.preventDefault();
3840
3874
  }
3841
- const touchEvent = ev instanceof CustomEvent && ev.detail ? ev.detail : ev;
3842
- (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handleDoubleTap(touchEvent);
3875
+ KritzelEventHelper.onLongTouchPress(ev, (event) => {
3876
+ if (!(this.store.state.activeTool instanceof KritzelSelectionTool)) {
3877
+ return;
3878
+ }
3879
+ this.contextMenuHandler.handleContextMenu(event);
3880
+ });
3881
+ this.host.setPointerCapture(ev.pointerId);
3882
+ this.store.state.pointers.set(ev.pointerId, ev);
3883
+ this.viewport.handlePointerDown(ev);
3884
+ (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handlePointerDown(ev);
3843
3885
  }
3844
- handleTouchStart(ev) {
3886
+ handlePointerMove(ev) {
3845
3887
  var _a, _b;
3846
3888
  if (this.store.state.isEnabled === false) {
3847
3889
  return;
3848
3890
  }
3849
- if (KritzelEventHelper.detectDoubleTap()) {
3850
- const doubleTapEvent = new CustomEvent('doubletap', { detail: event, bubbles: true, composed: true });
3851
- this.host.dispatchEvent(doubleTapEvent);
3852
- }
3853
- if (ev.touches.length > 1) {
3854
- clearTimeout(this.store.state.longTouchTimeout);
3855
- }
3856
3891
  if (ev.cancelable) {
3857
3892
  ev.preventDefault();
3858
3893
  }
3859
- this.store.state.longTouchTimeout = setTimeout(() => this.contextMenuHandler.handleContextMenuTouch(ev), this.store.state.longTouchDelay);
3860
- this.viewport.handleTouchStart(ev);
3861
- (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handleTouchStart(ev);
3894
+ this.store.state.pointers.set(ev.pointerId, ev);
3895
+ this.viewport.handlePointerMove(ev);
3896
+ (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handlePointerMove(ev);
3862
3897
  }
3863
- handleTouchMove(ev) {
3898
+ handlePointerUp(ev) {
3864
3899
  var _a, _b;
3865
3900
  if (this.store.state.isEnabled === false) {
3866
3901
  return;
@@ -3868,10 +3903,12 @@ const KritzelEngine = class {
3868
3903
  if (ev.cancelable) {
3869
3904
  ev.preventDefault();
3870
3905
  }
3871
- this.viewport.handleTouchMove(ev);
3872
- (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handleTouchMove(ev);
3906
+ this.store.state.pointers.delete(ev.pointerId);
3907
+ this.host.releasePointerCapture(ev.pointerId);
3908
+ this.viewport.handlePointerUp(ev);
3909
+ (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handlePointerUp(ev);
3873
3910
  }
3874
- handleTouchEnd(ev) {
3911
+ handlePointerCancel(ev) {
3875
3912
  var _a, _b;
3876
3913
  if (this.store.state.isEnabled === false) {
3877
3914
  return;
@@ -3879,20 +3916,20 @@ const KritzelEngine = class {
3879
3916
  if (ev.cancelable) {
3880
3917
  ev.preventDefault();
3881
3918
  }
3882
- clearTimeout(this.store.state.longTouchTimeout);
3883
- this.viewport.handleTouchEnd(ev);
3884
- (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handleTouchEnd(ev);
3919
+ this.host.releasePointerCapture(ev.pointerId);
3920
+ this.store.state.pointers.delete(ev.pointerId);
3921
+ this.viewport.handlePointerUp(ev);
3922
+ (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handlePointerUp(ev);
3885
3923
  }
3886
- handleTouchCancel(_ev) {
3887
- clearTimeout(this.store.state.longTouchTimeout);
3888
- }
3889
- handleWheel(ev) {
3890
- var _a, _b;
3891
- if (this.store.state.isContextMenuVisible) {
3892
- this.hideContextMenu();
3924
+ handleContextMenu(ev) {
3925
+ ev.preventDefault();
3926
+ if (this.store.state.isEnabled === false) {
3927
+ return;
3893
3928
  }
3894
- this.viewport.handleWheel(ev);
3895
- (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeTool) === null || _b === void 0 ? void 0 : _b.handleWheel(ev);
3929
+ if (ev.pointerType === 'touch') {
3930
+ return;
3931
+ }
3932
+ this.contextMenuHandler.handleContextMenu(ev);
3896
3933
  }
3897
3934
  handleResize() {
3898
3935
  this.viewport.handleResize();
@@ -3969,6 +4006,7 @@ const KritzelEngine = class {
3969
4006
  this.store.history.redo();
3970
4007
  }
3971
4008
  async hideContextMenu() {
4009
+ this.store.state.pointers.clear();
3972
4010
  this.store.state.isContextMenuVisible = false;
3973
4011
  this.store.state.selectionBox = null;
3974
4012
  this.store.state.isSelecting = false;
@@ -4021,20 +4059,20 @@ const KritzelEngine = class {
4021
4059
  const baseHandleSizePx = computedStyle.getPropertyValue('--kritzel-selection-handle-size').trim() || '6px';
4022
4060
  const baseHandleSize = parseFloat(baseHandleSizePx);
4023
4061
  const baseHandleTouchSize = baseHandleSize * 2 < 14 ? 14 : baseHandleSize;
4024
- return (index.h(index.Host, { key: '0c20c50e3ad8ac088902881c35c406ad2f0787d5' }, index.h("div", { key: 'a89d76b5f6a10cbc54c40d034a08b3ceb99be063', class: "debug-panel", style: { display: this.store.state.debugInfo.showViewportInfo ? 'block' : 'none' } }, index.h("div", { key: '94345439d02de7d005bb92abb377b7ebeb91fcdb' }, "TranslateX: ", (_a = this.store.state) === null || _a === void 0 ? void 0 :
4025
- _a.translateX), index.h("div", { key: '1e2e3ffc6ad760f089f4d02d94dfeb09bb5725cb' }, "TranslateY: ", (_b = this.store.state) === null || _b === void 0 ? void 0 :
4026
- _b.translateY), index.h("div", { key: '36d6170934959e19b95326d84b32c9abe2385edc' }, "ViewportWidth: ", (_c = this.store.state) === null || _c === void 0 ? void 0 :
4027
- _c.viewportWidth), index.h("div", { key: '57e5d37af3fd1f6ad24ea89ca525a6f0bc8e014b' }, "ViewportHeight: ", (_d = this.store.state) === null || _d === void 0 ? void 0 :
4028
- _d.viewportHeight), index.h("div", { key: '8281e788e350db75bbf1fe12dd8c17b91b429135' }, "ObjectsInViewport. ", this.store.objects.length), index.h("div", { key: '9f42aad27d0a266cbc720d1e13292bea5be84770' }, "Scale: ", (_e = this.store.state) === null || _e === void 0 ? void 0 :
4029
- _e.scale), index.h("div", { key: '76848c1a0eb2379ee0d0314523a540dbeb3d0697' }, "ActiveTool: ", (_g = (_f = this.store.state) === null || _f === void 0 ? void 0 : _f.activeTool) === null || _g === void 0 ? void 0 :
4030
- _g.name), index.h("div", { key: '77f8ff0b660227f7b25c12b74d70946bc1f66e78' }, "HasViewportChanged: ", ((_h = this.store.state) === null || _h === void 0 ? void 0 : _h.hasViewportChanged) ? 'true' : 'false'), index.h("div", { key: '229e94fee90a847a853419ae61bc131221313fc6' }, "IsEnabled: ", ((_j = this.store.state) === null || _j === void 0 ? void 0 : _j.isEnabled) ? 'true' : 'false'), index.h("div", { key: 'f31784916ab54f9a5eda02cffebe55a1f9aaa51f' }, "IsScaling: ", ((_k = this.store.state) === null || _k === void 0 ? void 0 : _k.isScaling) ? 'true' : 'false'), index.h("div", { key: '4611a6dd48f1033d42fc3b7813634cbc16bf9b3b' }, "IsPanning: ", ((_l = this.store.state) === null || _l === void 0 ? void 0 : _l.isPanning) ? 'true' : 'false'), index.h("div", { key: '14388f4b5cca60d8a2d8d474f941b53a78ad327d' }, "IsFocused: ", this.store.state.isFocused ? 'true' : 'false'), index.h("div", { key: '2f3dcd488855413e392f56718af640e369d99fae' }, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), index.h("div", { key: '2cd0e44a1d13eaf5d3a942f75a727a074bf37622' }, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), index.h("div", { key: '99d51cf25e02c9d06865bf1f847c704ad8a32110' }, "IsResizeHandleSelected: ", this.store.state.isResizeHandleSelected ? 'true' : 'false'), index.h("div", { key: '87ab9908a318b238ad1fb00e91dba9c485038443' }, "IsRotationHandleSelected: ", this.store.state.isRotationHandleSelected ? 'true' : 'false'), index.h("div", { key: '20f291bf45ba06b4107002e288b93f8f61ef9520' }, "IsDrawing: ", this.store.state.isDrawing ? 'true' : 'false'), index.h("div", { key: '52244f4f0d368e7bc183eed4c65abe536d134f44' }, "IsWriting: ", this.store.state.isWriting ? 'true' : 'false'), index.h("div", { key: '641edd47e7bccc7514ed6aeac3ecbead95568dde' }, "CursorX: ", (_m = this.store.state) === null || _m === void 0 ? void 0 :
4031
- _m.cursorX), index.h("div", { key: 'bf0826a9cbc800ca0f13d4de4da7dbb21241498f' }, "CursorY: ", (_o = this.store.state) === null || _o === void 0 ? void 0 :
4032
- _o.cursorY)), index.h("div", { key: '5659cb254f57b79ca8e33ab11a8087d5ca5088dc', class: "origin", style: {
4062
+ return (index.h(index.Host, { key: 'a797514d787c08c2cd6a2e526ace31fecddf8956' }, index.h("div", { key: 'd0d23c34809f26ab3c21f756923d1ef7a00ebb41', class: "debug-panel", style: { display: this.store.state.debugInfo.showViewportInfo ? 'block' : 'none' } }, index.h("div", { key: '302b23a9028483c7dc31f4ca983c8036f6de5b25' }, "TranslateX: ", (_a = this.store.state) === null || _a === void 0 ? void 0 :
4063
+ _a.translateX), index.h("div", { key: '2224e2bb5bd1feea8a65ac4f082342a40e8e18b5' }, "TranslateY: ", (_b = this.store.state) === null || _b === void 0 ? void 0 :
4064
+ _b.translateY), index.h("div", { key: '02108ee26500eb97a08d8460b6b71cdc553d6c90' }, "ViewportWidth: ", (_c = this.store.state) === null || _c === void 0 ? void 0 :
4065
+ _c.viewportWidth), index.h("div", { key: '8e87161155f4e2960985292be3101e9f57893381' }, "ViewportHeight: ", (_d = this.store.state) === null || _d === void 0 ? void 0 :
4066
+ _d.viewportHeight), index.h("div", { key: 'aa2469bda052787a93ea615451676dba4b4fb53e' }, "ObjectsInViewport. ", this.store.objects.length), index.h("div", { key: '593aaf98bfaec8aae03bd7a3f37e46e14f454333' }, "Scale: ", (_e = this.store.state) === null || _e === void 0 ? void 0 :
4067
+ _e.scale), index.h("div", { key: '6c9799e82d30236c6f1277830dec32358bfccd93' }, "ActiveTool: ", (_g = (_f = this.store.state) === null || _f === void 0 ? void 0 : _f.activeTool) === null || _g === void 0 ? void 0 :
4068
+ _g.name), index.h("div", { key: '3dbbec42f8a699a97ef65b5da35f2611866797e5' }, "HasViewportChanged: ", ((_h = this.store.state) === null || _h === void 0 ? void 0 : _h.hasViewportChanged) ? 'true' : 'false'), index.h("div", { key: '03a71e1efab2801e77e0d8dffc7a4814469613c7' }, "IsEnabled: ", ((_j = this.store.state) === null || _j === void 0 ? void 0 : _j.isEnabled) ? 'true' : 'false'), index.h("div", { key: '7663ed6cad2ed3b9b74bad5cb238a4cf0310e9e1' }, "IsScaling: ", ((_k = this.store.state) === null || _k === void 0 ? void 0 : _k.isScaling) ? 'true' : 'false'), index.h("div", { key: '957a1b0906ad9cecc46f470db1ad402d19f94d22' }, "IsPanning: ", ((_l = this.store.state) === null || _l === void 0 ? void 0 : _l.isPanning) ? 'true' : 'false'), index.h("div", { key: 'b73277742d0966445b6f49a0fb1433f80cab1d60' }, "IsFocused: ", this.store.state.isFocused ? 'true' : 'false'), index.h("div", { key: '6a4e0ca6d868b1f8ccfe2957f352fc454b3527ea' }, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), index.h("div", { key: 'da9dce9f4c38cd740f27ecc8de3c32edac2a7fe2' }, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), index.h("div", { key: 'f6b0d7cc9e828cac5a65879b9973944a444be6b1' }, "IsResizeHandleSelected: ", this.store.state.isResizeHandleSelected ? 'true' : 'false'), index.h("div", { key: '3ef7c46329e47a97703e49f47c8f5325f0d4b9b2' }, "IsRotationHandleSelected: ", this.store.state.isRotationHandleSelected ? 'true' : 'false'), index.h("div", { key: 'cab4fb21ede0b4f4925e9d7d2175ad8661f07907' }, "IsDrawing: ", this.store.state.isDrawing ? 'true' : 'false'), index.h("div", { key: '2f4eeaa711a56e2246495fe1eee46d5629c93364' }, "IsWriting: ", this.store.state.isWriting ? 'true' : 'false'), index.h("div", { key: 'ee2e5edcd140da8b957b468989c71e7c247063bb' }, "CursorX: ", (_m = this.store.state) === null || _m === void 0 ? void 0 :
4069
+ _m.cursorX), index.h("div", { key: '1fea9888ca2f1a9fed25ad0cac065d8278c78227' }, "CursorY: ", (_o = this.store.state) === null || _o === void 0 ? void 0 :
4070
+ _o.cursorY)), index.h("div", { key: '226c675711317ff06f1db5165fa19794310f2e1e', class: "origin", style: {
4033
4071
  transform: `matrix(${(_p = this.store.state) === null || _p === void 0 ? void 0 : _p.scale}, 0, 0, ${(_q = this.store.state) === null || _q === void 0 ? void 0 : _q.scale}, ${(_r = this.store.state) === null || _r === void 0 ? void 0 : _r.translateX}, ${(_s = this.store.state) === null || _s === void 0 ? void 0 : _s.translateY})`,
4034
4072
  } }, (_t = this.store.objects) === null || _t === void 0 ? void 0 :
4035
4073
  _t.map(object => {
4036
4074
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
4037
- return (index.h("div", { style: { transform: object === null || object === void 0 ? void 0 : object.transformationMatrix, transformOrigin: 'top left' } }, index.h("svg", { xmlns: "http://www.w3.org/2000/svg", key: object.id, id: object.id, class: "object", style: {
4075
+ return (index.h("div", { style: { transform: object === null || object === void 0 ? void 0 : object.transformationMatrix, transformOrigin: 'top left', zIndex: object.zIndex.toString(), position: 'absolute' } }, index.h("svg", { xmlns: "http://www.w3.org/2000/svg", key: object.id, id: object.id, class: "object", style: {
4038
4076
  height: object === null || object === void 0 ? void 0 : object.totalHeight.toString(),
4039
4077
  width: object === null || object === void 0 ? void 0 : object.totalWidth.toString(),
4040
4078
  left: '0',
@@ -4044,7 +4082,6 @@ const KritzelEngine = class {
4044
4082
  transformOrigin: 'center',
4045
4083
  opacity: object.markedForRemoval ? '0.5' : object.opacity.toString(),
4046
4084
  pointerEvents: object.markedForRemoval ? 'none' : 'auto',
4047
- zIndex: object.zIndex.toString(),
4048
4085
  } }, index.h("foreignObject", { x: "0", y: "0", width: object.totalWidth.toString(), height: object.totalHeight.toString(), style: {
4049
4086
  minHeight: '0',
4050
4087
  minWidth: '0',
@@ -4077,6 +4114,7 @@ const KritzelEngine = class {
4077
4114
  display: 'block',
4078
4115
  padding: '1px',
4079
4116
  whiteSpace: 'nowrap',
4117
+ pointerEvents: object.isReadonly ? 'none' : 'auto',
4080
4118
  cursor: object.isReadonly ? 'default' : 'text',
4081
4119
  caretColor: object.isReadonly ? 'transparent' : 'auto',
4082
4120
  } })), object instanceof KritzelSelectionGroup && (index.h("div", { ref: el => object.mount(el), style: {
@@ -4126,7 +4164,7 @@ const KritzelEngine = class {
4126
4164
  fill: 'transparent',
4127
4165
  cursor: 'grab',
4128
4166
  }, visibility: object.selected && !this.isSelecting ? 'visible' : 'hidden' }), index.h("g", { style: { display: this.store.state.debugInfo.showObjectInfo ? 'block' : 'none', pointerEvents: 'none' } }, index.h("foreignObject", { x: object.totalWidth.toString(), y: "0", width: "400px", height: "160px", style: { minHeight: '0', minWidth: '0', display: object.debugInfoVisible ? 'block' : 'none' } }, index.h("div", { style: { width: '100%', height: '100%' } }, index.h("div", { style: { whiteSpace: 'nowrap' } }, "zIndex: ", object.zIndex), index.h("div", { style: { whiteSpace: 'nowrap' } }, "translateX: ", object.translateX), index.h("div", { style: { whiteSpace: 'nowrap' } }, "translateY: ", object.translateY), index.h("div", { style: { whiteSpace: 'nowrap' } }, "width: ", object.width), index.h("div", { style: { whiteSpace: 'nowrap' } }, "height: ", object.height), index.h("div", { style: { whiteSpace: 'nowrap' } }, "scale: ", object.scale), index.h("div", { style: { whiteSpace: 'nowrap' } }, "rotation: ", object.rotation)))))));
4129
- }), index.h("svg", { key: '05a35ebb17312d00a4065dc6dc76f3a93a72eff4', class: "object", xmlns: "http://www.w3.org/2000/svg", style: {
4167
+ }), index.h("svg", { key: '34f891f9408d3b0174c67b869f49cce7329fd84a', class: "object", xmlns: "http://www.w3.org/2000/svg", style: {
4130
4168
  height: (_u = this.store.state.currentPath) === null || _u === void 0 ? void 0 : _u.height.toString(),
4131
4169
  width: (_v = this.store.state.currentPath) === null || _v === void 0 ? void 0 : _v.width.toString(),
4132
4170
  left: '0',
@@ -4136,12 +4174,12 @@ const KritzelEngine = class {
4136
4174
  transform: (_x = this.store.state.currentPath) === null || _x === void 0 ? void 0 : _x.transformationMatrix,
4137
4175
  transformOrigin: 'top left',
4138
4176
  overflow: 'visible',
4139
- }, viewBox: (_y = this.store.state.currentPath) === null || _y === void 0 ? void 0 : _y.viewBox }, index.h("path", { key: 'cb232e2697ce6ede2e4d9ed2e1b433ccde3961b5', d: (_z = this.store.state.currentPath) === null || _z === void 0 ? void 0 : _z.d, fill: (_0 = this.store.state.currentPath) === null || _0 === void 0 ? void 0 : _0.fill, stroke: (_1 = this.store.state.currentPath) === null || _1 === void 0 ? void 0 : _1.stroke }))), this.store.state.isContextMenuVisible && (index.h("kritzel-context-menu", { key: 'e41b88a78bbd25f692fbdba88fda80993055a078', ref: el => (this.contextMenuElement = el), items: this.store.state.contextMenuItems, style: {
4177
+ }, viewBox: (_y = this.store.state.currentPath) === null || _y === void 0 ? void 0 : _y.viewBox }, index.h("path", { key: '97360b7270a285a87a45459e497968a444cc83cb', d: (_z = this.store.state.currentPath) === null || _z === void 0 ? void 0 : _z.d, fill: (_0 = this.store.state.currentPath) === null || _0 === void 0 ? void 0 : _0.fill, stroke: (_1 = this.store.state.currentPath) === null || _1 === void 0 ? void 0 : _1.stroke }))), this.store.state.isContextMenuVisible && (index.h("kritzel-context-menu", { key: '111d7b1daccd69aaf914dfcd51f525f2ad81802e', class: "context-menu", ref: el => (this.contextMenuElement = el), items: this.store.state.contextMenuItems, style: {
4140
4178
  position: 'fixed',
4141
4179
  left: `${this.store.state.contextMenuX}px`,
4142
4180
  top: `${this.store.state.contextMenuY}px`,
4143
4181
  zIndex: '10000',
4144
- }, onActionSelected: event => this.handleContextMenuAction(event) })), ((_2 = this.store.state) === null || _2 === void 0 ? void 0 : _2.activeTool) instanceof KritzelEraserTool && !this.store.state.isScaling && index.h("kritzel-cursor-trail", { key: '1d96c0d7fa94ddcf5820fd76fbaf69c54b1face2' })));
4182
+ }, onActionSelected: event => this.handleContextMenuAction(event) })), ((_2 = this.store.state) === null || _2 === void 0 ? void 0 : _2.activeTool) instanceof KritzelEraserTool && !this.store.state.isScaling && index.h("kritzel-cursor-trail", { key: '9814ec7d95a84edc8af1bff319eff5f59b8cfc86' })));
4145
4183
  }
4146
4184
  get host() { return index.getElement(this); }
4147
4185
  };