@kritzel/engine 0.4.31

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 (373) hide show
  1. package/LICENSE.md +50 -0
  2. package/dist/cjs/app-globals-V2Kpy_OQ.js +5 -0
  3. package/dist/cjs/engine.constants-CakmdKMW.js +28206 -0
  4. package/dist/cjs/index-BbbWU2aN.js +1742 -0
  5. package/dist/cjs/index.cjs.js +4232 -0
  6. package/dist/cjs/kritzel-awareness-cursors_5.cjs.entry.js +28004 -0
  7. package/dist/cjs/loader.cjs.js +13 -0
  8. package/dist/cjs/stencil.cjs.js +25 -0
  9. package/dist/collection/classes/core/core.class.js +1389 -0
  10. package/dist/collection/classes/core/reviver.class.js +124 -0
  11. package/dist/collection/classes/core/store.class.js +337 -0
  12. package/dist/collection/classes/core/viewport.class.js +794 -0
  13. package/dist/collection/classes/core/workspace.class.js +112 -0
  14. package/dist/collection/classes/handlers/base.handler.js +20 -0
  15. package/dist/collection/classes/handlers/context-menu.handler.js +170 -0
  16. package/dist/collection/classes/handlers/hover.handler.js +35 -0
  17. package/dist/collection/classes/handlers/key.handler.js +162 -0
  18. package/dist/collection/classes/handlers/line-handle.handler.js +475 -0
  19. package/dist/collection/classes/handlers/move.handler.js +295 -0
  20. package/dist/collection/classes/handlers/resize.handler.js +327 -0
  21. package/dist/collection/classes/handlers/rotation.handler.js +174 -0
  22. package/dist/collection/classes/handlers/selection.handler.js +526 -0
  23. package/dist/collection/classes/managers/anchor.manager.js +1476 -0
  24. package/dist/collection/classes/managers/browser-permission.manager.js +64 -0
  25. package/dist/collection/classes/managers/clipboard.manager.js +346 -0
  26. package/dist/collection/classes/managers/clipboard.types.js +1 -0
  27. package/dist/collection/classes/managers/cursor.manager.js +139 -0
  28. package/dist/collection/classes/managers/license.manager.js +341 -0
  29. package/dist/collection/classes/managers/localization.manager.js +227 -0
  30. package/dist/collection/classes/managers/theme.manager.js +206 -0
  31. package/dist/collection/classes/objects/base-object.class.js +462 -0
  32. package/dist/collection/classes/objects/dynamic-object.class.js +437 -0
  33. package/dist/collection/classes/objects/group.class.js +590 -0
  34. package/dist/collection/classes/objects/image.class.js +500 -0
  35. package/dist/collection/classes/objects/line.class.js +789 -0
  36. package/dist/collection/classes/objects/path.class.js +578 -0
  37. package/dist/collection/classes/objects/selection-box.class.js +32 -0
  38. package/dist/collection/classes/objects/selection-group.class.js +752 -0
  39. package/dist/collection/classes/objects/shape.class.js +628 -0
  40. package/dist/collection/classes/objects/text.class.js +461 -0
  41. package/dist/collection/classes/providers/assets/asset-resolver.class.js +536 -0
  42. package/dist/collection/classes/providers/assets/http-asset-provider.class.js +111 -0
  43. package/dist/collection/classes/providers/assets/indexeddb-asset-provider.class.js +241 -0
  44. package/dist/collection/classes/providers/assets/presigned-asset-provider.class.js +86 -0
  45. package/dist/collection/classes/providers/paste-intent/event-paste-intent.provider.js +48 -0
  46. package/dist/collection/classes/providers/paste-intent/ios-paste-intent.provider.js +16 -0
  47. package/dist/collection/classes/providers/paste-intent/navigator-paste-intent.provider.js +86 -0
  48. package/dist/collection/classes/providers/sync/broadcast-sync-provider.class.js +100 -0
  49. package/dist/collection/classes/providers/sync/hocuspocus-sync-provider.class.js +333 -0
  50. package/dist/collection/classes/providers/sync/in-memory-sync-provider.class.js +69 -0
  51. package/dist/collection/classes/providers/sync/indexeddb-sync-provider.class.js +39 -0
  52. package/dist/collection/classes/providers/sync/websocket-sync-provider.class.js +110 -0
  53. package/dist/collection/classes/registries/dynamic-object-renderer.registry.js +52 -0
  54. package/dist/collection/classes/registries/font-registry.class.js +161 -0
  55. package/dist/collection/classes/registries/icon-registry.class.js +118 -0
  56. package/dist/collection/classes/registries/paste-intent-provider.registry.js +26 -0
  57. package/dist/collection/classes/registries/tool.registry.js +69 -0
  58. package/dist/collection/classes/structures/app-state-map.structure.js +461 -0
  59. package/dist/collection/classes/structures/object-map.structure.js +1103 -0
  60. package/dist/collection/classes/structures/quadtree.structure.js +251 -0
  61. package/dist/collection/classes/tools/base-tool.class.js +88 -0
  62. package/dist/collection/classes/tools/brush-tool.class.js +236 -0
  63. package/dist/collection/classes/tools/eraser-tool.class.js +133 -0
  64. package/dist/collection/classes/tools/image-tool.class.js +152 -0
  65. package/dist/collection/classes/tools/line-tool.class.js +249 -0
  66. package/dist/collection/classes/tools/selection-tool.class.js +611 -0
  67. package/dist/collection/classes/tools/shape-tool.class.js +251 -0
  68. package/dist/collection/classes/tools/text-tool.class.js +179 -0
  69. package/dist/collection/collection-manifest.json +17 -0
  70. package/dist/collection/components/kritzel-awareness-cursors/kritzel-awareness-cursors.css +115 -0
  71. package/dist/collection/components/kritzel-awareness-cursors/kritzel-awareness-cursors.js +380 -0
  72. package/dist/collection/components/kritzel-cursor-trail/kritzel-cursor-trail.css +10 -0
  73. package/dist/collection/components/kritzel-cursor-trail/kritzel-cursor-trail.js +153 -0
  74. package/dist/collection/components/kritzel-engine/kritzel-engine.css +81 -0
  75. package/dist/collection/components/kritzel-engine/kritzel-engine.js +6345 -0
  76. package/dist/collection/components/kritzel-icon/kritzel-icon.css +18 -0
  77. package/dist/collection/components/kritzel-icon/kritzel-icon.js +93 -0
  78. package/dist/collection/components/kritzel-watermark/kritzel-watermark.css +29 -0
  79. package/dist/collection/components/kritzel-watermark/kritzel-watermark.js +83 -0
  80. package/dist/collection/configs/default-asset-storage.config.js +9 -0
  81. package/dist/collection/configs/default-brush-tool.config.js +9 -0
  82. package/dist/collection/configs/default-engine-config.js +73 -0
  83. package/dist/collection/configs/default-line-tool.config.js +12 -0
  84. package/dist/collection/configs/default-shape-tool.config.js +15 -0
  85. package/dist/collection/configs/default-sync.config.js +6 -0
  86. package/dist/collection/configs/default-text-tool.config.js +12 -0
  87. package/dist/collection/constants/color-palette.constants.js +40 -0
  88. package/dist/collection/constants/core.constants.js +1 -0
  89. package/dist/collection/constants/engine.constants.js +4 -0
  90. package/dist/collection/constants/license.constants.js +25 -0
  91. package/dist/collection/constants/schema.constants.js +4 -0
  92. package/dist/collection/constants/storage.constants.js +1 -0
  93. package/dist/collection/constants/stroke-size.constants.js +2 -0
  94. package/dist/collection/constants/text-tool-fonts.constants.js +18 -0
  95. package/dist/collection/constants/version.js +6 -0
  96. package/dist/collection/enums/alignment.enum.js +9 -0
  97. package/dist/collection/enums/event-button.enum.js +6 -0
  98. package/dist/collection/enums/handle-type.enum.js +7 -0
  99. package/dist/collection/enums/shape-type.enum.js +6 -0
  100. package/dist/collection/events/active-workspace-change.event.js +1 -0
  101. package/dist/collection/events/editor-is-ready.event.js +1 -0
  102. package/dist/collection/events/login.event.js +1 -0
  103. package/dist/collection/helpers/alignment.helper.js +73 -0
  104. package/dist/collection/helpers/class.helper.js +5 -0
  105. package/dist/collection/helpers/color.helper.js +106 -0
  106. package/dist/collection/helpers/cursor.helper.js +57 -0
  107. package/dist/collection/helpers/devices.helper.js +28 -0
  108. package/dist/collection/helpers/event.helper.js +58 -0
  109. package/dist/collection/helpers/geometry.helper.js +149 -0
  110. package/dist/collection/helpers/html.helper.js +116 -0
  111. package/dist/collection/helpers/image-file.helper.js +6 -0
  112. package/dist/collection/helpers/keyboard.helper.js +55 -0
  113. package/dist/collection/helpers/localization.helper.js +25 -0
  114. package/dist/collection/helpers/math.helper.js +8 -0
  115. package/dist/collection/helpers/migration.helper.js +45 -0
  116. package/dist/collection/helpers/object.helper.js +29 -0
  117. package/dist/collection/helpers/svg-export.helper.js +655 -0
  118. package/dist/collection/helpers/theme.helper.js +77 -0
  119. package/dist/collection/helpers/tool-config.helper.js +63 -0
  120. package/dist/collection/helpers/wheel.helper.js +113 -0
  121. package/dist/collection/index.js +107 -0
  122. package/dist/collection/interfaces/anchor.interface.js +1 -0
  123. package/dist/collection/interfaces/arrow-head.interface.js +1 -0
  124. package/dist/collection/interfaces/asset-provider.interface.js +1 -0
  125. package/dist/collection/interfaces/asset-storage-config.interface.js +1 -0
  126. package/dist/collection/interfaces/asset.interface.js +1 -0
  127. package/dist/collection/interfaces/bounding-box.interface.js +1 -0
  128. package/dist/collection/interfaces/clonable.interface.js +1 -0
  129. package/dist/collection/interfaces/context-menu-item.interface.js +1 -0
  130. package/dist/collection/interfaces/context-menu-state.interface.js +1 -0
  131. package/dist/collection/interfaces/debug-info.interface.js +1 -0
  132. package/dist/collection/interfaces/dialog.interface.js +1 -0
  133. package/dist/collection/interfaces/document-metadata.interface.js +1 -0
  134. package/dist/collection/interfaces/dynamic-object-renderer.interface.js +1 -0
  135. package/dist/collection/interfaces/engine-state.interface.js +1 -0
  136. package/dist/collection/interfaces/font.interface.js +1 -0
  137. package/dist/collection/interfaces/localization.interface.js +1 -0
  138. package/dist/collection/interfaces/login-config.interface.js +1 -0
  139. package/dist/collection/interfaces/master-detail.interface.js +1 -0
  140. package/dist/collection/interfaces/menu-item.interface.js +1 -0
  141. package/dist/collection/interfaces/migration.interface.js +1 -0
  142. package/dist/collection/interfaces/notification.interface.js +1 -0
  143. package/dist/collection/interfaces/object-change-event.interface.js +1 -0
  144. package/dist/collection/interfaces/object-export.interface.js +1 -0
  145. package/dist/collection/interfaces/object.interface.js +1 -0
  146. package/dist/collection/interfaces/paste-intent-provider.interface.js +1 -0
  147. package/dist/collection/interfaces/point.interface.js +1 -0
  148. package/dist/collection/interfaces/polygon.interface.js +1 -0
  149. package/dist/collection/interfaces/remote-cursor.interface.js +1 -0
  150. package/dist/collection/interfaces/selection-state.interface.js +1 -0
  151. package/dist/collection/interfaces/serializable.interface.js +1 -0
  152. package/dist/collection/interfaces/settings.interface.js +1 -0
  153. package/dist/collection/interfaces/share.interface.js +1 -0
  154. package/dist/collection/interfaces/shortcut.interface.js +1 -0
  155. package/dist/collection/interfaces/sync-config.interface.js +21 -0
  156. package/dist/collection/interfaces/sync-provider.interface.js +1 -0
  157. package/dist/collection/interfaces/theme.interface.js +1 -0
  158. package/dist/collection/interfaces/tool-config.interface.js +1 -0
  159. package/dist/collection/interfaces/tool-type.interface.js +1 -0
  160. package/dist/collection/interfaces/tool.interface.js +1 -0
  161. package/dist/collection/interfaces/toolbar-item.interface.js +1 -0
  162. package/dist/collection/interfaces/undo-state.interface.js +1 -0
  163. package/dist/collection/interfaces/user.interface.js +1 -0
  164. package/dist/collection/interfaces/viewport-state.interface.js +1 -0
  165. package/dist/collection/locales/de-locale.js +119 -0
  166. package/dist/collection/locales/en-locale.js +120 -0
  167. package/dist/collection/locales/fr-locale.js +119 -0
  168. package/dist/collection/migrations/app-state.migrations.js +47 -0
  169. package/dist/collection/migrations/workspace.migrations.js +67 -0
  170. package/dist/collection/themes/dark-theme.js +340 -0
  171. package/dist/collection/themes/light-theme.js +346 -0
  172. package/dist/collection/types/deep-readonly.type.js +1 -0
  173. package/dist/collection/types/state.types.js +1 -0
  174. package/dist/components/index.d.ts +47 -0
  175. package/dist/components/index.js +4143 -0
  176. package/dist/components/kritzel-awareness-cursors.d.ts +11 -0
  177. package/dist/components/kritzel-awareness-cursors.js +6 -0
  178. package/dist/components/kritzel-cursor-trail.d.ts +11 -0
  179. package/dist/components/kritzel-cursor-trail.js +6 -0
  180. package/dist/components/kritzel-engine.d.ts +11 -0
  181. package/dist/components/kritzel-engine.js +52641 -0
  182. package/dist/components/kritzel-icon.d.ts +11 -0
  183. package/dist/components/kritzel-icon.js +6 -0
  184. package/dist/components/kritzel-watermark.d.ts +11 -0
  185. package/dist/components/kritzel-watermark.js +6 -0
  186. package/dist/components/p-B2Htv9ou.js +49 -0
  187. package/dist/components/p-BvRGQvVI.js +3456 -0
  188. package/dist/components/p-CfSx6HU_.js +1469 -0
  189. package/dist/components/p-YP8wAcF4.js +122 -0
  190. package/dist/components/p-fx6msYHJ.js +167 -0
  191. package/dist/esm/app-globals-DQuL1Twl.js +3 -0
  192. package/dist/esm/engine.constants-Bl5-pbq-.js +28143 -0
  193. package/dist/esm/index-BU9Mv7y0.js +1715 -0
  194. package/dist/esm/index.js +4134 -0
  195. package/dist/esm/kritzel-awareness-cursors_5.entry.js +27978 -0
  196. package/dist/esm/loader.js +11 -0
  197. package/dist/esm/stencil.js +21 -0
  198. package/dist/index.cjs.js +1 -0
  199. package/dist/index.js +1 -0
  200. package/dist/stencil/index.esm.js +4134 -0
  201. package/dist/stencil/p-BU9Mv7y0.js +1702 -0
  202. package/dist/stencil/p-Bl5-pbq-.js +28143 -0
  203. package/dist/stencil/p-DQuL1Twl.js +3 -0
  204. package/dist/stencil/p-f0a8b7af.entry.js +27978 -0
  205. package/dist/stencil/stencil.esm.js +21 -0
  206. package/dist/types/classes/core/core.class.d.ts +532 -0
  207. package/dist/types/classes/core/reviver.class.d.ts +32 -0
  208. package/dist/types/classes/core/store.class.d.ts +198 -0
  209. package/dist/types/classes/core/viewport.class.d.ts +256 -0
  210. package/dist/types/classes/core/workspace.class.d.ts +95 -0
  211. package/dist/types/classes/handlers/base.handler.d.ts +18 -0
  212. package/dist/types/classes/handlers/context-menu.handler.d.ts +67 -0
  213. package/dist/types/classes/handlers/hover.handler.d.ts +23 -0
  214. package/dist/types/classes/handlers/key.handler.d.ts +44 -0
  215. package/dist/types/classes/handlers/line-handle.handler.d.ts +115 -0
  216. package/dist/types/classes/handlers/move.handler.d.ts +94 -0
  217. package/dist/types/classes/handlers/resize.handler.d.ts +95 -0
  218. package/dist/types/classes/handlers/rotation.handler.d.ts +50 -0
  219. package/dist/types/classes/handlers/selection.handler.d.ts +153 -0
  220. package/dist/types/classes/managers/anchor.manager.d.ts +513 -0
  221. package/dist/types/classes/managers/browser-permission.manager.d.ts +41 -0
  222. package/dist/types/classes/managers/clipboard.manager.d.ts +71 -0
  223. package/dist/types/classes/managers/clipboard.types.d.ts +23 -0
  224. package/dist/types/classes/managers/cursor.manager.d.ts +66 -0
  225. package/dist/types/classes/managers/license.manager.d.ts +147 -0
  226. package/dist/types/classes/managers/localization.manager.d.ts +145 -0
  227. package/dist/types/classes/managers/theme.manager.d.ts +112 -0
  228. package/dist/types/classes/objects/base-object.class.d.ts +266 -0
  229. package/dist/types/classes/objects/dynamic-object.class.d.ts +148 -0
  230. package/dist/types/classes/objects/group.class.d.ts +231 -0
  231. package/dist/types/classes/objects/image.class.d.ts +246 -0
  232. package/dist/types/classes/objects/line.class.d.ts +285 -0
  233. package/dist/types/classes/objects/path.class.d.ts +220 -0
  234. package/dist/types/classes/objects/selection-box.class.d.ts +19 -0
  235. package/dist/types/classes/objects/selection-group.class.d.ts +267 -0
  236. package/dist/types/classes/objects/shape.class.d.ts +322 -0
  237. package/dist/types/classes/objects/text.class.d.ts +197 -0
  238. package/dist/types/classes/providers/assets/asset-resolver.class.d.ts +141 -0
  239. package/dist/types/classes/providers/assets/http-asset-provider.class.d.ts +79 -0
  240. package/dist/types/classes/providers/assets/indexeddb-asset-provider.class.d.ts +69 -0
  241. package/dist/types/classes/providers/assets/presigned-asset-provider.class.d.ts +69 -0
  242. package/dist/types/classes/providers/paste-intent/event-paste-intent.provider.d.ts +8 -0
  243. package/dist/types/classes/providers/paste-intent/ios-paste-intent.provider.d.ts +6 -0
  244. package/dist/types/classes/providers/paste-intent/navigator-paste-intent.provider.d.ts +9 -0
  245. package/dist/types/classes/providers/sync/broadcast-sync-provider.class.d.ts +23 -0
  246. package/dist/types/classes/providers/sync/hocuspocus-sync-provider.class.d.ts +163 -0
  247. package/dist/types/classes/providers/sync/in-memory-sync-provider.class.d.ts +39 -0
  248. package/dist/types/classes/providers/sync/indexeddb-sync-provider.class.d.ts +25 -0
  249. package/dist/types/classes/providers/sync/websocket-sync-provider.class.d.ts +63 -0
  250. package/dist/types/classes/registries/dynamic-object-renderer.registry.d.ts +32 -0
  251. package/dist/types/classes/registries/font-registry.class.d.ts +19 -0
  252. package/dist/types/classes/registries/icon-registry.class.d.ts +39 -0
  253. package/dist/types/classes/registries/paste-intent-provider.registry.d.ts +10 -0
  254. package/dist/types/classes/registries/tool.registry.d.ts +53 -0
  255. package/dist/types/classes/structures/app-state-map.structure.d.ts +171 -0
  256. package/dist/types/classes/structures/object-map.structure.d.ts +403 -0
  257. package/dist/types/classes/structures/quadtree.structure.d.ts +128 -0
  258. package/dist/types/classes/tools/base-tool.class.d.ts +72 -0
  259. package/dist/types/classes/tools/brush-tool.class.d.ts +68 -0
  260. package/dist/types/classes/tools/eraser-tool.class.d.ts +38 -0
  261. package/dist/types/classes/tools/image-tool.class.d.ts +74 -0
  262. package/dist/types/classes/tools/line-tool.class.d.ts +63 -0
  263. package/dist/types/classes/tools/selection-tool.class.d.ts +188 -0
  264. package/dist/types/classes/tools/shape-tool.class.d.ts +90 -0
  265. package/dist/types/classes/tools/text-tool.class.d.ts +66 -0
  266. package/dist/types/components/kritzel-awareness-cursors/kritzel-awareness-cursors.d.ts +29 -0
  267. package/dist/types/components/kritzel-cursor-trail/kritzel-cursor-trail.d.ts +19 -0
  268. package/dist/types/components/kritzel-engine/kritzel-engine.d.ts +695 -0
  269. package/dist/types/components/kritzel-icon/kritzel-icon.d.ts +6 -0
  270. package/dist/types/components/kritzel-watermark/kritzel-watermark.d.ts +20 -0
  271. package/dist/types/components.d.ts +981 -0
  272. package/dist/types/configs/default-asset-storage.config.d.ts +8 -0
  273. package/dist/types/configs/default-brush-tool.config.d.ts +2 -0
  274. package/dist/types/configs/default-engine-config.d.ts +2 -0
  275. package/dist/types/configs/default-line-tool.config.d.ts +2 -0
  276. package/dist/types/configs/default-shape-tool.config.d.ts +2 -0
  277. package/dist/types/configs/default-sync.config.d.ts +5 -0
  278. package/dist/types/configs/default-text-tool.config.d.ts +2 -0
  279. package/dist/types/constants/color-palette.constants.d.ts +31 -0
  280. package/dist/types/constants/core.constants.d.ts +0 -0
  281. package/dist/types/constants/engine.constants.d.ts +4 -0
  282. package/dist/types/constants/license.constants.d.ts +25 -0
  283. package/dist/types/constants/schema.constants.d.ts +4 -0
  284. package/dist/types/constants/storage.constants.d.ts +1 -0
  285. package/dist/types/constants/stroke-size.constants.d.ts +2 -0
  286. package/dist/types/constants/text-tool-fonts.constants.d.ts +3 -0
  287. package/dist/types/constants/version.d.ts +6 -0
  288. package/dist/types/enums/alignment.enum.d.ts +8 -0
  289. package/dist/types/enums/event-button.enum.d.ts +5 -0
  290. package/dist/types/enums/handle-type.enum.d.ts +6 -0
  291. package/dist/types/enums/shape-type.enum.d.ts +5 -0
  292. package/dist/types/events/active-workspace-change.event.d.ts +7 -0
  293. package/dist/types/events/editor-is-ready.event.d.ts +18 -0
  294. package/dist/types/events/login.event.d.ts +3 -0
  295. package/dist/types/helpers/alignment.helper.d.ts +21 -0
  296. package/dist/types/helpers/class.helper.d.ts +3 -0
  297. package/dist/types/helpers/color.helper.d.ts +34 -0
  298. package/dist/types/helpers/cursor.helper.d.ts +22 -0
  299. package/dist/types/helpers/devices.helper.d.ts +8 -0
  300. package/dist/types/helpers/event.helper.d.ts +6 -0
  301. package/dist/types/helpers/geometry.helper.d.ts +38 -0
  302. package/dist/types/helpers/html.helper.d.ts +8 -0
  303. package/dist/types/helpers/image-file.helper.d.ts +3 -0
  304. package/dist/types/helpers/keyboard.helper.d.ts +6 -0
  305. package/dist/types/helpers/localization.helper.d.ts +18 -0
  306. package/dist/types/helpers/math.helper.d.ts +4 -0
  307. package/dist/types/helpers/migration.helper.d.ts +30 -0
  308. package/dist/types/helpers/object.helper.d.ts +9 -0
  309. package/dist/types/helpers/svg-export.helper.d.ts +231 -0
  310. package/dist/types/helpers/theme.helper.d.ts +42 -0
  311. package/dist/types/helpers/tool-config.helper.d.ts +4 -0
  312. package/dist/types/helpers/wheel.helper.d.ts +9 -0
  313. package/dist/types/index.d.ts +109 -0
  314. package/dist/types/interfaces/anchor.interface.d.ts +147 -0
  315. package/dist/types/interfaces/arrow-head.interface.d.ts +27 -0
  316. package/dist/types/interfaces/asset-provider.interface.d.ts +88 -0
  317. package/dist/types/interfaces/asset-storage-config.interface.d.ts +40 -0
  318. package/dist/types/interfaces/asset.interface.d.ts +43 -0
  319. package/dist/types/interfaces/bounding-box.interface.d.ts +8 -0
  320. package/dist/types/interfaces/clonable.interface.d.ts +3 -0
  321. package/dist/types/interfaces/context-menu-item.interface.d.ts +25 -0
  322. package/dist/types/interfaces/context-menu-state.interface.d.ts +16 -0
  323. package/dist/types/interfaces/debug-info.interface.d.ts +7 -0
  324. package/dist/types/interfaces/dialog.interface.d.ts +4 -0
  325. package/dist/types/interfaces/document-metadata.interface.d.ts +6 -0
  326. package/dist/types/interfaces/dynamic-object-renderer.interface.d.ts +40 -0
  327. package/dist/types/interfaces/engine-state.interface.d.ts +82 -0
  328. package/dist/types/interfaces/font.interface.d.ts +15 -0
  329. package/dist/types/interfaces/localization.interface.d.ts +143 -0
  330. package/dist/types/interfaces/login-config.interface.d.ts +24 -0
  331. package/dist/types/interfaces/master-detail.interface.d.ts +14 -0
  332. package/dist/types/interfaces/menu-item.interface.d.ts +27 -0
  333. package/dist/types/interfaces/migration.interface.d.ts +16 -0
  334. package/dist/types/interfaces/notification.interface.d.ts +10 -0
  335. package/dist/types/interfaces/object-change-event.interface.d.ts +31 -0
  336. package/dist/types/interfaces/object-export.interface.d.ts +20 -0
  337. package/dist/types/interfaces/object.interface.d.ts +53 -0
  338. package/dist/types/interfaces/paste-intent-provider.interface.d.ts +10 -0
  339. package/dist/types/interfaces/point.interface.d.ts +4 -0
  340. package/dist/types/interfaces/polygon.interface.d.ts +7 -0
  341. package/dist/types/interfaces/remote-cursor.interface.d.ts +18 -0
  342. package/dist/types/interfaces/selection-state.interface.d.ts +7 -0
  343. package/dist/types/interfaces/serializable.interface.d.ts +5 -0
  344. package/dist/types/interfaces/settings.interface.d.ts +25 -0
  345. package/dist/types/interfaces/share.interface.d.ts +9 -0
  346. package/dist/types/interfaces/shortcut.interface.d.ts +10 -0
  347. package/dist/types/interfaces/sync-config.interface.d.ts +41 -0
  348. package/dist/types/interfaces/sync-provider.interface.d.ts +66 -0
  349. package/dist/types/interfaces/theme.interface.d.ts +553 -0
  350. package/dist/types/interfaces/tool-config.interface.d.ts +24 -0
  351. package/dist/types/interfaces/tool-type.interface.d.ts +1 -0
  352. package/dist/types/interfaces/tool.interface.d.ts +8 -0
  353. package/dist/types/interfaces/toolbar-item.interface.d.ts +66 -0
  354. package/dist/types/interfaces/undo-state.interface.d.ts +6 -0
  355. package/dist/types/interfaces/user.interface.d.ts +22 -0
  356. package/dist/types/interfaces/viewport-state.interface.d.ts +7 -0
  357. package/dist/types/locales/de-locale.d.ts +5 -0
  358. package/dist/types/locales/en-locale.d.ts +6 -0
  359. package/dist/types/locales/fr-locale.d.ts +5 -0
  360. package/dist/types/migrations/app-state.migrations.d.ts +11 -0
  361. package/dist/types/migrations/workspace.migrations.d.ts +11 -0
  362. package/dist/types/stencil-public-runtime.d.ts +1873 -0
  363. package/dist/types/themes/dark-theme.d.ts +5 -0
  364. package/dist/types/themes/light-theme.d.ts +5 -0
  365. package/dist/types/types/deep-readonly.type.d.ts +7 -0
  366. package/dist/types/types/state.types.d.ts +3 -0
  367. package/loader/cdn.js +1 -0
  368. package/loader/index.cjs.js +1 -0
  369. package/loader/index.d.ts +24 -0
  370. package/loader/index.es2017.js +1 -0
  371. package/loader/index.js +2 -0
  372. package/package.json +101 -0
  373. package/readme.md +11 -0
@@ -0,0 +1,500 @@
1
+ import { AssetNotFoundError } from "../providers/assets/asset-resolver.class";
2
+ import { KritzelBaseObject } from "./base-object.class";
3
+ import { KritzelMathHelper } from "../../helpers/math.helper";
4
+ /**
5
+ * Represents an image object on the canvas.
6
+ *
7
+ * Image bytes are NOT stored on this object or inside the Yjs document.
8
+ * Instead, the image is identified by a stable `assetId`; the actual
9
+ * bytes live in the asset storage layer (see `KritzelAssetResolver`).
10
+ * This keeps the CRDT small and lets images be served from pluggable
11
+ * storage (IndexedDB, HTTP, pre-signed S3, ...).
12
+ *
13
+ * Legacy images persisted before the asset layer existed may still carry
14
+ * a `src` data URL; the renderer and migration path treat `src` as a
15
+ * read-only fallback that is upgraded to an `assetId` on first load.
16
+ */
17
+ export class KritzelImage extends KritzelBaseObject {
18
+ __class__ = 'KritzelImage';
19
+ /**
20
+ * Stable asset identifier (uuid) persisted in the Yjs document.
21
+ * Used by the asset resolver to locate the image bytes across
22
+ * devices and storage backends.
23
+ */
24
+ assetId = '';
25
+ /**
26
+ * MIME type of the referenced asset (e.g. `image/png`). Persisted in
27
+ * the Yjs document alongside `assetId` so the renderer can hint
28
+ * browsers and the exporter can produce correct data URLs.
29
+ */
30
+ mimeType = '';
31
+ /**
32
+ * Legacy inline source (typically a `data:` URL). Preserved only for
33
+ * backward compatibility with documents that were created before the
34
+ * asset storage layer existed. New images should use `assetId`.
35
+ *
36
+ * @deprecated Use `assetId` with an asset storage provider instead.
37
+ */
38
+ src = '';
39
+ maxWidth = 300;
40
+ maxHeight = 300;
41
+ maxCompressionSize = 1200;
42
+ // --- Transient (not persisted to Yjs) ---
43
+ /**
44
+ * URL resolved from the asset storage layer (e.g. a `blob:` or https URL).
45
+ * Not serialized into the Yjs document.
46
+ */
47
+ resolvedSrc;
48
+ /**
49
+ * Current load state for the referenced asset.
50
+ * Not serialized into the Yjs document.
51
+ */
52
+ loadState = 'idle';
53
+ /**
54
+ * Maximum number of resolution attempts per page load before the
55
+ * image is considered permanently failed. Defaults to 3.
56
+ *
57
+ * Only attempts that fail with a definitive "asset not found"
58
+ * (i.e. {@link AssetNotFoundError}) consume this budget. Transient
59
+ * failures (network blips, remote temporarily unreachable) do not
60
+ * count against the budget; they are bounded by
61
+ * {@link maxTransientRetryDurationMs} instead.
62
+ *
63
+ * The counter is transient (not persisted to Yjs) and resets every
64
+ * time a fresh `KritzelImage` instance is constructed, so a full page
65
+ * reload always grants a fresh budget.
66
+ */
67
+ maxLoadAttempts = 3;
68
+ /**
69
+ * Number of resolution attempts that have failed with a definitive
70
+ * "asset not found" so far for the current page load. Only updates
71
+ * for {@link AssetNotFoundError} rejections; transient failures do
72
+ * not increment this counter. Not serialized into the Yjs document.
73
+ */
74
+ loadAttempts = 0;
75
+ /**
76
+ * Maximum wall-clock duration (in milliseconds) the image will keep
77
+ * retrying transient resolution failures before giving up and
78
+ * surfacing the error placeholder. Defaults to 30 seconds.
79
+ *
80
+ * This bound exists so that a permanently-broken backend eventually
81
+ * surfaces UX feedback even when failures look "transient" (and
82
+ * therefore do not consume {@link maxLoadAttempts}).
83
+ */
84
+ maxTransientRetryDurationMs = 30_000;
85
+ /**
86
+ * Wall-clock timestamp (ms since epoch) of the first transient
87
+ * failure in the current retry chain. `null` when no transient
88
+ * retries are in flight. Reset on success and on definitive miss.
89
+ * Not serialized into the Yjs document.
90
+ */
91
+ transientRetryStartedAt = null;
92
+ /**
93
+ * Creates a new KritzelImage instance.
94
+ * @param config - Optional configuration object to initialize image properties
95
+ * including assetId, src, position (x, y), translation, and scale.
96
+ */
97
+ constructor(config) {
98
+ super();
99
+ this.assetId = config?.assetId || '';
100
+ this.mimeType = config?.mimeType || '';
101
+ this.src = config?.src || '';
102
+ this.x = config?.x || 0;
103
+ this.y = config?.y || 0;
104
+ this.translateX = config?.translateX || 0;
105
+ this.translateY = config?.translateY || 0;
106
+ this.rotation = KritzelMathHelper.degreesToRadians(config?.rotation ?? 0);
107
+ this.scale = config?.scale || 1;
108
+ this.width = config?.width || 0;
109
+ this.height = config?.height || 0;
110
+ this.maxWidth = config?.maxWidth ?? 300;
111
+ this.maxHeight = config?.maxHeight ?? 300;
112
+ this.maxLoadAttempts = config?.maxLoadAttempts ?? 3;
113
+ }
114
+ /**
115
+ * Factory method to create a new KritzelImage instance with core integration.
116
+ * Initializes the image with default values and links it to the core store.
117
+ * @param core - The KritzelCore instance providing access to store and state management.
118
+ * @returns A new KritzelImage instance configured with the core context.
119
+ */
120
+ static create(core, config) {
121
+ const object = new KritzelImage(config);
122
+ object._core = core;
123
+ object.id = object.generateId();
124
+ object.workspaceId = core.store.state.activeWorkspace.id;
125
+ object.userId = core.user?.id;
126
+ object.x = config?.x ?? 0;
127
+ object.y = config?.y ?? 0;
128
+ object.translateX = config?.translateX ?? 0;
129
+ object.translateY = config?.translateY ?? 0;
130
+ object.scale = config?.scale ?? object._core.store.state.scale;
131
+ object.rotation = KritzelMathHelper.degreesToRadians(config?.rotation ?? 0);
132
+ object.zIndex = core.store.currentZIndex;
133
+ return object;
134
+ }
135
+ /**
136
+ * Resizes the image while maintaining aspect ratio based on the new height.
137
+ * Updates the image's position and dimensions, then syncs changes to y.js
138
+ * for collaborative editing support.
139
+ * @param x - The new x translation coordinate.
140
+ * @param y - The new y translation coordinate.
141
+ * @param width - The new width (used for validation, not directly applied).
142
+ * @param height - The new height used to calculate the scale factor.
143
+ */
144
+ resize(x, y, width, height) {
145
+ if (width <= 1 || height <= 1) {
146
+ return;
147
+ }
148
+ const scaleFactor = height / this.height;
149
+ this.width = this.width * scaleFactor;
150
+ this.height = this.height * scaleFactor;
151
+ this.translateX = x;
152
+ this.translateY = y;
153
+ // Update to sync changes to y.js and propagate to other tabs
154
+ this._core.store.objects.update(this);
155
+ }
156
+ /**
157
+ * Serializes the image, excluding transient rendering state so the
158
+ * Yjs document never persists blob URLs or load lifecycle flags.
159
+ */
160
+ serialize() {
161
+ const plain = super.serialize();
162
+ // Strip transient, non-persistent rendering state.
163
+ delete plain.resolvedSrc;
164
+ delete plain.loadState;
165
+ delete plain.loadAttempts;
166
+ delete plain.transientRetryStartedAt;
167
+ return plain;
168
+ }
169
+ /**
170
+ * Carries transient asset-loading state (resolved URL, load lifecycle,
171
+ * retry counters) over from the previous local instance when a remote
172
+ * Yjs update produces a freshly-revived replacement. Without this,
173
+ * frequent remote updates (e.g. another user dragging the image)
174
+ * would reset `loadState` to `'idle'` on every tick and cause the
175
+ * skeleton to flicker between renders.
176
+ */
177
+ adoptTransientStateFrom(previous) {
178
+ if (!(previous instanceof KritzelImage))
179
+ return;
180
+ // Only carry over the resolved URL when the asset reference itself
181
+ // hasn't changed; otherwise the new asset must be re-resolved.
182
+ if (previous.assetId === this.assetId) {
183
+ this.resolvedSrc = previous.resolvedSrc;
184
+ this.loadState = previous.loadState;
185
+ this.loadAttempts = previous.loadAttempts;
186
+ this.transientRetryStartedAt = previous.transientRetryStartedAt;
187
+ }
188
+ }
189
+ /**
190
+ * Triggers (idempotent) resolution of the referenced asset. Updates
191
+ * `resolvedSrc` and `loadState` as the resolution progresses and
192
+ * schedules a re-render when the URL is available.
193
+ *
194
+ * Failure handling distinguishes two cases:
195
+ * - Definitive miss ({@link AssetNotFoundError}): consumes one slot
196
+ * of the {@link maxLoadAttempts} budget. Once exhausted, the
197
+ * image is marked permanently `'error'` for the remainder of the
198
+ * page load to avoid hammering an unavailable backend; a full
199
+ * reload (which constructs a fresh instance) grants a new budget.
200
+ * - Transient failure (network blip, resolver init in flight, ...):
201
+ * does NOT consume the attempt budget. Retries continue with the
202
+ * same exponential backoff up to
203
+ * {@link maxTransientRetryDurationMs} of wall-clock time, after
204
+ * which the image is marked `'error'`.
205
+ */
206
+ ensureResolved() {
207
+ if (this.loadState === 'loading' || this.loadState === 'ready')
208
+ return;
209
+ if (this.loadState === 'error')
210
+ return;
211
+ if (!this.assetId)
212
+ return;
213
+ if (!this._core?.assetResolver)
214
+ return;
215
+ if (this.loadAttempts >= this.maxLoadAttempts) {
216
+ this.loadState = 'error';
217
+ return;
218
+ }
219
+ this.loadState = 'loading';
220
+ const attemptIndex = this.loadAttempts; // backoff base only; bumped on real misses
221
+ this._core.assetResolver
222
+ .resolve(this.assetId)
223
+ .then(url => {
224
+ this.resolvedSrc = url;
225
+ this.loadState = 'ready';
226
+ // Reset transient retry tracking on success.
227
+ this.transientRetryStartedAt = null;
228
+ this._core?.rerender();
229
+ })
230
+ .catch(err => {
231
+ const isDefinitiveMiss = err instanceof AssetNotFoundError;
232
+ if (isDefinitiveMiss) {
233
+ this.loadAttempts += 1;
234
+ // Definitive miss resets the transient deadline so a later
235
+ // transient retry chain (post-recovery) starts fresh.
236
+ this.transientRetryStartedAt = null;
237
+ const attemptsExhausted = this.loadAttempts >= this.maxLoadAttempts;
238
+ console.warn(`[KritzelImage] Asset ${this.assetId} not found ` +
239
+ `(attempt ${this.loadAttempts}/${this.maxLoadAttempts}):`, err);
240
+ if (attemptsExhausted) {
241
+ this.loadState = 'error';
242
+ this._core?.rerender();
243
+ return;
244
+ }
245
+ this.scheduleRetry(this.loadAttempts);
246
+ return;
247
+ }
248
+ // Transient failure: do not burn the per-page-load budget, but
249
+ // bound retries by a wall-clock deadline so a permanently broken
250
+ // backend still surfaces feedback eventually.
251
+ const now = Date.now();
252
+ if (this.transientRetryStartedAt === null) {
253
+ this.transientRetryStartedAt = now;
254
+ }
255
+ const elapsed = now - this.transientRetryStartedAt;
256
+ const deadlineExceeded = elapsed >= this.maxTransientRetryDurationMs;
257
+ console.warn(`[KritzelImage] Transient resolve failure for asset ${this.assetId} ` +
258
+ `(elapsed ${Math.round(elapsed / 1000)}s/${Math.round(this.maxTransientRetryDurationMs / 1000)}s):`, err);
259
+ if (deadlineExceeded) {
260
+ this.loadState = 'error';
261
+ this._core?.rerender();
262
+ return;
263
+ }
264
+ // Use the existing attempt count as the backoff base. Transient
265
+ // retries do not increment loadAttempts, so the backoff remains
266
+ // bounded at the first step (250ms) until a real miss happens.
267
+ this.scheduleRetry(attemptIndex + 1);
268
+ });
269
+ }
270
+ /**
271
+ * Schedules a retry of {@link ensureResolved} with a small exponential
272
+ * backoff. The backoff base is the current attempt index so successive
273
+ * definitive misses ramp up gradually.
274
+ */
275
+ scheduleRetry(attemptBase) {
276
+ // Reset to 'idle' so the next call (or scheduled tick) is allowed to
277
+ // proceed past the early-return guard in ensureResolved().
278
+ this.loadState = 'idle';
279
+ const backoffMs = Math.min(2000, 250 * Math.pow(2, Math.max(0, attemptBase - 1)));
280
+ setTimeout(() => {
281
+ if (this.loadState === 'idle') {
282
+ this.ensureResolved();
283
+ }
284
+ }, backoffMs);
285
+ }
286
+ /**
287
+ * One-shot migration for legacy images that were persisted with an
288
+ * inline `src` data URL. Uploads the bytes to the asset resolver and
289
+ * swaps the image to use the resulting `assetId`, clearing `src` so
290
+ * the Yjs document no longer carries the raw payload.
291
+ */
292
+ migrateLegacyDataUrlIfNeeded() {
293
+ if (this.assetId)
294
+ return;
295
+ if (!this.src || !this.src.startsWith('data:'))
296
+ return;
297
+ if (!this._core?.assetResolver)
298
+ return;
299
+ const legacySrc = this.src;
300
+ // Render the legacy data URL directly until migration completes.
301
+ this.resolvedSrc = legacySrc;
302
+ this.loadState = 'ready';
303
+ this._core.assetResolver
304
+ .putDataUrl(legacySrc, { kind: 'image' })
305
+ .then(asset => {
306
+ this.assetId = asset.id;
307
+ this.mimeType = asset.mimeType;
308
+ this.src = '';
309
+ // Persist the migrated reference back into Yjs.
310
+ this._core?.store.objects?.update(this);
311
+ })
312
+ .catch(err => {
313
+ console.warn('[KritzelImage] Failed to migrate legacy data URL to asset storage:', err);
314
+ });
315
+ }
316
+ /**
317
+ * Kicks off asset resolution (or legacy data-URL migration) without
318
+ * requiring the `<img>` element to be mounted. Safe to call multiple
319
+ * times; both underlying paths are idempotent.
320
+ *
321
+ * Useful for the renderer's loading-skeleton path, where the actual
322
+ * `<img>` is not in the DOM yet but the asset bytes still need to
323
+ * start loading.
324
+ */
325
+ ensureLoaded() {
326
+ if (this.assetId && !this.resolvedSrc) {
327
+ this.ensureResolved();
328
+ }
329
+ else if (!this.assetId && this.src?.startsWith('data:')) {
330
+ this.migrateLegacyDataUrlIfNeeded();
331
+ }
332
+ }
333
+ /**
334
+ * Prepares image objects for insertion into the canvas while preserving
335
+ * the standard object-first flow (`new KritzelImage(...); addObject(image)`).
336
+ *
337
+ * Behavior:
338
+ * - If `assetId` is already set, no-op.
339
+ * - If `src` is set (URL or data URL), uploads bytes through the asset
340
+ * resolver, fills `assetId`/`mimeType`, computes dimensions when needed,
341
+ * and seeds `resolvedSrc` for immediate rendering.
342
+ */
343
+ async prepareForInsert() {
344
+ if (this.assetId || !this.src) {
345
+ return;
346
+ }
347
+ if (!this._core?.assetResolver) {
348
+ return;
349
+ }
350
+ const source = this.src;
351
+ const response = await fetch(source);
352
+ if (!response.ok) {
353
+ throw new Error(`Failed to load image source: ${source} (HTTP ${response.status})`);
354
+ }
355
+ const blob = await response.blob();
356
+ const mimeType = blob.type || 'image/png';
357
+ const { naturalWidth, naturalHeight } = await this.measureImageBlob(blob);
358
+ const asset = await this._core.assetResolver.put(blob, {
359
+ mimeType,
360
+ kind: 'image',
361
+ width: naturalWidth,
362
+ height: naturalHeight,
363
+ });
364
+ this.assetId = asset.id;
365
+ this.mimeType = asset.mimeType;
366
+ if (this.width <= 0 || this.height <= 0) {
367
+ const { scaledWidth, scaledHeight } = this.calculateScaledDimensions({
368
+ width: naturalWidth,
369
+ height: naturalHeight,
370
+ });
371
+ this.width = scaledWidth;
372
+ this.height = scaledHeight;
373
+ }
374
+ this.resolvedSrc = await this._core.assetResolver.resolve(asset.id);
375
+ this.loadState = 'ready';
376
+ this.src = '';
377
+ }
378
+ /**
379
+ * Measures intrinsic image dimensions from a Blob.
380
+ */
381
+ async measureImageBlob(blob) {
382
+ const objectUrl = URL.createObjectURL(blob);
383
+ try {
384
+ return await new Promise((resolve, reject) => {
385
+ const img = new Image();
386
+ img.onload = () => resolve({ naturalWidth: img.naturalWidth, naturalHeight: img.naturalHeight });
387
+ img.onerror = err => reject(err);
388
+ img.src = objectUrl;
389
+ });
390
+ }
391
+ finally {
392
+ URL.revokeObjectURL(objectUrl);
393
+ }
394
+ }
395
+ /**
396
+ * Overrides base mount to kick off asset resolution the first time
397
+ * the image is attached to the DOM. Legacy images persisted with an
398
+ * inline `src` data URL are opportunistically migrated to the asset
399
+ * storage layer on first mount.
400
+ */
401
+ mount(element) {
402
+ super.mount(element);
403
+ this.ensureLoaded();
404
+ }
405
+ /**
406
+ * Creates a KritzelImage from a URL, handling image loading and dimension calculation.
407
+ * Loads the image, calculates scaled dimensions respecting maxWidth/maxHeight constraints,
408
+ * and returns a fully configured KritzelImage instance.
409
+ *
410
+ * Intended for legacy / data-URL code paths only. New callers should
411
+ * upload through the asset resolver and construct the image from the
412
+ * resulting asset descriptor.
413
+ * @param src - The image URL or data URI to load.
414
+ * @param config - Optional partial configuration to pass to the KritzelImage constructor.
415
+ * @returns A promise resolving to a fully configured KritzelImage with correct dimensions.
416
+ */
417
+ static fromUrl(src, config) {
418
+ return new Promise((resolve, reject) => {
419
+ const img = new Image();
420
+ img.onload = () => {
421
+ const image = new KritzelImage({ ...config, src });
422
+ const { scaledWidth, scaledHeight } = image.calculateScaledDimensions(img);
423
+ image.width = scaledWidth;
424
+ image.height = scaledHeight;
425
+ resolve(image);
426
+ };
427
+ img.onerror = (err) => reject(err);
428
+ img.src = src;
429
+ });
430
+ }
431
+ /**
432
+ * Creates a fully initialized KritzelImage from a Blob.
433
+ * Uploads the blob via the asset resolver and sets up dimensions/asset references.
434
+ *
435
+ * @param core - The KritzelCore instance providing the asset resolver and state.
436
+ * @param blob - The image Blob (e.g. from clipboard or file picker).
437
+ * @param config - Optional configuration to merge into the new image.
438
+ * @returns A promise resolving to a fully loaded KritzelImage object.
439
+ */
440
+ static async fromBlob(core, blob, config) {
441
+ const objectUrl = URL.createObjectURL(blob);
442
+ try {
443
+ const dimensions = await new Promise((resolve, reject) => {
444
+ const img = new Image();
445
+ img.onload = () => resolve({ naturalWidth: img.naturalWidth, naturalHeight: img.naturalHeight });
446
+ img.onerror = err => reject(err);
447
+ img.src = objectUrl;
448
+ });
449
+ const mimeType = blob.type || 'image/png';
450
+ const asset = await core.assetResolver.put(blob, {
451
+ mimeType,
452
+ kind: 'image',
453
+ width: dimensions.naturalWidth,
454
+ height: dimensions.naturalHeight,
455
+ });
456
+ const image = KritzelImage.create(core, config);
457
+ image.assetId = asset.id;
458
+ image.mimeType = asset.mimeType;
459
+ const { scaledWidth, scaledHeight } = image.calculateScaledDimensions({
460
+ width: dimensions.naturalWidth,
461
+ height: dimensions.naturalHeight,
462
+ });
463
+ image.width = scaledWidth;
464
+ image.height = scaledHeight;
465
+ image.resolvedSrc = await core.assetResolver.resolve(asset.id);
466
+ image.loadState = 'ready';
467
+ return image;
468
+ }
469
+ finally {
470
+ URL.revokeObjectURL(objectUrl);
471
+ }
472
+ }
473
+ /**
474
+ * Calculates scaled dimensions for an image while respecting maxWidth and maxHeight constraints.
475
+ * Maintains the original aspect ratio by using the smaller of the two scale ratios.
476
+ * @param img - The HTMLImageElement to calculate dimensions for.
477
+ * @returns An object containing the scaled width and height values.
478
+ */
479
+ calculateScaledDimensions(img) {
480
+ let scaledWidth = img.width;
481
+ let scaledHeight = img.height;
482
+ if (img.width > this.maxWidth || img.height > this.maxHeight) {
483
+ const widthRatio = this.maxWidth / img.width;
484
+ const heightRatio = this.maxHeight / img.height;
485
+ const scaleRatio = Math.min(widthRatio, heightRatio);
486
+ scaledWidth = img.width * scaleRatio;
487
+ scaledHeight = img.height * scaleRatio;
488
+ }
489
+ return { scaledWidth, scaledHeight };
490
+ }
491
+ getSupportedExportFormats() {
492
+ return ['png'];
493
+ }
494
+ async exportAs(format, context) {
495
+ if (format !== 'png') {
496
+ return null;
497
+ }
498
+ return context.getObjectAsPngDataUrl(this);
499
+ }
500
+ }