kritzel-react 0.1.30 → 0.1.32

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 (209) hide show
  1. package/dist/kritzel-react/lib/components/stencil-generated/components.js +122 -0
  2. package/dist/kritzel-react/lib/index.js +2 -0
  3. package/dist/kritzel-stencil/src/classes/core/core.class.js +797 -0
  4. package/dist/kritzel-stencil/src/classes/core/reviver.class.js +97 -0
  5. package/dist/kritzel-stencil/src/classes/core/store.class.js +153 -0
  6. package/dist/kritzel-stencil/src/classes/core/viewport.class.js +311 -0
  7. package/dist/kritzel-stencil/src/classes/core/workspace.class.js +34 -0
  8. package/dist/kritzel-stencil/src/classes/handlers/base.handler.js +6 -0
  9. package/dist/kritzel-stencil/src/classes/handlers/context-menu.handler.js +63 -0
  10. package/dist/kritzel-stencil/src/classes/handlers/hover.handler.js +18 -0
  11. package/dist/kritzel-stencil/src/classes/handlers/key.handler.js +76 -0
  12. package/dist/kritzel-stencil/src/classes/handlers/line-handle.handler.js +382 -0
  13. package/dist/kritzel-stencil/src/classes/handlers/move.handler.js +213 -0
  14. package/dist/kritzel-stencil/src/classes/handlers/resize.handler.js +205 -0
  15. package/dist/kritzel-stencil/src/classes/handlers/rotation.handler.js +117 -0
  16. package/dist/kritzel-stencil/src/classes/handlers/selection.handler.js +313 -0
  17. package/dist/kritzel-stencil/src/classes/managers/anchor.manager.js +1056 -0
  18. package/dist/kritzel-stencil/src/classes/managers/cursor.manager.js +117 -0
  19. package/dist/kritzel-stencil/src/classes/managers/theme.manager.js +103 -0
  20. package/dist/kritzel-stencil/src/classes/objects/base-object.class.js +249 -0
  21. package/dist/kritzel-stencil/src/classes/objects/custom-element.class.js +60 -0
  22. package/dist/kritzel-stencil/src/classes/objects/group.class.js +407 -0
  23. package/dist/kritzel-stencil/src/classes/objects/image.class.js +55 -0
  24. package/dist/kritzel-stencil/src/classes/objects/line.class.js +608 -0
  25. package/dist/kritzel-stencil/src/classes/objects/path.class.js +401 -0
  26. package/dist/kritzel-stencil/src/classes/objects/selection-box.class.js +21 -0
  27. package/dist/kritzel-stencil/src/classes/objects/selection-group.class.js +409 -0
  28. package/dist/kritzel-stencil/src/classes/objects/shape.class.js +412 -0
  29. package/dist/kritzel-stencil/src/classes/objects/text.class.js +292 -0
  30. package/dist/kritzel-stencil/src/classes/providers/broadcast-sync-provider.class.js +101 -0
  31. package/dist/kritzel-stencil/src/classes/providers/hocuspocus-sync-provider.class.js +241 -0
  32. package/dist/kritzel-stencil/src/classes/providers/indexeddb-sync-provider.class.js +43 -0
  33. package/dist/kritzel-stencil/src/classes/providers/websocket-sync-provider.class.js +98 -0
  34. package/dist/kritzel-stencil/src/classes/registries/icon-registry.class.js +66 -0
  35. package/dist/kritzel-stencil/src/classes/registries/tool.registry.js +21 -0
  36. package/dist/kritzel-stencil/src/classes/structures/app-state-map.structure.js +212 -0
  37. package/dist/kritzel-stencil/src/classes/structures/object-map.structure.js +414 -0
  38. package/dist/kritzel-stencil/src/classes/structures/quadtree.structure.js +151 -0
  39. package/dist/kritzel-stencil/src/classes/tools/base-tool.class.js +36 -0
  40. package/dist/kritzel-stencil/src/classes/tools/brush-tool.class.js +161 -0
  41. package/dist/kritzel-stencil/src/classes/tools/eraser-tool.class.js +85 -0
  42. package/dist/kritzel-stencil/src/classes/tools/image-tool.class.js +83 -0
  43. package/dist/kritzel-stencil/src/classes/tools/line-tool.class.js +187 -0
  44. package/dist/kritzel-stencil/src/classes/tools/selection-tool.class.js +429 -0
  45. package/dist/kritzel-stencil/src/classes/tools/shape-tool.class.js +196 -0
  46. package/dist/kritzel-stencil/src/classes/tools/text-tool.class.js +100 -0
  47. package/dist/kritzel-stencil/src/components/core/kritzel-engine/kritzel-engine.js +1343 -0
  48. package/dist/kritzel-stencil/src/components/shared/kritzel-brush-style/kritzel-brush-style.js +46 -0
  49. package/dist/kritzel-stencil/src/components/shared/kritzel-dropdown/kritzel-dropdown.js +312 -0
  50. package/dist/kritzel-stencil/src/components/shared/kritzel-font-family/kritzel-font-family.js +60 -0
  51. package/dist/kritzel-stencil/src/components/shared/kritzel-line-endings/kritzel-line-endings.js +105 -0
  52. package/dist/kritzel-stencil/src/components/shared/kritzel-shape-fill/kritzel-shape-fill.js +53 -0
  53. package/dist/kritzel-stencil/src/components/ui/kritzel-context-menu/kritzel-context-menu.js +137 -0
  54. package/dist/kritzel-stencil/src/configs/default-brush-tool.config.js +9 -0
  55. package/dist/kritzel-stencil/src/configs/default-engine-config.js +63 -0
  56. package/dist/kritzel-stencil/src/configs/default-line-tool.config.js +9 -0
  57. package/dist/kritzel-stencil/src/configs/default-sync.config.js +9 -0
  58. package/dist/kritzel-stencil/src/configs/default-text-tool.config.js +7 -0
  59. package/dist/kritzel-stencil/src/constants/color-palette.constants.js +37 -0
  60. package/dist/kritzel-stencil/src/constants/engine.constants.js +2 -0
  61. package/dist/kritzel-stencil/src/enums/event-button.enum.js +6 -0
  62. package/dist/kritzel-stencil/src/enums/handle-type.enum.js +7 -0
  63. package/dist/kritzel-stencil/src/enums/shape-type.enum.js +6 -0
  64. package/dist/kritzel-stencil/src/helpers/class.helper.js +5 -0
  65. package/dist/kritzel-stencil/src/helpers/color.helper.js +106 -0
  66. package/dist/kritzel-stencil/src/helpers/cursor.helper.js +57 -0
  67. package/dist/kritzel-stencil/src/helpers/devices.helper.js +28 -0
  68. package/dist/kritzel-stencil/src/helpers/event.helper.js +58 -0
  69. package/dist/kritzel-stencil/src/helpers/geometry.helper.js +149 -0
  70. package/dist/kritzel-stencil/src/helpers/keyboard.helper.js +51 -0
  71. package/dist/kritzel-stencil/src/helpers/math.helper.js +5 -0
  72. package/dist/kritzel-stencil/src/helpers/object.helper.js +11 -0
  73. package/dist/kritzel-stencil/src/helpers/theme.helper.js +69 -0
  74. package/dist/kritzel-stencil/src/index.js +41 -0
  75. package/dist/kritzel-stencil/src/interfaces/anchor.interface.js +1 -0
  76. package/dist/kritzel-stencil/src/interfaces/arrow-head.interface.js +1 -0
  77. package/dist/kritzel-stencil/src/interfaces/bounding-box.interface.js +1 -0
  78. package/dist/kritzel-stencil/src/interfaces/clonable.interface.js +1 -0
  79. package/dist/kritzel-stencil/src/interfaces/context-menu-item.interface.js +1 -0
  80. package/dist/kritzel-stencil/src/interfaces/debug-info.interface.js +1 -0
  81. package/dist/kritzel-stencil/src/interfaces/dialog.interface.js +1 -0
  82. package/dist/kritzel-stencil/src/interfaces/displayable-shortcut.interface.js +1 -0
  83. package/dist/kritzel-stencil/src/interfaces/engine-state.interface.js +1 -0
  84. package/dist/kritzel-stencil/src/interfaces/line-options.interface.js +1 -0
  85. package/dist/kritzel-stencil/src/interfaces/master-detail.interface.js +1 -0
  86. package/dist/kritzel-stencil/src/interfaces/menu-item.interface.js +1 -0
  87. package/dist/kritzel-stencil/src/interfaces/object.interface.js +1 -0
  88. package/dist/kritzel-stencil/src/interfaces/path-options.interface.js +1 -0
  89. package/dist/kritzel-stencil/src/interfaces/point.interface.js +1 -0
  90. package/dist/kritzel-stencil/src/interfaces/polygon.interface.js +1 -0
  91. package/dist/kritzel-stencil/src/interfaces/serializable.interface.js +1 -0
  92. package/dist/kritzel-stencil/src/interfaces/settings.interface.js +1 -0
  93. package/dist/kritzel-stencil/src/interfaces/shortcut.interface.js +1 -0
  94. package/dist/kritzel-stencil/src/interfaces/sync-config.interface.js +1 -0
  95. package/dist/kritzel-stencil/src/interfaces/sync-provider.interface.js +1 -0
  96. package/dist/kritzel-stencil/src/interfaces/theme.interface.js +1 -0
  97. package/dist/kritzel-stencil/src/interfaces/tool-config.interface.js +1 -0
  98. package/dist/kritzel-stencil/src/interfaces/tool.interface.js +1 -0
  99. package/dist/kritzel-stencil/src/interfaces/toolbar-control.interface.js +1 -0
  100. package/dist/kritzel-stencil/src/interfaces/undo-state.interface.js +1 -0
  101. package/dist/kritzel-stencil/src/themes/dark-theme.js +198 -0
  102. package/dist/kritzel-stencil/src/themes/light-theme.js +199 -0
  103. package/dist/kritzel-stencil/src/types/shortcut.type.js +1 -0
  104. package/dist/kritzel-stencil/src/types/state.types.js +1 -0
  105. package/dist/types/kritzel-react/lib/components/stencil-generated/components.d.ts +74 -0
  106. package/dist/types/kritzel-react/lib/index.d.ts +2 -0
  107. package/dist/types/kritzel-stencil/src/classes/core/core.class.d.ts +101 -0
  108. package/dist/types/kritzel-stencil/src/classes/core/reviver.class.d.ts +6 -0
  109. package/dist/types/kritzel-stencil/src/classes/core/store.class.d.ts +53 -0
  110. package/dist/types/kritzel-stencil/src/classes/core/viewport.class.d.ts +48 -0
  111. package/dist/types/kritzel-stencil/src/classes/core/workspace.class.d.ts +24 -0
  112. package/dist/types/kritzel-stencil/src/classes/handlers/base.handler.d.ts +5 -0
  113. package/dist/types/kritzel-stencil/src/classes/handlers/context-menu.handler.d.ts +8 -0
  114. package/dist/types/kritzel-stencil/src/classes/handlers/hover.handler.d.ts +6 -0
  115. package/dist/types/kritzel-stencil/src/classes/handlers/key.handler.d.ts +11 -0
  116. package/dist/types/kritzel-stencil/src/classes/handlers/line-handle.handler.d.ts +34 -0
  117. package/dist/types/kritzel-stencil/src/classes/handlers/move.handler.d.ts +29 -0
  118. package/dist/types/kritzel-stencil/src/classes/handlers/resize.handler.d.ts +24 -0
  119. package/dist/types/kritzel-stencil/src/classes/handlers/rotation.handler.d.ts +12 -0
  120. package/dist/types/kritzel-stencil/src/classes/handlers/selection.handler.d.ts +27 -0
  121. package/dist/types/kritzel-stencil/src/classes/managers/anchor.manager.d.ts +180 -0
  122. package/dist/types/kritzel-stencil/src/classes/managers/cursor.manager.d.ts +43 -0
  123. package/dist/types/kritzel-stencil/src/classes/managers/theme.manager.d.ts +56 -0
  124. package/dist/types/kritzel-stencil/src/classes/objects/base-object.class.d.ts +76 -0
  125. package/dist/types/kritzel-stencil/src/classes/objects/custom-element.class.d.ts +26 -0
  126. package/dist/types/kritzel-stencil/src/classes/objects/group.class.d.ts +97 -0
  127. package/dist/types/kritzel-stencil/src/classes/objects/image.class.d.ts +17 -0
  128. package/dist/types/kritzel-stencil/src/classes/objects/line.class.d.ts +101 -0
  129. package/dist/types/kritzel-stencil/src/classes/objects/path.class.d.ts +62 -0
  130. package/dist/types/kritzel-stencil/src/classes/objects/selection-box.class.d.ts +6 -0
  131. package/dist/types/kritzel-stencil/src/classes/objects/selection-group.class.d.ts +67 -0
  132. package/dist/types/kritzel-stencil/src/classes/objects/shape.class.d.ts +124 -0
  133. package/dist/types/kritzel-stencil/src/classes/objects/text.class.d.ts +56 -0
  134. package/dist/types/kritzel-stencil/src/classes/providers/broadcast-sync-provider.class.d.ts +18 -0
  135. package/dist/types/kritzel-stencil/src/classes/providers/hocuspocus-sync-provider.class.d.ts +120 -0
  136. package/dist/types/kritzel-stencil/src/classes/providers/indexeddb-sync-provider.class.d.ts +22 -0
  137. package/dist/types/kritzel-stencil/src/classes/providers/websocket-sync-provider.class.d.ts +52 -0
  138. package/dist/types/kritzel-stencil/src/classes/registries/icon-registry.class.d.ts +9 -0
  139. package/dist/types/kritzel-stencil/src/classes/registries/tool.registry.d.ts +8 -0
  140. package/dist/types/kritzel-stencil/src/classes/structures/app-state-map.structure.d.ts +31 -0
  141. package/dist/types/kritzel-stencil/src/classes/structures/object-map.structure.d.ts +63 -0
  142. package/dist/types/kritzel-stencil/src/classes/structures/quadtree.structure.d.ts +36 -0
  143. package/dist/types/kritzel-stencil/src/classes/tools/base-tool.class.d.ts +20 -0
  144. package/dist/types/kritzel-stencil/src/classes/tools/brush-tool.class.d.ts +14 -0
  145. package/dist/types/kritzel-stencil/src/classes/tools/eraser-tool.class.d.ts +9 -0
  146. package/dist/types/kritzel-stencil/src/classes/tools/image-tool.class.d.ts +15 -0
  147. package/dist/types/kritzel-stencil/src/classes/tools/line-tool.class.d.ts +19 -0
  148. package/dist/types/kritzel-stencil/src/classes/tools/selection-tool.class.d.ts +54 -0
  149. package/dist/types/kritzel-stencil/src/classes/tools/shape-tool.class.d.ts +39 -0
  150. package/dist/types/kritzel-stencil/src/classes/tools/text-tool.class.d.ts +13 -0
  151. package/dist/types/kritzel-stencil/src/components/core/kritzel-engine/kritzel-engine.d.ts +111 -0
  152. package/dist/types/kritzel-stencil/src/components/shared/kritzel-brush-style/kritzel-brush-style.d.ts +11 -0
  153. package/dist/types/kritzel-stencil/src/components/shared/kritzel-dropdown/kritzel-dropdown.d.ts +46 -0
  154. package/dist/types/kritzel-stencil/src/components/shared/kritzel-font-family/kritzel-font-family.d.ts +13 -0
  155. package/dist/types/kritzel-stencil/src/components/shared/kritzel-line-endings/kritzel-line-endings.d.ts +21 -0
  156. package/dist/types/kritzel-stencil/src/components/shared/kritzel-shape-fill/kritzel-shape-fill.d.ts +10 -0
  157. package/dist/types/kritzel-stencil/src/components/ui/kritzel-context-menu/kritzel-context-menu.d.ts +21 -0
  158. package/dist/types/kritzel-stencil/src/configs/default-brush-tool.config.d.ts +2 -0
  159. package/dist/types/kritzel-stencil/src/configs/default-engine-config.d.ts +2 -0
  160. package/dist/types/kritzel-stencil/src/configs/default-line-tool.config.d.ts +2 -0
  161. package/dist/types/kritzel-stencil/src/configs/default-sync.config.d.ts +5 -0
  162. package/dist/types/kritzel-stencil/src/configs/default-text-tool.config.d.ts +2 -0
  163. package/dist/types/kritzel-stencil/src/constants/color-palette.constants.d.ts +29 -0
  164. package/dist/types/kritzel-stencil/src/constants/engine.constants.d.ts +2 -0
  165. package/dist/types/kritzel-stencil/src/enums/event-button.enum.d.ts +5 -0
  166. package/dist/types/kritzel-stencil/src/enums/handle-type.enum.d.ts +6 -0
  167. package/dist/types/kritzel-stencil/src/enums/shape-type.enum.d.ts +5 -0
  168. package/dist/types/kritzel-stencil/src/helpers/class.helper.d.ts +3 -0
  169. package/dist/types/kritzel-stencil/src/helpers/color.helper.d.ts +33 -0
  170. package/dist/types/kritzel-stencil/src/helpers/cursor.helper.d.ts +22 -0
  171. package/dist/types/kritzel-stencil/src/helpers/devices.helper.d.ts +8 -0
  172. package/dist/types/kritzel-stencil/src/helpers/event.helper.d.ts +6 -0
  173. package/dist/types/kritzel-stencil/src/helpers/geometry.helper.d.ts +38 -0
  174. package/dist/types/kritzel-stencil/src/helpers/keyboard.helper.d.ts +6 -0
  175. package/dist/types/kritzel-stencil/src/helpers/math.helper.d.ts +3 -0
  176. package/dist/types/kritzel-stencil/src/helpers/object.helper.d.ts +4 -0
  177. package/dist/types/kritzel-stencil/src/helpers/theme.helper.d.ts +41 -0
  178. package/dist/types/kritzel-stencil/src/index.d.ts +42 -0
  179. package/dist/types/kritzel-stencil/src/interfaces/anchor.interface.d.ts +137 -0
  180. package/dist/types/kritzel-stencil/src/interfaces/arrow-head.interface.d.ts +27 -0
  181. package/dist/types/kritzel-stencil/src/interfaces/bounding-box.interface.d.ts +8 -0
  182. package/dist/types/kritzel-stencil/src/interfaces/clonable.interface.d.ts +3 -0
  183. package/dist/types/kritzel-stencil/src/interfaces/context-menu-item.interface.d.ts +17 -0
  184. package/dist/types/kritzel-stencil/src/interfaces/debug-info.interface.d.ts +4 -0
  185. package/dist/types/kritzel-stencil/src/interfaces/dialog.interface.d.ts +4 -0
  186. package/dist/types/kritzel-stencil/src/interfaces/displayable-shortcut.interface.d.ts +5 -0
  187. package/dist/types/kritzel-stencil/src/interfaces/engine-state.interface.d.ts +73 -0
  188. package/dist/types/kritzel-stencil/src/interfaces/line-options.interface.d.ts +23 -0
  189. package/dist/types/kritzel-stencil/src/interfaces/master-detail.interface.d.ts +14 -0
  190. package/dist/types/kritzel-stencil/src/interfaces/menu-item.interface.d.ts +24 -0
  191. package/dist/types/kritzel-stencil/src/interfaces/object.interface.d.ts +53 -0
  192. package/dist/types/kritzel-stencil/src/interfaces/path-options.interface.d.ts +11 -0
  193. package/dist/types/kritzel-stencil/src/interfaces/point.interface.d.ts +4 -0
  194. package/dist/types/kritzel-stencil/src/interfaces/polygon.interface.d.ts +7 -0
  195. package/dist/types/kritzel-stencil/src/interfaces/serializable.interface.d.ts +5 -0
  196. package/dist/types/kritzel-stencil/src/interfaces/settings.interface.d.ts +11 -0
  197. package/dist/types/kritzel-stencil/src/interfaces/shortcut.interface.d.ts +10 -0
  198. package/dist/types/kritzel-stencil/src/interfaces/sync-config.interface.d.ts +22 -0
  199. package/dist/types/kritzel-stencil/src/interfaces/sync-provider.interface.d.ts +29 -0
  200. package/dist/types/kritzel-stencil/src/interfaces/theme.interface.d.ts +330 -0
  201. package/dist/types/kritzel-stencil/src/interfaces/tool-config.interface.d.ts +26 -0
  202. package/dist/types/kritzel-stencil/src/interfaces/tool.interface.d.ts +7 -0
  203. package/dist/types/kritzel-stencil/src/interfaces/toolbar-control.interface.d.ts +58 -0
  204. package/dist/types/kritzel-stencil/src/interfaces/undo-state.interface.d.ts +6 -0
  205. package/dist/types/kritzel-stencil/src/themes/dark-theme.d.ts +5 -0
  206. package/dist/types/kritzel-stencil/src/themes/light-theme.d.ts +5 -0
  207. package/dist/types/kritzel-stencil/src/types/shortcut.type.d.ts +1 -0
  208. package/dist/types/kritzel-stencil/src/types/state.types.d.ts +3 -0
  209. package/package.json +2 -2
@@ -0,0 +1,313 @@
1
+ import { KritzelEventHelper } from '../../helpers/event.helper';
2
+ import { KritzelSelectionBox } from '../objects/selection-box.class';
3
+ import { KritzelSelectionGroup } from '../objects/selection-group.class';
4
+ import { KritzelGroup } from '../objects/group.class';
5
+ import { KritzelBaseHandler } from './base.handler';
6
+ export class KritzelSelectionHandler extends KritzelBaseHandler {
7
+ get isSelectionClick() {
8
+ const selectionBox = this._core.store.selectionBox;
9
+ return selectionBox && selectionBox.width === 0 && selectionBox.height === 0;
10
+ }
11
+ get isSelectionDrag() {
12
+ const selectionBox = this._core.store.selectionBox;
13
+ return selectionBox && (selectionBox.width > 0 || selectionBox.height > 0);
14
+ }
15
+ constructor(core) {
16
+ super(core);
17
+ this.touchStartX = 0;
18
+ this.touchStartY = 0;
19
+ this.touchStartTimeout = null;
20
+ // Track previously selected objects for efficient deselection (WeakRef to avoid memory leaks)
21
+ this._previouslySelectedObjects = new Set();
22
+ }
23
+ handlePointerDown(event) {
24
+ if (event.pointerType === 'mouse') {
25
+ if (KritzelEventHelper.isLeftClick(event) && !this._core.store.selectionGroup) {
26
+ this.startMouseSelection(event);
27
+ }
28
+ }
29
+ if (event.pointerType === 'touch' || event.pointerType === 'pen') {
30
+ this.touchStartTimeout = setTimeout(() => {
31
+ if (this._core.store.state.pointers.size === 1 && !this._core.store.state.isScaling && !this._core.store.selectionGroup) {
32
+ this.startTouchSelection();
33
+ this.updateTouchSelection();
34
+ }
35
+ }, 80);
36
+ }
37
+ }
38
+ handlePointerMove(event) {
39
+ if (event.pointerType === 'mouse') {
40
+ if (this._core.store.state.isSelecting) {
41
+ this.updateMouseSelection(event);
42
+ }
43
+ }
44
+ if (event.pointerType === 'touch' || event.pointerType === 'pen') {
45
+ const activePointers = Array.from(this._core.store.state.pointers.values());
46
+ const x = Math.round(activePointers[0].clientX - this._core.store.offsetX);
47
+ const y = Math.round(activePointers[0].clientY - this._core.store.offsetY);
48
+ const moveDeltaX = Math.abs(x - this.touchStartX);
49
+ const moveDeltaY = Math.abs(y - this.touchStartY);
50
+ const moveThreshold = 5;
51
+ if ((moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) && this._core.store.state.isSelecting) {
52
+ this.updateTouchSelection();
53
+ clearTimeout(this._core.store.state.longTouchTimeout);
54
+ }
55
+ }
56
+ }
57
+ handlePointerUp(event) {
58
+ if (event.pointerType === 'mouse') {
59
+ if (KritzelEventHelper.isLeftClick(event)) {
60
+ const hasObjectsMoved = this._core.store.state.hasObjectsChanged;
61
+ const selectionGroup = this._core.store.selectionGroup;
62
+ if ((selectionGroup === null || selectionGroup === void 0 ? void 0 : selectionGroup.objects.length) === 1 && hasObjectsMoved === false) {
63
+ selectionGroup.objects[0].edit(event);
64
+ }
65
+ this._core.store.state.hasObjectsChanged = false;
66
+ if (this._core.store.state.isSelecting) {
67
+ if (this.isSelectionClick) {
68
+ this.handleSelectionClick(event);
69
+ }
70
+ if (this.isSelectionDrag) {
71
+ this.updateMouseSelection(event);
72
+ this.addSelectedObjectsToSelectionGroup();
73
+ this.removeSelectionBox();
74
+ }
75
+ this._core.engine.emitObjectsChange();
76
+ }
77
+ }
78
+ }
79
+ if (event.pointerType === 'touch' || event.pointerType === 'pen') {
80
+ clearTimeout(this.touchStartTimeout);
81
+ const hasObjectsMoved = this._core.store.state.hasObjectsChanged;
82
+ const selectionGroup = this._core.store.selectionGroup;
83
+ if ((selectionGroup === null || selectionGroup === void 0 ? void 0 : selectionGroup.objects.length) === 1 && hasObjectsMoved === false) {
84
+ selectionGroup.objects[0].edit(event);
85
+ }
86
+ this._core.store.state.hasObjectsChanged = false;
87
+ if (this._core.store.state.isSelecting) {
88
+ if (this.isSelectionClick) {
89
+ this.handleSelectionClick(event);
90
+ }
91
+ if (this.isSelectionDrag) {
92
+ this.updateTouchSelection();
93
+ this.addSelectedObjectsToSelectionGroup();
94
+ this.removeSelectionBox();
95
+ }
96
+ this._core.engine.emitObjectsChange();
97
+ this._core.store.state.skipContextMenu = false;
98
+ }
99
+ }
100
+ }
101
+ removeSelectionBox() {
102
+ this._core.store.state.isSelecting = false;
103
+ this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox);
104
+ this._core.store.setSelectionBox(null);
105
+ }
106
+ startMouseSelection(event) {
107
+ let clientX, clientY;
108
+ clientX = event.clientX - this._core.store.offsetX;
109
+ clientY = event.clientY - this._core.store.offsetY;
110
+ const selectionBox = KritzelSelectionBox.create(this._core);
111
+ this.startX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;
112
+ this.startY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;
113
+ selectionBox.translateX = this.startX;
114
+ selectionBox.translateY = this.startY;
115
+ this._core.store.state.isSelecting = true;
116
+ this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || o instanceof KritzelSelectionGroup);
117
+ this._core.store.setSelectionBox(null);
118
+ this._core.store.setSelectionGroup(null);
119
+ this._core.store.state.objects.insert(selectionBox);
120
+ this._core.store.setSelectionBox(selectionBox);
121
+ }
122
+ startTouchSelection() {
123
+ const activePointers = Array.from(this._core.store.state.pointers.values());
124
+ const firstTouch = activePointers[0];
125
+ if (!firstTouch) {
126
+ return;
127
+ }
128
+ let clientX, clientY;
129
+ clientX = Math.round(firstTouch.clientX - this._core.store.offsetX);
130
+ clientY = Math.round(firstTouch.clientY - this._core.store.offsetY);
131
+ this.touchStartX = clientX;
132
+ this.touchStartY = clientY;
133
+ const selectionBox = KritzelSelectionBox.create(this._core);
134
+ this.startX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;
135
+ this.startY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;
136
+ selectionBox.translateX = this.startX;
137
+ selectionBox.translateY = this.startY;
138
+ this._core.store.state.isSelecting = true;
139
+ this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || o instanceof KritzelSelectionGroup);
140
+ this._core.store.setSelectionBox(null);
141
+ this._core.store.setSelectionGroup(null);
142
+ this._core.store.state.objects.insert(selectionBox);
143
+ this._core.store.setSelectionBox(selectionBox);
144
+ }
145
+ updateMouseSelection(event) {
146
+ let clientX, clientY;
147
+ clientX = event.clientX - this._core.store.offsetX;
148
+ clientY = event.clientY - this._core.store.offsetY;
149
+ const selectionBox = this._core.store.selectionBox;
150
+ if (selectionBox) {
151
+ const currentX = (clientX - this._core.store.state.translateX) / selectionBox.scale;
152
+ const currentY = (clientY - this._core.store.state.translateY) / selectionBox.scale;
153
+ const width = Math.abs(currentX - this.startX) * selectionBox.scale;
154
+ const height = Math.abs(currentY - this.startY) * selectionBox.scale;
155
+ selectionBox.width = width;
156
+ selectionBox.height = height;
157
+ selectionBox.translateX = Math.min(currentX, this.startX);
158
+ selectionBox.translateY = Math.min(currentY, this.startY);
159
+ if (width > 0 || height > 0) {
160
+ this.updateSelectedObjects();
161
+ }
162
+ else {
163
+ this.clearSelectionPreview();
164
+ }
165
+ }
166
+ }
167
+ updateTouchSelection() {
168
+ const activePointers = Array.from(this._core.store.state.pointers.values());
169
+ const firstTouch = activePointers[0];
170
+ if (!firstTouch) {
171
+ return;
172
+ }
173
+ let clientX, clientY;
174
+ clientX = Math.round(firstTouch.clientX - this._core.store.offsetX);
175
+ clientY = Math.round(firstTouch.clientY - this._core.store.offsetY);
176
+ const selectionBox = this._core.store.selectionBox;
177
+ if (selectionBox) {
178
+ const currentX = (clientX - this._core.store.state.translateX) / selectionBox.scale;
179
+ const currentY = (clientY - this._core.store.state.translateY) / selectionBox.scale;
180
+ const width = Math.abs(currentX - this.startX) * selectionBox.scale;
181
+ const height = Math.abs(currentY - this.startY) * selectionBox.scale;
182
+ selectionBox.width = width;
183
+ selectionBox.height = height;
184
+ selectionBox.translateX = Math.min(currentX, this.startX);
185
+ selectionBox.translateY = Math.min(currentY, this.startY);
186
+ if (width > 0 || height > 0) {
187
+ this.updateSelectedObjects();
188
+ }
189
+ else {
190
+ this.clearSelectionPreview();
191
+ }
192
+ }
193
+ }
194
+ updateSelectedObjects() {
195
+ const selectionBox = this._core.store.selectionBox;
196
+ if (!selectionBox)
197
+ return;
198
+ // Compute rotatedPolygon once per update (not per object)
199
+ const selectionPolygon = selectionBox.rotatedPolygon;
200
+ // Calculate bounding box from the polygon we already have to avoid recomputing it
201
+ // calling selectionBox.rotatedBoundingBox would trigger another rotatedPolygon computation
202
+ const xValues = [selectionPolygon.topLeft.x, selectionPolygon.topRight.x, selectionPolygon.bottomRight.x, selectionPolygon.bottomLeft.x];
203
+ const yValues = [selectionPolygon.topLeft.y, selectionPolygon.topRight.y, selectionPolygon.bottomRight.y, selectionPolygon.bottomLeft.y];
204
+ const minX = Math.min(...xValues);
205
+ const maxX = Math.max(...xValues);
206
+ const minY = Math.min(...yValues);
207
+ const maxY = Math.max(...yValues);
208
+ // Use quadtree spatial query to get only nearby candidates - O(log n + k) instead of O(n)
209
+ const selectionBounds = {
210
+ x: minX,
211
+ y: minY,
212
+ z: selectionBox.scale,
213
+ width: maxX - minX,
214
+ height: maxY - minY
215
+ };
216
+ const candidates = this._core.store.state.objects.query(selectionBounds);
217
+ // Track newly selected objects for efficient comparison
218
+ const newlySelectedObjects = new Set();
219
+ // Only test candidates that overlap the bounding box
220
+ for (const object of candidates) {
221
+ if (object instanceof KritzelSelectionBox)
222
+ continue;
223
+ const isHit = object.hitTestPolygon(selectionPolygon);
224
+ object.isSelected = isHit;
225
+ if (isHit) {
226
+ newlySelectedObjects.add(object);
227
+ }
228
+ }
229
+ // Deselect only objects that were previously selected but aren't anymore
230
+ // This is O(k) where k is the number of previously selected objects, not O(n)
231
+ for (const prevObj of this._previouslySelectedObjects) {
232
+ if (!newlySelectedObjects.has(prevObj)) {
233
+ prevObj.isSelected = false;
234
+ }
235
+ }
236
+ this._previouslySelectedObjects = newlySelectedObjects;
237
+ }
238
+ handleSelectionClick(event) {
239
+ const selectedObject = this.getTopmostHitObject(event);
240
+ this.clearSelectionPreview();
241
+ this.addObjectToSelectionGroup(selectedObject);
242
+ this.removeSelectionBox();
243
+ }
244
+ getTopmostHitObject(event) {
245
+ const pointerX = this._core.store.state.pointerX;
246
+ const pointerY = this._core.store.state.pointerY;
247
+ const overlappingObjects = this._core.getObjectsFromPointerEvent(event, '.object');
248
+ for (const object of overlappingObjects) {
249
+ if (object instanceof KritzelSelectionBox)
250
+ continue;
251
+ if (object.hitTest(pointerX, pointerY)) {
252
+ return object;
253
+ }
254
+ }
255
+ return null;
256
+ }
257
+ clearSelectionPreview() {
258
+ // Only clear previously tracked selected objects - O(k) instead of O(n)
259
+ for (const obj of this._previouslySelectedObjects) {
260
+ obj.isSelected = false;
261
+ }
262
+ this._previouslySelectedObjects.clear();
263
+ }
264
+ addObjectToSelectionGroup(object) {
265
+ if (!object) {
266
+ return;
267
+ }
268
+ // Resolve child objects to their parent groups
269
+ const parentGroup = KritzelGroup.findParentGroup(this._core, object.id);
270
+ const objectToSelect = parentGroup || object;
271
+ objectToSelect.isSelected = false;
272
+ const selectionGroup = KritzelSelectionGroup.create(this._core);
273
+ selectionGroup.addOrRemove(objectToSelect);
274
+ selectionGroup.isSelected = true;
275
+ selectionGroup.rotation = objectToSelect.rotation;
276
+ this._core.addSelectionGroup(selectionGroup);
277
+ this._core.rerender();
278
+ }
279
+ addSelectedObjectsToSelectionGroup() {
280
+ const selectedObjects = this._core.store.selectedObjects;
281
+ if (selectedObjects.length === 0) {
282
+ return;
283
+ }
284
+ // Build parent group lookup map ONCE - O(g * c) instead of O(n * g * c)
285
+ const allGroups = this._core.store.state.objects.filter(obj => obj.__class__ === 'KritzelGroup');
286
+ const childToParentMap = new Map();
287
+ for (const group of allGroups) {
288
+ for (const childId of group.childIds) {
289
+ childToParentMap.set(childId, group);
290
+ }
291
+ }
292
+ // Resolve child objects to their parent groups in a single pass - O(n)
293
+ const resolvedObjects = new Map();
294
+ for (const obj of selectedObjects) {
295
+ const parentGroup = childToParentMap.get(obj.id);
296
+ const toSelect = parentGroup || obj;
297
+ resolvedObjects.set(toSelect.id, toSelect);
298
+ obj.isSelected = false;
299
+ }
300
+ // Create selection group and set all IDs at once (no per-item refresh)
301
+ const selectionGroup = KritzelSelectionGroup.create(this._core);
302
+ selectionGroup.objectIds = Array.from(resolvedObjects.keys());
303
+ // Only refresh dimensions and capture snapshots ONCE at the end - O(n) instead of O(n²)
304
+ selectionGroup.captureUnchangedSnapshots();
305
+ selectionGroup.refreshObjectDimensions();
306
+ selectionGroup.isSelected = true;
307
+ if (selectionGroup.length === 1) {
308
+ selectionGroup.rotation = selectionGroup.objects[0].rotation;
309
+ }
310
+ this._core.addSelectionGroup(selectionGroup);
311
+ this._core.rerender();
312
+ }
313
+ }