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,97 @@
1
+ import { KritzelImage } from "../objects/image.class";
2
+ import { KritzelLine } from "../objects/line.class";
3
+ import { KritzelPath } from "../objects/path.class";
4
+ import { KritzelShape } from "../objects/shape.class";
5
+ import { KritzelSelectionGroup } from "../objects/selection-group.class";
6
+ import { KritzelGroup } from "../objects/group.class";
7
+ import { KritzelText } from "../objects/text.class";
8
+ import { KritzelBrushTool } from "../tools/brush-tool.class";
9
+ import { KritzelEraserTool } from "../tools/eraser-tool.class";
10
+ import { KritzelImageTool } from "../tools/image-tool.class";
11
+ import { KritzelLineTool } from "../tools/line-tool.class";
12
+ import { KritzelSelectionTool } from "../tools/selection-tool.class";
13
+ import { KritzelTextTool } from "../tools/text-tool.class";
14
+ import { KritzelShapeTool } from "../tools/shape-tool.class";
15
+ import { KritzelCustomElement } from "../objects/custom-element.class";
16
+ import { KritzelWorkspace } from "../..";
17
+ export class KritzelReviver {
18
+ constructor(core) {
19
+ this._core = core;
20
+ }
21
+ revive(obj) {
22
+ if (obj && typeof obj === 'object') {
23
+ if (obj.__class__) {
24
+ let revivedObj;
25
+ switch (obj.__class__) {
26
+ case 'KritzelPath':
27
+ revivedObj = KritzelPath.create(this._core).deserialize(obj);
28
+ break;
29
+ case 'KritzelLine':
30
+ revivedObj = KritzelLine.create(this._core).deserialize(obj);
31
+ break;
32
+ case 'KritzelText':
33
+ revivedObj = KritzelText.create(this._core, obj.fontSize, obj.fontFamily).deserialize(obj);
34
+ break;
35
+ case 'KritzelShape':
36
+ revivedObj = KritzelShape.create(this._core, {
37
+ shapeType: obj.shapeType,
38
+ fillColor: obj.fillColor,
39
+ strokeColor: obj.strokeColor,
40
+ strokeWidth: obj.strokeWidth,
41
+ fontSize: obj.fontSize,
42
+ fontFamily: obj.fontFamily,
43
+ fontColor: obj.fontColor,
44
+ }).deserialize(obj);
45
+ break;
46
+ case 'KritzelImage':
47
+ revivedObj = KritzelImage.create(this._core).deserialize(obj);
48
+ break;
49
+ case 'KritzelCustomElement':
50
+ revivedObj = KritzelCustomElement.create(this._core).deserialize(obj);
51
+ break;
52
+ case 'KritzelSelectionGroup':
53
+ revivedObj = KritzelSelectionGroup.create(this._core).deserialize(obj);
54
+ break;
55
+ case 'KritzelGroup':
56
+ revivedObj = KritzelGroup.create(this._core).deserialize(obj);
57
+ break;
58
+ case 'KritzelWorkspace':
59
+ revivedObj = KritzelWorkspace.create(this._core, obj).deserialize(obj);
60
+ break;
61
+ case 'KritzelBrushTool':
62
+ revivedObj = new KritzelBrushTool(this._core);
63
+ break;
64
+ case 'KritzelEraserTool':
65
+ revivedObj = new KritzelEraserTool(this._core);
66
+ break;
67
+ case 'KritzelImageTool':
68
+ revivedObj = new KritzelImageTool(this._core);
69
+ break;
70
+ case 'KritzelSelectionTool':
71
+ revivedObj = new KritzelSelectionTool(this._core);
72
+ break;
73
+ case 'KritzelTextTool':
74
+ revivedObj = new KritzelTextTool(this._core);
75
+ break;
76
+ case 'KritzelLineTool':
77
+ revivedObj = new KritzelLineTool(this._core);
78
+ break;
79
+ case 'KritzelShapeTool':
80
+ revivedObj = new KritzelShapeTool(this._core);
81
+ break;
82
+ default:
83
+ revivedObj = obj;
84
+ }
85
+ return revivedObj;
86
+ }
87
+ const newObj = Array.isArray(obj) ? [] : {};
88
+ for (const key in obj) {
89
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
90
+ newObj[key] = this.revive(obj[key]);
91
+ }
92
+ }
93
+ return newObj;
94
+ }
95
+ return obj;
96
+ }
97
+ }
@@ -0,0 +1,153 @@
1
+ import { KritzelSelectionGroup } from '../objects/selection-group.class';
2
+ import { KritzelSelectionBox } from '../objects/selection-box.class';
3
+ import { KritzelText } from '../objects/text.class';
4
+ import { KritzelShape } from '../objects/shape.class';
5
+ import { KritzelPath } from '../objects/path.class';
6
+ import { KritzelLine } from '../objects/line.class';
7
+ import { KritzelObjectMap } from '../structures/object-map.structure';
8
+ export class KritzelStore {
9
+ get state() {
10
+ return this._state;
11
+ }
12
+ get currentZIndex() {
13
+ return Math.max(0, ...this._state.objects.filter(o => !(o instanceof KritzelSelectionGroup) && !(o instanceof KritzelSelectionBox)).map(o => o.zIndex)) + 1;
14
+ }
15
+ get totalObjectCount() {
16
+ return this._state.objects.totalCount;
17
+ }
18
+ get allObjects() {
19
+ return this._state.objects.allObjects();
20
+ }
21
+ get objectsInViewport() {
22
+ const viewportBounds = {
23
+ x: -this._state.translateX / this._state.scale,
24
+ y: -this._state.translateY / this._state.scale,
25
+ z: this._state.scale,
26
+ width: this._state.viewportWidth / this._state.scale,
27
+ height: this._state.viewportHeight / this._state.scale,
28
+ depth: 100,
29
+ };
30
+ return this._state.objects
31
+ .query(viewportBounds)
32
+ .filter(obj => !(obj instanceof KritzelSelectionGroup) && !(obj instanceof KritzelSelectionBox))
33
+ .sort((a, b) => a.zIndex - b.zIndex);
34
+ }
35
+ get objectsToRender() {
36
+ const objects = this.objectsInViewport;
37
+ // Add selection objects explicitly since they are filtered out of objectsInViewport
38
+ const selectionGroup = this.selectionGroup;
39
+ if (selectionGroup) {
40
+ objects.push(selectionGroup);
41
+ }
42
+ const selectionBox = this.selectionBox;
43
+ if (selectionBox) {
44
+ objects.push(selectionBox);
45
+ }
46
+ // Sort combined list by zIndex to ensure correct rendering order
47
+ // This is fast since objectsInViewport is already small compared to allObjects
48
+ return objects.sort((a, b) => a.zIndex - b.zIndex);
49
+ }
50
+ get allNonSelectionObjects() {
51
+ return this._state.objects.allObjects().filter(o => !(o instanceof KritzelSelectionGroup) && !(o instanceof KritzelSelectionBox));
52
+ }
53
+ get selectedObjects() {
54
+ return this.allObjects.filter(o => !(o instanceof KritzelSelectionGroup)).filter(o => o.isSelected);
55
+ }
56
+ get selectionBox() {
57
+ if (this._selectionBoxCacheValid) {
58
+ return this._cachedSelectionBox;
59
+ }
60
+ const selectionBoxes = this._state.objects.filter(o => o instanceof KritzelSelectionBox);
61
+ this._cachedSelectionBox = selectionBoxes.length > 0 ? selectionBoxes[0] : null;
62
+ this._selectionBoxCacheValid = true;
63
+ return this._cachedSelectionBox;
64
+ }
65
+ get selectionGroup() {
66
+ if (this._selectionGroupCacheValid) {
67
+ return this._cachedSelectionGroup;
68
+ }
69
+ const selectionGroups = this._state.objects.filter(o => o instanceof KritzelSelectionGroup);
70
+ this._cachedSelectionGroup = selectionGroups.length > 0 ? selectionGroups[0] : null;
71
+ this._selectionGroupCacheValid = true;
72
+ return this._cachedSelectionGroup;
73
+ }
74
+ /**
75
+ * Invalidate cached selection objects. Call this when selection objects are inserted or removed.
76
+ */
77
+ invalidateSelectionCache() {
78
+ this._selectionBoxCacheValid = false;
79
+ this._selectionGroupCacheValid = false;
80
+ }
81
+ /**
82
+ * Directly set the cached selection box reference for O(1) access.
83
+ * Use this when creating the selection box to avoid a filter lookup.
84
+ */
85
+ setSelectionBox(box) {
86
+ this._cachedSelectionBox = box;
87
+ this._selectionBoxCacheValid = true;
88
+ }
89
+ /**
90
+ * Directly set the cached selection group reference for O(1) access.
91
+ * Use this when creating the selection group to avoid a filter lookup.
92
+ */
93
+ setSelectionGroup(group) {
94
+ this._cachedSelectionGroup = group;
95
+ this._selectionGroupCacheValid = true;
96
+ }
97
+ get activeText() {
98
+ const activeTexts = this._state.objects.filter(o => o instanceof KritzelText && o.isEditing);
99
+ return activeTexts.length > 0 ? activeTexts[0] : null;
100
+ }
101
+ get activeShape() {
102
+ const activeShapes = this._state.objects.filter(o => o instanceof KritzelShape && o.isEditing);
103
+ return activeShapes.length > 0 ? activeShapes[0] : null;
104
+ }
105
+ get currentPath() {
106
+ const drawingPaths = this._state.objects.filter(o => o instanceof KritzelPath && o.isCompleted === false);
107
+ return drawingPaths.length > 0 ? drawingPaths[0] : null;
108
+ }
109
+ get currentLine() {
110
+ const drawingLines = this._state.objects.filter(o => o instanceof KritzelLine && o.isCompleted === false);
111
+ return drawingLines.length > 0 ? drawingLines[0] : null;
112
+ }
113
+ get offsetX() {
114
+ return this._state.host.getBoundingClientRect().left;
115
+ }
116
+ get offsetY() {
117
+ return this._state.host.getBoundingClientRect().top;
118
+ }
119
+ get isDisabled() {
120
+ return this._state.isEnabled === false || this._state.isReady === false || this._state.activeWorkspace === null;
121
+ }
122
+ get isPointerDown() {
123
+ return this._state.pointers.size > 0;
124
+ }
125
+ constructor(state) {
126
+ this._listeners = new Map();
127
+ // Cached references for O(1) access to frequently accessed special objects
128
+ this._cachedSelectionBox = null;
129
+ this._cachedSelectionGroup = null;
130
+ this._selectionBoxCacheValid = false;
131
+ this._selectionGroupCacheValid = false;
132
+ this._state = state;
133
+ this._state.objects = new KritzelObjectMap();
134
+ }
135
+ onStateChange(property, listener) {
136
+ if (!this._listeners.has(property)) {
137
+ this._listeners.set(property, new Set());
138
+ }
139
+ this._listeners.get(property).add(listener);
140
+ }
141
+ getState(property) {
142
+ return this._state[property];
143
+ }
144
+ setState(property, value) {
145
+ const oldValue = this._state[property];
146
+ if (oldValue !== value) {
147
+ this._state[property] = value;
148
+ if (this._listeners.has(property)) {
149
+ this._listeners.get(property).forEach(listener => listener(value, oldValue, String(property)));
150
+ }
151
+ }
152
+ }
153
+ }
@@ -0,0 +1,311 @@
1
+ import { KritzelMouseButton } from '../../enums/event-button.enum';
2
+ import { KritzelSelectionBox } from '../objects/selection-box.class';
3
+ import { debounce } from 'lodash';
4
+ export class KritzelViewport {
5
+ constructor(core, host) {
6
+ this._animationFrameId = null;
7
+ this.initialTouchDistance = 0;
8
+ this.startX = 0;
9
+ this.startY = 0;
10
+ this._core = core;
11
+ this._core.store.state.host = host;
12
+ this._core.store.state.viewportWidth = host.clientWidth;
13
+ this._core.store.state.viewportHeight = host.clientHeight;
14
+ this._core.store.state.startX = 0;
15
+ this._core.store.state.startY = 0;
16
+ this._core.store.state.translateX = 0;
17
+ this._core.store.state.translateY = 0;
18
+ this._debounceUpdate = debounce(() => {
19
+ this._core.updateWorkspaceViewport(this._core.store.state.translateX, this._core.store.state.translateY, this._core.store.state.scale);
20
+ }, 300);
21
+ this._debounceEndScaling = debounce(() => {
22
+ this._core.store.state.isScaling = false;
23
+ this._core.rerender();
24
+ }, 100);
25
+ }
26
+ /**
27
+ * Cancels any pending debounced viewport updates.
28
+ * Should be called before switching workspaces to prevent the old workspace's
29
+ * viewport state from being saved to the new workspace.
30
+ */
31
+ cancelPendingUpdates() {
32
+ this._debounceUpdate.cancel();
33
+ }
34
+ handleResize() {
35
+ this._core.store.state.viewportWidth = this._core.store.state.host.clientWidth;
36
+ this._core.store.state.viewportHeight = this._core.store.state.host.clientHeight;
37
+ this._core.store.state.hasViewportChanged = true;
38
+ this._core.rerender();
39
+ }
40
+ handlePointerDown(event) {
41
+ // Cancel any ongoing viewport animation when user starts interacting
42
+ this.cancelViewportAnimation();
43
+ if (event.pointerType === 'mouse') {
44
+ const adjustedClientX = event.clientX - this._core.store.offsetX;
45
+ const adjustedClientY = event.clientY - this._core.store.offsetY;
46
+ if (event.button === KritzelMouseButton.Right) {
47
+ this._core.store.state.isPanning = true;
48
+ this._core.store.state.startX = adjustedClientX;
49
+ this._core.store.state.startY = adjustedClientY;
50
+ }
51
+ }
52
+ if (event.pointerType === 'touch' || event.pointerType === 'pen') {
53
+ const activePointers = Array.from(this._core.store.state.pointers.values());
54
+ if (activePointers.length === 2) {
55
+ const currentPath = this._core.store.currentPath;
56
+ if (currentPath) {
57
+ this._core.store.state.objects.remove(obj => obj.id === currentPath.id);
58
+ }
59
+ // Clear selection box when scaling starts to prevent it from remaining on screen
60
+ if (this._core.store.state.isSelecting) {
61
+ this._core.store.state.isSelecting = false;
62
+ this._core.store.state.objects.remove(obj => obj instanceof KritzelSelectionBox);
63
+ this._core.store.setSelectionBox(null);
64
+ // Clear selection preview state from objects - use selectedObjects for efficiency
65
+ this._core.store.selectedObjects.forEach(object => {
66
+ object.isSelected = false;
67
+ });
68
+ }
69
+ this._core.store.state.isScaling = true;
70
+ const firstTouchX = activePointers[0].clientX - this._core.store.offsetX;
71
+ const firstTouchY = activePointers[0].clientY - this._core.store.offsetY;
72
+ const secondTouchX = activePointers[1].clientX - this._core.store.offsetX;
73
+ const secondTouchY = activePointers[1].clientY - this._core.store.offsetY;
74
+ this.initialTouchDistance = Math.sqrt(Math.pow(firstTouchX - secondTouchX, 2) + Math.pow(firstTouchY - secondTouchY, 2));
75
+ this.startX = (firstTouchX + secondTouchX) / 2;
76
+ this.startY = (firstTouchY + secondTouchY) / 2;
77
+ this._core.rerender();
78
+ }
79
+ }
80
+ }
81
+ handlePointerMove(event) {
82
+ if (event.pointerType === 'mouse') {
83
+ const hostRect = this._core.store.state.host.getBoundingClientRect();
84
+ const xRelativeToHost = event.clientX - hostRect.left;
85
+ const yRelativeToHost = event.clientY - hostRect.top;
86
+ this._core.store.state.pointerX = (xRelativeToHost - this._core.store.state.translateX) / this._core.store.state.scale;
87
+ this._core.store.state.pointerY = (yRelativeToHost - this._core.store.state.translateY) / this._core.store.state.scale;
88
+ if (this._core.store.state.isPanning) {
89
+ const dx = xRelativeToHost - this._core.store.state.startX;
90
+ const dy = yRelativeToHost - this._core.store.state.startY;
91
+ this._core.store.state.translateX += dx;
92
+ this._core.store.state.translateY += dy;
93
+ this._core.store.state.startX = xRelativeToHost;
94
+ this._core.store.state.startY = yRelativeToHost;
95
+ this._core.store.state.hasViewportChanged = true;
96
+ this._core.store.state.skipContextMenu = true;
97
+ this._core.rerender();
98
+ this._debounceUpdate();
99
+ }
100
+ }
101
+ if (event.pointerType === 'touch' || event.pointerType === 'pen') {
102
+ const hostRect = this._core.store.state.host.getBoundingClientRect();
103
+ const xRelativeToHost = event.clientX - hostRect.left;
104
+ const yRelativeToHost = event.clientY - hostRect.top;
105
+ this._core.store.state.pointerX = (xRelativeToHost - this._core.store.state.translateX) / this._core.store.state.scale;
106
+ this._core.store.state.pointerY = (yRelativeToHost - this._core.store.state.translateY) / this._core.store.state.scale;
107
+ const activePointers = Array.from(this._core.store.state.pointers.values());
108
+ if (activePointers.length === 2) {
109
+ const firstTouchX = activePointers[0].clientX - this._core.store.offsetX;
110
+ const firstTouchY = activePointers[0].clientY - this._core.store.offsetY;
111
+ const secondTouchX = activePointers[1].clientX - this._core.store.offsetX;
112
+ const secondTouchY = activePointers[1].clientY - this._core.store.offsetY;
113
+ const currentTouchDistance = Math.sqrt(Math.pow(firstTouchX - secondTouchX, 2) + Math.pow(firstTouchY - secondTouchY, 2));
114
+ const midpointX = (firstTouchX + secondTouchX) / 2;
115
+ const midpointY = (firstTouchY + secondTouchY) / 2;
116
+ const scaleRatio = currentTouchDistance / this.initialTouchDistance;
117
+ const newScale = this._core.store.state.scale * scaleRatio;
118
+ if (newScale > this._core.store.state.scaleMax || newScale < this._core.store.state.scaleMin) {
119
+ this._core.store.state.translateX = this._core.store.state.translateX + midpointX - this.startX;
120
+ this._core.store.state.translateY = this._core.store.state.translateY + midpointY - this.startY;
121
+ }
122
+ else {
123
+ const translateXAdjustment = (midpointX - this._core.store.state.translateX) * (scaleRatio - 1);
124
+ const translateYAdjustment = (midpointY - this._core.store.state.translateY) * (scaleRatio - 1);
125
+ this._core.store.state.translateX = this._core.store.state.translateX + midpointX - this.startX - translateXAdjustment;
126
+ this._core.store.state.translateY = this._core.store.state.translateY + midpointY - this.startY - translateYAdjustment;
127
+ this._core.store.state.scale = newScale;
128
+ this.initialTouchDistance = currentTouchDistance;
129
+ }
130
+ this.startX = midpointX;
131
+ this.startY = midpointY;
132
+ this._core.store.state.hasViewportChanged = true;
133
+ this._core.rerender();
134
+ this._debounceUpdate();
135
+ }
136
+ }
137
+ }
138
+ handlePointerUp(event) {
139
+ if (event.pointerType === 'mouse') {
140
+ if (this._core.store.state.isPanning) {
141
+ this._core.store.state.isPanning = false;
142
+ this._core.rerender();
143
+ }
144
+ }
145
+ if (event.pointerType === 'touch' || event.pointerType === 'pen') {
146
+ if (this._core.store.state.pointers.size === 0) {
147
+ this._debounceEndScaling();
148
+ }
149
+ }
150
+ }
151
+ handleWheel(event) {
152
+ // Cancel any ongoing viewport animation when user scrolls
153
+ this.cancelViewportAnimation();
154
+ if (event.ctrlKey) {
155
+ this.handleZoom(event);
156
+ }
157
+ else {
158
+ this.handlePan(event);
159
+ }
160
+ }
161
+ centerInViewport(object) {
162
+ const { scale, viewportWidth, viewportHeight } = this._core.store.state;
163
+ const { x, y, width, height } = object.rotatedBoundingBox;
164
+ const objectCenterX = x + width / 2;
165
+ const objectCenterY = y + height / 2;
166
+ this._core.store.state.translateX = viewportWidth / 2 - objectCenterX * scale;
167
+ this._core.store.state.translateY = viewportHeight / 2 - objectCenterY * scale;
168
+ this._core.store.state.hasViewportChanged = true;
169
+ this._core.rerender();
170
+ this._debounceUpdate();
171
+ }
172
+ centerFitInViewport(object) {
173
+ const scaleX = this._core.store.state.viewportWidth / (object.rotatedBoundingBox.width * 1.1);
174
+ const scaleY = this._core.store.state.viewportHeight / (object.rotatedBoundingBox.height * 1.1);
175
+ const newScale = Math.min(scaleX, scaleY, this._core.store.state.scaleMax);
176
+ const clampedScale = Math.max(newScale, this._core.store.state.scaleMin);
177
+ this._core.store.state.scale = clampedScale;
178
+ this.centerInViewport(object);
179
+ }
180
+ handleZoom(event) {
181
+ this._core.store.state.isScaling = true;
182
+ const rect = this._core.store.state.host.getBoundingClientRect();
183
+ const xRelativeToHost = event.clientX - rect.left;
184
+ const yRelativeToHost = event.clientY - rect.top;
185
+ this._core.store.state.pointerX = (xRelativeToHost - this._core.store.state.translateX) / this._core.store.state.scale;
186
+ this._core.store.state.pointerY = (yRelativeToHost - this._core.store.state.translateY) / this._core.store.state.scale;
187
+ const rawScaleFactor = 1 + (event.deltaY * -0.012);
188
+ const scaleFactor = Math.max(0.8, Math.min(1.2, rawScaleFactor));
189
+ const newScale = Math.min(this._core.store.state.scaleMax, Math.max(this._core.store.state.scaleMin, this._core.store.state.scale * scaleFactor));
190
+ const scaleRatio = newScale / this._core.store.state.scale;
191
+ const translateXAdjustment = (xRelativeToHost - this._core.store.state.translateX) * (scaleRatio - 1);
192
+ const translateYAdjustment = (yRelativeToHost - this._core.store.state.translateY) * (scaleRatio - 1);
193
+ this._core.store.state.scale = newScale;
194
+ this._core.store.state.translateX = this._core.store.state.translateX - translateXAdjustment;
195
+ this._core.store.state.translateY = this._core.store.state.translateY - translateYAdjustment;
196
+ // Apply horizontal pan from trackpad pinch+drag gestures
197
+ if (event.deltaX !== 0) {
198
+ this._core.store.state.translateX -= event.deltaX * 0.8;
199
+ }
200
+ this._core.store.state.hasViewportChanged = true;
201
+ this._core.rerender();
202
+ this._debounceUpdate();
203
+ this._debounceEndScaling();
204
+ }
205
+ handlePan(event) {
206
+ const panSpeed = 0.8;
207
+ this._core.store.state.translateX = this._core.store.state.translateX - event.deltaX * panSpeed;
208
+ this._core.store.state.translateY = this._core.store.state.translateY - event.deltaY * panSpeed;
209
+ this._core.store.state.hasViewportChanged = true;
210
+ this._core.rerender();
211
+ this._debounceUpdate();
212
+ }
213
+ /**
214
+ * Cancels any ongoing viewport animation.
215
+ * Called when user interacts with the canvas during animation.
216
+ */
217
+ cancelViewportAnimation() {
218
+ if (this._animationFrameId !== null) {
219
+ cancelAnimationFrame(this._animationFrameId);
220
+ this._animationFrameId = null;
221
+ }
222
+ }
223
+ /**
224
+ * Animates the viewport to the specified position and scale.
225
+ * @param targetTranslateX - Target X translation
226
+ * @param targetTranslateY - Target Y translation
227
+ * @param targetScale - Target scale
228
+ * @param duration - Animation duration in milliseconds (default 150)
229
+ */
230
+ animateViewportTo(targetTranslateX, targetTranslateY, targetScale, duration = 150) {
231
+ // Cancel any existing animation
232
+ this.cancelViewportAnimation();
233
+ const startTranslateX = this._core.store.state.translateX;
234
+ const startTranslateY = this._core.store.state.translateY;
235
+ const startScale = this._core.store.state.scale;
236
+ const startTime = performance.now();
237
+ const animate = (currentTime) => {
238
+ const elapsed = currentTime - startTime;
239
+ const progress = Math.min(elapsed / duration, 1);
240
+ // easeOutCubic easing function
241
+ const eased = 1 - Math.pow(1 - progress, 3);
242
+ this._core.store.state.translateX = startTranslateX + (targetTranslateX - startTranslateX) * eased;
243
+ this._core.store.state.translateY = startTranslateY + (targetTranslateY - startTranslateY) * eased;
244
+ this._core.store.state.scale = startScale + (targetScale - startScale) * eased;
245
+ this._core.store.state.hasViewportChanged = true;
246
+ this._core.rerender();
247
+ if (progress < 1) {
248
+ this._animationFrameId = requestAnimationFrame(animate);
249
+ }
250
+ else {
251
+ this._animationFrameId = null;
252
+ this._debounceUpdate();
253
+ }
254
+ };
255
+ this._animationFrameId = requestAnimationFrame(animate);
256
+ }
257
+ /**
258
+ * Centers and fits the nearest content objects in the viewport.
259
+ * Finds up to maxObjects closest objects to the current viewport center
260
+ * and animates the viewport to show them.
261
+ * @param maxObjects - Maximum number of objects to consider (default 20)
262
+ * @returns true if content was found and viewport is animating, false if no content exists
263
+ */
264
+ centerFitNearestContent(maxObjects = 20) {
265
+ const allObjects = this._core.store.allNonSelectionObjects;
266
+ if (allObjects.length === 0) {
267
+ return false;
268
+ }
269
+ // Calculate current viewport center in canvas coordinates
270
+ const viewportCenterX = -this._core.store.state.translateX / this._core.store.state.scale + this._core.store.state.viewportWidth / 2 / this._core.store.state.scale;
271
+ const viewportCenterY = -this._core.store.state.translateY / this._core.store.state.scale + this._core.store.state.viewportHeight / 2 / this._core.store.state.scale;
272
+ // Sort objects by distance from viewport center (using object center)
273
+ const objectsWithDistance = allObjects.map(obj => {
274
+ const bounds = obj.rotatedBoundingBox;
275
+ const objectCenterX = bounds.x + bounds.width / 2;
276
+ const objectCenterY = bounds.y + bounds.height / 2;
277
+ const distance = Math.sqrt(Math.pow(objectCenterX - viewportCenterX, 2) + Math.pow(objectCenterY - viewportCenterY, 2));
278
+ return { obj, distance };
279
+ });
280
+ objectsWithDistance.sort((a, b) => a.distance - b.distance);
281
+ // Take up to maxObjects closest objects
282
+ const nearestObjects = objectsWithDistance.slice(0, maxObjects).map(item => item.obj);
283
+ // Calculate combined bounds of nearest objects
284
+ let minX = Infinity;
285
+ let minY = Infinity;
286
+ let maxX = -Infinity;
287
+ let maxY = -Infinity;
288
+ for (const obj of nearestObjects) {
289
+ const bounds = obj.rotatedBoundingBox;
290
+ minX = Math.min(minX, bounds.x);
291
+ minY = Math.min(minY, bounds.y);
292
+ maxX = Math.max(maxX, bounds.x + bounds.width);
293
+ maxY = Math.max(maxY, bounds.y + bounds.height);
294
+ }
295
+ const contentWidth = maxX - minX;
296
+ const contentHeight = maxY - minY;
297
+ const contentCenterX = minX + contentWidth / 2;
298
+ const contentCenterY = minY + contentHeight / 2;
299
+ // Calculate scale to fit with 10% padding
300
+ const scaleX = this._core.store.state.viewportWidth / (contentWidth * 1.1);
301
+ const scaleY = this._core.store.state.viewportHeight / (contentHeight * 1.1);
302
+ const newScale = Math.min(scaleX, scaleY, this._core.store.state.scaleMax);
303
+ const clampedScale = Math.max(newScale, this._core.store.state.scaleMin);
304
+ // Calculate target translation to center content
305
+ const targetTranslateX = this._core.store.state.viewportWidth / 2 - contentCenterX * clampedScale;
306
+ const targetTranslateY = this._core.store.state.viewportHeight / 2 - contentCenterY * clampedScale;
307
+ // Animate to the target position
308
+ this.animateViewportTo(targetTranslateX, targetTranslateY, clampedScale);
309
+ return true;
310
+ }
311
+ }
@@ -0,0 +1,34 @@
1
+ export class KritzelWorkspace {
2
+ constructor(id, name, viewport = { translateX: 0, translateY: 0, scale: 1 }) {
3
+ this.__class__ = 'KritzelWorkspace';
4
+ this.id = id;
5
+ this.name = name;
6
+ this.createdAt = new Date();
7
+ this.updatedAt = new Date();
8
+ this.viewport = viewport;
9
+ }
10
+ static create(core, obj) {
11
+ const workspace = new KritzelWorkspace(obj.id, obj.name, obj.viewport);
12
+ workspace._core = core;
13
+ return workspace;
14
+ }
15
+ addObject(obj) {
16
+ this._core.engine.addObject(obj);
17
+ }
18
+ serialize() {
19
+ return {
20
+ __class__: this.__class__,
21
+ id: this.id,
22
+ name: this.name,
23
+ createdAt: this.createdAt.toISOString(),
24
+ updatedAt: this.updatedAt.toISOString(),
25
+ viewport: this.viewport,
26
+ };
27
+ }
28
+ deserialize(object) {
29
+ Object.assign(this, object);
30
+ this.createdAt = new Date(object.createdAt);
31
+ this.updatedAt = new Date(object.updatedAt);
32
+ return this;
33
+ }
34
+ }
@@ -0,0 +1,6 @@
1
+ export class KritzelBaseHandler {
2
+ constructor(core) {
3
+ this._core = core;
4
+ void this._core; // Avoid unused variable warning
5
+ }
6
+ }
@@ -0,0 +1,63 @@
1
+ import { KritzelSelectionGroup } from '../objects/selection-group.class';
2
+ import { KritzelBaseHandler } from './base.handler';
3
+ import { KritzelSelectionTool } from '../tools/selection-tool.class';
4
+ import { KritzelSelectionBox } from '../objects/selection-box.class';
5
+ export class KritzelContextMenuHandler extends KritzelBaseHandler {
6
+ constructor(core, globalContextMenuItems, objectContextMenuItems) {
7
+ super(core);
8
+ this.globalContextMenuItems = [];
9
+ this.objectContextMenuItems = [];
10
+ this.globalContextMenuItems = globalContextMenuItems;
11
+ this.objectContextMenuItems = objectContextMenuItems;
12
+ }
13
+ handleContextMenu(event) {
14
+ var _a;
15
+ if (!(this._core.store.state.activeTool instanceof KritzelSelectionTool)) {
16
+ return;
17
+ }
18
+ if (this._core.store.state.skipContextMenu) {
19
+ this._core.store.state.skipContextMenu = false;
20
+ return;
21
+ }
22
+ const selectionTool = this._core.store.state.activeTool;
23
+ (_a = selectionTool === null || selectionTool === void 0 ? void 0 : selectionTool.moveHandler) === null || _a === void 0 ? void 0 : _a.cancelPendingDrag();
24
+ if (this._core.store.selectionBox) {
25
+ this._core.store.state.objects.remove(object => object instanceof KritzelSelectionBox);
26
+ this._core.store.setSelectionBox(null);
27
+ this._core.store.state.isSelecting = false;
28
+ }
29
+ const selectedObject = this._core.getObjectFromPointerEvent(event, '.object');
30
+ if (selectedObject && !(selectedObject instanceof KritzelSelectionGroup) && !(selectedObject instanceof KritzelSelectionBox)) {
31
+ const selectionGroup = KritzelSelectionGroup.create(this._core);
32
+ selectionGroup.addOrRemove(selectedObject);
33
+ selectionGroup.isSelected = true;
34
+ selectionGroup.rotation = selectedObject.rotation;
35
+ this._core.store.state.isSelecting = false;
36
+ const currentSelectionGroup = this._core.store.selectionGroup;
37
+ if (currentSelectionGroup) {
38
+ this._core.removeSelectionGroup();
39
+ }
40
+ this._core.addSelectionGroup(selectionGroup);
41
+ this._core.rerender();
42
+ }
43
+ this._core.store.state.contextMenuItems = this._core.store.selectionGroup ? this.objectContextMenuItems : this.globalContextMenuItems;
44
+ let x = event.clientX - this._core.store.offsetX;
45
+ let y = event.clientY - this._core.store.offsetY;
46
+ const menuWidthEstimate = 150;
47
+ const menuHeightEstimate = 200;
48
+ const margin = 10;
49
+ if (x + menuWidthEstimate > window.innerWidth - margin) {
50
+ x = window.innerWidth - menuWidthEstimate - margin;
51
+ }
52
+ if (y + menuHeightEstimate > window.innerHeight - margin) {
53
+ y = window.innerHeight - menuHeightEstimate - margin;
54
+ }
55
+ x = Math.max(margin, x);
56
+ y = Math.max(margin, y);
57
+ this._core.store.state.contextMenuX = x;
58
+ this._core.store.state.contextMenuY = y;
59
+ this._core.store.state.isContextMenuVisible = true;
60
+ this._core.store.state.isEnabled = false;
61
+ this._core.rerender();
62
+ }
63
+ }