kritzel-stencil 0.0.168 → 0.0.170

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 (100) hide show
  1. package/dist/cjs/{default-line-tool.config-CK85ewK0.js → default-line-tool.config-JuTDR6PF.js} +515 -10
  2. package/dist/cjs/default-line-tool.config-JuTDR6PF.js.map +1 -0
  3. package/dist/cjs/index.cjs.js +2 -1
  4. package/dist/cjs/index.cjs.js.map +1 -1
  5. package/dist/cjs/kritzel-color_22.cjs.entry.js +120 -6
  6. package/dist/cjs/loader.cjs.js +1 -1
  7. package/dist/cjs/stencil.cjs.js +1 -1
  8. package/dist/collection/classes/core/core.class.js +89 -1
  9. package/dist/collection/classes/core/core.class.js.map +1 -1
  10. package/dist/collection/classes/core/reviver.class.js +4 -0
  11. package/dist/collection/classes/core/reviver.class.js.map +1 -1
  12. package/dist/collection/classes/handlers/key.handler.js +3 -0
  13. package/dist/collection/classes/handlers/key.handler.js.map +1 -1
  14. package/dist/collection/classes/handlers/move.handler.js +63 -0
  15. package/dist/collection/classes/handlers/move.handler.js.map +1 -1
  16. package/dist/collection/classes/handlers/rotation.handler.js +2 -0
  17. package/dist/collection/classes/handlers/rotation.handler.js.map +1 -1
  18. package/dist/collection/classes/handlers/selection.handler.js +23 -5
  19. package/dist/collection/classes/handlers/selection.handler.js.map +1 -1
  20. package/dist/collection/classes/objects/group.class.js +394 -0
  21. package/dist/collection/classes/objects/group.class.js.map +1 -0
  22. package/dist/collection/classes/objects/line.class.js +2 -1
  23. package/dist/collection/classes/objects/line.class.js.map +1 -1
  24. package/dist/collection/classes/objects/selection-group.class.js +20 -0
  25. package/dist/collection/classes/objects/selection-group.class.js.map +1 -1
  26. package/dist/collection/classes/registries/icon-registry.class.js +2 -0
  27. package/dist/collection/classes/registries/icon-registry.class.js.map +1 -1
  28. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +17 -2
  29. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js.map +1 -1
  30. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +43 -3
  31. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -1
  32. package/dist/collection/helpers/event.helper.js +10 -2
  33. package/dist/collection/helpers/event.helper.js.map +1 -1
  34. package/dist/collection/index.js +1 -0
  35. package/dist/collection/index.js.map +1 -1
  36. package/dist/components/index.js +3 -3
  37. package/dist/components/kritzel-brush-style.js +1 -1
  38. package/dist/components/kritzel-context-menu.js +1 -1
  39. package/dist/components/kritzel-control-brush-config.js +1 -1
  40. package/dist/components/kritzel-control-text-config.js +1 -1
  41. package/dist/components/kritzel-controls.js +1 -1
  42. package/dist/components/kritzel-editor.js +27 -12
  43. package/dist/components/kritzel-editor.js.map +1 -1
  44. package/dist/components/kritzel-engine.js +1 -1
  45. package/dist/components/kritzel-icon.js +1 -1
  46. package/dist/components/kritzel-menu-item.js +1 -1
  47. package/dist/components/kritzel-menu.js +1 -1
  48. package/dist/components/kritzel-split-button.js +1 -1
  49. package/dist/components/kritzel-utility-panel.js +1 -1
  50. package/dist/components/kritzel-workspace-manager.js +1 -1
  51. package/dist/components/{p-BG2m-Sq9.js → p-9Sbn9-7-.js} +611 -16
  52. package/dist/components/p-9Sbn9-7-.js.map +1 -0
  53. package/dist/components/{p-Bwv1dxAB.js → p-BUsg2vtg.js} +12 -4
  54. package/dist/components/{p-Bwv1dxAB.js.map → p-BUsg2vtg.js.map} +1 -1
  55. package/dist/components/{p-BoazmhlG.js → p-C6-tSCMR.js} +3 -3
  56. package/dist/components/{p-BoazmhlG.js.map → p-C6-tSCMR.js.map} +1 -1
  57. package/dist/components/{p-Cv4BGNPb.js → p-CIts5Uma.js} +4 -2
  58. package/dist/components/p-CIts5Uma.js.map +1 -0
  59. package/dist/components/{p-BSBMBjhq.js → p-CQd5oYXp.js} +3 -3
  60. package/dist/components/{p-BSBMBjhq.js.map → p-CQd5oYXp.js.map} +1 -1
  61. package/dist/components/{p-D8L0t-Ro.js → p-Co5HWjr6.js} +3 -3
  62. package/dist/components/{p-D8L0t-Ro.js.map → p-Co5HWjr6.js.map} +1 -1
  63. package/dist/components/{p-5OECjGHq.js → p-DG7VXGxX.js} +3 -3
  64. package/dist/components/{p-5OECjGHq.js.map → p-DG7VXGxX.js.map} +1 -1
  65. package/dist/components/{p-D1YAsWrL.js → p-D_uh1RUI.js} +3 -3
  66. package/dist/components/{p-D1YAsWrL.js.map → p-D_uh1RUI.js.map} +1 -1
  67. package/dist/components/{p-xcQV8l_c.js → p-cv2RCdI1.js} +7 -7
  68. package/dist/components/{p-xcQV8l_c.js.map → p-cv2RCdI1.js.map} +1 -1
  69. package/dist/components/{p-BmdYFhLx.js → p-nZdy-Ii5.js} +4 -4
  70. package/dist/components/{p-BmdYFhLx.js.map → p-nZdy-Ii5.js.map} +1 -1
  71. package/dist/components/{p-CiM-IPaD.js → p-y25EBKEA.js} +5 -5
  72. package/dist/components/{p-CiM-IPaD.js.map → p-y25EBKEA.js.map} +1 -1
  73. package/dist/esm/{default-line-tool.config-kK3fdCJH.js → default-line-tool.config-CuBm2vpW.js} +515 -11
  74. package/dist/esm/default-line-tool.config-CuBm2vpW.js.map +1 -0
  75. package/dist/esm/index.js +2 -2
  76. package/dist/esm/kritzel-color_22.entry.js +120 -6
  77. package/dist/esm/loader.js +1 -1
  78. package/dist/esm/stencil.js +1 -1
  79. package/dist/stencil/index.esm.js +1 -1
  80. package/dist/stencil/p-CuBm2vpW.js +2 -0
  81. package/dist/stencil/p-CuBm2vpW.js.map +1 -0
  82. package/dist/stencil/p-c9201236.entry.js +10 -0
  83. package/dist/stencil/p-c9201236.entry.js.map +1 -0
  84. package/dist/stencil/stencil.esm.js +1 -1
  85. package/dist/types/classes/core/core.class.d.ts +11 -1
  86. package/dist/types/classes/handlers/move.handler.d.ts +11 -0
  87. package/dist/types/classes/objects/group.class.d.ts +97 -0
  88. package/dist/types/classes/objects/selection-group.class.d.ts +5 -0
  89. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +2 -0
  90. package/dist/types/components.d.ts +4 -2
  91. package/dist/types/index.d.ts +1 -0
  92. package/package.json +1 -1
  93. package/dist/cjs/default-line-tool.config-CK85ewK0.js.map +0 -1
  94. package/dist/components/p-BG2m-Sq9.js.map +0 -1
  95. package/dist/components/p-Cv4BGNPb.js.map +0 -1
  96. package/dist/esm/default-line-tool.config-kK3fdCJH.js.map +0 -1
  97. package/dist/stencil/p-8ee3959e.entry.js +0 -10
  98. package/dist/stencil/p-8ee3959e.entry.js.map +0 -1
  99. package/dist/stencil/p-kK3fdCJH.js +0 -2
  100. package/dist/stencil/p-kK3fdCJH.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"rotation.handler.js","sourceRoot":"","sources":["../../../src/classes/handlers/rotation.handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { KritzelEventHelper } from '../../helpers/event.helper';\r\nimport { KritzelBaseHandler } from './base.handler';\r\nimport { KritzelCore } from '../core/core.class';\r\nimport { KritzelBaseObject } from '../objects/base-object.class';\r\n\r\nexport class KritzelRotationHandler extends KritzelBaseHandler {\r\n initialRotation: number = 0;\r\n\r\n rotation: number = 0;\r\n\r\n unchangedObjects: KritzelBaseObject<any>[] = [];\r\n\r\n initialSelectionGroupRotation: number = 0;\r\n\r\n constructor(core: KritzelCore) {\r\n super(core);\r\n }\r\n\r\n private reset() {\r\n this.initialRotation = 0;\r\n this.rotation = 0;\r\n this.unchangedObjects = [];\r\n }\r\n\r\n handlePointerDown(event: PointerEvent): void {\r\n if (event.pointerType === 'mouse') {\r\n if (KritzelEventHelper.isLeftClick(event)) {\r\n const selectionGroup = this._core.store.selectionGroup;\r\n if (selectionGroup && this._core.store.state.isRotationHandleSelected) {\r\n const clientX = event.clientX - this._core.store.offsetX;\r\n const clientY = event.clientY - this._core.store.offsetY;\r\n\r\n this._core.store.state.isRotating = true;\r\n\r\n const objectScale = selectionGroup.scale || 1;\r\n const centerX = selectionGroup.translateX + selectionGroup.width / 2 / objectScale;\r\n const centerY = selectionGroup.translateY + selectionGroup.height / 2 / objectScale;\r\n\r\n const cursorX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;\r\n const cursorY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;\r\n\r\n this.initialSelectionGroupRotation = selectionGroup.rotation;\r\n this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - selectionGroup.rotation;\r\n\r\n this.unchangedObjects = selectionGroup.objects.map(obj => obj.clone());\r\n }\r\n }\r\n }\r\n\r\n if (event.pointerType === 'touch') {\r\n const activePointers = Array.from(this._core.store.state.pointers.values());\r\n const firstTouch = activePointers[0];\r\n\r\n if (!firstTouch) {\r\n return;\r\n }\r\n\r\n if (activePointers.length === 1) {\r\n const selectionGroup = this._core.store.selectionGroup;\r\n if (selectionGroup && this._core.store.state.isRotationHandleSelected) {\r\n const clientX = Math.round(firstTouch.clientX - this._core.store.offsetX);\r\n const clientY = Math.round(firstTouch.clientY - this._core.store.offsetY);\r\n\r\n this._core.store.state.isRotating = true;\r\n\r\n const objectScale = selectionGroup.scale || 1;\r\n const centerX = selectionGroup.translateX + selectionGroup.width / 2 / objectScale;\r\n const centerY = selectionGroup.translateY + selectionGroup.height / 2 / objectScale;\r\n\r\n const cursorX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;\r\n const cursorY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;\r\n\r\n this.initialSelectionGroupRotation = selectionGroup.rotation;\r\n this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - selectionGroup.rotation;\r\n\r\n this.unchangedObjects = selectionGroup.objects.map(obj => obj.clone());\r\n\r\n clearTimeout(this._core.store.state.longTouchTimeout);\r\n }\r\n }\r\n }\r\n }\r\n\r\n handlePointerMove(event: PointerEvent): void {\r\n if (event.pointerType === 'mouse') {\r\n const selectionGroup = this._core.store.selectionGroup;\r\n if (this._core.store.state.isRotating && selectionGroup) {\r\n const clientX = event.clientX - this._core.store.offsetX;\r\n const clientY = event.clientY - this._core.store.offsetY;\r\n\r\n const objectScale = selectionGroup.scale || 1;\r\n const groupCenterX = selectionGroup.translateX + selectionGroup.width / 2 / objectScale;\r\n const groupCenterY = selectionGroup.translateY + selectionGroup.height / 2 / objectScale;\r\n\r\n const cursorX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;\r\n const cursorY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;\r\n\r\n const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);\r\n\r\n this.rotation = currentRotation - this.initialRotation;\r\n\r\n selectionGroup.rotate(this.rotation);\r\n }\r\n }\r\n\r\n if (event.pointerType === 'touch') {\r\n const activePointers = Array.from(this._core.store.state.pointers.values());\r\n const firstTouch = activePointers[0];\r\n\r\n if (!firstTouch) {\r\n return;\r\n }\r\n\r\n const selectionGroup = this._core.store.selectionGroup;\r\n if (this._core.store.state.isRotating && selectionGroup) {\r\n const clientX = Math.round(firstTouch.clientX - this._core.store.offsetX);\r\n const clientY = Math.round(firstTouch.clientY - this._core.store.offsetY);\r\n\r\n const objectScale = selectionGroup.scale || 1;\r\n const groupCenterX = selectionGroup.translateX + selectionGroup.width / 2 / objectScale;\r\n const groupCenterY = selectionGroup.translateY + selectionGroup.height / 2 / objectScale;\r\n\r\n const cursorX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;\r\n const cursorY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;\r\n\r\n const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);\r\n\r\n this.rotation = currentRotation - this.initialRotation;\r\n\r\n selectionGroup.rotate(this.rotation);\r\n\r\n clearTimeout(this._core.store.state.longTouchTimeout);\r\n }\r\n }\r\n }\r\n\r\n handlePointerUp(event: PointerEvent): void {\r\n if (event.pointerType === 'mouse') {\r\n if (this._core.store.state.isRotating) {\r\n this._core.store.selectionGroup.update();\r\n this._core.engine.emitObjectsChange();\r\n this._core.store.state.isRotating = false;\r\n this._core.store.state.hasObjectsChanged = true;\r\n\r\n this.reset();\r\n }\r\n }\r\n\r\n if (event.pointerType === 'touch') {\r\n if (this._core.store.state.isRotating) {\r\n this._core.store.selectionGroup.update();\r\n this._core.engine.emitObjectsChange();\r\n this._core.store.state.isRotating = false;\r\n this._core.store.state.hasObjectsChanged = true;\r\n\r\n this.reset();\r\n\r\n clearTimeout(this._core.store.state.longTouchTimeout);\r\n }\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"rotation.handler.js","sourceRoot":"","sources":["../../../src/classes/handlers/rotation.handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { KritzelEventHelper } from '../../helpers/event.helper';\r\nimport { KritzelBaseHandler } from './base.handler';\r\nimport { KritzelCore } from '../core/core.class';\r\nimport { KritzelBaseObject } from '../objects/base-object.class';\r\n\r\nexport class KritzelRotationHandler extends KritzelBaseHandler {\r\n initialRotation: number = 0;\r\n\r\n rotation: number = 0;\r\n\r\n unchangedObjects: KritzelBaseObject<any>[] = [];\r\n\r\n initialSelectionGroupRotation: number = 0;\r\n\r\n constructor(core: KritzelCore) {\r\n super(core);\r\n }\r\n\r\n private reset() {\r\n this.initialRotation = 0;\r\n this.rotation = 0;\r\n this.unchangedObjects = [];\r\n }\r\n\r\n handlePointerDown(event: PointerEvent): void {\r\n if (event.pointerType === 'mouse') {\r\n if (KritzelEventHelper.isLeftClick(event)) {\r\n const selectionGroup = this._core.store.selectionGroup;\r\n if (selectionGroup && this._core.store.state.isRotationHandleSelected) {\r\n selectionGroup.beginTransform();\r\n\r\n const clientX = event.clientX - this._core.store.offsetX;\r\n const clientY = event.clientY - this._core.store.offsetY;\r\n\r\n this._core.store.state.isRotating = true;\r\n\r\n const objectScale = selectionGroup.scale || 1;\r\n const centerX = selectionGroup.translateX + selectionGroup.width / 2 / objectScale;\r\n const centerY = selectionGroup.translateY + selectionGroup.height / 2 / objectScale;\r\n\r\n const cursorX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;\r\n const cursorY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;\r\n\r\n this.initialSelectionGroupRotation = selectionGroup.rotation;\r\n this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - selectionGroup.rotation;\r\n\r\n this.unchangedObjects = selectionGroup.objects.map(obj => obj.clone());\r\n }\r\n }\r\n }\r\n\r\n if (event.pointerType === 'touch') {\r\n const activePointers = Array.from(this._core.store.state.pointers.values());\r\n const firstTouch = activePointers[0];\r\n\r\n if (!firstTouch) {\r\n return;\r\n }\r\n\r\n if (activePointers.length === 1) {\r\n const selectionGroup = this._core.store.selectionGroup;\r\n if (selectionGroup && this._core.store.state.isRotationHandleSelected) {\r\n selectionGroup.beginTransform();\r\n\r\n const clientX = Math.round(firstTouch.clientX - this._core.store.offsetX);\r\n const clientY = Math.round(firstTouch.clientY - this._core.store.offsetY);\r\n\r\n this._core.store.state.isRotating = true;\r\n\r\n const objectScale = selectionGroup.scale || 1;\r\n const centerX = selectionGroup.translateX + selectionGroup.width / 2 / objectScale;\r\n const centerY = selectionGroup.translateY + selectionGroup.height / 2 / objectScale;\r\n\r\n const cursorX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;\r\n const cursorY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;\r\n\r\n this.initialSelectionGroupRotation = selectionGroup.rotation;\r\n this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - selectionGroup.rotation;\r\n\r\n this.unchangedObjects = selectionGroup.objects.map(obj => obj.clone());\r\n\r\n clearTimeout(this._core.store.state.longTouchTimeout);\r\n }\r\n }\r\n }\r\n }\r\n\r\n handlePointerMove(event: PointerEvent): void {\r\n if (event.pointerType === 'mouse') {\r\n const selectionGroup = this._core.store.selectionGroup;\r\n if (this._core.store.state.isRotating && selectionGroup) {\r\n const clientX = event.clientX - this._core.store.offsetX;\r\n const clientY = event.clientY - this._core.store.offsetY;\r\n\r\n const objectScale = selectionGroup.scale || 1;\r\n const groupCenterX = selectionGroup.translateX + selectionGroup.width / 2 / objectScale;\r\n const groupCenterY = selectionGroup.translateY + selectionGroup.height / 2 / objectScale;\r\n\r\n const cursorX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;\r\n const cursorY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;\r\n\r\n const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);\r\n\r\n this.rotation = currentRotation - this.initialRotation;\r\n\r\n selectionGroup.rotate(this.rotation);\r\n }\r\n }\r\n\r\n if (event.pointerType === 'touch') {\r\n const activePointers = Array.from(this._core.store.state.pointers.values());\r\n const firstTouch = activePointers[0];\r\n\r\n if (!firstTouch) {\r\n return;\r\n }\r\n\r\n const selectionGroup = this._core.store.selectionGroup;\r\n if (this._core.store.state.isRotating && selectionGroup) {\r\n const clientX = Math.round(firstTouch.clientX - this._core.store.offsetX);\r\n const clientY = Math.round(firstTouch.clientY - this._core.store.offsetY);\r\n\r\n const objectScale = selectionGroup.scale || 1;\r\n const groupCenterX = selectionGroup.translateX + selectionGroup.width / 2 / objectScale;\r\n const groupCenterY = selectionGroup.translateY + selectionGroup.height / 2 / objectScale;\r\n\r\n const cursorX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;\r\n const cursorY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;\r\n\r\n const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);\r\n\r\n this.rotation = currentRotation - this.initialRotation;\r\n\r\n selectionGroup.rotate(this.rotation);\r\n\r\n clearTimeout(this._core.store.state.longTouchTimeout);\r\n }\r\n }\r\n }\r\n\r\n handlePointerUp(event: PointerEvent): void {\r\n if (event.pointerType === 'mouse') {\r\n if (this._core.store.state.isRotating) {\r\n this._core.store.selectionGroup.update();\r\n this._core.engine.emitObjectsChange();\r\n this._core.store.state.isRotating = false;\r\n this._core.store.state.hasObjectsChanged = true;\r\n\r\n this.reset();\r\n }\r\n }\r\n\r\n if (event.pointerType === 'touch') {\r\n if (this._core.store.state.isRotating) {\r\n this._core.store.selectionGroup.update();\r\n this._core.engine.emitObjectsChange();\r\n this._core.store.state.isRotating = false;\r\n this._core.store.state.hasObjectsChanged = true;\r\n\r\n this.reset();\r\n\r\n clearTimeout(this._core.store.state.longTouchTimeout);\r\n }\r\n }\r\n }\r\n}\r\n"]}
@@ -1,6 +1,7 @@
1
1
  import { KritzelEventHelper } from "../../helpers/event.helper";
2
2
  import { KritzelSelectionBox } from "../objects/selection-box.class";
3
3
  import { KritzelSelectionGroup } from "../objects/selection-group.class";
4
+ import { KritzelGroup } from "../objects/group.class";
4
5
  import { KritzelBaseHandler } from "./base.handler";
5
6
  export class KritzelSelectionHandler extends KritzelBaseHandler {
6
7
  startX;
@@ -217,11 +218,14 @@ export class KritzelSelectionHandler extends KritzelBaseHandler {
217
218
  if (!object) {
218
219
  return;
219
220
  }
220
- object.isSelected = false;
221
+ // Resolve child objects to their parent groups
222
+ const parentGroup = KritzelGroup.findParentGroup(this._core, object.id);
223
+ const objectToSelect = parentGroup || object;
224
+ objectToSelect.isSelected = false;
221
225
  const selectionGroup = KritzelSelectionGroup.create(this._core);
222
- selectionGroup.addOrRemove(object);
226
+ selectionGroup.addOrRemove(objectToSelect);
223
227
  selectionGroup.isSelected = true;
224
- selectionGroup.rotation = object.rotation;
228
+ selectionGroup.rotation = objectToSelect.rotation;
225
229
  this._core.addSelectionGroup(selectionGroup);
226
230
  this._core.rerender();
227
231
  }
@@ -230,10 +234,24 @@ export class KritzelSelectionHandler extends KritzelBaseHandler {
230
234
  if (selectedObjects.length === 0) {
231
235
  return;
232
236
  }
237
+ // Resolve child objects to their parent groups to avoid double-move
238
+ const resolvedObjects = new Map();
239
+ selectedObjects.forEach(obj => {
240
+ // Check if this object is a child of a KritzelGroup
241
+ const parentGroup = KritzelGroup.findParentGroup(this._core, obj.id);
242
+ if (parentGroup) {
243
+ // Add the parent group instead of the child
244
+ resolvedObjects.set(parentGroup.id, parentGroup);
245
+ }
246
+ else {
247
+ // Not a child of any group, add the object itself
248
+ resolvedObjects.set(obj.id, obj);
249
+ }
250
+ obj.isSelected = false;
251
+ });
233
252
  const selectionGroup = KritzelSelectionGroup.create(this._core);
234
- selectedObjects.forEach(o => {
253
+ resolvedObjects.forEach(o => {
235
254
  selectionGroup.addOrRemove(o);
236
- o.isSelected = false;
237
255
  });
238
256
  selectionGroup.isSelected = true;
239
257
  if (selectionGroup.length === 1) {
@@ -1 +1 @@
1
- {"version":3,"file":"selection.handler.js","sourceRoot":"","sources":["../../../src/classes/handlers/selection.handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { KritzelEventHelper } from '../../helpers/event.helper';\r\nimport { KritzelSelectionBox } from '../objects/selection-box.class';\r\nimport { KritzelSelectionGroup } from '../objects/selection-group.class';\r\nimport { KritzelBaseHandler } from './base.handler';\r\nimport { KritzelBaseObject } from '../objects/base-object.class';\r\nimport { KritzelCore } from '../core/core.class';\r\n\r\nexport class KritzelSelectionHandler extends KritzelBaseHandler {\r\n startX: number;\r\n startY: number;\r\n\r\n touchStartX: number = 0;\r\n touchStartY: number = 0;\r\n\r\n touchStartTimeout: any = null;\r\n\r\n get isSelectionClick() {\r\n const selectionBox = this._core.store.selectionBox;\r\n return selectionBox && selectionBox.width === 0 && selectionBox.height === 0;\r\n }\r\n\r\n get isSelectionDrag() {\r\n const selectionBox = this._core.store.selectionBox;\r\n return selectionBox && (selectionBox.width > 0 || selectionBox.height > 0);\r\n }\r\n\r\n constructor(core: KritzelCore) {\r\n super(core);\r\n }\r\n\r\n handlePointerDown(event: PointerEvent) {\r\n if (event.pointerType === 'mouse') {\r\n if (KritzelEventHelper.isLeftClick(event) && !this._core.store.selectionGroup) {\r\n this.startMouseSelection(event);\r\n }\r\n }\r\n\r\n if (event.pointerType === 'touch') {\r\n this.touchStartTimeout = setTimeout(() => {\r\n if (this._core.store.state.pointers.size === 1 && !this._core.store.state.isScaling && !this._core.store.selectionGroup) {\r\n this.startTouchSelection();\r\n this.updateTouchSelection();\r\n }\r\n }, 80);\r\n }\r\n }\r\n\r\n handlePointerMove(event: PointerEvent) {\r\n if (event.pointerType === 'mouse') {\r\n if (this._core.store.state.isSelecting) {\r\n this.updateMouseSelection(event);\r\n }\r\n }\r\n\r\n if (event.pointerType === 'touch') {\r\n const activePointers = Array.from(this._core.store.state.pointers.values());\r\n\r\n const x = Math.round(activePointers[0].clientX - this._core.store.offsetX);\r\n const y = Math.round(activePointers[0].clientY - this._core.store.offsetY);\r\n\r\n const moveDeltaX = Math.abs(x - this.touchStartX);\r\n const moveDeltaY = Math.abs(y - this.touchStartY);\r\n const moveThreshold = 5;\r\n\r\n if ((moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) && this._core.store.state.isSelecting) {\r\n this.updateTouchSelection();\r\n\r\n clearTimeout(this._core.store.state.longTouchTimeout);\r\n }\r\n }\r\n }\r\n\r\n handlePointerUp(event: PointerEvent) {\r\n if (event.pointerType === 'mouse') {\r\n if (KritzelEventHelper.isLeftClick(event)) {\r\n const hasObjectsMoved = this._core.store.state.hasObjectsChanged;\r\n const selectionGroup = this._core.store.selectionGroup;\r\n\r\n if (selectionGroup?.objects.length === 1 && hasObjectsMoved === false) {\r\n selectionGroup.objects[0].edit(event);\r\n }\r\n\r\n this._core.store.state.hasObjectsChanged = false;\r\n\r\n if (this._core.store.state.isSelecting) {\r\n if (this.isSelectionClick) {\r\n this.handleSelectionClick(event);\r\n }\r\n\r\n if (this.isSelectionDrag) {\r\n this.updateMouseSelection(event);\r\n this.addSelectedObjectsToSelectionGroup();\r\n this.removeSelectionBox();\r\n }\r\n\r\n this._core.engine.emitObjectsChange();\r\n }\r\n }\r\n }\r\n\r\n if (event.pointerType === 'touch') {\r\n clearTimeout(this.touchStartTimeout);\r\n\r\n const hasObjectsMoved = this._core.store.state.hasObjectsChanged;\r\n const selectionGroup = this._core.store.selectionGroup;\r\n\r\n if (selectionGroup?.objects.length === 1 && hasObjectsMoved === false) {\r\n selectionGroup.objects[0].edit(event);\r\n }\r\n\r\n this._core.store.state.hasObjectsChanged = false;\r\n\r\n if (this._core.store.state.isSelecting) {\r\n if (this.isSelectionClick) {\r\n this.handleSelectionClick(event);\r\n }\r\n\r\n if (this.isSelectionDrag) {\r\n this.updateTouchSelection();\r\n this.addSelectedObjectsToSelectionGroup();\r\n this.removeSelectionBox();\r\n }\r\n\r\n this._core.engine.emitObjectsChange();\r\n this._core.store.state.skipContextMenu = false;\r\n }\r\n }\r\n }\r\n\r\n private removeSelectionBox(): void {\r\n this._core.store.state.isSelecting = false;\r\n this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox);\r\n }\r\n\r\n private startMouseSelection(event: MouseEvent): void {\r\n let clientX, clientY;\r\n\r\n clientX = event.clientX - this._core.store.offsetX;\r\n clientY = event.clientY - this._core.store.offsetY;\r\n\r\n const selectionBox = KritzelSelectionBox.create(this._core);\r\n\r\n this.startX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;\r\n this.startY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;\r\n\r\n selectionBox.translateX = this.startX;\r\n selectionBox.translateY = this.startY;\r\n\r\n this._core.store.state.isSelecting = true;\r\n\r\n this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || o instanceof KritzelSelectionGroup);\r\n this._core.store.state.objects.insert(selectionBox);\r\n }\r\n\r\n private startTouchSelection(): void {\r\n const activePointers = Array.from(this._core.store.state.pointers.values());\r\n const firstTouch = activePointers[0];\r\n\r\n if (!firstTouch) {\r\n return;\r\n }\r\n\r\n let clientX, clientY;\r\n\r\n clientX = Math.round(firstTouch.clientX - this._core.store.offsetX);\r\n clientY = Math.round(firstTouch.clientY - this._core.store.offsetY);\r\n this.touchStartX = clientX;\r\n this.touchStartY = clientY;\r\n\r\n const selectionBox = KritzelSelectionBox.create(this._core);\r\n\r\n this.startX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;\r\n this.startY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;\r\n\r\n selectionBox.translateX = this.startX;\r\n selectionBox.translateY = this.startY;\r\n\r\n this._core.store.state.isSelecting = true;\r\n\r\n this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || o instanceof KritzelSelectionGroup);\r\n this._core.store.state.objects.insert(selectionBox);\r\n }\r\n\r\n private updateMouseSelection(event: MouseEvent): void {\r\n let clientX, clientY;\r\n\r\n clientX = event.clientX - this._core.store.offsetX;\r\n clientY = event.clientY - this._core.store.offsetY;\r\n\r\n const selectionBox = this._core.store.selectionBox;\r\n\r\n if (selectionBox) {\r\n const currentX = (clientX - this._core.store.state.translateX) / selectionBox.scale;\r\n const currentY = (clientY - this._core.store.state.translateY) / selectionBox.scale;\r\n\r\n const width = Math.abs(currentX - this.startX) * selectionBox.scale;\r\n const height = Math.abs(currentY - this.startY) * selectionBox.scale;\r\n\r\n selectionBox.width = width;\r\n selectionBox.height = height;\r\n selectionBox.translateX = Math.min(currentX, this.startX);\r\n selectionBox.translateY = Math.min(currentY, this.startY);\r\n\r\n if (width > 0 || height > 0) {\r\n this.updateSelectedObjects();\r\n } else {\r\n this.clearSelectionPreview();\r\n }\r\n }\r\n }\r\n\r\n private updateTouchSelection(): void {\r\n const activePointers = Array.from(this._core.store.state.pointers.values());\r\n const firstTouch = activePointers[0];\r\n\r\n if (!firstTouch) {\r\n return;\r\n }\r\n\r\n let clientX, clientY;\r\n\r\n clientX = Math.round(firstTouch.clientX - this._core.store.offsetX);\r\n clientY = Math.round(firstTouch.clientY - this._core.store.offsetY);\r\n\r\n const selectionBox = this._core.store.selectionBox;\r\n\r\n if (selectionBox) {\r\n const currentX = (clientX - this._core.store.state.translateX) / selectionBox.scale;\r\n const currentY = (clientY - this._core.store.state.translateY) / selectionBox.scale;\r\n\r\n const width = Math.abs(currentX - this.startX) * selectionBox.scale;\r\n const height = Math.abs(currentY - this.startY) * selectionBox.scale;\r\n\r\n selectionBox.width = width;\r\n selectionBox.height = height;\r\n selectionBox.translateX = Math.min(currentX, this.startX);\r\n selectionBox.translateY = Math.min(currentY, this.startY);\r\n\r\n if (width > 0 || height > 0) {\r\n this.updateSelectedObjects();\r\n } else {\r\n this.clearSelectionPreview();\r\n }\r\n }\r\n }\r\n\r\n private updateSelectedObjects(): void {\r\n const selectionBox = this._core.store.selectionBox;\r\n if (selectionBox) {\r\n this._core.store.allObjects\r\n .filter(o => !(o instanceof KritzelSelectionBox))\r\n .forEach(object => (object.isSelected = object.hitTestPolygon(selectionBox.rotatedPolygon)));\r\n }\r\n }\r\n\r\n private handleSelectionClick(event: PointerEvent): void {\r\n const selectedObject = this.getTopmostHitObject(event);\r\n\r\n this.clearSelectionPreview();\r\n\r\n this.addObjectToSelectionGroup(selectedObject);\r\n this.removeSelectionBox();\r\n }\r\n\r\n private getTopmostHitObject(event: PointerEvent): KritzelBaseObject<any> | null {\r\n const pointerX = this._core.store.state.pointerX;\r\n const pointerY = this._core.store.state.pointerY;\r\n const overlappingObjects = this._core.getObjectsFromPointerEvent(event, '.object');\r\n\r\n for (const object of overlappingObjects) {\r\n if (object.hitTest(pointerX, pointerY)) {\r\n return object;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private clearSelectionPreview(): void {\r\n this._core.store.allNonSelectionObjects.forEach(object => {\r\n object.isSelected = false;\r\n });\r\n }\r\n\r\n private addObjectToSelectionGroup(object: KritzelBaseObject): void {\r\n if (!object) {\r\n return;\r\n }\r\n\r\n object.isSelected = false;\r\n\r\n const selectionGroup = KritzelSelectionGroup.create(this._core);\r\n selectionGroup.addOrRemove(object);\r\n selectionGroup.isSelected = true;\r\n selectionGroup.rotation = object.rotation;\r\n\r\n this._core.addSelectionGroup(selectionGroup);\r\n this._core.rerender();\r\n }\r\n\r\n private addSelectedObjectsToSelectionGroup(): void {\r\n const selectedObjects = this._core.store.selectedObjects;\r\n\r\n if (selectedObjects.length === 0) {\r\n return;\r\n }\r\n\r\n const selectionGroup = KritzelSelectionGroup.create(this._core);\r\n selectedObjects.forEach(o => {\r\n selectionGroup.addOrRemove(o);\r\n o.isSelected = false;\r\n });\r\n\r\n selectionGroup.isSelected = true;\r\n\r\n if (selectionGroup.length === 1) {\r\n selectionGroup.rotation = selectionGroup.objects[0].rotation;\r\n }\r\n\r\n this._core.addSelectionGroup(selectionGroup);\r\n this._core.rerender();\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"selection.handler.js","sourceRoot":"","sources":["../../../src/classes/handlers/selection.handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { KritzelEventHelper } from '../../helpers/event.helper';\r\nimport { KritzelSelectionBox } from '../objects/selection-box.class';\r\nimport { KritzelSelectionGroup } from '../objects/selection-group.class';\r\nimport { KritzelGroup } from '../objects/group.class';\r\nimport { KritzelBaseHandler } from './base.handler';\r\nimport { KritzelBaseObject } from '../objects/base-object.class';\r\nimport { KritzelCore } from '../core/core.class';\r\n\r\nexport class KritzelSelectionHandler extends KritzelBaseHandler {\r\n startX: number;\r\n startY: number;\r\n\r\n touchStartX: number = 0;\r\n touchStartY: number = 0;\r\n\r\n touchStartTimeout: any = null;\r\n\r\n get isSelectionClick() {\r\n const selectionBox = this._core.store.selectionBox;\r\n return selectionBox && selectionBox.width === 0 && selectionBox.height === 0;\r\n }\r\n\r\n get isSelectionDrag() {\r\n const selectionBox = this._core.store.selectionBox;\r\n return selectionBox && (selectionBox.width > 0 || selectionBox.height > 0);\r\n }\r\n\r\n constructor(core: KritzelCore) {\r\n super(core);\r\n }\r\n\r\n handlePointerDown(event: PointerEvent) {\r\n if (event.pointerType === 'mouse') {\r\n if (KritzelEventHelper.isLeftClick(event) && !this._core.store.selectionGroup) {\r\n this.startMouseSelection(event);\r\n }\r\n }\r\n\r\n if (event.pointerType === 'touch') {\r\n this.touchStartTimeout = setTimeout(() => {\r\n if (this._core.store.state.pointers.size === 1 && !this._core.store.state.isScaling && !this._core.store.selectionGroup) {\r\n this.startTouchSelection();\r\n this.updateTouchSelection();\r\n }\r\n }, 80);\r\n }\r\n }\r\n\r\n handlePointerMove(event: PointerEvent) {\r\n if (event.pointerType === 'mouse') {\r\n if (this._core.store.state.isSelecting) {\r\n this.updateMouseSelection(event);\r\n }\r\n }\r\n\r\n if (event.pointerType === 'touch') {\r\n const activePointers = Array.from(this._core.store.state.pointers.values());\r\n\r\n const x = Math.round(activePointers[0].clientX - this._core.store.offsetX);\r\n const y = Math.round(activePointers[0].clientY - this._core.store.offsetY);\r\n\r\n const moveDeltaX = Math.abs(x - this.touchStartX);\r\n const moveDeltaY = Math.abs(y - this.touchStartY);\r\n const moveThreshold = 5;\r\n\r\n if ((moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) && this._core.store.state.isSelecting) {\r\n this.updateTouchSelection();\r\n\r\n clearTimeout(this._core.store.state.longTouchTimeout);\r\n }\r\n }\r\n }\r\n\r\n handlePointerUp(event: PointerEvent) {\r\n if (event.pointerType === 'mouse') {\r\n if (KritzelEventHelper.isLeftClick(event)) {\r\n const hasObjectsMoved = this._core.store.state.hasObjectsChanged;\r\n const selectionGroup = this._core.store.selectionGroup;\r\n\r\n if (selectionGroup?.objects.length === 1 && hasObjectsMoved === false) {\r\n selectionGroup.objects[0].edit(event);\r\n }\r\n\r\n this._core.store.state.hasObjectsChanged = false;\r\n\r\n if (this._core.store.state.isSelecting) {\r\n if (this.isSelectionClick) {\r\n this.handleSelectionClick(event);\r\n }\r\n\r\n if (this.isSelectionDrag) {\r\n this.updateMouseSelection(event);\r\n this.addSelectedObjectsToSelectionGroup();\r\n this.removeSelectionBox();\r\n }\r\n\r\n this._core.engine.emitObjectsChange();\r\n }\r\n }\r\n }\r\n\r\n if (event.pointerType === 'touch') {\r\n clearTimeout(this.touchStartTimeout);\r\n\r\n const hasObjectsMoved = this._core.store.state.hasObjectsChanged;\r\n const selectionGroup = this._core.store.selectionGroup;\r\n\r\n if (selectionGroup?.objects.length === 1 && hasObjectsMoved === false) {\r\n selectionGroup.objects[0].edit(event);\r\n }\r\n\r\n this._core.store.state.hasObjectsChanged = false;\r\n\r\n if (this._core.store.state.isSelecting) {\r\n if (this.isSelectionClick) {\r\n this.handleSelectionClick(event);\r\n }\r\n\r\n if (this.isSelectionDrag) {\r\n this.updateTouchSelection();\r\n this.addSelectedObjectsToSelectionGroup();\r\n this.removeSelectionBox();\r\n }\r\n\r\n this._core.engine.emitObjectsChange();\r\n this._core.store.state.skipContextMenu = false;\r\n }\r\n }\r\n }\r\n\r\n private removeSelectionBox(): void {\r\n this._core.store.state.isSelecting = false;\r\n this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox);\r\n }\r\n\r\n private startMouseSelection(event: MouseEvent): void {\r\n let clientX, clientY;\r\n\r\n clientX = event.clientX - this._core.store.offsetX;\r\n clientY = event.clientY - this._core.store.offsetY;\r\n\r\n const selectionBox = KritzelSelectionBox.create(this._core);\r\n\r\n this.startX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;\r\n this.startY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;\r\n\r\n selectionBox.translateX = this.startX;\r\n selectionBox.translateY = this.startY;\r\n\r\n this._core.store.state.isSelecting = true;\r\n\r\n this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || o instanceof KritzelSelectionGroup);\r\n this._core.store.state.objects.insert(selectionBox);\r\n }\r\n\r\n private startTouchSelection(): void {\r\n const activePointers = Array.from(this._core.store.state.pointers.values());\r\n const firstTouch = activePointers[0];\r\n\r\n if (!firstTouch) {\r\n return;\r\n }\r\n\r\n let clientX, clientY;\r\n\r\n clientX = Math.round(firstTouch.clientX - this._core.store.offsetX);\r\n clientY = Math.round(firstTouch.clientY - this._core.store.offsetY);\r\n this.touchStartX = clientX;\r\n this.touchStartY = clientY;\r\n\r\n const selectionBox = KritzelSelectionBox.create(this._core);\r\n\r\n this.startX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;\r\n this.startY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;\r\n\r\n selectionBox.translateX = this.startX;\r\n selectionBox.translateY = this.startY;\r\n\r\n this._core.store.state.isSelecting = true;\r\n\r\n this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || o instanceof KritzelSelectionGroup);\r\n this._core.store.state.objects.insert(selectionBox);\r\n }\r\n\r\n private updateMouseSelection(event: MouseEvent): void {\r\n let clientX, clientY;\r\n\r\n clientX = event.clientX - this._core.store.offsetX;\r\n clientY = event.clientY - this._core.store.offsetY;\r\n\r\n const selectionBox = this._core.store.selectionBox;\r\n\r\n if (selectionBox) {\r\n const currentX = (clientX - this._core.store.state.translateX) / selectionBox.scale;\r\n const currentY = (clientY - this._core.store.state.translateY) / selectionBox.scale;\r\n\r\n const width = Math.abs(currentX - this.startX) * selectionBox.scale;\r\n const height = Math.abs(currentY - this.startY) * selectionBox.scale;\r\n\r\n selectionBox.width = width;\r\n selectionBox.height = height;\r\n selectionBox.translateX = Math.min(currentX, this.startX);\r\n selectionBox.translateY = Math.min(currentY, this.startY);\r\n\r\n if (width > 0 || height > 0) {\r\n this.updateSelectedObjects();\r\n } else {\r\n this.clearSelectionPreview();\r\n }\r\n }\r\n }\r\n\r\n private updateTouchSelection(): void {\r\n const activePointers = Array.from(this._core.store.state.pointers.values());\r\n const firstTouch = activePointers[0];\r\n\r\n if (!firstTouch) {\r\n return;\r\n }\r\n\r\n let clientX, clientY;\r\n\r\n clientX = Math.round(firstTouch.clientX - this._core.store.offsetX);\r\n clientY = Math.round(firstTouch.clientY - this._core.store.offsetY);\r\n\r\n const selectionBox = this._core.store.selectionBox;\r\n\r\n if (selectionBox) {\r\n const currentX = (clientX - this._core.store.state.translateX) / selectionBox.scale;\r\n const currentY = (clientY - this._core.store.state.translateY) / selectionBox.scale;\r\n\r\n const width = Math.abs(currentX - this.startX) * selectionBox.scale;\r\n const height = Math.abs(currentY - this.startY) * selectionBox.scale;\r\n\r\n selectionBox.width = width;\r\n selectionBox.height = height;\r\n selectionBox.translateX = Math.min(currentX, this.startX);\r\n selectionBox.translateY = Math.min(currentY, this.startY);\r\n\r\n if (width > 0 || height > 0) {\r\n this.updateSelectedObjects();\r\n } else {\r\n this.clearSelectionPreview();\r\n }\r\n }\r\n }\r\n\r\n private updateSelectedObjects(): void {\r\n const selectionBox = this._core.store.selectionBox;\r\n if (selectionBox) {\r\n this._core.store.allObjects\r\n .filter(o => !(o instanceof KritzelSelectionBox))\r\n .forEach(object => (object.isSelected = object.hitTestPolygon(selectionBox.rotatedPolygon)));\r\n }\r\n }\r\n\r\n private handleSelectionClick(event: PointerEvent): void {\r\n const selectedObject = this.getTopmostHitObject(event);\r\n\r\n this.clearSelectionPreview();\r\n\r\n this.addObjectToSelectionGroup(selectedObject);\r\n this.removeSelectionBox();\r\n }\r\n\r\n private getTopmostHitObject(event: PointerEvent): KritzelBaseObject<any> | null {\r\n const pointerX = this._core.store.state.pointerX;\r\n const pointerY = this._core.store.state.pointerY;\r\n const overlappingObjects = this._core.getObjectsFromPointerEvent(event, '.object');\r\n\r\n for (const object of overlappingObjects) {\r\n if (object.hitTest(pointerX, pointerY)) {\r\n return object;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private clearSelectionPreview(): void {\r\n this._core.store.allNonSelectionObjects.forEach(object => {\r\n object.isSelected = false;\r\n });\r\n }\r\n\r\n private addObjectToSelectionGroup(object: KritzelBaseObject): void {\r\n if (!object) {\r\n return;\r\n }\r\n\r\n // Resolve child objects to their parent groups\r\n const parentGroup = KritzelGroup.findParentGroup(this._core, object.id);\r\n const objectToSelect = parentGroup || object;\r\n\r\n objectToSelect.isSelected = false;\r\n\r\n const selectionGroup = KritzelSelectionGroup.create(this._core);\r\n selectionGroup.addOrRemove(objectToSelect);\r\n selectionGroup.isSelected = true;\r\n selectionGroup.rotation = objectToSelect.rotation;\r\n\r\n this._core.addSelectionGroup(selectionGroup);\r\n this._core.rerender();\r\n }\r\n\r\n private addSelectedObjectsToSelectionGroup(): void {\r\n const selectedObjects = this._core.store.selectedObjects;\r\n\r\n if (selectedObjects.length === 0) {\r\n return;\r\n }\r\n\r\n // Resolve child objects to their parent groups to avoid double-move\r\n const resolvedObjects = new Map<string, KritzelBaseObject<any>>();\r\n\r\n selectedObjects.forEach(obj => {\r\n // Check if this object is a child of a KritzelGroup\r\n const parentGroup = KritzelGroup.findParentGroup(this._core, obj.id);\r\n\r\n if (parentGroup) {\r\n // Add the parent group instead of the child\r\n resolvedObjects.set(parentGroup.id, parentGroup);\r\n } else {\r\n // Not a child of any group, add the object itself\r\n resolvedObjects.set(obj.id, obj);\r\n }\r\n\r\n obj.isSelected = false;\r\n });\r\n\r\n const selectionGroup = KritzelSelectionGroup.create(this._core);\r\n resolvedObjects.forEach(o => {\r\n selectionGroup.addOrRemove(o);\r\n });\r\n\r\n selectionGroup.isSelected = true;\r\n\r\n if (selectionGroup.length === 1) {\r\n selectionGroup.rotation = selectionGroup.objects[0].rotation;\r\n }\r\n\r\n this._core.addSelectionGroup(selectionGroup);\r\n this._core.rerender();\r\n }\r\n}\r\n"]}
@@ -0,0 +1,394 @@
1
+ import { KritzelBaseObject } from "./base-object.class";
2
+ /**
3
+ * KritzelGroup represents a permanent grouping of objects that act as a single unit.
4
+ *
5
+ * Unlike KritzelSelectionGroup (which is ephemeral and used for temporary multi-selection),
6
+ * KritzelGroup is persisted and saved with the workspace. Grouped objects move, resize,
7
+ * rotate, copy, and delete together as one unit.
8
+ *
9
+ * Key features:
10
+ * - Supports nested groups (groups can contain other groups)
11
+ * - Clicking any child selects the entire group
12
+ * - Can be ungrouped to restore children to top-level objects
13
+ */
14
+ export class KritzelGroup extends KritzelBaseObject {
15
+ __class__ = 'KritzelGroup';
16
+ /**
17
+ * IDs of child objects within this group.
18
+ * Children can be any KritzelBaseObject, including other KritzelGroups for nesting.
19
+ */
20
+ childIds = [];
21
+ /**
22
+ * Snapshots of child states for transformation operations (resize, rotate).
23
+ * Similar pattern to KritzelSelectionGroup.
24
+ */
25
+ unchangedChildSnapshots = new Map();
26
+ snapshotRotation = 0;
27
+ snapshotTranslateX = 0;
28
+ snapshotTranslateY = 0;
29
+ snapshotTotalWidth = 0;
30
+ snapshotTotalHeight = 0;
31
+ snapshotScale = 1;
32
+ /**
33
+ * Retrieves the actual child objects from the store by their IDs.
34
+ */
35
+ get children() {
36
+ return this.childIds
37
+ .map(id => {
38
+ const found = this._core.store.state.objects.filter(obj => obj.id === id);
39
+ return found.length > 0 ? found[0] : null;
40
+ })
41
+ .filter((obj) => obj !== null);
42
+ }
43
+ /**
44
+ * Returns the number of children in this group.
45
+ */
46
+ get length() {
47
+ return this.childIds.length;
48
+ }
49
+ /**
50
+ * Creates a new empty KritzelGroup.
51
+ */
52
+ static create(core) {
53
+ const group = new KritzelGroup();
54
+ group._core = core;
55
+ group.id = group.generateId();
56
+ group.workspaceId = core.store.state.activeWorkspace.id;
57
+ group.scale = core.store.state.scale;
58
+ group.zIndex = core.store.currentZIndex;
59
+ return group;
60
+ }
61
+ /**
62
+ * Creates a KritzelGroup from an array of objects.
63
+ * The objects are added as children and their bounding box is calculated.
64
+ */
65
+ static createFromObjects(core, objects) {
66
+ const group = KritzelGroup.create(core);
67
+ // Add all objects as children
68
+ objects.forEach(obj => {
69
+ group.childIds.push(obj.id);
70
+ });
71
+ // Calculate bounding box from children
72
+ group.refreshBoundingBox();
73
+ group.captureChildSnapshots();
74
+ return group;
75
+ }
76
+ /**
77
+ * Finds the parent KritzelGroup that contains the given object as a child.
78
+ * Returns null if the object is not a child of any group.
79
+ */
80
+ static findParentGroup(core, objectId) {
81
+ const allGroups = core.store.state.objects
82
+ .filter(obj => obj.__class__ === 'KritzelGroup');
83
+ for (const group of allGroups) {
84
+ if (group.childIds.includes(objectId)) {
85
+ return group;
86
+ }
87
+ }
88
+ return null;
89
+ }
90
+ /**
91
+ * Adds a child object to this group.
92
+ */
93
+ addChild(object) {
94
+ if (!this.childIds.includes(object.id)) {
95
+ this.childIds.push(object.id);
96
+ this.refreshBoundingBox();
97
+ this.captureChildSnapshots();
98
+ }
99
+ }
100
+ /**
101
+ * Removes a child object from this group.
102
+ */
103
+ removeChild(objectId) {
104
+ const index = this.childIds.indexOf(objectId);
105
+ if (index !== -1) {
106
+ this.childIds.splice(index, 1);
107
+ this.refreshBoundingBox();
108
+ this.captureChildSnapshots();
109
+ }
110
+ }
111
+ /**
112
+ * Ungroups this group, returning all children to top-level objects.
113
+ * The group itself should be removed after calling this.
114
+ */
115
+ ungroup() {
116
+ return this.children;
117
+ }
118
+ /**
119
+ * Finalizes the group after children have been positioned (e.g., after paste).
120
+ * Refreshes the bounding box and captures child snapshots.
121
+ */
122
+ finalize() {
123
+ this.refreshBoundingBox();
124
+ this.captureChildSnapshots();
125
+ }
126
+ /**
127
+ * Recalculates the group's bounding box based on its children.
128
+ */
129
+ refreshBoundingBox() {
130
+ if (this.children.length === 0) {
131
+ this.width = 0;
132
+ this.height = 0;
133
+ this.translateX = 0;
134
+ this.translateY = 0;
135
+ return;
136
+ }
137
+ if (this.children.length === 1) {
138
+ // Single child: inherit its bounding box
139
+ const child = this.children[0];
140
+ this.translateX = child.boundingBox.x;
141
+ this.translateY = child.boundingBox.y;
142
+ this.width = child.boundingBox.width * this.scale;
143
+ this.height = child.boundingBox.height * this.scale;
144
+ return;
145
+ }
146
+ // Multiple children: calculate encompassing bounding box
147
+ const rotation = this.rotation;
148
+ const cos = Math.cos(-rotation);
149
+ const sin = Math.sin(-rotation);
150
+ let minX = Infinity;
151
+ let maxX = -Infinity;
152
+ let minY = Infinity;
153
+ let maxY = -Infinity;
154
+ this.children.forEach(child => {
155
+ const polygon = child.rotatedPolygon;
156
+ const corners = [polygon.topLeft, polygon.topRight, polygon.bottomRight, polygon.bottomLeft];
157
+ corners.forEach(corner => {
158
+ // Rotate corner into local space (aligned with group rotation)
159
+ const rx = corner.x * cos - corner.y * sin;
160
+ const ry = corner.x * sin + corner.y * cos;
161
+ if (rx < minX)
162
+ minX = rx;
163
+ if (rx > maxX)
164
+ maxX = rx;
165
+ if (ry < minY)
166
+ minY = ry;
167
+ if (ry > maxY)
168
+ maxY = ry;
169
+ });
170
+ });
171
+ // Dimensions in world units (unrotated)
172
+ const worldWidth = maxX - minX;
173
+ const worldHeight = maxY - minY;
174
+ this.width = (worldWidth - this.padding) * this.scale;
175
+ this.height = (worldHeight - this.padding) * this.scale;
176
+ // Center of the box in rotated space
177
+ const cRx = (minX + maxX) / 2;
178
+ const cRy = (minY + maxY) / 2;
179
+ // Rotate center back to world space
180
+ const cosR = Math.cos(rotation);
181
+ const sinR = Math.sin(rotation);
182
+ const cx = cRx * cosR - cRy * sinR;
183
+ const cy = cRx * sinR + cRy * cosR;
184
+ this.translateX = cx - (this.width / this.scale + 2 * this.padding) / 2;
185
+ this.translateY = cy - (this.height / this.scale + 2 * this.padding) / 2;
186
+ }
187
+ /**
188
+ * Captures snapshots of child states for transformation operations.
189
+ */
190
+ captureChildSnapshots() {
191
+ this.unchangedChildSnapshots.clear();
192
+ this.snapshotRotation = this.rotation;
193
+ this.snapshotTranslateX = this.translateX;
194
+ this.snapshotTranslateY = this.translateY;
195
+ this.snapshotTotalWidth = this.totalWidth;
196
+ this.snapshotTotalHeight = this.totalHeight;
197
+ this.snapshotScale = this.scale || 1;
198
+ this.children.forEach(child => {
199
+ this.unchangedChildSnapshots.set(child.id, {
200
+ id: child.id,
201
+ translateX: child.translateX,
202
+ translateY: child.translateY,
203
+ rotation: child.rotation,
204
+ width: child.width,
205
+ height: child.height,
206
+ totalWidth: child.totalWidth,
207
+ totalHeight: child.totalHeight,
208
+ scale: child.scale,
209
+ });
210
+ });
211
+ }
212
+ // ─────────────────────────────────────────────────────────────────────────────
213
+ // TRANSFORMATION METHODS
214
+ // ─────────────────────────────────────────────────────────────────────────────
215
+ move(startX, startY, endX, endY) {
216
+ const deltaX = (startX - endX) / this._core.store.state.scale;
217
+ const deltaY = (startY - endY) / this._core.store.state.scale;
218
+ this.translateX += deltaX;
219
+ this.translateY += deltaY;
220
+ this._core.store.state.objects.transaction(() => {
221
+ this._core.store.state.objects.update(this);
222
+ this.children.forEach(child => {
223
+ child.move(startX, startY, endX, endY);
224
+ // Update any lines anchored to this child
225
+ this._core.anchorManager.updateAnchorsForObject(child.id);
226
+ });
227
+ });
228
+ // Update snapshots
229
+ this.unchangedChildSnapshots.forEach(snapshot => {
230
+ snapshot.translateX += deltaX;
231
+ snapshot.translateY += deltaY;
232
+ });
233
+ }
234
+ resize(x, y, width, height) {
235
+ const widthScaleFactor = width / this.width;
236
+ const heightScaleFactor = height / this.height;
237
+ // Calculate old center
238
+ const oldCenterX = this.translateX + this.totalWidth / 2 / this.scale;
239
+ const oldCenterY = this.translateY + this.totalHeight / 2 / this.scale;
240
+ // Calculate new center
241
+ const newTotalWidth = width + this.padding * 2;
242
+ const newTotalHeight = height + this.padding * 2;
243
+ const newCenterX = x + newTotalWidth / 2 / this.scale;
244
+ const newCenterY = y + newTotalHeight / 2 / this.scale;
245
+ const rotation = this.rotation;
246
+ const cos = Math.cos(-rotation);
247
+ const sin = Math.sin(-rotation);
248
+ const cosR = Math.cos(rotation);
249
+ const sinR = Math.sin(rotation);
250
+ this._core.store.state.objects.transaction(() => {
251
+ this.children.forEach(child => {
252
+ // Calculate child center
253
+ const childCenterX = child.translateX + child.totalWidth / 2 / child.scale;
254
+ const childCenterY = child.translateY + child.totalHeight / 2 / child.scale;
255
+ // Vector from old group center to child center
256
+ const dx = childCenterX - oldCenterX;
257
+ const dy = childCenterY - oldCenterY;
258
+ // Rotate to local space
259
+ const localX = dx * cos - dy * sin;
260
+ const localY = dx * sin + dy * cos;
261
+ // Scale in local space
262
+ const scaledLocalX = localX * widthScaleFactor;
263
+ const scaledLocalY = localY * heightScaleFactor;
264
+ // Rotate back to world space
265
+ const rotatedX = scaledLocalX * cosR - scaledLocalY * sinR;
266
+ const rotatedY = scaledLocalX * sinR + scaledLocalY * cosR;
267
+ // New child center
268
+ const newChildCenterX = newCenterX + rotatedX;
269
+ const newChildCenterY = newCenterY + rotatedY;
270
+ // Calculate relative rotation for scaling
271
+ const relativeRotation = child.rotation - rotation;
272
+ const cosRel = Math.cos(relativeRotation);
273
+ const sinRel = Math.sin(relativeRotation);
274
+ const newChildWidthScale = Math.sqrt(Math.pow(widthScaleFactor * cosRel, 2) + Math.pow(heightScaleFactor * sinRel, 2));
275
+ const newChildHeightScale = Math.sqrt(Math.pow(widthScaleFactor * sinRel, 2) + Math.pow(heightScaleFactor * cosRel, 2));
276
+ const updatedWidth = child.width * newChildWidthScale;
277
+ const updatedHeight = child.height * newChildHeightScale;
278
+ const updatedTotalWidth = updatedWidth + child.padding * 2;
279
+ const updatedTotalHeight = updatedHeight + child.padding * 2;
280
+ const updatedX = newChildCenterX - updatedTotalWidth / 2 / child.scale;
281
+ const updatedY = newChildCenterY - updatedTotalHeight / 2 / child.scale;
282
+ child.resize(updatedX, updatedY, updatedWidth, updatedHeight);
283
+ // Update anchored lines
284
+ this._core.anchorManager.updateAnchorsForObject(child.id);
285
+ });
286
+ this.refreshBoundingBox();
287
+ this.captureChildSnapshots();
288
+ this._core.store.state.objects.update(this);
289
+ });
290
+ }
291
+ rotate(value) {
292
+ this.rotation = value;
293
+ const centerX = this.translateX + this.totalWidth / 2 / this.scale;
294
+ const centerY = this.translateY + this.totalHeight / 2 / this.scale;
295
+ const angle = value - this.snapshotRotation;
296
+ const cos = Math.cos(angle);
297
+ const sin = Math.sin(angle);
298
+ this._core.store.state.objects.transaction(() => {
299
+ this._core.store.state.objects.update(this);
300
+ this.children.forEach(child => {
301
+ const unchangedSnapshot = this.unchangedChildSnapshots.get(child.id);
302
+ if (!unchangedSnapshot)
303
+ return;
304
+ const offsetX = this.getOffsetXToCenterFromSnapshot(unchangedSnapshot);
305
+ const offsetY = this.getOffsetYToCenterFromSnapshot(unchangedSnapshot);
306
+ const rotatedX = cos * offsetX - sin * offsetY;
307
+ const rotatedY = sin * offsetX + cos * offsetY;
308
+ child.translateX = centerX + rotatedX - child.totalWidth / 2 / child.scale;
309
+ child.translateY = centerY + rotatedY - child.totalHeight / 2 / child.scale;
310
+ child.rotate(this.children.length === 1 ? value : unchangedSnapshot.rotation + angle);
311
+ });
312
+ });
313
+ }
314
+ getOffsetXToCenterFromSnapshot(snapshot) {
315
+ const childCenterX = snapshot.translateX + snapshot.totalWidth / snapshot.scale / 2;
316
+ const groupScale = this.snapshotScale || this.scale || 1;
317
+ const groupCenterX = this.snapshotTranslateX + this.snapshotTotalWidth / groupScale / 2;
318
+ return childCenterX - groupCenterX;
319
+ }
320
+ getOffsetYToCenterFromSnapshot(snapshot) {
321
+ const childCenterY = snapshot.translateY + snapshot.totalHeight / snapshot.scale / 2;
322
+ const groupScale = this.snapshotScale || this.scale || 1;
323
+ const groupCenterY = this.snapshotTranslateY + this.snapshotTotalHeight / groupScale / 2;
324
+ return childCenterY - groupCenterY;
325
+ }
326
+ // ─────────────────────────────────────────────────────────────────────────────
327
+ // HIT TESTING
328
+ // ─────────────────────────────────────────────────────────────────────────────
329
+ hitTest(x, y) {
330
+ // Check if point is inside any child
331
+ return this.children.some(child => child.hitTest(x, y));
332
+ }
333
+ hitTestPolygon(polygon) {
334
+ // Check if polygon intersects with any child
335
+ return this.children.some(child => child.hitTestPolygon(polygon));
336
+ }
337
+ // ─────────────────────────────────────────────────────────────────────────────
338
+ // COPY & SERIALIZATION
339
+ // ─────────────────────────────────────────────────────────────────────────────
340
+ copy() {
341
+ const copiedGroup = KritzelGroup.create(this._core);
342
+ // Deep copy all children but DON'T add to store yet
343
+ // Store the copied children temporarily for paste() to handle
344
+ const copiedChildren = [];
345
+ this.children
346
+ .sort((a, b) => a.zIndex - b.zIndex)
347
+ .forEach(child => {
348
+ const copiedChild = child.copy();
349
+ copiedChildren.push(copiedChild);
350
+ copiedGroup.childIds.push(copiedChild.id);
351
+ });
352
+ // Store copied children on the group for paste() to access
353
+ copiedGroup._pendingChildren = copiedChildren;
354
+ // Copy group properties
355
+ copiedGroup.rotation = this.rotation;
356
+ copiedGroup.translateX = this.translateX;
357
+ copiedGroup.translateY = this.translateY;
358
+ copiedGroup.width = this.width;
359
+ copiedGroup.height = this.height;
360
+ return copiedGroup;
361
+ }
362
+ serialize() {
363
+ const { _core, _elementRef, element, totalWidth, totalHeight, unchangedChildSnapshots, ...remainingProps } = this;
364
+ const clonedProps = structuredClone(remainingProps);
365
+ // Convert Map to plain object for serialization
366
+ clonedProps.unchangedChildSnapshots = Object.fromEntries(this.unchangedChildSnapshots);
367
+ return clonedProps;
368
+ }
369
+ deserialize(object) {
370
+ super.deserialize(object);
371
+ // Restore the Map from serialized object
372
+ if (object.unchangedChildSnapshots) {
373
+ this.unchangedChildSnapshots = new Map(Object.entries(object.unchangedChildSnapshots));
374
+ }
375
+ return this;
376
+ }
377
+ update() {
378
+ this._core.store.state.objects.update(this);
379
+ }
380
+ /**
381
+ * Updates the workspace ID for this group and all its children.
382
+ */
383
+ updateWorkspaceId(workspaceId) {
384
+ this.workspaceId = workspaceId;
385
+ this.children.forEach(child => {
386
+ child.workspaceId = workspaceId;
387
+ // Recursively update nested groups
388
+ if (child instanceof KritzelGroup) {
389
+ child.updateWorkspaceId(workspaceId);
390
+ }
391
+ });
392
+ }
393
+ }
394
+ //# sourceMappingURL=group.class.js.map