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,409 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { KritzelGeometryHelper } from '../../helpers/geometry.helper';
13
+ import { KritzelBaseObject } from './base-object.class';
14
+ import { KritzelGroup } from './group.class';
15
+ export class KritzelSelectionGroup extends KritzelBaseObject {
16
+ constructor() {
17
+ super(...arguments);
18
+ this.__class__ = 'KritzelSelectionGroup';
19
+ // Store only object IDs instead of full objects
20
+ this._objectIds = [];
21
+ // Cached objects array - invalidated when objectIds changes
22
+ this._cachedObjects = null;
23
+ this._cachedObjectIdsHash = '';
24
+ // Store snapshots of object state for transformations (rotation, resize)
25
+ this.unchangedObjectSnapshots = new Map();
26
+ this.snapshotRotation = 0;
27
+ }
28
+ get objectIds() {
29
+ return this._objectIds;
30
+ }
31
+ set objectIds(value) {
32
+ this._objectIds = value;
33
+ this._cachedObjects = null; // Invalidate cache
34
+ }
35
+ /**
36
+ * Invalidate the cached objects array. Call this when objects might have changed
37
+ * externally (e.g., after undo/redo operations).
38
+ */
39
+ invalidateObjectsCache() {
40
+ this._cachedObjects = null;
41
+ }
42
+ // Getter to retrieve actual objects from the store by their IDs
43
+ // Optimized: Caches result and only recomputes when objectIds changes
44
+ get objects() {
45
+ const currentHash = this._objectIds.join(',');
46
+ if (this._cachedObjects !== null && this._cachedObjectIdsHash === currentHash) {
47
+ return this._cachedObjects;
48
+ }
49
+ const idSet = new Set(this._objectIds);
50
+ const foundObjects = this._core.store.state.objects.filter(obj => idSet.has(obj.id));
51
+ // Preserve the original order from objectIds
52
+ const objectMap = new Map(foundObjects.map(obj => [obj.id, obj]));
53
+ this._cachedObjects = this._objectIds
54
+ .map(id => objectMap.get(id))
55
+ .filter((obj) => obj !== undefined);
56
+ this._cachedObjectIdsHash = currentHash;
57
+ return this._cachedObjects;
58
+ }
59
+ get length() {
60
+ return this.objectIds.length;
61
+ }
62
+ static create(core) {
63
+ const object = new KritzelSelectionGroup();
64
+ object._core = core;
65
+ object.id = object.generateId();
66
+ object.workspaceId = core.store.state.activeWorkspace.id;
67
+ object.scale = core.store.state.scale;
68
+ object.zIndex = 99999;
69
+ return object;
70
+ }
71
+ addOrRemove(object) {
72
+ const index = this._objectIds.findIndex(id => id === object.id);
73
+ if (index === -1) {
74
+ this._objectIds.push(object.id);
75
+ }
76
+ else {
77
+ this._objectIds.splice(index, 1);
78
+ }
79
+ this._cachedObjects = null; // Invalidate cache
80
+ const children = this.objects; // Get cached objects once
81
+ this.captureUnchangedSnapshots(children);
82
+ this.refreshObjectDimensions(children);
83
+ }
84
+ /**
85
+ * Prepares the selection group and its children for a transform interaction (rotate/resize).
86
+ * Ensures snapshot state is aligned with the current visual state.
87
+ */
88
+ beginTransform() {
89
+ const children = this.objects; // Get cached objects once
90
+ // Keep the selection group's bounding box current before snapshotting.
91
+ this.refreshObjectDimensions(children);
92
+ this.captureUnchangedSnapshots(children);
93
+ // Groups need their own child snapshots aligned with the current transform.
94
+ for (const obj of children) {
95
+ if (obj instanceof KritzelGroup) {
96
+ obj.finalize();
97
+ }
98
+ }
99
+ }
100
+ deselectAllChildren() {
101
+ const children = this.objects;
102
+ for (const obj of children) {
103
+ obj.isSelected = false;
104
+ }
105
+ }
106
+ updateWorkspaceId(workspaceId) {
107
+ this.workspaceId = workspaceId;
108
+ const children = this.objects;
109
+ for (const obj of children) {
110
+ obj.workspaceId = workspaceId;
111
+ }
112
+ }
113
+ updateZIndices(startZIndex) {
114
+ const children = this.objects;
115
+ for (let i = 0; i < children.length; i++) {
116
+ children[i].zIndex = startZIndex + i;
117
+ }
118
+ }
119
+ updatePosition(x, y) {
120
+ const children = this.objects;
121
+ for (const obj of children) {
122
+ const deltaX = obj.translateX - this.translateX;
123
+ const deltaY = obj.translateY - this.translateY;
124
+ obj.updatePosition(x + deltaX, y + deltaY);
125
+ }
126
+ // Update snapshots
127
+ this.unchangedObjectSnapshots.forEach(snapshot => {
128
+ const deltaX = snapshot.translateX - this.translateX;
129
+ const deltaY = snapshot.translateY - this.translateY;
130
+ snapshot.translateX = x + deltaX;
131
+ snapshot.translateY = y + deltaY;
132
+ });
133
+ this.translateX = x;
134
+ this.translateY = y;
135
+ this._core.store.state.objects.update(this);
136
+ }
137
+ /**
138
+ * Capture snapshots of current object states for undo/redo operations
139
+ * @param cachedObjects Optional pre-fetched objects array to avoid redundant getter calls
140
+ */
141
+ captureUnchangedSnapshots(cachedObjects) {
142
+ this.unchangedObjectSnapshots.clear();
143
+ this.snapshotRotation = this.rotation;
144
+ const children = cachedObjects !== null && cachedObjects !== void 0 ? cachedObjects : this.objects;
145
+ children.forEach(obj => {
146
+ this.unchangedObjectSnapshots.set(obj.id, {
147
+ id: obj.id,
148
+ translateX: obj.translateX,
149
+ translateY: obj.translateY,
150
+ rotation: obj.rotation,
151
+ width: obj.width,
152
+ height: obj.height,
153
+ totalWidth: obj.totalWidth,
154
+ totalHeight: obj.totalHeight,
155
+ scale: obj.scale,
156
+ });
157
+ });
158
+ }
159
+ serialize() {
160
+ const _a = this, { _core, _elementRef, element, totalWidth, totalHeight, unchangedObjectSnapshots, _cachedObjects, _cachedObjectIdsHash } = _a, remainingProps = __rest(_a, ["_core", "_elementRef", "element", "totalWidth", "totalHeight", "unchangedObjectSnapshots", "_cachedObjects", "_cachedObjectIdsHash"]);
161
+ const clonedProps = structuredClone(remainingProps);
162
+ // Ensure objectIds is serialized with the correct key name (getter returns _objectIds)
163
+ clonedProps.objectIds = this.objectIds;
164
+ delete clonedProps._objectIds;
165
+ if (element && typeof element === 'object' && 'nodeType' in element && element.nodeType === 1) {
166
+ clonedProps.element = element.cloneNode(true);
167
+ }
168
+ // Convert Map to plain object for serialization
169
+ clonedProps.unchangedObjectSnapshots = Object.fromEntries(this.unchangedObjectSnapshots);
170
+ return clonedProps;
171
+ }
172
+ deserialize(object) {
173
+ // First, deserialize all base properties using parent's deserialize
174
+ super.deserialize(object);
175
+ // Restore objectIds through setter
176
+ if (object.objectIds) {
177
+ this.objectIds = object.objectIds;
178
+ }
179
+ // Restore the Map from serialized object
180
+ if (object.unchangedObjectSnapshots) {
181
+ this.unchangedObjectSnapshots = new Map(Object.entries(object.unchangedObjectSnapshots));
182
+ }
183
+ return this;
184
+ }
185
+ update() {
186
+ // Only update the selection group itself
187
+ // Child objects are already updated during move/resize/rotate operations
188
+ // Updating them again here would create redundant y.js updates
189
+ this._core.store.state.objects.update(this);
190
+ }
191
+ move(startX, startY, endX, endY) {
192
+ const deltaX = (startX - endX) / this._core.store.state.scale;
193
+ const deltaY = (startY - endY) / this._core.store.state.scale;
194
+ this.translateX += deltaX;
195
+ this.translateY += deltaY;
196
+ this._core.store.state.objects.transaction(() => {
197
+ this._core.store.state.objects.update(this);
198
+ const children = this.objects;
199
+ for (const obj of children) {
200
+ obj.move(startX, startY, endX, endY);
201
+ // Update any lines that are anchored to this object
202
+ this._core.anchorManager.updateAnchorsForObject(obj.id);
203
+ }
204
+ });
205
+ // Update snapshots
206
+ this.unchangedObjectSnapshots.forEach(snapshot => {
207
+ snapshot.translateX += deltaX;
208
+ snapshot.translateY += deltaY;
209
+ });
210
+ }
211
+ resize(x, y, width, height) {
212
+ const widthScaleFactor = width / this.width;
213
+ const heightScaleFactor = height / this.height;
214
+ // Calculate old center
215
+ const oldCenterX = this.translateX + this.totalWidth / 2 / this.scale;
216
+ const oldCenterY = this.translateY + this.totalHeight / 2 / this.scale;
217
+ // Calculate new center
218
+ const newTotalWidth = width + this.padding * 2;
219
+ const newTotalHeight = height + this.padding * 2;
220
+ const newCenterX = x + newTotalWidth / 2 / this.scale;
221
+ const newCenterY = y + newTotalHeight / 2 / this.scale;
222
+ const rotation = this.rotation;
223
+ const cos = Math.cos(-rotation);
224
+ const sin = Math.sin(-rotation);
225
+ const cosR = Math.cos(rotation);
226
+ const sinR = Math.sin(rotation);
227
+ this._core.store.state.objects.transaction(() => {
228
+ // Cache objects once to avoid repeated getter calls during resize
229
+ const children = this.objects;
230
+ children.forEach(child => {
231
+ // Calculate child center
232
+ const childCenterX = child.translateX + child.totalWidth / 2 / child.scale;
233
+ const childCenterY = child.translateY + child.totalHeight / 2 / child.scale;
234
+ // Vector from old group center to child center
235
+ const dx = childCenterX - oldCenterX;
236
+ const dy = childCenterY - oldCenterY;
237
+ // Rotate to local space (align with group axes)
238
+ const localX = dx * cos - dy * sin;
239
+ const localY = dx * sin + dy * cos;
240
+ // Scale in local space
241
+ const scaledLocalX = localX * widthScaleFactor;
242
+ const scaledLocalY = localY * heightScaleFactor;
243
+ // Rotate back to world space
244
+ const rotatedX = scaledLocalX * cosR - scaledLocalY * sinR;
245
+ const rotatedY = scaledLocalX * sinR + scaledLocalY * cosR;
246
+ // New child center
247
+ const newChildCenterX = newCenterX + rotatedX;
248
+ const newChildCenterY = newCenterY + rotatedY;
249
+ // New child top-left
250
+ // Calculate relative rotation
251
+ const relativeRotation = child.rotation - rotation;
252
+ const cosRel = Math.cos(relativeRotation);
253
+ const sinRel = Math.sin(relativeRotation);
254
+ // Project the group's scale factors onto the child's local axes
255
+ // We use absolute values because scaling is magnitude-based
256
+ // If the child is aligned (0 deg), cos=1, sin=0 -> scales match
257
+ // If the child is 90 deg, cos=0, sin=1 -> scales swap
258
+ const newChildWidthScale = Math.sqrt(Math.pow(widthScaleFactor * cosRel, 2) + Math.pow(heightScaleFactor * sinRel, 2));
259
+ const newChildHeightScale = Math.sqrt(Math.pow(widthScaleFactor * sinRel, 2) + Math.pow(heightScaleFactor * cosRel, 2));
260
+ const updatedWidth = child.width * newChildWidthScale;
261
+ const updatedHeight = child.height * newChildHeightScale;
262
+ const updatedTotalWidth = updatedWidth + child.padding * 2;
263
+ const updatedTotalHeight = updatedHeight + child.padding * 2;
264
+ const updatedX = newChildCenterX - updatedTotalWidth / 2 / child.scale;
265
+ const updatedY = newChildCenterY - updatedTotalHeight / 2 / child.scale;
266
+ child.resize(updatedX, updatedY, updatedWidth, updatedHeight);
267
+ // Update any lines that are anchored to this child object
268
+ this._core.anchorManager.updateAnchorsForObject(child.id);
269
+ });
270
+ // Refresh dimensions and update the SelectionGroup to propagate changes to other tabs
271
+ this.refreshObjectDimensions(children);
272
+ this.captureUnchangedSnapshots(children);
273
+ this._core.store.state.objects.update(this);
274
+ });
275
+ }
276
+ rotate(value) {
277
+ this.rotation = value;
278
+ const centerX = this.translateX + this.totalWidth / 2 / this.scale;
279
+ const centerY = this.translateY + this.totalHeight / 2 / this.scale;
280
+ const angle = value - this.snapshotRotation;
281
+ const cos = Math.cos(angle);
282
+ const sin = Math.sin(angle);
283
+ // Cache objects once to avoid repeated getter calls during rotation
284
+ const children = this.objects;
285
+ this._core.store.state.objects.transaction(() => {
286
+ // Update the SelectionGroup itself to propagate rotation to other tabs
287
+ this._core.store.state.objects.update(this);
288
+ const childCount = children.length;
289
+ for (const child of children) {
290
+ const unchangedSnapshot = this.unchangedObjectSnapshots.get(child.id);
291
+ if (!unchangedSnapshot)
292
+ continue;
293
+ const offsetX = this.getOffsetXToCenterFromSnapshot(unchangedSnapshot);
294
+ const offsetY = this.getOffsetYToCenterFromSnapshot(unchangedSnapshot);
295
+ const rotatedX = cos * offsetX - sin * offsetY;
296
+ const rotatedY = sin * offsetX + cos * offsetY;
297
+ child.translateX = centerX + rotatedX - child.totalWidth / 2 / child.scale;
298
+ child.translateY = centerY + rotatedY - child.totalHeight / 2 / child.scale;
299
+ child.rotate(childCount === 1 ? value : unchangedSnapshot.rotation + angle);
300
+ }
301
+ });
302
+ }
303
+ copy() {
304
+ const selectionGroup = KritzelSelectionGroup.create(this._core);
305
+ const children = this.objects;
306
+ // Sort children by zIndex and copy them
307
+ const sortedChildren = [...children].sort((a, b) => a.zIndex - b.zIndex);
308
+ for (const obj of sortedChildren) {
309
+ const copiedObject = obj.copy();
310
+ selectionGroup.addOrRemove(copiedObject);
311
+ }
312
+ selectionGroup.captureUnchangedSnapshots();
313
+ if (children.length === 1) {
314
+ selectionGroup.rotation = children[0].rotation;
315
+ }
316
+ return selectionGroup;
317
+ }
318
+ /**
319
+ * Refreshes the selection group's bounding box dimensions based on contained objects.
320
+ * @param cachedObjects Optional pre-fetched objects array to avoid redundant getter calls
321
+ * @param skipPersist If true, only updates local state without persisting to Yjs (used during undo/redo)
322
+ */
323
+ refreshObjectDimensions(cachedObjects, skipPersist = false) {
324
+ const children = cachedObjects !== null && cachedObjects !== void 0 ? cachedObjects : this.objects;
325
+ if (children.length === 1) {
326
+ const obj = children[0];
327
+ this.minX = obj.boundingBox.x / this.scale;
328
+ this.maxX = obj.boundingBox.x / this.scale + obj.boundingBox.width;
329
+ this.minY = obj.boundingBox.y / this.scale;
330
+ this.maxY = obj.boundingBox.y / this.scale + obj.boundingBox.height;
331
+ this.translateX = (this.minX - this.padding) * this.scale;
332
+ this.translateY = (this.minY - this.padding) * this.scale;
333
+ this.width = (this.maxX - this.minX - this.padding) * this.scale;
334
+ this.height = (this.maxY - this.minY - this.padding) * this.scale;
335
+ }
336
+ else {
337
+ const rotation = this.rotation;
338
+ const cos = Math.cos(-rotation);
339
+ const sin = Math.sin(-rotation);
340
+ let minX = Infinity;
341
+ let maxX = -Infinity;
342
+ let minY = Infinity;
343
+ let maxY = -Infinity;
344
+ children.forEach(obj => {
345
+ const polygon = obj.rotatedPolygon;
346
+ const corners = [polygon.topLeft, polygon.topRight, polygon.bottomRight, polygon.bottomLeft];
347
+ corners.forEach(corner => {
348
+ // Rotate corner into local space (aligned with group rotation)
349
+ const rx = corner.x * cos - corner.y * sin;
350
+ const ry = corner.x * sin + corner.y * cos;
351
+ if (rx < minX)
352
+ minX = rx;
353
+ if (rx > maxX)
354
+ maxX = rx;
355
+ if (ry < minY)
356
+ minY = ry;
357
+ if (ry > maxY)
358
+ maxY = ry;
359
+ });
360
+ });
361
+ // Dimensions in world units (unrotated)
362
+ const worldWidth = maxX - minX;
363
+ const worldHeight = maxY - minY;
364
+ this.width = (worldWidth - this.padding) * this.scale;
365
+ this.height = (worldHeight - this.padding) * this.scale;
366
+ // Center of the box in rotated space
367
+ const cRx = (minX + maxX) / 2;
368
+ const cRy = (minY + maxY) / 2;
369
+ // Rotate center back to world space
370
+ const cosR = Math.cos(rotation);
371
+ const sinR = Math.sin(rotation);
372
+ const cx = cRx * cosR - cRy * sinR;
373
+ const cy = cRx * sinR + cRy * cosR;
374
+ this.translateX = cx - (this.width / this.scale + 2 * this.padding) / 2;
375
+ this.translateY = cy - (this.height / this.scale + 2 * this.padding) / 2;
376
+ }
377
+ if (!skipPersist) {
378
+ this._core.store.state.objects.update(this);
379
+ }
380
+ }
381
+ getOffsetXToCenterFromSnapshot(snapshot) {
382
+ const objCenterX = snapshot.translateX + snapshot.totalWidth / snapshot.scale / 2;
383
+ const groupCenterX = this.translateX + this.totalWidth / this.scale / 2;
384
+ return objCenterX - groupCenterX;
385
+ }
386
+ getOffsetYToCenterFromSnapshot(snapshot) {
387
+ const objCenterY = snapshot.translateY + snapshot.totalHeight / snapshot.scale / 2;
388
+ const groupCenterY = this.translateY + this.totalHeight / this.scale / 2;
389
+ return objCenterY - groupCenterY;
390
+ }
391
+ hitTest(x, y) {
392
+ const children = this.objects;
393
+ const isSingleLine = children.length === 1 && children[0].__class__ === 'KritzelLine';
394
+ if (isSingleLine) {
395
+ return children[0].hitTest(x, y);
396
+ }
397
+ const polygon = this.rotatedPolygon;
398
+ const polyPoints = [polygon.topLeft, polygon.topRight, polygon.bottomRight, polygon.bottomLeft];
399
+ if (KritzelGeometryHelper.isPointInPolygon({ x, y }, polyPoints)) {
400
+ return true;
401
+ }
402
+ for (const obj of children) {
403
+ if (obj.hitTest(x, y)) {
404
+ return true;
405
+ }
406
+ }
407
+ return false;
408
+ }
409
+ }