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,149 @@
1
+ export class KritzelGeometryHelper {
2
+ static doPolygonsIntersect(polygon1, polygon2) {
3
+ // 1. Convert polygons to array of points for easier processing
4
+ const points1 = [polygon1.bottomLeft, polygon1.bottomRight, polygon1.topRight, polygon1.topLeft];
5
+ const points2 = [polygon2.bottomLeft, polygon2.bottomRight, polygon2.topRight, polygon2.topLeft];
6
+ // 2. Check if any point of polygon1 is inside polygon2
7
+ for (const point of points1) {
8
+ if (this.isPointInPolygon(point, points2)) {
9
+ return true;
10
+ }
11
+ }
12
+ // 3. Check if any point of polygon2 is inside polygon1
13
+ for (const point of points2) {
14
+ if (this.isPointInPolygon(point, points1)) {
15
+ return true;
16
+ }
17
+ }
18
+ // 4. Check for edge intersections (more complex)
19
+ for (let i = 0; i < points1.length; i++) {
20
+ const p1a = points1[i];
21
+ const p1b = points1[(i + 1) % points1.length]; // Wrap around to the first point
22
+ for (let j = 0; j < points2.length; j++) {
23
+ const p2a = points2[j];
24
+ const p2b = points2[(j + 1) % points2.length];
25
+ if (this.intersectLines(p1a, p1b, p2a, p2b)) {
26
+ return true;
27
+ }
28
+ }
29
+ }
30
+ return false; // No intersection found
31
+ }
32
+ static isPointInPolygon(point, polygon) {
33
+ let inside = false;
34
+ for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
35
+ const xi = polygon[i].x, yi = polygon[i].y;
36
+ const xj = polygon[j].x, yj = polygon[j].y;
37
+ const intersect = yi > point.y !== yj > point.y && point.x < ((xj - xi) * (point.y - yi)) / (yj - yi) + xi;
38
+ if (intersect)
39
+ inside = !inside;
40
+ }
41
+ return inside;
42
+ }
43
+ static intersectLines(p1a, p1b, p2a, p2b) {
44
+ const det = (p1b.x - p1a.x) * (p2b.y - p2a.y) - (p1b.y - p1a.y) * (p2b.x - p2a.x);
45
+ if (det === 0) {
46
+ return false; // Lines are parallel
47
+ }
48
+ const t = ((p2a.x - p1a.x) * (p2b.y - p2a.y) - (p2a.y - p1a.y) * (p2b.x - p2a.x)) / det;
49
+ const u = -((p1a.x - p2a.x) * (p1b.y - p1a.y) - (p1a.y - p2a.y) * (p1b.x - p1a.x)) / det;
50
+ return t >= 0 && t <= 1 && u >= 0 && u <= 1;
51
+ }
52
+ /**
53
+ * Finds the intersection point between a line segment and a line segment.
54
+ * Returns the intersection point or null if no intersection.
55
+ */
56
+ static getLineIntersectionPoint(p1a, p1b, p2a, p2b) {
57
+ const det = (p1b.x - p1a.x) * (p2b.y - p2a.y) - (p1b.y - p1a.y) * (p2b.x - p2a.x);
58
+ if (det === 0) {
59
+ return null; // Lines are parallel
60
+ }
61
+ const t = ((p2a.x - p1a.x) * (p2b.y - p2a.y) - (p2a.y - p1a.y) * (p2b.x - p2a.x)) / det;
62
+ const u = -((p1a.x - p2a.x) * (p1b.y - p1a.y) - (p1a.y - p2a.y) * (p1b.x - p1a.x)) / det;
63
+ if (t >= 0 && t <= 1 && u >= 0 && u <= 1) {
64
+ return {
65
+ x: p1a.x + t * (p1b.x - p1a.x),
66
+ y: p1a.y + t * (p1b.y - p1a.y)
67
+ };
68
+ }
69
+ return null;
70
+ }
71
+ /**
72
+ * Finds the closest intersection point between a line segment (from lineStart to lineEnd)
73
+ * and a polygon. Returns the intersection point closest to lineStart, or null if no intersection.
74
+ */
75
+ static getLinePolygonIntersection(lineStart, lineEnd, polygon) {
76
+ const points = [polygon.topLeft, polygon.topRight, polygon.bottomRight, polygon.bottomLeft];
77
+ let closestIntersection = null;
78
+ let closestDistance = Infinity;
79
+ for (let i = 0; i < points.length; i++) {
80
+ const edgeStart = points[i];
81
+ const edgeEnd = points[(i + 1) % points.length];
82
+ const intersection = this.getLineIntersectionPoint(lineStart, lineEnd, edgeStart, edgeEnd);
83
+ if (intersection) {
84
+ const distance = Math.sqrt(Math.pow(intersection.x - lineStart.x, 2) +
85
+ Math.pow(intersection.y - lineStart.y, 2));
86
+ if (distance < closestDistance) {
87
+ closestDistance = distance;
88
+ closestIntersection = intersection;
89
+ }
90
+ }
91
+ }
92
+ return closestIntersection;
93
+ }
94
+ /**
95
+ * Generates a polygon approximation of an ellipse.
96
+ * @param centerX - X coordinate of ellipse center
97
+ * @param centerY - Y coordinate of ellipse center
98
+ * @param rx - Horizontal radius
99
+ * @param ry - Vertical radius
100
+ * @param segments - Number of segments (more = smoother approximation)
101
+ * @param rotation - Optional rotation angle in radians
102
+ */
103
+ static getEllipsePolygonApproximation(centerX, centerY, rx, ry, segments = 32, rotation = 0) {
104
+ const points = [];
105
+ const cos = Math.cos(rotation);
106
+ const sin = Math.sin(rotation);
107
+ for (let i = 0; i < segments; i++) {
108
+ const angle = (2 * Math.PI * i) / segments;
109
+ // Point on unrotated ellipse
110
+ const px = rx * Math.cos(angle);
111
+ const py = ry * Math.sin(angle);
112
+ // Apply rotation around center
113
+ const rotatedX = centerX + px * cos - py * sin;
114
+ const rotatedY = centerY + px * sin + py * cos;
115
+ points.push({ x: rotatedX, y: rotatedY });
116
+ }
117
+ return points;
118
+ }
119
+ /**
120
+ * Finds the closest intersection point between a line segment and a polygon
121
+ * defined as an array of points. Returns the intersection closest to lineStart,
122
+ * or null if no intersection.
123
+ */
124
+ static getLinePointsArrayIntersection(lineStart, lineEnd, polygonPoints) {
125
+ let closestIntersection = null;
126
+ let closestDistance = Infinity;
127
+ for (let i = 0; i < polygonPoints.length; i++) {
128
+ const edgeStart = polygonPoints[i];
129
+ const edgeEnd = polygonPoints[(i + 1) % polygonPoints.length];
130
+ const intersection = this.getLineIntersectionPoint(lineStart, lineEnd, edgeStart, edgeEnd);
131
+ if (intersection) {
132
+ const distance = Math.sqrt(Math.pow(intersection.x - lineStart.x, 2) +
133
+ Math.pow(intersection.y - lineStart.y, 2));
134
+ if (distance < closestDistance) {
135
+ closestDistance = distance;
136
+ closestIntersection = intersection;
137
+ }
138
+ }
139
+ }
140
+ return closestIntersection;
141
+ }
142
+ /**
143
+ * Checks if a point is inside a polygon defined as an array of points.
144
+ * This is a convenience wrapper that works with arbitrary polygon point arrays.
145
+ */
146
+ static isPointInPolygonPoints(point, polygonPoints) {
147
+ return this.isPointInPolygon(point, polygonPoints);
148
+ }
149
+ }
@@ -0,0 +1,51 @@
1
+ import { KritzelDevicesHelper } from './devices.helper';
2
+ export class KritzelKeyboardHelper {
3
+ static forceHideKeyboard() {
4
+ if (document.activeElement instanceof HTMLElement) {
5
+ document.activeElement.blur();
6
+ }
7
+ }
8
+ static enableInteractiveWidget() {
9
+ const meta = document.querySelector('meta[name="viewport"][content*="interactive-widget=resizes-content"]');
10
+ if (meta) {
11
+ let currentContent = meta.getAttribute('content');
12
+ if (!currentContent.includes('interactive-widget=resizes-content')) {
13
+ currentContent += ', interactive-widget=resizes-content';
14
+ }
15
+ meta.setAttribute('content', currentContent);
16
+ }
17
+ }
18
+ static disableInteractiveWidget() {
19
+ const meta = document.querySelector('meta[name="viewport"][content*="interactive-widget=resizes-content"]');
20
+ if (meta) {
21
+ let currentContent = meta.getAttribute('content');
22
+ let newContent = currentContent.replace(/\s*interactive-widget=resizes-content\s*[,;]?/g, '');
23
+ newContent = newContent
24
+ .replace(/,(\s*,)+/g, ',')
25
+ .replace(/^,/, '')
26
+ .replace(/,$/, '')
27
+ .trim();
28
+ meta.setAttribute('content', newContent);
29
+ }
30
+ }
31
+ static onKeyboardVisibleChanged(callback) {
32
+ if ('visualViewport' in window) {
33
+ const VIEWPORT_VS_CLIENT_HEIGHT_RATIO = 0.75;
34
+ const onResize = (event) => {
35
+ const target = event.target;
36
+ const isMobileDevice = KritzelDevicesHelper.isMobile();
37
+ const isViewportReduced = (target.height * target.scale) / window.screen.height < VIEWPORT_VS_CLIENT_HEIGHT_RATIO;
38
+ const isOpen = isMobileDevice && isViewportReduced;
39
+ callback(isOpen);
40
+ };
41
+ window.visualViewport.addEventListener('resize', onResize);
42
+ return () => window.visualViewport.removeEventListener('resize', onResize);
43
+ }
44
+ else {
45
+ // Fallback for older browsers does not provide a reliable event-based mechanism.
46
+ console.warn('Listening for keyboard visibility changes is not reliably supported in this browser.');
47
+ // Return a no-op cleanup function.
48
+ return () => { };
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,5 @@
1
+ export class KritzelMathHelper {
2
+ static average(a, b) {
3
+ return (a + b) / 2;
4
+ }
5
+ }
@@ -0,0 +1,11 @@
1
+ export class ObjectHelper {
2
+ static generateUUID() {
3
+ return Math.random().toString(36).substr(2, 9);
4
+ }
5
+ static isEmpty(obj) {
6
+ if (obj === null || obj === undefined) {
7
+ return true;
8
+ }
9
+ return (Object === null || Object === void 0 ? void 0 : Object.keys(obj).length) === 0 && (obj === null || obj === void 0 ? void 0 : obj.constructor) === Object;
10
+ }
11
+ }
@@ -0,0 +1,69 @@
1
+ export class ThemeHelper {
2
+ /**
3
+ * Converts a camelCase string to kebab-case.
4
+ * @example ThemeHelper.camelToKebab('controlHoverBackgroundColor') → 'control-hover-background-color'
5
+ * @example ThemeHelper.camelToKebab('backgroundColor') → 'background-color'
6
+ * @example ThemeHelper.camelToKebab('gap') → 'gap'
7
+ */
8
+ static camelToKebab(str) {
9
+ return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
10
+ }
11
+ /**
12
+ * Recursively flattens a theme object into a map of CSS variable names to values.
13
+ * Skips the 'name' property at the root level since it's the theme identifier, not a CSS value.
14
+ *
15
+ * @param theme - The theme object to flatten
16
+ * @param prefix - The CSS variable prefix (default: '--kritzel')
17
+ * @returns A Map of CSS variable names to their values
18
+ *
19
+ * @example
20
+ * ThemeHelper.flattenThemeToVariables(lightTheme)
21
+ * // Returns Map {
22
+ * // '--kritzel-global-pointer-cursor' => 'pointer',
23
+ * // '--kritzel-controls-gap' => '8px',
24
+ * // ...
25
+ * // }
26
+ */
27
+ static flattenThemeToVariables(theme, prefix = '--kritzel') {
28
+ const variables = new Map();
29
+ const recurse = (obj, currentPrefix, isRoot = false) => {
30
+ for (const [key, value] of Object.entries(obj)) {
31
+ // Skip the 'name' property at the root level
32
+ if (isRoot && key === 'name') {
33
+ continue;
34
+ }
35
+ const kebabKey = ThemeHelper.camelToKebab(key);
36
+ const variableName = `${currentPrefix}-${kebabKey}`;
37
+ if (typeof value === 'object' && value !== null) {
38
+ recurse(value, variableName);
39
+ }
40
+ else if (typeof value === 'string') {
41
+ variables.set(variableName, value);
42
+ }
43
+ }
44
+ };
45
+ recurse(theme, prefix, true);
46
+ return variables;
47
+ }
48
+ /**
49
+ * Applies a map of CSS variables to an HTML element.
50
+ *
51
+ * @param element - The target HTML element
52
+ * @param variables - A Map of CSS variable names to values
53
+ */
54
+ static applyVariablesToElement(element, variables) {
55
+ for (const [name, value] of variables) {
56
+ element.style.setProperty(name, value);
57
+ }
58
+ }
59
+ /**
60
+ * Convenience method that flattens a theme and applies it to an element in one call.
61
+ *
62
+ * @param element - The target HTML element
63
+ * @param theme - The theme object to apply
64
+ */
65
+ static applyThemeToElement(element, theme) {
66
+ const variables = ThemeHelper.flattenThemeToVariables(theme);
67
+ ThemeHelper.applyVariablesToElement(element, variables);
68
+ }
69
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @fileoverview entry point for your component library
3
+ *
4
+ * This is the entry point for your component library. Use this file to export utilities,
5
+ * constants or data structure that accompany your components.
6
+ *
7
+ * DO NOT use this file to export your components. Instead, use the recommended approaches
8
+ * to consume components of this package as outlined in the `README.md`.
9
+ */
10
+ export * from './classes/objects/text.class';
11
+ export * from './classes/objects/path.class';
12
+ export * from './classes/objects/image.class';
13
+ export * from './classes/objects/line.class';
14
+ export * from './classes/objects/group.class';
15
+ export * from './classes/tools/brush-tool.class';
16
+ export * from './classes/tools/line-tool.class';
17
+ export * from './classes/tools/eraser-tool.class';
18
+ export * from './classes/tools/image-tool.class';
19
+ export * from './classes/tools/text-tool.class';
20
+ export * from './helpers/cursor.helper';
21
+ export * from './classes/tools/selection-tool.class';
22
+ export * from './classes/providers/broadcast-sync-provider.class';
23
+ export * from './classes/providers/indexeddb-sync-provider.class';
24
+ export * from './classes/providers/websocket-sync-provider.class';
25
+ export * from './classes/providers/hocuspocus-sync-provider.class';
26
+ export * from './classes/structures/app-state-map.structure';
27
+ export * from './classes/core/workspace.class';
28
+ export * from './classes/managers/anchor.manager';
29
+ export * from './interfaces/toolbar-control.interface';
30
+ export * from './interfaces/menu-item.interface';
31
+ export * from './interfaces/sync-provider.interface';
32
+ export * from './interfaces/sync-config.interface';
33
+ export * from './interfaces/anchor.interface';
34
+ export * from './configs/default-brush-tool.config';
35
+ export * from './configs/default-text-tool.config';
36
+ export * from './configs/default-line-tool.config';
37
+ export * from './interfaces/theme.interface';
38
+ export * from './interfaces/shortcut.interface';
39
+ export * from './themes/light-theme';
40
+ export * from './themes/dark-theme';
41
+ export * from './classes/managers/theme.manager';
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Dark theme preset
3
+ */
4
+ export const darkTheme = {
5
+ name: 'dark',
6
+ global: {
7
+ borderColor: '#3a3a3a',
8
+ dividerColor: '#3a3a3a',
9
+ focusColor: '#ffffff',
10
+ focusRingColor: '#ffffff',
11
+ hoverBackground: 'hsl(0, 0%, 100%, 8%)',
12
+ iconColor: 'currentColor',
13
+ scrollbarThumbColor: '#555555',
14
+ textPrimary: '#ffffff',
15
+ textSecondary: '#e0e0e0',
16
+ },
17
+ selection: {
18
+ borderColor: '#0A84FF',
19
+ handleColor: '#1a1a1a',
20
+ },
21
+ checkerboard: {
22
+ colorDark: '#4a4a4a',
23
+ colorLight: '#3a3a3a',
24
+ },
25
+ backToContent: {
26
+ activeBackgroundColor: 'hsl(0, 0%, 100%, 12%)',
27
+ backgroundColor: '#2a2a2a',
28
+ border: '1px solid #3a3a3a',
29
+ boxShadow: '0 0 6px rgba(0, 0, 0, 0.3)',
30
+ color: '#ffffff',
31
+ hoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
32
+ },
33
+ colorPalette: {
34
+ circleBorderColor: '#4a4a4a',
35
+ hoverBackgroundColor: '#3a3a3a',
36
+ selectedBackgroundColor: '#3a3a3a',
37
+ },
38
+ contextMenu: {
39
+ backgroundColor: '#2a2a2a',
40
+ border: '1px solid #3a3a3a',
41
+ boxShadow: '0 1px 8px rgba(0, 0, 0, 0.4)',
42
+ itemActiveBackgroundColor: 'hsl(0, 0%, 100%, 12%)',
43
+ itemColor: '#e0e0e0',
44
+ itemDisabledColor: '#666666',
45
+ itemHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
46
+ },
47
+ controls: {
48
+ backgroundColor: '#2a2a2a',
49
+ border: '1px solid #3a3a3a',
50
+ boxShadow: '0 0 6px rgba(0, 0, 0, 0.3)',
51
+ controlActiveBackgroundColor: 'hsl(0, 0%, 100%, 12%)',
52
+ controlColor: '#ffffff',
53
+ controlHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
54
+ controlSelectedBackgroundColor: '#0A84FF',
55
+ controlSelectedColor: '#ffffff',
56
+ },
57
+ dialog: {
58
+ backdropColor: 'rgba(0, 0, 0, 0.6)',
59
+ backgroundColor: '#2a2a2a',
60
+ border: '1px solid #3a3a3a',
61
+ boxShadow: '0 4px 24px rgba(0, 0, 0, 0.5)',
62
+ closeButtonActiveBackground: 'hsl(0, 0%, 100%, 12%)',
63
+ closeButtonBackground: 'transparent',
64
+ closeButtonColor: '#e0e0e0',
65
+ closeButtonHoverBackground: 'hsl(0, 0%, 100%, 8%)',
66
+ closeButtonHoverColor: '#ffffff',
67
+ footerBorder: '1px solid #3a3a3a',
68
+ headerBorder: '1px solid #3a3a3a',
69
+ titleColor: '#ffffff',
70
+ },
71
+ dropdown: {
72
+ accentColor: '#0A84FF',
73
+ hoverBackgroundColor: '#3a3a3a',
74
+ selectedBackgroundColor: 'rgba(10, 132, 255, 0.2)',
75
+ textColor: '#e0e0e0',
76
+ },
77
+ engine: {
78
+ backgroundColor: '#1a1a1a',
79
+ },
80
+ fontSize: {
81
+ hoverBackgroundColor: '#3a3a3a',
82
+ selectedBackgroundColor: '#3a3a3a',
83
+ textColor: '#e0e0e0',
84
+ },
85
+ lineEndings: {
86
+ hoverBackgroundColor: '#3a3a3a',
87
+ labelColor: '#999999',
88
+ optionBackground: '#2a2a2a',
89
+ selectedBackgroundColor: '#3a3a3a',
90
+ },
91
+ masterDetail: {
92
+ backButtonColor: '#e0e0e0',
93
+ backgroundColor: '#2a2a2a',
94
+ detailBackgroundColor: '#2a2a2a',
95
+ detailFocusOutline: '2px solid #ffffff',
96
+ menuBackgroundColor: '#2a2a2a',
97
+ menuBorderRight: '1px solid #3a3a3a',
98
+ menuItemActiveBackgroundColor: 'hsl(0, 0%, 100%, 12%)',
99
+ menuItemBackgroundColor: 'transparent',
100
+ menuItemChevronColor: '#666666',
101
+ menuItemColor: '#e0e0e0',
102
+ menuItemDisabledColor: '#666666',
103
+ menuItemFocusOutline: '2px solid #ffffff',
104
+ menuItemHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
105
+ menuItemSelectedBackgroundColor: '#0A84FF',
106
+ menuItemSelectedColor: '#ffffff',
107
+ menuItemSelectedHoverBackgroundColor: '#0A84FF',
108
+ },
109
+ menu: {
110
+ backgroundColor: '#2a2a2a',
111
+ border: '1px solid #3a3a3a',
112
+ boxShadow: '0 0 6px rgba(0, 0, 0, 0.3)',
113
+ itemButtonHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
114
+ itemChildOpenBackgroundColor: 'hsl(0, 0%, 100%, 6%)',
115
+ itemColor: '#e0e0e0',
116
+ itemEditingBackgroundColor: '#3a3a3a',
117
+ itemInputBorder: '1px solid #ffffff',
118
+ itemInputBorderColorOnSelected: '#ffffff',
119
+ itemInputCaretColor: '#e0e0e0',
120
+ itemInputCaretColorOnSelected: '#ffffff',
121
+ itemInputSelectionColor: '#b0b0b0',
122
+ itemInputSelectionColorOnSelected: 'rgba(255, 255, 255, 0.35)',
123
+ itemInputSelectionTextColor: '#ffffff',
124
+ itemInputSelectionTextColorOnSelected: '#ffffff',
125
+ itemOverlayBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
126
+ itemSelectedBackgroundColor: '#0A84FF',
127
+ itemSelectedColor: '#ffffff',
128
+ },
129
+ moreMenu: {
130
+ backgroundColor: '#2a2a2a',
131
+ border: '1px solid #3a3a3a',
132
+ borderRadius: '12px',
133
+ boxShadow: '0 0 6px rgba(0, 0, 0, 0.3)',
134
+ buttonActiveBackgroundColor: 'hsl(0, 0%, 100%, 12%)',
135
+ buttonColor: '#ffffff',
136
+ buttonHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
137
+ innerBorderRadius: '12px',
138
+ },
139
+ numericInput: {
140
+ borderColor: '#3a3a3a',
141
+ focusBorderColor: '#ffffff',
142
+ hoverBorderColor: '#4a4a4a',
143
+ inputBackground: '#1a1a1a',
144
+ labelColor: '#999999',
145
+ spinnerActiveBackground: 'hsl(0, 0%, 100%, 12%)',
146
+ spinnerBackground: 'transparent',
147
+ spinnerColor: '#e0e0e0',
148
+ spinnerHoverBackground: 'hsl(0, 0%, 100%, 8%)',
149
+ textColor: '#e0e0e0',
150
+ },
151
+ opacitySlider: {
152
+ activeColor: '#0A84FF',
153
+ thumbBorderColor: '#0A84FF',
154
+ thumbColor: '#ffffff',
155
+ trackColor: '#4a4a4a',
156
+ },
157
+ settings: {
158
+ contentHeadingColor: '#ffffff',
159
+ contentTextColor: '#e0e0e0',
160
+ descriptionColor: '#999999',
161
+ labelColor: '#e0e0e0',
162
+ },
163
+ shapeFill: {
164
+ hoverBackgroundColor: '#3a3a3a',
165
+ optionBackground: '#2a2a2a',
166
+ selectedBackgroundColor: '#3a3a3a',
167
+ },
168
+ slideToggle: {
169
+ thumbColor: '#ffffff',
170
+ trackCheckedColor: '#0A84FF',
171
+ trackColor: '#4a4a4a',
172
+ transitionDuration: '0.2s',
173
+ },
174
+ splitButton: {
175
+ backgroundColor: '#2a2a2a',
176
+ border: '1px solid #3a3a3a',
177
+ boxShadow: '0 0 6px rgba(0, 0, 0, 0.3)',
178
+ color: '#ffffff',
179
+ dividerBackgroundColor: '#3a3a3a',
180
+ hoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
181
+ },
182
+ strokeSize: {
183
+ hoverBackgroundColor: '#3a3a3a',
184
+ selectedBackgroundColor: '#3a3a3a',
185
+ },
186
+ tooltip: {
187
+ backgroundColor: '#2a2a2a',
188
+ border: '1px solid #3a3a3a',
189
+ boxShadow: '0 1px 8px rgba(0, 0, 0, 0.4)',
190
+ color: '#ffffff',
191
+ },
192
+ utilityPanel: {
193
+ backgroundColor: '#3a3a3a',
194
+ buttonColor: '#e0e0e0',
195
+ buttonHoverBackgroundColor: 'hsl(0, 0%, 100%, 8%)',
196
+ separatorColor: 'hsl(0, 0%, 100%, 12%)',
197
+ },
198
+ };