js-draw 0.25.1 → 1.0.1

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 (750) hide show
  1. package/README.md +80 -26
  2. package/build-config.json +22 -21
  3. package/dist/Editor.css +1281 -0
  4. package/dist/bundle.js +3 -3
  5. package/dist/bundledStyles.js +1 -1
  6. package/dist/cjs/Editor.d.ts +91 -12
  7. package/dist/cjs/Editor.js +619 -590
  8. package/dist/cjs/EditorImage.d.ts +5 -2
  9. package/dist/cjs/EditorImage.js +258 -297
  10. package/dist/cjs/EventDispatcher.js +17 -19
  11. package/dist/cjs/Pointer.d.ts +3 -1
  12. package/dist/cjs/Pointer.js +41 -44
  13. package/dist/cjs/SVGLoader.d.ts +7 -1
  14. package/dist/cjs/SVGLoader.js +373 -474
  15. package/dist/cjs/UndoRedoHistory.js +28 -40
  16. package/dist/cjs/Viewport.d.ts +1 -4
  17. package/dist/cjs/Viewport.js +150 -193
  18. package/dist/cjs/bundle/bundled.js +4 -1
  19. package/dist/cjs/commands/Command.js +22 -49
  20. package/dist/cjs/commands/Duplicate.js +28 -44
  21. package/dist/cjs/commands/Erase.js +36 -54
  22. package/dist/cjs/commands/SerializableCommand.js +20 -35
  23. package/dist/cjs/commands/UnresolvedCommand.js +14 -29
  24. package/dist/cjs/commands/invertCommand.js +29 -51
  25. package/dist/cjs/commands/lib.js +9 -6
  26. package/dist/cjs/commands/localization.d.ts +1 -1
  27. package/dist/cjs/commands/localization.js +9 -9
  28. package/dist/cjs/commands/uniteCommands.js +57 -87
  29. package/dist/cjs/components/AbstractComponent.d.ts +11 -3
  30. package/dist/cjs/components/AbstractComponent.js +141 -169
  31. package/dist/cjs/components/BackgroundComponent.d.ts +3 -6
  32. package/dist/cjs/components/BackgroundComponent.js +124 -149
  33. package/dist/cjs/components/ImageComponent.d.ts +3 -5
  34. package/dist/cjs/components/ImageComponent.js +95 -175
  35. package/dist/cjs/components/RestylableComponent.d.ts +1 -1
  36. package/dist/cjs/components/RestylableComponent.js +41 -56
  37. package/dist/cjs/components/SVGGlobalAttributesObject.d.ts +1 -3
  38. package/dist/cjs/components/SVGGlobalAttributesObject.js +34 -51
  39. package/dist/cjs/components/Stroke.d.ts +4 -6
  40. package/dist/cjs/components/Stroke.js +95 -121
  41. package/dist/cjs/components/TextComponent.d.ts +2 -4
  42. package/dist/cjs/components/TextComponent.js +189 -234
  43. package/dist/cjs/components/UnknownSVGObject.d.ts +1 -3
  44. package/dist/cjs/components/UnknownSVGObject.js +30 -43
  45. package/dist/cjs/components/builders/ArrowBuilder.d.ts +1 -1
  46. package/dist/cjs/components/builders/ArrowBuilder.js +43 -42
  47. package/dist/cjs/components/builders/CircleBuilder.js +43 -43
  48. package/dist/cjs/components/builders/FreehandLineBuilder.d.ts +3 -2
  49. package/dist/cjs/components/builders/FreehandLineBuilder.js +73 -86
  50. package/dist/cjs/components/builders/LineBuilder.d.ts +1 -1
  51. package/dist/cjs/components/builders/LineBuilder.js +38 -36
  52. package/dist/cjs/components/builders/PressureSensitiveFreehandLineBuilder.d.ts +1 -1
  53. package/dist/cjs/components/builders/PressureSensitiveFreehandLineBuilder.js +131 -139
  54. package/dist/cjs/components/builders/RectangleBuilder.d.ts +1 -1
  55. package/dist/cjs/components/builders/RectangleBuilder.js +31 -31
  56. package/dist/cjs/components/builders/types.d.ts +1 -1
  57. package/dist/cjs/components/lib.d.ts +3 -1
  58. package/dist/cjs/components/lib.js +10 -7
  59. package/dist/cjs/components/localization.js +4 -4
  60. package/dist/cjs/components/util/StrokeSmoother.d.ts +1 -2
  61. package/dist/cjs/components/util/StrokeSmoother.js +67 -72
  62. package/dist/cjs/components/util/describeComponentList.d.ts +1 -1
  63. package/dist/cjs/components/util/describeComponentList.js +4 -5
  64. package/dist/cjs/dialogs/makeAboutDialog.d.ts +15 -0
  65. package/dist/cjs/dialogs/makeAboutDialog.js +54 -0
  66. package/dist/cjs/inputEvents.d.ts +84 -0
  67. package/dist/cjs/inputEvents.js +40 -0
  68. package/dist/cjs/lib.d.ts +29 -13
  69. package/dist/cjs/lib.js +38 -23
  70. package/dist/cjs/localization.js +19 -18
  71. package/dist/cjs/localizations/de.js +117 -13
  72. package/dist/cjs/localizations/en.js +4 -13
  73. package/dist/cjs/localizations/es.js +62 -23
  74. package/dist/cjs/localizations/getLocalizationTable.js +15 -13
  75. package/dist/cjs/rendering/Display.d.ts +1 -2
  76. package/dist/cjs/rendering/Display.js +70 -83
  77. package/dist/cjs/rendering/RenderablePathSpec.d.ts +15 -0
  78. package/dist/cjs/rendering/RenderablePathSpec.js +70 -0
  79. package/dist/cjs/rendering/RenderingStyle.d.ts +4 -4
  80. package/dist/cjs/rendering/RenderingStyle.js +18 -28
  81. package/dist/cjs/rendering/TextRenderingStyle.d.ts +10 -10
  82. package/dist/cjs/rendering/TextRenderingStyle.js +13 -18
  83. package/dist/cjs/rendering/caching/CacheRecord.d.ts +1 -2
  84. package/dist/cjs/rendering/caching/CacheRecord.js +20 -22
  85. package/dist/cjs/rendering/caching/CacheRecordManager.d.ts +1 -1
  86. package/dist/cjs/rendering/caching/CacheRecordManager.js +17 -15
  87. package/dist/cjs/rendering/caching/RenderingCache.js +19 -19
  88. package/dist/cjs/rendering/caching/RenderingCacheNode.d.ts +1 -1
  89. package/dist/cjs/rendering/caching/RenderingCacheNode.js +98 -118
  90. package/dist/cjs/rendering/caching/testUtils.js +24 -23
  91. package/dist/cjs/rendering/caching/types.d.ts +3 -3
  92. package/dist/cjs/rendering/lib.js +8 -5
  93. package/dist/cjs/rendering/localization.js +5 -5
  94. package/dist/cjs/rendering/renderers/AbstractRenderer.d.ts +2 -11
  95. package/dist/cjs/rendering/renderers/AbstractRenderer.js +53 -57
  96. package/dist/cjs/rendering/renderers/CanvasRenderer.d.ts +3 -5
  97. package/dist/cjs/rendering/renderers/CanvasRenderer.js +91 -106
  98. package/dist/cjs/rendering/renderers/DummyRenderer.d.ts +1 -4
  99. package/dist/cjs/rendering/renderers/DummyRenderer.js +56 -76
  100. package/dist/cjs/rendering/renderers/SVGRenderer.d.ts +5 -5
  101. package/dist/cjs/rendering/renderers/SVGRenderer.js +194 -176
  102. package/dist/cjs/rendering/renderers/TextOnlyRenderer.d.ts +1 -3
  103. package/dist/cjs/rendering/renderers/TextOnlyRenderer.js +47 -72
  104. package/dist/cjs/shortcuts/KeyBinding.d.ts +5 -0
  105. package/dist/cjs/shortcuts/KeyBinding.js +94 -70
  106. package/dist/cjs/shortcuts/KeyboardShortcutManager.d.ts +1 -1
  107. package/dist/cjs/shortcuts/KeyboardShortcutManager.js +36 -45
  108. package/dist/cjs/shortcuts/lib.js +5 -2
  109. package/dist/cjs/testing/createEditor.js +7 -4
  110. package/dist/cjs/testing/getUniquePointerId.js +4 -5
  111. package/dist/cjs/testing/lib.js +5 -2
  112. package/dist/cjs/testing/sendPenEvent.d.ts +2 -2
  113. package/dist/cjs/testing/sendPenEvent.js +10 -7
  114. package/dist/cjs/testing/sendTouchEvent.d.ts +2 -2
  115. package/dist/cjs/testing/sendTouchEvent.js +34 -16
  116. package/dist/cjs/toolbar/AbstractToolbar.d.ts +166 -0
  117. package/dist/cjs/toolbar/AbstractToolbar.js +410 -0
  118. package/dist/cjs/toolbar/DropdownToolbar.d.ts +43 -0
  119. package/dist/cjs/toolbar/DropdownToolbar.js +176 -0
  120. package/dist/cjs/toolbar/EdgeToolbar.d.ts +47 -0
  121. package/dist/cjs/toolbar/EdgeToolbar.js +422 -0
  122. package/dist/cjs/toolbar/IconProvider.d.ts +54 -30
  123. package/dist/cjs/toolbar/IconProvider.js +652 -224
  124. package/dist/cjs/toolbar/constants.d.ts +1 -0
  125. package/dist/cjs/toolbar/constants.js +4 -0
  126. package/dist/cjs/toolbar/lib.d.ts +4 -2
  127. package/dist/cjs/toolbar/lib.js +10 -3
  128. package/dist/cjs/toolbar/localization.d.ts +9 -2
  129. package/dist/cjs/toolbar/localization.js +26 -19
  130. package/dist/cjs/toolbar/types.d.ts +7 -0
  131. package/dist/cjs/toolbar/widgets/ActionButtonWidget.d.ts +1 -1
  132. package/dist/cjs/toolbar/widgets/ActionButtonWidget.js +23 -39
  133. package/dist/cjs/toolbar/widgets/BaseToolWidget.d.ts +1 -1
  134. package/dist/cjs/toolbar/widgets/BaseToolWidget.js +35 -37
  135. package/dist/cjs/toolbar/widgets/BaseWidget.d.ts +60 -5
  136. package/dist/cjs/toolbar/widgets/BaseWidget.js +232 -177
  137. package/dist/cjs/toolbar/widgets/DocumentPropertiesWidget.js +130 -117
  138. package/dist/cjs/toolbar/widgets/EraserToolWidget.d.ts +1 -3
  139. package/dist/cjs/toolbar/widgets/EraserToolWidget.js +45 -73
  140. package/dist/cjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
  141. package/dist/cjs/toolbar/widgets/HandToolWidget.js +126 -141
  142. package/dist/cjs/toolbar/widgets/InsertImageWidget.d.ts +9 -7
  143. package/dist/cjs/toolbar/widgets/InsertImageWidget.js +147 -212
  144. package/dist/cjs/toolbar/widgets/OverflowWidget.js +33 -61
  145. package/dist/cjs/toolbar/widgets/PenToolWidget.d.ts +8 -1
  146. package/dist/cjs/toolbar/widgets/PenToolWidget.js +162 -234
  147. package/dist/cjs/toolbar/widgets/SelectionToolWidget.d.ts +3 -1
  148. package/dist/cjs/toolbar/widgets/SelectionToolWidget.js +105 -177
  149. package/dist/cjs/toolbar/widgets/TextToolWidget.js +64 -87
  150. package/dist/cjs/toolbar/widgets/components/makeColorInput.d.ts +10 -0
  151. package/dist/cjs/toolbar/{makeColorInput.js → widgets/components/makeColorInput.js} +57 -34
  152. package/dist/cjs/toolbar/widgets/components/makeFileInput.d.ts +12 -0
  153. package/dist/cjs/toolbar/widgets/components/makeFileInput.js +111 -0
  154. package/dist/cjs/toolbar/widgets/components/makeGridSelector.d.ts +24 -0
  155. package/dist/cjs/toolbar/widgets/components/makeGridSelector.js +127 -0
  156. package/dist/cjs/toolbar/widgets/components/makeSeparator.d.ts +7 -0
  157. package/dist/cjs/toolbar/widgets/components/makeSeparator.js +16 -0
  158. package/dist/cjs/toolbar/widgets/components/makeThicknessSlider.d.ts +8 -0
  159. package/dist/cjs/toolbar/widgets/components/makeThicknessSlider.js +47 -0
  160. package/dist/cjs/toolbar/widgets/keybindings.js +8 -5
  161. package/dist/cjs/toolbar/widgets/layout/DropdownLayoutManager.d.ts +21 -0
  162. package/dist/cjs/toolbar/widgets/layout/DropdownLayoutManager.js +199 -0
  163. package/dist/cjs/toolbar/widgets/layout/EdgeToolbarLayoutManager.d.ts +14 -0
  164. package/dist/cjs/toolbar/widgets/layout/EdgeToolbarLayoutManager.js +60 -0
  165. package/dist/cjs/toolbar/widgets/layout/types.d.ts +63 -0
  166. package/dist/cjs/toolbar/widgets/layout/types.js +2 -0
  167. package/dist/cjs/toolbar/widgets/lib.d.ts +1 -1
  168. package/dist/cjs/toolbar/widgets/lib.js +15 -11
  169. package/dist/cjs/tools/BaseTool.d.ts +28 -9
  170. package/dist/cjs/tools/BaseTool.js +128 -51
  171. package/dist/cjs/tools/Eraser.d.ts +8 -1
  172. package/dist/cjs/tools/Eraser.js +82 -92
  173. package/dist/cjs/tools/FindTool.d.ts +1 -1
  174. package/dist/cjs/tools/FindTool.js +61 -77
  175. package/dist/cjs/tools/InputFilter/FunctionMapper.d.ts +12 -0
  176. package/dist/cjs/tools/InputFilter/FunctionMapper.js +21 -0
  177. package/dist/cjs/tools/InputFilter/InputMapper.d.ts +23 -0
  178. package/dist/cjs/tools/InputFilter/InputMapper.js +38 -0
  179. package/dist/cjs/tools/InputFilter/InputPipeline.d.ts +15 -0
  180. package/dist/cjs/tools/InputFilter/InputPipeline.js +54 -0
  181. package/dist/cjs/tools/InputFilter/InputStabilizer.d.ts +29 -0
  182. package/dist/cjs/tools/InputFilter/InputStabilizer.js +181 -0
  183. package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.d.ts +21 -0
  184. package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.js +84 -0
  185. package/dist/cjs/tools/PanZoom.d.ts +4 -2
  186. package/dist/cjs/tools/PanZoom.js +186 -248
  187. package/dist/cjs/tools/PasteHandler.d.ts +1 -1
  188. package/dist/cjs/tools/PasteHandler.js +49 -148
  189. package/dist/cjs/tools/Pen.d.ts +12 -11
  190. package/dist/cjs/tools/Pen.js +123 -158
  191. package/dist/cjs/tools/PipetteTool.d.ts +11 -2
  192. package/dist/cjs/tools/PipetteTool.js +51 -48
  193. package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +1 -1
  194. package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.js +15 -30
  195. package/dist/cjs/tools/SelectionTool/Selection.d.ts +5 -5
  196. package/dist/cjs/tools/SelectionTool/Selection.js +308 -415
  197. package/dist/cjs/tools/SelectionTool/SelectionHandle.d.ts +15 -5
  198. package/dist/cjs/tools/SelectionTool/SelectionHandle.js +63 -37
  199. package/dist/cjs/tools/SelectionTool/SelectionTool.d.ts +4 -4
  200. package/dist/cjs/tools/SelectionTool/SelectionTool.js +164 -187
  201. package/dist/cjs/tools/SelectionTool/TransformMode.d.ts +1 -1
  202. package/dist/cjs/tools/SelectionTool/TransformMode.js +65 -66
  203. package/dist/cjs/tools/SoundUITool.d.ts +2 -1
  204. package/dist/cjs/tools/SoundUITool.js +70 -84
  205. package/dist/cjs/tools/TextTool.d.ts +5 -3
  206. package/dist/cjs/tools/TextTool.js +169 -173
  207. package/dist/cjs/tools/ToolController.d.ts +16 -2
  208. package/dist/cjs/tools/ToolController.js +124 -100
  209. package/dist/cjs/tools/ToolEnabledGroup.js +6 -9
  210. package/dist/cjs/tools/ToolSwitcherShortcut.d.ts +1 -1
  211. package/dist/cjs/tools/ToolSwitcherShortcut.js +16 -32
  212. package/dist/cjs/tools/ToolbarShortcutHandler.d.ts +1 -1
  213. package/dist/cjs/tools/ToolbarShortcutHandler.js +17 -33
  214. package/dist/cjs/tools/UndoRedoShortcut.d.ts +1 -1
  215. package/dist/cjs/tools/UndoRedoShortcut.js +12 -27
  216. package/dist/cjs/tools/keybindings.js +21 -18
  217. package/dist/cjs/tools/lib.js +17 -14
  218. package/dist/cjs/tools/localization.d.ts +2 -1
  219. package/dist/cjs/tools/localization.js +8 -7
  220. package/dist/cjs/types.d.ts +22 -80
  221. package/dist/cjs/types.js +8 -16
  222. package/dist/cjs/util/ReactiveValue.d.ts +65 -0
  223. package/dist/cjs/util/ReactiveValue.js +166 -0
  224. package/dist/cjs/util/assertions.js +5 -8
  225. package/dist/cjs/util/fileToBase64.js +6 -6
  226. package/dist/cjs/util/guessKeyCodeFromKey.d.ts +9 -0
  227. package/dist/cjs/util/guessKeyCodeFromKey.js +32 -0
  228. package/dist/cjs/util/listPrefixMatch.d.ts +6 -0
  229. package/dist/cjs/util/listPrefixMatch.js +17 -0
  230. package/dist/cjs/util/stopPropagationOfScrollingWheelEvents.d.ts +2 -0
  231. package/dist/cjs/util/stopPropagationOfScrollingWheelEvents.js +17 -0
  232. package/dist/cjs/util/untilNextAnimationFrame.js +3 -3
  233. package/dist/cjs/util/waitForAll.js +3 -3
  234. package/dist/cjs/util/waitForTimeout.js +3 -3
  235. package/dist/cjs/version.d.ts +4 -0
  236. package/dist/cjs/version.js +5 -0
  237. package/dist/mjs/Editor.d.ts +91 -12
  238. package/dist/mjs/Editor.mjs +565 -563
  239. package/dist/mjs/EditorImage.d.ts +5 -2
  240. package/dist/mjs/EditorImage.mjs +248 -291
  241. package/dist/mjs/EventDispatcher.mjs +17 -20
  242. package/dist/mjs/Pointer.d.ts +3 -1
  243. package/dist/mjs/Pointer.mjs +40 -44
  244. package/dist/mjs/SVGLoader.d.ts +7 -1
  245. package/dist/mjs/SVGLoader.mjs +338 -466
  246. package/dist/mjs/UndoRedoHistory.mjs +27 -39
  247. package/dist/mjs/Viewport.d.ts +1 -4
  248. package/dist/mjs/Viewport.mjs +139 -187
  249. package/dist/mjs/commands/Command.mjs +21 -49
  250. package/dist/mjs/commands/Duplicate.mjs +22 -41
  251. package/dist/mjs/commands/Erase.mjs +30 -51
  252. package/dist/mjs/commands/SerializableCommand.mjs +16 -34
  253. package/dist/mjs/commands/UnresolvedCommand.mjs +10 -29
  254. package/dist/mjs/commands/invertCommand.mjs +24 -49
  255. package/dist/mjs/commands/localization.d.ts +1 -1
  256. package/dist/mjs/commands/localization.mjs +10 -10
  257. package/dist/mjs/commands/uniteCommands.mjs +52 -85
  258. package/dist/mjs/components/AbstractComponent.d.ts +11 -3
  259. package/dist/mjs/components/AbstractComponent.mjs +135 -166
  260. package/dist/mjs/components/BackgroundComponent.d.ts +3 -6
  261. package/dist/mjs/components/BackgroundComponent.mjs +107 -136
  262. package/dist/mjs/components/ImageComponent.d.ts +3 -5
  263. package/dist/mjs/components/ImageComponent.mjs +90 -174
  264. package/dist/mjs/components/RestylableComponent.d.ts +1 -1
  265. package/dist/mjs/components/RestylableComponent.mjs +35 -53
  266. package/dist/mjs/components/SVGGlobalAttributesObject.d.ts +1 -3
  267. package/dist/mjs/components/SVGGlobalAttributesObject.mjs +29 -50
  268. package/dist/mjs/components/Stroke.d.ts +4 -6
  269. package/dist/mjs/components/Stroke.mjs +89 -119
  270. package/dist/mjs/components/TextComponent.d.ts +2 -4
  271. package/dist/mjs/components/TextComponent.mjs +180 -228
  272. package/dist/mjs/components/UnknownSVGObject.d.ts +1 -3
  273. package/dist/mjs/components/UnknownSVGObject.mjs +26 -43
  274. package/dist/mjs/components/builders/ArrowBuilder.d.ts +1 -1
  275. package/dist/mjs/components/builders/ArrowBuilder.mjs +32 -35
  276. package/dist/mjs/components/builders/CircleBuilder.mjs +35 -38
  277. package/dist/mjs/components/builders/FreehandLineBuilder.d.ts +3 -2
  278. package/dist/mjs/components/builders/FreehandLineBuilder.mjs +52 -69
  279. package/dist/mjs/components/builders/LineBuilder.d.ts +1 -1
  280. package/dist/mjs/components/builders/LineBuilder.mjs +30 -32
  281. package/dist/mjs/components/builders/PressureSensitiveFreehandLineBuilder.d.ts +1 -1
  282. package/dist/mjs/components/builders/PressureSensitiveFreehandLineBuilder.mjs +103 -115
  283. package/dist/mjs/components/builders/RectangleBuilder.d.ts +1 -1
  284. package/dist/mjs/components/builders/RectangleBuilder.mjs +27 -31
  285. package/dist/mjs/components/builders/types.d.ts +1 -1
  286. package/dist/mjs/components/lib.d.ts +3 -1
  287. package/dist/mjs/components/lib.mjs +1 -1
  288. package/dist/mjs/components/localization.mjs +5 -5
  289. package/dist/mjs/components/util/StrokeSmoother.d.ts +1 -2
  290. package/dist/mjs/components/util/StrokeSmoother.mjs +63 -69
  291. package/dist/mjs/components/util/describeComponentList.d.ts +1 -1
  292. package/dist/mjs/components/util/describeComponentList.mjs +4 -5
  293. package/dist/mjs/dialogs/makeAboutDialog.d.ts +15 -0
  294. package/dist/mjs/dialogs/makeAboutDialog.mjs +52 -0
  295. package/dist/mjs/inputEvents.d.ts +84 -0
  296. package/dist/mjs/inputEvents.mjs +34 -0
  297. package/dist/mjs/lib.d.ts +29 -13
  298. package/dist/mjs/lib.mjs +30 -13
  299. package/dist/mjs/localization.mjs +14 -13
  300. package/dist/mjs/localizations/de.mjs +116 -12
  301. package/dist/mjs/localizations/en.mjs +3 -12
  302. package/dist/mjs/localizations/es.mjs +61 -22
  303. package/dist/mjs/localizations/getLocalizationTable.mjs +12 -13
  304. package/dist/mjs/rendering/Display.d.ts +1 -2
  305. package/dist/mjs/rendering/Display.mjs +62 -79
  306. package/dist/mjs/rendering/RenderablePathSpec.d.ts +15 -0
  307. package/dist/mjs/rendering/RenderablePathSpec.mjs +64 -0
  308. package/dist/mjs/rendering/RenderingStyle.d.ts +4 -4
  309. package/dist/mjs/rendering/RenderingStyle.mjs +16 -26
  310. package/dist/mjs/rendering/TextRenderingStyle.d.ts +10 -10
  311. package/dist/mjs/rendering/TextRenderingStyle.mjs +12 -17
  312. package/dist/mjs/rendering/caching/CacheRecord.d.ts +1 -2
  313. package/dist/mjs/rendering/caching/CacheRecord.mjs +20 -23
  314. package/dist/mjs/rendering/caching/CacheRecordManager.d.ts +1 -1
  315. package/dist/mjs/rendering/caching/CacheRecordManager.mjs +13 -15
  316. package/dist/mjs/rendering/caching/RenderingCache.mjs +13 -17
  317. package/dist/mjs/rendering/caching/RenderingCacheNode.d.ts +1 -1
  318. package/dist/mjs/rendering/caching/RenderingCacheNode.mjs +94 -115
  319. package/dist/mjs/rendering/caching/testUtils.mjs +19 -21
  320. package/dist/mjs/rendering/caching/types.d.ts +3 -3
  321. package/dist/mjs/rendering/localization.mjs +6 -6
  322. package/dist/mjs/rendering/renderers/AbstractRenderer.d.ts +2 -11
  323. package/dist/mjs/rendering/renderers/AbstractRenderer.mjs +47 -52
  324. package/dist/mjs/rendering/renderers/CanvasRenderer.d.ts +3 -5
  325. package/dist/mjs/rendering/renderers/CanvasRenderer.mjs +84 -103
  326. package/dist/mjs/rendering/renderers/DummyRenderer.d.ts +1 -4
  327. package/dist/mjs/rendering/renderers/DummyRenderer.mjs +51 -75
  328. package/dist/mjs/rendering/renderers/SVGRenderer.d.ts +5 -5
  329. package/dist/mjs/rendering/renderers/SVGRenderer.mjs +185 -171
  330. package/dist/mjs/rendering/renderers/TextOnlyRenderer.d.ts +1 -3
  331. package/dist/mjs/rendering/renderers/TextOnlyRenderer.mjs +43 -72
  332. package/dist/mjs/shortcuts/KeyBinding.d.ts +5 -0
  333. package/dist/mjs/shortcuts/KeyBinding.mjs +94 -71
  334. package/dist/mjs/shortcuts/KeyboardShortcutManager.d.ts +1 -1
  335. package/dist/mjs/shortcuts/KeyboardShortcutManager.mjs +32 -44
  336. package/dist/mjs/testing/createEditor.mjs +2 -2
  337. package/dist/mjs/testing/getUniquePointerId.mjs +4 -5
  338. package/dist/mjs/testing/sendPenEvent.d.ts +2 -2
  339. package/dist/mjs/testing/sendPenEvent.mjs +5 -5
  340. package/dist/mjs/testing/sendTouchEvent.d.ts +2 -2
  341. package/dist/mjs/testing/sendTouchEvent.mjs +8 -16
  342. package/dist/mjs/toolbar/AbstractToolbar.d.ts +166 -0
  343. package/dist/mjs/toolbar/AbstractToolbar.mjs +405 -0
  344. package/dist/mjs/toolbar/DropdownToolbar.d.ts +43 -0
  345. package/dist/mjs/toolbar/DropdownToolbar.mjs +168 -0
  346. package/dist/mjs/toolbar/EdgeToolbar.d.ts +47 -0
  347. package/dist/mjs/toolbar/EdgeToolbar.mjs +414 -0
  348. package/dist/mjs/toolbar/IconProvider.d.ts +54 -30
  349. package/dist/mjs/toolbar/IconProvider.mjs +644 -219
  350. package/dist/mjs/toolbar/constants.d.ts +1 -0
  351. package/dist/mjs/toolbar/constants.mjs +1 -0
  352. package/dist/mjs/toolbar/lib.d.ts +4 -2
  353. package/dist/mjs/toolbar/lib.mjs +3 -1
  354. package/dist/mjs/toolbar/localization.d.ts +9 -2
  355. package/dist/mjs/toolbar/localization.mjs +27 -20
  356. package/dist/mjs/toolbar/types.d.ts +7 -0
  357. package/dist/mjs/toolbar/widgets/ActionButtonWidget.d.ts +1 -1
  358. package/dist/mjs/toolbar/widgets/ActionButtonWidget.mjs +19 -39
  359. package/dist/mjs/toolbar/widgets/BaseToolWidget.d.ts +1 -1
  360. package/dist/mjs/toolbar/widgets/BaseToolWidget.mjs +30 -36
  361. package/dist/mjs/toolbar/widgets/BaseWidget.d.ts +60 -5
  362. package/dist/mjs/toolbar/widgets/BaseWidget.mjs +227 -176
  363. package/dist/mjs/toolbar/widgets/DocumentPropertiesWidget.mjs +98 -111
  364. package/dist/mjs/toolbar/widgets/EraserToolWidget.d.ts +1 -3
  365. package/dist/mjs/toolbar/widgets/EraserToolWidget.mjs +41 -73
  366. package/dist/mjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
  367. package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +94 -136
  368. package/dist/mjs/toolbar/widgets/InsertImageWidget.d.ts +9 -7
  369. package/dist/mjs/toolbar/widgets/InsertImageWidget.mjs +140 -208
  370. package/dist/mjs/toolbar/widgets/OverflowWidget.mjs +30 -62
  371. package/dist/mjs/toolbar/widgets/PenToolWidget.d.ts +8 -1
  372. package/dist/mjs/toolbar/widgets/PenToolWidget.mjs +150 -225
  373. package/dist/mjs/toolbar/widgets/SelectionToolWidget.d.ts +3 -1
  374. package/dist/mjs/toolbar/widgets/SelectionToolWidget.mjs +97 -173
  375. package/dist/mjs/toolbar/widgets/TextToolWidget.mjs +59 -85
  376. package/dist/mjs/toolbar/widgets/components/makeColorInput.d.ts +10 -0
  377. package/dist/mjs/toolbar/{makeColorInput.mjs → widgets/components/makeColorInput.mjs} +53 -33
  378. package/dist/mjs/toolbar/widgets/components/makeFileInput.d.ts +12 -0
  379. package/dist/mjs/toolbar/widgets/components/makeFileInput.mjs +106 -0
  380. package/dist/mjs/toolbar/widgets/components/makeGridSelector.d.ts +24 -0
  381. package/dist/mjs/toolbar/widgets/components/makeGridSelector.mjs +122 -0
  382. package/dist/mjs/toolbar/widgets/components/makeSeparator.d.ts +7 -0
  383. package/dist/mjs/toolbar/widgets/components/makeSeparator.mjs +14 -0
  384. package/dist/mjs/toolbar/widgets/components/makeThicknessSlider.d.ts +8 -0
  385. package/dist/mjs/toolbar/widgets/components/makeThicknessSlider.mjs +45 -0
  386. package/dist/mjs/toolbar/widgets/keybindings.mjs +5 -5
  387. package/dist/mjs/toolbar/widgets/layout/DropdownLayoutManager.d.ts +21 -0
  388. package/dist/mjs/toolbar/widgets/layout/DropdownLayoutManager.mjs +193 -0
  389. package/dist/mjs/toolbar/widgets/layout/EdgeToolbarLayoutManager.d.ts +14 -0
  390. package/dist/mjs/toolbar/widgets/layout/EdgeToolbarLayoutManager.mjs +57 -0
  391. package/dist/mjs/toolbar/widgets/layout/types.d.ts +63 -0
  392. package/dist/mjs/toolbar/widgets/lib.d.ts +1 -1
  393. package/dist/mjs/toolbar/widgets/lib.mjs +1 -1
  394. package/dist/mjs/tools/BaseTool.d.ts +28 -9
  395. package/dist/mjs/tools/BaseTool.mjs +127 -50
  396. package/dist/mjs/tools/Eraser.d.ts +8 -1
  397. package/dist/mjs/tools/Eraser.mjs +72 -86
  398. package/dist/mjs/tools/FindTool.d.ts +1 -1
  399. package/dist/mjs/tools/FindTool.mjs +55 -75
  400. package/dist/mjs/tools/InputFilter/FunctionMapper.d.ts +12 -0
  401. package/dist/mjs/tools/InputFilter/FunctionMapper.mjs +15 -0
  402. package/dist/mjs/tools/InputFilter/InputMapper.d.ts +23 -0
  403. package/dist/mjs/tools/InputFilter/InputMapper.mjs +36 -0
  404. package/dist/mjs/tools/InputFilter/InputPipeline.d.ts +15 -0
  405. package/dist/mjs/tools/InputFilter/InputPipeline.mjs +49 -0
  406. package/dist/mjs/tools/InputFilter/InputStabilizer.d.ts +29 -0
  407. package/dist/mjs/tools/InputFilter/InputStabilizer.mjs +175 -0
  408. package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.d.ts +21 -0
  409. package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.mjs +78 -0
  410. package/dist/mjs/tools/PanZoom.d.ts +4 -2
  411. package/dist/mjs/tools/PanZoom.mjs +169 -235
  412. package/dist/mjs/tools/PasteHandler.d.ts +1 -1
  413. package/dist/mjs/tools/PasteHandler.mjs +42 -145
  414. package/dist/mjs/tools/Pen.d.ts +12 -11
  415. package/dist/mjs/tools/Pen.mjs +115 -154
  416. package/dist/mjs/tools/PipetteTool.d.ts +11 -2
  417. package/dist/mjs/tools/PipetteTool.mjs +47 -48
  418. package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +1 -1
  419. package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.mjs +9 -28
  420. package/dist/mjs/tools/SelectionTool/Selection.d.ts +5 -5
  421. package/dist/mjs/tools/SelectionTool/Selection.mjs +268 -401
  422. package/dist/mjs/tools/SelectionTool/SelectionHandle.d.ts +15 -5
  423. package/dist/mjs/tools/SelectionTool/SelectionHandle.mjs +62 -37
  424. package/dist/mjs/tools/SelectionTool/SelectionTool.d.ts +4 -4
  425. package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +153 -179
  426. package/dist/mjs/tools/SelectionTool/TransformMode.d.ts +1 -1
  427. package/dist/mjs/tools/SelectionTool/TransformMode.mjs +52 -59
  428. package/dist/mjs/tools/SoundUITool.d.ts +2 -1
  429. package/dist/mjs/tools/SoundUITool.mjs +66 -84
  430. package/dist/mjs/tools/TextTool.d.ts +5 -3
  431. package/dist/mjs/tools/TextTool.mjs +155 -163
  432. package/dist/mjs/tools/ToolController.d.ts +16 -2
  433. package/dist/mjs/tools/ToolController.mjs +81 -84
  434. package/dist/mjs/tools/ToolEnabledGroup.mjs +6 -10
  435. package/dist/mjs/tools/ToolSwitcherShortcut.d.ts +1 -1
  436. package/dist/mjs/tools/ToolSwitcherShortcut.mjs +12 -32
  437. package/dist/mjs/tools/ToolbarShortcutHandler.d.ts +1 -1
  438. package/dist/mjs/tools/ToolbarShortcutHandler.mjs +13 -33
  439. package/dist/mjs/tools/UndoRedoShortcut.d.ts +1 -1
  440. package/dist/mjs/tools/UndoRedoShortcut.mjs +7 -26
  441. package/dist/mjs/tools/keybindings.mjs +34 -34
  442. package/dist/mjs/tools/localization.d.ts +2 -1
  443. package/dist/mjs/tools/localization.mjs +9 -8
  444. package/dist/mjs/types.d.ts +22 -80
  445. package/dist/mjs/types.mjs +7 -15
  446. package/dist/mjs/util/ReactiveValue.d.ts +65 -0
  447. package/dist/mjs/util/ReactiveValue.mjs +161 -0
  448. package/dist/mjs/util/assertions.mjs +5 -8
  449. package/dist/mjs/util/fileToBase64.mjs +6 -6
  450. package/dist/mjs/util/guessKeyCodeFromKey.d.ts +9 -0
  451. package/dist/mjs/util/guessKeyCodeFromKey.mjs +30 -0
  452. package/dist/mjs/util/listPrefixMatch.d.ts +6 -0
  453. package/dist/mjs/util/listPrefixMatch.mjs +15 -0
  454. package/dist/mjs/util/stopPropagationOfScrollingWheelEvents.d.ts +2 -0
  455. package/dist/mjs/util/stopPropagationOfScrollingWheelEvents.mjs +15 -0
  456. package/dist/mjs/util/untilNextAnimationFrame.mjs +3 -3
  457. package/dist/mjs/util/waitForAll.mjs +3 -3
  458. package/dist/mjs/util/waitForTimeout.mjs +3 -3
  459. package/dist/mjs/version.d.ts +4 -0
  460. package/dist/mjs/version.mjs +3 -0
  461. package/dist-test/test_imports/package.json +1 -1
  462. package/dist-test/test_imports/test-imports.js +5 -11
  463. package/dist-test/test_imports/test-require.cjs +6 -11
  464. package/package.json +11 -22
  465. package/src/Coloris.css +8 -8
  466. package/src/Editor.loadFrom.test.ts +1 -1
  467. package/src/Editor.scss +148 -0
  468. package/src/Editor.test.ts +107 -0
  469. package/src/Editor.toSVG.test.ts +184 -1
  470. package/src/Editor.ts +325 -53
  471. package/src/EditorImage.test.ts +4 -7
  472. package/src/EditorImage.ts +10 -4
  473. package/src/Pointer.ts +18 -5
  474. package/src/SVGLoader.ts +77 -15
  475. package/src/UndoRedoHistory.test.ts +2 -1
  476. package/src/Viewport.ts +1 -4
  477. package/src/commands/Erase.ts +1 -0
  478. package/src/commands/localization.ts +1 -1
  479. package/src/commands/uniteCommands.test.ts +3 -3
  480. package/src/components/AbstractComponent.transformBy.test.ts +2 -1
  481. package/src/components/AbstractComponent.ts +12 -3
  482. package/src/components/BackgroundComponent.test.ts +1 -2
  483. package/src/components/BackgroundComponent.ts +3 -8
  484. package/src/components/ImageComponent.ts +1 -3
  485. package/src/components/RestylableComponent.ts +1 -1
  486. package/src/components/SVGGlobalAttributesObject.ts +1 -3
  487. package/src/components/Stroke.test.ts +4 -6
  488. package/src/components/Stroke.ts +5 -7
  489. package/src/components/TextComponent.test.ts +1 -3
  490. package/src/components/TextComponent.ts +1 -4
  491. package/src/components/UnknownSVGObject.ts +3 -3
  492. package/src/components/builders/ArrowBuilder.ts +1 -2
  493. package/src/components/builders/CircleBuilder.ts +3 -5
  494. package/src/components/builders/FreehandLineBuilder.test.ts +2 -3
  495. package/src/components/builders/FreehandLineBuilder.ts +3 -5
  496. package/src/components/builders/LineBuilder.ts +3 -3
  497. package/src/components/builders/PressureSensitiveFreehandLineBuilder.ts +3 -4
  498. package/src/components/builders/RectangleBuilder.ts +3 -4
  499. package/src/components/builders/types.ts +1 -1
  500. package/src/components/lib.ts +1 -1
  501. package/src/components/util/StrokeSmoother.ts +7 -7
  502. package/src/dialogs/dialogs.scss +36 -0
  503. package/src/dialogs/makeAboutDialog.scss +41 -0
  504. package/src/dialogs/makeAboutDialog.ts +82 -0
  505. package/src/inputEvents.ts +143 -0
  506. package/src/lib.ts +35 -13
  507. package/src/localizations/de.ts +2 -2
  508. package/src/localizations/es.ts +5 -5
  509. package/src/rendering/Display.ts +1 -2
  510. package/src/rendering/RenderablePathSpec.ts +88 -0
  511. package/src/rendering/RenderingStyle.test.ts +1 -1
  512. package/src/rendering/RenderingStyle.ts +1 -1
  513. package/src/rendering/caching/CacheRecord.test.ts +1 -2
  514. package/src/rendering/caching/CacheRecord.ts +1 -2
  515. package/src/rendering/caching/CacheRecordManager.ts +1 -1
  516. package/src/rendering/caching/RenderingCache.test.ts +3 -4
  517. package/src/rendering/caching/RenderingCache.ts +1 -1
  518. package/src/rendering/caching/RenderingCacheNode.ts +1 -2
  519. package/src/rendering/caching/testUtils.ts +1 -1
  520. package/src/rendering/caching/types.ts +3 -3
  521. package/src/rendering/renderers/AbstractRenderer.ts +4 -14
  522. package/src/rendering/renderers/CanvasRenderer.ts +17 -12
  523. package/src/rendering/renderers/DummyRenderer.test.ts +1 -2
  524. package/src/rendering/renderers/DummyRenderer.ts +1 -4
  525. package/src/rendering/renderers/SVGRenderer.ts +68 -11
  526. package/src/rendering/renderers/TextOnlyRenderer.ts +1 -4
  527. package/src/shortcuts/KeyBinding.test.ts +10 -0
  528. package/src/shortcuts/KeyBinding.ts +74 -35
  529. package/src/shortcuts/KeyboardShortcutManager.test.ts +1 -1
  530. package/src/styles.js +1 -1
  531. package/src/testing/sendPenEvent.ts +2 -2
  532. package/src/testing/sendTouchEvent.ts +2 -2
  533. package/src/toolbar/{toolbar.css → AbstractToolbar.scss} +47 -85
  534. package/src/toolbar/AbstractToolbar.ts +542 -0
  535. package/src/toolbar/DropdownToolbar.scss +46 -0
  536. package/src/toolbar/DropdownToolbar.ts +220 -0
  537. package/src/toolbar/EdgeToolbar.scss +511 -0
  538. package/src/toolbar/EdgeToolbar.test.ts +54 -0
  539. package/src/toolbar/EdgeToolbar.ts +543 -0
  540. package/src/toolbar/IconProvider.ts +189 -133
  541. package/src/toolbar/constants.ts +1 -0
  542. package/src/toolbar/lib.ts +4 -2
  543. package/src/toolbar/localization.ts +39 -17
  544. package/src/toolbar/toolbar.scss +11 -0
  545. package/src/toolbar/types.ts +8 -0
  546. package/src/toolbar/widgets/ActionButtonWidget.ts +2 -2
  547. package/src/toolbar/widgets/BaseToolWidget.ts +17 -1
  548. package/src/toolbar/widgets/BaseWidget.ts +179 -112
  549. package/src/toolbar/widgets/DocumentPropertiesWidget.scss +7 -0
  550. package/src/toolbar/widgets/DocumentPropertiesWidget.ts +26 -10
  551. package/src/toolbar/widgets/EraserToolWidget.ts +21 -22
  552. package/src/toolbar/widgets/HandToolWidget.scss +14 -0
  553. package/src/toolbar/widgets/HandToolWidget.ts +21 -32
  554. package/src/toolbar/widgets/InsertImageWidget.scss +41 -0
  555. package/src/toolbar/widgets/InsertImageWidget.ts +90 -65
  556. package/src/toolbar/widgets/PenToolWidget.css +0 -51
  557. package/src/toolbar/widgets/PenToolWidget.ts +106 -146
  558. package/src/toolbar/widgets/SelectionToolWidget.scss +6 -0
  559. package/src/toolbar/widgets/SelectionToolWidget.ts +83 -85
  560. package/src/toolbar/widgets/TextToolWidget.ts +9 -5
  561. package/src/toolbar/widgets/components/components.scss +5 -0
  562. package/src/toolbar/widgets/components/makeColorInput.scss +82 -0
  563. package/src/toolbar/{makeColorInput.ts → widgets/components/makeColorInput.ts} +39 -14
  564. package/src/toolbar/widgets/components/makeFileInput.scss +77 -0
  565. package/src/toolbar/widgets/components/makeFileInput.ts +128 -0
  566. package/src/toolbar/widgets/components/makeGridSelector.scss +60 -0
  567. package/src/toolbar/widgets/components/makeGridSelector.ts +179 -0
  568. package/src/toolbar/widgets/components/makeSeparator.scss +14 -0
  569. package/src/toolbar/widgets/components/makeSeparator.ts +17 -0
  570. package/src/toolbar/widgets/components/makeThicknessSlider.scss +9 -0
  571. package/src/toolbar/widgets/components/makeThicknessSlider.ts +62 -0
  572. package/src/toolbar/widgets/keybindings.ts +1 -3
  573. package/src/toolbar/widgets/layout/DropdownLayoutManager.ts +262 -0
  574. package/src/toolbar/widgets/layout/EdgeToolbarLayoutManager.ts +71 -0
  575. package/src/toolbar/widgets/layout/types.ts +74 -0
  576. package/src/toolbar/widgets/lib.ts +2 -2
  577. package/src/tools/BaseTool.ts +102 -30
  578. package/src/tools/Eraser.test.ts +2 -2
  579. package/src/tools/Eraser.ts +24 -11
  580. package/src/tools/FindTool.css +3 -3
  581. package/src/tools/FindTool.test.ts +67 -0
  582. package/src/tools/FindTool.ts +3 -3
  583. package/src/tools/InputFilter/FunctionMapper.ts +17 -0
  584. package/src/tools/InputFilter/InputMapper.ts +41 -0
  585. package/src/tools/InputFilter/InputPipeline.test.ts +41 -0
  586. package/src/tools/InputFilter/InputPipeline.ts +34 -0
  587. package/src/tools/InputFilter/InputStabilizer.ts +254 -0
  588. package/src/tools/InputFilter/StrokeKeyboardControl.ts +104 -0
  589. package/src/tools/PanZoom.test.ts +3 -13
  590. package/src/tools/PanZoom.ts +33 -10
  591. package/src/tools/PasteHandler.ts +2 -3
  592. package/src/tools/Pen.test.ts +2 -4
  593. package/src/tools/Pen.ts +54 -70
  594. package/src/tools/PipetteTool.ts +31 -2
  595. package/src/tools/SelectionTool/SelectAllShortcutHandler.ts +1 -1
  596. package/src/tools/SelectionTool/Selection.ts +52 -16
  597. package/src/tools/SelectionTool/SelectionHandle.ts +46 -12
  598. package/src/tools/SelectionTool/SelectionTool.css +23 -11
  599. package/src/tools/SelectionTool/SelectionTool.test.ts +130 -21
  600. package/src/tools/SelectionTool/SelectionTool.ts +62 -48
  601. package/src/tools/SelectionTool/TransformMode.ts +1 -3
  602. package/src/tools/SoundUITool.ts +13 -4
  603. package/src/tools/TextTool.ts +29 -30
  604. package/src/tools/ToolController.ts +60 -36
  605. package/src/tools/ToolSwitcherShortcut.ts +1 -1
  606. package/src/tools/ToolbarShortcutHandler.ts +1 -1
  607. package/src/tools/UndoRedoShortcut.test.ts +10 -4
  608. package/src/tools/UndoRedoShortcut.ts +1 -1
  609. package/src/tools/keybindings.ts +17 -17
  610. package/src/tools/localization.ts +4 -2
  611. package/src/tools/tools.scss +4 -0
  612. package/src/types.ts +25 -113
  613. package/src/util/ReactiveValue.test.ts +168 -0
  614. package/src/util/ReactiveValue.ts +241 -0
  615. package/src/util/guessKeyCodeFromKey.ts +36 -0
  616. package/src/util/listPrefixMatch.ts +19 -0
  617. package/src/util/stopPropagationOfScrollingWheelEvents.ts +20 -0
  618. package/src/version.test.ts +12 -0
  619. package/src/version.ts +3 -0
  620. package/tsconfig.json +1 -1
  621. package/typedoc.json +4 -0
  622. package/dist/cjs/Color4.d.ts +0 -69
  623. package/dist/cjs/Color4.js +0 -263
  624. package/dist/cjs/math/Mat33.d.ts +0 -123
  625. package/dist/cjs/math/Mat33.js +0 -340
  626. package/dist/cjs/math/Vec2.d.ts +0 -33
  627. package/dist/cjs/math/Vec2.js +0 -37
  628. package/dist/cjs/math/Vec3.d.ts +0 -106
  629. package/dist/cjs/math/Vec3.js +0 -183
  630. package/dist/cjs/math/lib.d.ts +0 -7
  631. package/dist/cjs/math/lib.js +0 -15
  632. package/dist/cjs/math/polynomial/solveQuadratic.d.ts +0 -9
  633. package/dist/cjs/math/polynomial/solveQuadratic.js +0 -39
  634. package/dist/cjs/math/rounding.d.ts +0 -4
  635. package/dist/cjs/math/rounding.js +0 -140
  636. package/dist/cjs/math/shapes/Abstract2DShape.d.ts +0 -49
  637. package/dist/cjs/math/shapes/Abstract2DShape.js +0 -42
  638. package/dist/cjs/math/shapes/BezierJSWrapper.d.ts +0 -36
  639. package/dist/cjs/math/shapes/BezierJSWrapper.js +0 -109
  640. package/dist/cjs/math/shapes/CubicBezier.d.ts +0 -17
  641. package/dist/cjs/math/shapes/CubicBezier.js +0 -50
  642. package/dist/cjs/math/shapes/LineSegment2.d.ts +0 -70
  643. package/dist/cjs/math/shapes/LineSegment2.js +0 -204
  644. package/dist/cjs/math/shapes/Path.d.ts +0 -93
  645. package/dist/cjs/math/shapes/Path.js +0 -865
  646. package/dist/cjs/math/shapes/PointShape2D.d.ts +0 -18
  647. package/dist/cjs/math/shapes/PointShape2D.js +0 -46
  648. package/dist/cjs/math/shapes/QuadraticBezier.d.ts +0 -34
  649. package/dist/cjs/math/shapes/QuadraticBezier.js +0 -133
  650. package/dist/cjs/math/shapes/Rect2.d.ts +0 -57
  651. package/dist/cjs/math/shapes/Rect2.js +0 -311
  652. package/dist/cjs/math/shapes/Triangle.d.ts +0 -46
  653. package/dist/cjs/math/shapes/Triangle.js +0 -148
  654. package/dist/cjs/toolbar/HTMLToolbar.d.ts +0 -105
  655. package/dist/cjs/toolbar/HTMLToolbar.js +0 -465
  656. package/dist/cjs/toolbar/makeColorInput.d.ts +0 -6
  657. package/dist/mjs/Color4.d.ts +0 -69
  658. package/dist/mjs/Color4.mjs +0 -260
  659. package/dist/mjs/Color4.test.d.ts +0 -1
  660. package/dist/mjs/math/Mat33.d.ts +0 -123
  661. package/dist/mjs/math/Mat33.mjs +0 -338
  662. package/dist/mjs/math/Mat33.test.d.ts +0 -1
  663. package/dist/mjs/math/Vec2.d.ts +0 -33
  664. package/dist/mjs/math/Vec2.mjs +0 -34
  665. package/dist/mjs/math/Vec2.test.d.ts +0 -1
  666. package/dist/mjs/math/Vec3.d.ts +0 -106
  667. package/dist/mjs/math/Vec3.mjs +0 -181
  668. package/dist/mjs/math/Vec3.test.d.ts +0 -1
  669. package/dist/mjs/math/lib.d.ts +0 -7
  670. package/dist/mjs/math/lib.mjs +0 -7
  671. package/dist/mjs/math/polynomial/solveQuadratic.d.ts +0 -9
  672. package/dist/mjs/math/polynomial/solveQuadratic.mjs +0 -37
  673. package/dist/mjs/math/polynomial/solveQuadratic.test.d.ts +0 -1
  674. package/dist/mjs/math/rounding.d.ts +0 -4
  675. package/dist/mjs/math/rounding.mjs +0 -133
  676. package/dist/mjs/math/rounding.test.d.ts +0 -1
  677. package/dist/mjs/math/shapes/Abstract2DShape.d.ts +0 -49
  678. package/dist/mjs/math/shapes/Abstract2DShape.mjs +0 -40
  679. package/dist/mjs/math/shapes/BezierJSWrapper.d.ts +0 -36
  680. package/dist/mjs/math/shapes/BezierJSWrapper.mjs +0 -107
  681. package/dist/mjs/math/shapes/CubicBezier.d.ts +0 -17
  682. package/dist/mjs/math/shapes/CubicBezier.mjs +0 -48
  683. package/dist/mjs/math/shapes/LineSegment2.d.ts +0 -70
  684. package/dist/mjs/math/shapes/LineSegment2.mjs +0 -202
  685. package/dist/mjs/math/shapes/LineSegment2.test.d.ts +0 -1
  686. package/dist/mjs/math/shapes/Path.d.ts +0 -93
  687. package/dist/mjs/math/shapes/Path.fromString.test.d.ts +0 -1
  688. package/dist/mjs/math/shapes/Path.mjs +0 -862
  689. package/dist/mjs/math/shapes/Path.test.d.ts +0 -1
  690. package/dist/mjs/math/shapes/Path.toString.test.d.ts +0 -1
  691. package/dist/mjs/math/shapes/PointShape2D.d.ts +0 -18
  692. package/dist/mjs/math/shapes/PointShape2D.mjs +0 -44
  693. package/dist/mjs/math/shapes/QuadraticBezier.d.ts +0 -34
  694. package/dist/mjs/math/shapes/QuadraticBezier.mjs +0 -131
  695. package/dist/mjs/math/shapes/QuadraticBezier.test.d.ts +0 -1
  696. package/dist/mjs/math/shapes/Rect2.d.ts +0 -57
  697. package/dist/mjs/math/shapes/Rect2.mjs +0 -309
  698. package/dist/mjs/math/shapes/Rect2.test.d.ts +0 -1
  699. package/dist/mjs/math/shapes/Triangle.d.ts +0 -46
  700. package/dist/mjs/math/shapes/Triangle.mjs +0 -146
  701. package/dist/mjs/math/shapes/Triangle.test.d.ts +0 -1
  702. package/dist/mjs/toolbar/HTMLToolbar.d.ts +0 -105
  703. package/dist/mjs/toolbar/HTMLToolbar.mjs +0 -462
  704. package/dist/mjs/toolbar/makeColorInput.d.ts +0 -6
  705. package/src/Color4.test.ts +0 -47
  706. package/src/Color4.ts +0 -304
  707. package/src/Editor.css +0 -98
  708. package/src/math/Mat33.test.ts +0 -244
  709. package/src/math/Mat33.ts +0 -442
  710. package/src/math/Vec2.test.ts +0 -30
  711. package/src/math/Vec2.ts +0 -40
  712. package/src/math/Vec3.test.ts +0 -44
  713. package/src/math/Vec3.ts +0 -218
  714. package/src/math/lib.ts +0 -15
  715. package/src/math/polynomial/solveQuadratic.test.ts +0 -39
  716. package/src/math/polynomial/solveQuadratic.ts +0 -43
  717. package/src/math/rounding.test.ts +0 -65
  718. package/src/math/rounding.ts +0 -156
  719. package/src/math/shapes/Abstract2DShape.ts +0 -63
  720. package/src/math/shapes/BezierJSWrapper.ts +0 -93
  721. package/src/math/shapes/CubicBezier.ts +0 -35
  722. package/src/math/shapes/LineSegment2.test.ts +0 -99
  723. package/src/math/shapes/LineSegment2.ts +0 -231
  724. package/src/math/shapes/Path.fromString.test.ts +0 -223
  725. package/src/math/shapes/Path.test.ts +0 -309
  726. package/src/math/shapes/Path.toString.test.ts +0 -77
  727. package/src/math/shapes/Path.ts +0 -1027
  728. package/src/math/shapes/PointShape2D.ts +0 -33
  729. package/src/math/shapes/QuadraticBezier.test.ts +0 -31
  730. package/src/math/shapes/QuadraticBezier.ts +0 -141
  731. package/src/math/shapes/Rect2.test.ts +0 -209
  732. package/src/math/shapes/Rect2.ts +0 -344
  733. package/src/math/shapes/Triangle.test.ts +0 -61
  734. package/src/math/shapes/Triangle.ts +0 -139
  735. package/src/toolbar/HTMLToolbar.ts +0 -567
  736. package/src/toolbar/widgets/InsertImageWidget.css +0 -44
  737. package/src/tools/tools.css +0 -4
  738. /package/dist/cjs/{Color4.test.d.ts → Editor.test.d.ts} +0 -0
  739. /package/dist/cjs/{math/Mat33.test.d.ts → toolbar/EdgeToolbar.test.d.ts} +0 -0
  740. /package/dist/cjs/{math/Vec2.test.d.ts → tools/FindTool.test.d.ts} +0 -0
  741. /package/dist/cjs/{math/Vec3.test.d.ts → tools/InputFilter/InputPipeline.test.d.ts} +0 -0
  742. /package/dist/cjs/{math/polynomial/solveQuadratic.test.d.ts → util/ReactiveValue.test.d.ts} +0 -0
  743. /package/dist/cjs/{math/rounding.test.d.ts → version.test.d.ts} +0 -0
  744. /package/dist/{cjs/math/shapes/LineSegment2.test.d.ts → mjs/Editor.test.d.ts} +0 -0
  745. /package/dist/{cjs/math/shapes/Path.fromString.test.d.ts → mjs/toolbar/EdgeToolbar.test.d.ts} +0 -0
  746. /package/dist/{cjs/math/shapes/Path.test.d.ts → mjs/toolbar/widgets/layout/types.mjs} +0 -0
  747. /package/dist/{cjs/math/shapes/Path.toString.test.d.ts → mjs/tools/FindTool.test.d.ts} +0 -0
  748. /package/dist/{cjs/math/shapes/QuadraticBezier.test.d.ts → mjs/tools/InputFilter/InputPipeline.test.d.ts} +0 -0
  749. /package/dist/{cjs/math/shapes/Rect2.test.d.ts → mjs/util/ReactiveValue.test.d.ts} +0 -0
  750. /package/dist/{cjs/math/shapes/Triangle.test.d.ts → mjs/version.test.d.ts} +0 -0
package/src/Editor.ts CHANGED
@@ -1,25 +1,19 @@
1
1
  import EditorImage from './EditorImage';
2
2
  import ToolController from './tools/ToolController';
3
- import { InputEvtType, PointerEvt, EditorNotifier, EditorEventType, ImageLoader, HTMLPointerEventName, HTMLPointerEventFilter } from './types';
3
+ import { EditorNotifier, EditorEventType, ImageLoader } from './types';
4
+ import { HTMLPointerEventName, HTMLPointerEventFilter, InputEvtType, PointerEvt, keyUpEventFromHTMLEvent, keyPressEventFromHTMLEvent, KeyPressEvent } from './inputEvents';
4
5
  import Command from './commands/Command';
5
6
  import UndoRedoHistory from './UndoRedoHistory';
6
7
  import Viewport from './Viewport';
7
8
  import EventDispatcher from './EventDispatcher';
8
- import { Point2, Vec2 } from './math/Vec2';
9
- import Vec3 from './math/Vec3';
10
- import HTMLToolbar from './toolbar/HTMLToolbar';
11
- import { RenderablePathSpec } from './rendering/renderers/AbstractRenderer';
9
+ import { Point2, Vec2, Vec3, Color4, Mat33, Rect2, toRoundedString } from '@js-draw/math';
12
10
  import Display, { RenderingMode } from './rendering/Display';
13
11
  import SVGRenderer from './rendering/renderers/SVGRenderer';
14
- import Color4 from './Color4';
15
12
  import SVGLoader from './SVGLoader';
16
13
  import Pointer from './Pointer';
17
- import Mat33 from './math/Mat33';
18
- import Rect2 from './math/shapes/Rect2';
19
14
  import { EditorLocalization } from './localization';
20
15
  import getLocalizationTable from './localizations/getLocalizationTable';
21
16
  import IconProvider from './toolbar/IconProvider';
22
- import { toRoundedString } from './math/rounding';
23
17
  import CanvasRenderer from './rendering/renderers/CanvasRenderer';
24
18
  import untilNextAnimationFrame from './util/untilNextAnimationFrame';
25
19
  import fileToBase64 from './util/fileToBase64';
@@ -31,6 +25,13 @@ import BackgroundComponent, { BackgroundType } from './components/BackgroundComp
31
25
  import sendPenEvent from './testing/sendPenEvent';
32
26
  import KeyboardShortcutManager from './shortcuts/KeyboardShortcutManager';
33
27
  import KeyBinding from './shortcuts/KeyBinding';
28
+ import AbstractToolbar from './toolbar/AbstractToolbar';
29
+ import EdgeToolbar from './toolbar/EdgeToolbar';
30
+ import StrokeKeyboardControl from './tools/InputFilter/StrokeKeyboardControl';
31
+ import guessKeyCodeFromKey from './util/guessKeyCodeFromKey';
32
+ import RenderablePathSpec from './rendering/RenderablePathSpec';
33
+ import makeAboutDialog, { AboutDialogEntry } from './dialogs/makeAboutDialog';
34
+ import version from './version';
34
35
 
35
36
  export interface EditorSettings {
36
37
  /** Defaults to `RenderingMode.CanvasRenderer` */
@@ -48,6 +49,8 @@ export interface EditorSettings {
48
49
 
49
50
  /** Minimum zoom fraction (e.g. 0.5 → 50% zoom). */
50
51
  minZoom: number,
52
+
53
+ /** Maximum zoom fraction (e.g. 2 → 200% zoom). */
51
54
  maxZoom: number,
52
55
 
53
56
  /**
@@ -62,7 +65,41 @@ export interface EditorSettings {
62
65
  */
63
66
  keyboardShortcutOverrides: Record<string, Array<KeyBinding>>,
64
67
 
68
+ /**
69
+ * Provides a set of icons for the editor.
70
+ *
71
+ * See, for example, the `@js-draw/material-icons` package.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * import * as jsdraw from 'js-draw';
76
+ * import MaterialIconProvider from '@js-draw/material-icons';
77
+ * import 'js-draw/styles';
78
+ *
79
+ * const settings: Partial<jsdraw.EditorSettings> = {
80
+ * // Default to material icons
81
+ * iconProvider: new MaterialIconProvider(),
82
+ *
83
+ * // Only scroll the editor if it's focused.
84
+ * wheelEventsEnabled: 'only-if-focused',
85
+ * };
86
+ *
87
+ * // Add an editor to the document, using the above settings
88
+ * const editor = new jsdraw.Editor(document.body, settings);
89
+ *
90
+ * // Add a toolbar to the editor
91
+ * const toolbar = jsdraw.makeEdgeToolbar(editor);
92
+ *
93
+ * // Add the default tool items
94
+ * toolbar.addDefaults();
95
+ * ```
96
+ */
65
97
  iconProvider: IconProvider,
98
+
99
+ /**
100
+ * Additional messages to show in the "about" dialog.
101
+ */
102
+ notices: AboutDialogEntry[],
66
103
  }
67
104
 
68
105
  /**
@@ -207,6 +244,7 @@ export class Editor {
207
244
  maxZoom: settings.maxZoom ?? 1e12,
208
245
  keyboardShortcutOverrides: settings.keyboardShortcutOverrides ?? {},
209
246
  iconProvider: settings.iconProvider ?? new IconProvider(),
247
+ notices: [],
210
248
  };
211
249
  this.icons = this.settings.iconProvider;
212
250
 
@@ -215,7 +253,7 @@ export class Editor {
215
253
  this.container = document.createElement('div');
216
254
  this.renderingRegion = document.createElement('div');
217
255
  this.container.appendChild(this.renderingRegion);
218
- this.container.className = 'imageEditorContainer';
256
+ this.container.classList.add('imageEditorContainer', 'js-draw');
219
257
 
220
258
  this.loadingWarning = document.createElement('div');
221
259
  this.loadingWarning.classList.add('loadingMessage');
@@ -253,6 +291,9 @@ export class Editor {
253
291
  this.history = new UndoRedoHistory(this, this.announceRedoCallback, this.announceUndoCallback);
254
292
  this.toolController = new ToolController(this, this.localization);
255
293
 
294
+ // TODO: Make this pipeline configurable (e.g. allow users to add global input stabilization)
295
+ this.toolController.addInputMapper(StrokeKeyboardControl.fromEditor(this));
296
+
256
297
  parent.appendChild(this.container);
257
298
 
258
299
  this.viewport.updateScreenSize(
@@ -327,8 +368,8 @@ export class Editor {
327
368
  * Creates a toolbar. If `defaultLayout` is true, default buttons are used.
328
369
  * @returns a reference to the toolbar.
329
370
  */
330
- public addToolbar(defaultLayout: boolean = true): HTMLToolbar {
331
- const toolbar = new HTMLToolbar(this, this.container, this.localization);
371
+ public addToolbar(defaultLayout: boolean = true): AbstractToolbar {
372
+ const toolbar = new EdgeToolbar(this, this.container, this.localization);
332
373
 
333
374
  if (defaultLayout) {
334
375
  toolbar.addDefaults();
@@ -383,25 +424,17 @@ export class Editor {
383
424
  return false;
384
425
  });
385
426
 
386
- this.notifier.on(EditorEventType.DisplayResized, _event => {
427
+ const handleResize = () => {
387
428
  this.viewport.updateScreenSize(
388
429
  Vec2.of(this.display.width, this.display.height)
389
430
  );
390
- this.queueRerender();
391
- });
392
-
393
- const handleResize = () => {
394
- this.notifier.dispatch(EditorEventType.DisplayResized, {
395
- kind: EditorEventType.DisplayResized,
396
- newSize: Vec2.of(
397
- this.display.width,
398
- this.display.height
399
- ),
400
- });
431
+ this.rerender();
432
+ this.updateEditorSizeVariables();
401
433
  };
402
434
 
403
435
  if ('ResizeObserver' in (window as any)) {
404
436
  const resizeObserver = new ResizeObserver(handleResize);
437
+ resizeObserver.observe(this.renderingRegion);
405
438
  resizeObserver.observe(this.container);
406
439
  } else {
407
440
  addEventListener('resize', handleResize);
@@ -433,9 +466,20 @@ export class Editor {
433
466
  });
434
467
  }
435
468
 
469
+ private updateEditorSizeVariables() {
470
+ // Add CSS variables so that absolutely-positioned children of the editor can
471
+ // still fill the screen.
472
+ this.container.style.setProperty(
473
+ '--editor-current-width-px', `${this.container.clientWidth}px`
474
+ );
475
+ this.container.style.setProperty(
476
+ '--editor-current-height-px', `${this.container.clientHeight}px`
477
+ );
478
+ }
479
+
436
480
  private pointers: Record<number, Pointer> = {};
437
481
  private getPointerList() {
438
- const nowTime = (new Date()).getTime();
482
+ const nowTime = performance.now();
439
483
 
440
484
  const res: Pointer[] = [];
441
485
  for (const id in this.pointers) {
@@ -610,6 +654,13 @@ export class Editor {
610
654
  * Forward pointer events from `elem` to this editor. Such that right-click/right-click drag
611
655
  * events are also forwarded, `elem`'s contextmenu is disabled.
612
656
  *
657
+ * `filter` is called once per pointer event, before doing any other processing. If `filter` returns `true` the event is
658
+ * forwarded to the editor.
659
+ *
660
+ * **Note**: `otherEventsFilter` is like `filter`, but is called for other pointer-related
661
+ * events that could also be forwarded to the editor. To forward just pointer events,
662
+ * for example, `otherEventsFilter` could be given as `()=>false`.
663
+ *
613
664
  * @example
614
665
  * ```ts
615
666
  * const overlay = document.createElement('div');
@@ -625,11 +676,25 @@ export class Editor {
625
676
  * });
626
677
  * ```
627
678
  */
628
- public handlePointerEventsFrom(elem: HTMLElement, filter?: HTMLPointerEventFilter) {
679
+ public handlePointerEventsFrom(
680
+ elem: HTMLElement,
681
+ filter?: HTMLPointerEventFilter,
682
+ otherEventsFilter?: (eventName: string, event: Event)=>boolean,
683
+ ) {
629
684
  // May be required to prevent text selection on iOS/Safari:
630
685
  // See https://stackoverflow.com/a/70992717/17055750
631
- const touchstartListener = (evt: Event) => evt.preventDefault();
686
+ const touchstartListener = (evt: Event) => {
687
+ if (otherEventsFilter && !otherEventsFilter('touchstart', evt)) {
688
+ return;
689
+ }
690
+
691
+ evt.preventDefault();
692
+ };
632
693
  const contextmenuListener = (evt: Event) => {
694
+ if (otherEventsFilter && !otherEventsFilter('contextmenu', evt)) {
695
+ return;
696
+ }
697
+
633
698
  // Don't show a context menu
634
699
  evt.preventDefault();
635
700
  };
@@ -646,7 +711,7 @@ export class Editor {
646
711
  const event = evt as PointerEvent;
647
712
 
648
713
  if (filter && !filter(eventName, event)) {
649
- return true;
714
+ return undefined;
650
715
  }
651
716
 
652
717
  return this.handleHTMLPointerEvent(eventName, event);
@@ -668,32 +733,171 @@ export class Editor {
668
733
  };
669
734
  }
670
735
 
671
- /** Adds event listners for keypresses to `elem` and forwards those events to the editor. */
672
- public handleKeyEventsFrom(elem: HTMLElement) {
673
- elem.addEventListener('keydown', evt => {
674
- if (evt.key === 't' || evt.key === 'T') {
675
- evt.preventDefault();
736
+ /**
737
+ * Like {@link handlePointerEventsFrom} except ignores short input gestures like clicks.
738
+ *
739
+ * `filter` is called once per event, before doing any other processing. If `filter` returns `true` the event is
740
+ * forwarded to the editor.
741
+ *
742
+ * `otherEventsFilter` is passed unmodified to `handlePointerEventsFrom`.
743
+ */
744
+ public handlePointerEventsExceptClicksFrom(
745
+ elem: HTMLElement,
746
+ filter?: HTMLPointerEventFilter,
747
+ otherEventsFilter?: (eventName: string, event: Event)=>boolean,
748
+ ) {
749
+ type GestureRecord = {
750
+ // Buffer events: Send events to the editor only if the pointer has moved enough to
751
+ // suggest that the user is attempting to draw, rather than click to close the color picker.
752
+ eventBuffer: [ HTMLPointerEventName, PointerEvent ][];
753
+ startPoint: Point2;
754
+ };
755
+
756
+ // Maps pointer IDs to gesture start points
757
+ const gestureData: Record<number, GestureRecord> = Object.create(null);
758
+
759
+ return this.handlePointerEventsFrom(elem, (eventName, event) => {
760
+ if (filter && !filter(eventName, event)) {
761
+ return false;
762
+ }
763
+
764
+ // Position of the current event.
765
+ const currentPos = Vec2.of(event.pageX, event.pageY);
766
+
767
+ const pointerId = event.pointerId ?? 0;
768
+
769
+ // Whether to send the current event to the editor
770
+ let sendToEditor = true;
771
+
772
+ if (eventName === 'pointerdown') {
773
+ // Buffer the event, but don't send it to the editor yet.
774
+ // We don't want to send single-click events, but we do want to send full strokes.
775
+ gestureData[pointerId] = {
776
+ eventBuffer: [ [eventName, event] ],
777
+ startPoint: currentPos,
778
+ };
779
+
780
+ // Capture the pointer so we receive future events even if the overlay is hidden.
781
+ elem.setPointerCapture(event.pointerId);
782
+
783
+ // Don't send to the editor.
784
+ sendToEditor = false;
785
+ }
786
+ else if (eventName === 'pointermove' && gestureData[pointerId]) {
787
+ const gestureStartPos = gestureData[pointerId].startPoint;
788
+ const eventBuffer = gestureData[pointerId].eventBuffer;
789
+
790
+ // Skip if the pointer hasn't moved enough to not be a "click".
791
+ const strokeStartThreshold = 10;
792
+ const isWithinClickThreshold = gestureStartPos && currentPos.minus(gestureStartPos).magnitude() < strokeStartThreshold;
793
+ if (isWithinClickThreshold) {
794
+ eventBuffer.push([ eventName, event ]);
795
+ sendToEditor = false;
796
+ } else {
797
+ // Send all buffered events to the editor -- start the stroke.
798
+ for (const [ eventName, event ] of eventBuffer) {
799
+ this.handleHTMLPointerEvent(eventName, event);
800
+ }
801
+
802
+ gestureData[pointerId].eventBuffer = [];
803
+ sendToEditor = true;
804
+ }
805
+ }
806
+ // Pointers that aren't down -- send to the editor.
807
+ else if (eventName === 'pointermove') {
808
+ sendToEditor = true;
809
+ }
810
+ // Otherwise, if we received a pointerup/pointercancel without flushing all pointerevents from the
811
+ // buffer, the gesture wasn't recognised as a stroke. Thus, the editor isn't expecting a pointerup/
812
+ // pointercancel event.
813
+ else if (
814
+ (eventName === 'pointerup' || eventName === 'pointercancel')
815
+ && gestureData[pointerId] && gestureData[pointerId].eventBuffer.length > 0
816
+ ) {
817
+ elem.releasePointerCapture(event.pointerId);
818
+
819
+ // Don't send to the editor.
820
+ sendToEditor = false;
821
+
822
+ delete gestureData[pointerId];
823
+ }
824
+
825
+ // Forward all other events to the editor.
826
+ return sendToEditor;
827
+ }, otherEventsFilter);
828
+ }
829
+
830
+ /**
831
+ * Adds event listners for keypresses (and drop events) on `elem` and forwards those
832
+ * events to the editor.
833
+ *
834
+ * If the given `filter` returns `false` for an event, the event is ignored and not
835
+ * passed to the editor.
836
+ */
837
+ public handleKeyEventsFrom(
838
+ elem: HTMLElement,
839
+ filter: (event: KeyboardEvent)=>boolean = ()=>true
840
+ ) {
841
+ // Track which keys are down so we can release them when the element
842
+ // loses focus. This is particularly important for keys like Control
843
+ // that can trigger shortcuts that cause the editor to lose focus before
844
+ // the keyup event is triggered.
845
+ let keysDown: KeyPressEvent[] = [];
846
+
847
+ type KeyEventLike = { key: string; code: string };
848
+
849
+ // Return whether two objects that are similar to keyboard events represent the
850
+ // same key.
851
+ const keyEventsMatch = (a: KeyEventLike, b: KeyEventLike) => {
852
+ return a.key === b.key && a.code === b.code;
853
+ };
854
+
855
+ elem.addEventListener('keydown', htmlEvent => {
856
+ if (!filter(htmlEvent)) {
857
+ return;
858
+ }
859
+
860
+ const event = keyPressEventFromHTMLEvent(htmlEvent);
861
+
862
+ // Add event to the list of keys that are down (so long as it
863
+ // isn't a duplicate).
864
+ if (!keysDown.some(other => keyEventsMatch(other, event))) {
865
+ keysDown.push(event);
866
+ }
867
+
868
+ if (event.key === 't' || event.key === 'T') {
869
+ htmlEvent.preventDefault();
676
870
  this.display.rerenderAsText();
677
- } else if (this.toolController.dispatchInputEvent({
678
- kind: InputEvtType.KeyPressEvent,
679
- key: evt.key,
680
- ctrlKey: evt.ctrlKey || evt.metaKey,
681
- altKey: evt.altKey,
682
- })) {
683
- evt.preventDefault();
684
- } else if (evt.key === 'Escape') {
871
+ } else if (this.toolController.dispatchInputEvent(event)) {
872
+ htmlEvent.preventDefault();
873
+ } else if (event.key === 'Escape') {
685
874
  this.renderingRegion.blur();
686
875
  }
687
876
  });
688
877
 
689
- elem.addEventListener('keyup', evt => {
690
- if (this.toolController.dispatchInputEvent({
691
- kind: InputEvtType.KeyUpEvent,
692
- key: evt.key,
693
- ctrlKey: evt.ctrlKey || evt.metaKey,
694
- altKey: evt.altKey,
695
- })) {
696
- evt.preventDefault();
878
+ elem.addEventListener('keyup', htmlEvent => {
879
+ // Remove the key from keysDown -- it's no longer down.
880
+ keysDown = keysDown.filter(event => {
881
+ const matches = keyEventsMatch(event, htmlEvent);
882
+ return !matches;
883
+ });
884
+
885
+ if (!filter(htmlEvent)) {
886
+ return;
887
+ }
888
+
889
+ const event = keyUpEventFromHTMLEvent(htmlEvent);
890
+ if (this.toolController.dispatchInputEvent(event)) {
891
+ htmlEvent.preventDefault();
892
+ }
893
+ });
894
+
895
+ elem.addEventListener('blur', () => {
896
+ for (const event of keysDown) {
897
+ this.toolController.dispatchInputEvent({
898
+ ...event,
899
+ kind: InputEvtType.KeyUpEvent,
900
+ });
697
901
  }
698
902
  });
699
903
 
@@ -850,12 +1054,12 @@ export class Editor {
850
1054
  return;
851
1055
  }
852
1056
 
853
- // Draw a rectangle around the region that will be visible on save
854
1057
  const renderer = this.display.getDryInkRenderer();
855
1058
 
856
1059
  this.image.renderWithCache(renderer, this.display.getCache(), this.viewport);
857
1060
 
858
1061
  if (showImageBounds) {
1062
+ // Draw a rectangle around the region that will be visible on save
859
1063
  const exportRectFill = { fill: Color4.fromHex('#44444455') };
860
1064
  const exportRectStrokeWidth = 5 * this.viewport.getSizeOfPixelOnCanvas();
861
1065
  renderer.drawRect(
@@ -922,19 +1126,34 @@ export class Editor {
922
1126
  return styleSheet;
923
1127
  }
924
1128
 
925
- // Dispatch a keyboard event to the currently selected tool.
926
- // Intended for unit testing
1129
+ /**
1130
+ * Dispatch a keyboard event to the currently selected tool.
1131
+ * Intended for unit testing.
1132
+ *
1133
+ * If `shiftKey` is undefined, it is guessed from `key`.
1134
+ *
1135
+ * At present, the **key code** dispatched is guessed from the given key and,
1136
+ * while this works for ASCII alphanumeric characters, this does not work for
1137
+ * most non-alphanumeric keys.
1138
+ *
1139
+ * Because guessing the key code from `key` is problematic, **only use this for testing**.
1140
+ */
927
1141
  public sendKeyboardEvent(
928
1142
  eventType: InputEvtType.KeyPressEvent|InputEvtType.KeyUpEvent,
929
1143
  key: string,
930
1144
  ctrlKey: boolean = false,
931
1145
  altKey: boolean = false,
1146
+ shiftKey: boolean|undefined = undefined,
932
1147
  ) {
1148
+ shiftKey ??= key.toUpperCase() === key && key.toLowerCase() !== key;
1149
+
933
1150
  this.toolController.dispatchInputEvent({
934
1151
  kind: eventType,
935
1152
  key,
1153
+ code: guessKeyCodeFromKey(key),
936
1154
  ctrlKey,
937
1155
  altKey,
1156
+ shiftKey,
938
1157
  });
939
1158
  }
940
1159
 
@@ -1157,7 +1376,7 @@ export class Editor {
1157
1376
  }
1158
1377
 
1159
1378
  /**
1160
- * Alias for loadFrom(SVGLoader.fromString).
1379
+ * Alias for `loadFrom(SVGLoader.fromString)`.
1161
1380
  *
1162
1381
  * This is particularly useful when accessing a bundled version of the editor,
1163
1382
  * where `SVGLoader.fromString` is unavailable.
@@ -1166,6 +1385,59 @@ export class Editor {
1166
1385
  const loader = SVGLoader.fromString(svgData, sanitize);
1167
1386
  await this.loadFrom(loader);
1168
1387
  }
1388
+
1389
+ private closeAboutDialog: (()=>void)|null = null;
1390
+
1391
+ /**
1392
+ * Shows an information dialog with legal notices.
1393
+ */
1394
+ public showAboutDialog() {
1395
+ const iconLicenseText = this.icons.licenseInfo();
1396
+
1397
+ const notices: AboutDialogEntry[] = [];
1398
+ notices.push({
1399
+ heading: 'js-draw',
1400
+ text: [
1401
+ `v${version.number}`,
1402
+ '',
1403
+ 'Image debug information (from when this dialog was opened):',
1404
+ ` ${this.viewport.getScaleFactor()}x zoom, ${180/Math.PI * this.viewport.getRotationAngle()} rotation`,
1405
+ ` ${this.image.estimateNumElements()} components`,
1406
+ ` ${this.getImportExportRect().w}x${this.getImportExportRect().h} size`,
1407
+ ].join('\n'),
1408
+ });
1409
+
1410
+ notices.push({
1411
+ heading: 'Libraries',
1412
+ text: [
1413
+ 'js-draw uses several libraries at runtime. Particularly noteworthy are:',
1414
+ ' - The Coloris color picker: https://github.com/mdbassit/Coloris',
1415
+ ' - The bezier.js Bézier curve library: https://github.com/Pomax/bezierjs'
1416
+ ].join('\n'),
1417
+ minimized: true,
1418
+ });
1419
+
1420
+ if (iconLicenseText) {
1421
+ notices.push({
1422
+ heading: 'Icon Pack',
1423
+ text: iconLicenseText,
1424
+ minimized: true,
1425
+ });
1426
+ }
1427
+
1428
+ notices.push(...this.settings.notices);
1429
+
1430
+
1431
+ this.closeAboutDialog?.();
1432
+ this.closeAboutDialog = makeAboutDialog(this, notices).close;
1433
+ }
1434
+
1435
+ /** Removes and destroys the editor */
1436
+ public remove() {
1437
+ this.container.remove();
1438
+
1439
+ // TODO: Is additional cleanup necessary here?
1440
+ }
1169
1441
  }
1170
1442
 
1171
1443
  export default Editor;
@@ -1,14 +1,11 @@
1
1
  import EditorImage from './EditorImage';
2
2
  import Stroke from './components/Stroke';
3
- import { Vec2 } from './math/Vec2';
4
- import Path, { PathCommandType } from './math/shapes/Path';
5
- import Color4 from './Color4';
3
+ import { Vec2, Color4, Path, PathCommandType, Rect2, Mat33 } from '@js-draw/math';
6
4
  import DummyRenderer from './rendering/renderers/DummyRenderer';
7
5
  import createEditor from './testing/createEditor';
8
6
  import RenderingStyle from './rendering/RenderingStyle';
9
- import Rect2 from './math/shapes/Rect2';
10
- import Mat33 from './math/Mat33';
11
7
  import { SerializableCommand } from './lib';
8
+ import { pathToRenderable } from './rendering/RenderablePathSpec';
12
9
 
13
10
  describe('EditorImage', () => {
14
11
  const testStroke = new Stroke([
@@ -60,12 +57,12 @@ describe('EditorImage', () => {
60
57
  const image = editor.image;
61
58
 
62
59
  const leftmostStroke = new Stroke([
63
- Path.fromString('M0,0L1,1L0,1').toRenderable(testFill),
60
+ pathToRenderable(Path.fromString('M0,0L1,1L0,1'), testFill),
64
61
  ]);
65
62
 
66
63
  // Lowercase ls: lineTo(Δx, Δy) instead of lineTo(x, y)
67
64
  const rightmostStroke = new Stroke([
68
- Path.fromString('M-10,0 l1,1 l0,-1').toRenderable(testFill),
65
+ pathToRenderable(Path.fromString('M-10,0 l1,1 l0,-1'), testFill),
69
66
  ]);
70
67
 
71
68
  expect(!leftmostStroke.getBBox().intersects(rightmostStroke.getBBox()));
@@ -2,13 +2,11 @@ import Editor from './Editor';
2
2
  import AbstractRenderer from './rendering/renderers/AbstractRenderer';
3
3
  import Viewport from './Viewport';
4
4
  import AbstractComponent from './components/AbstractComponent';
5
- import Rect2 from './math/shapes/Rect2';
5
+ import { Rect2, Vec2, Mat33, Mat33Array } from '@js-draw/math';
6
6
  import { EditorLocalization } from './localization';
7
7
  import RenderingCache from './rendering/caching/RenderingCache';
8
8
  import SerializableCommand from './commands/SerializableCommand';
9
9
  import EventDispatcher from './EventDispatcher';
10
- import { Vec2 } from './math/Vec2';
11
- import Mat33, { Mat33Array } from './math/Mat33';
12
10
  import { assertIsNumber, assertIsNumberArray } from './util/assertions';
13
11
 
14
12
  // @internal Sort by z-index, low to high
@@ -27,6 +25,7 @@ export default class EditorImage {
27
25
  private root: ImageNode;
28
26
  private background: ImageNode;
29
27
  private componentsById: Record<string, AbstractComponent>;
28
+ private componentCount: number = 0;
30
29
 
31
30
  /** Viewport for the exported/imported image. */
32
31
  private importExportViewport: Viewport;
@@ -117,6 +116,11 @@ export default class EditorImage {
117
116
  return leaves.map(leaf => leaf.getContent()!);
118
117
  }
119
118
 
119
+ /** Returns the number of elements added to this image. @internal */
120
+ public estimateNumElements() {
121
+ return this.componentCount;
122
+ }
123
+
120
124
  /** @returns a list of `AbstractComponent`s intersecting `region`, sorted by z-index. */
121
125
  public getElementsIntersectingRegion(region: Rect2): AbstractComponent[] {
122
126
  const leaves = this.root.getLeavesIntersectingRegion(region);
@@ -125,8 +129,9 @@ export default class EditorImage {
125
129
  return leaves.map(leaf => leaf.getContent()!);
126
130
  }
127
131
 
128
- /** @internal */
132
+ /** Called whenever an element is completely removed. @internal */
129
133
  public onDestroyElement(elem: AbstractComponent) {
134
+ this.componentCount --;
130
135
  delete this.componentsById[elem.getId()];
131
136
  }
132
137
 
@@ -142,6 +147,7 @@ export default class EditorImage {
142
147
  private addElementDirectly(elem: AbstractComponent): ImageNode {
143
148
  elem.onAddToImage(this);
144
149
 
150
+ this.componentCount ++;
145
151
  this.componentsById[elem.getId()] = elem;
146
152
 
147
153
  // If a background component, add to the background. Else,
package/src/Pointer.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Point2, Vec2 } from './math/Vec2';
1
+ import { Point2, Vec2 } from '@js-draw/math';
2
2
  import Viewport from './Viewport';
3
3
 
4
4
  export enum PointerDevice {
@@ -31,7 +31,7 @@ export default class Pointer {
31
31
  // Unique ID for the pointer
32
32
  public readonly id: number,
33
33
 
34
- // Numeric timestamp (milliseconds, as from `(new Date).getTime()`)
34
+ // Numeric timestamp (milliseconds, as from `performance.now()`).
35
35
  public readonly timeStamp: number,
36
36
  ) {
37
37
  }
@@ -76,6 +76,20 @@ export default class Pointer {
76
76
  return this.withCanvasPosition(canvasPos, viewport);
77
77
  }
78
78
 
79
+ /** Returns a copy of this pointer with a changed timestamp. */
80
+ public withTimestamp(timeStamp: number) {
81
+ return new Pointer(
82
+ this.screenPos,
83
+ this.canvasPos,
84
+ this.pressure,
85
+ this.isPrimary,
86
+ this.down,
87
+ this.device,
88
+ this.id,
89
+ timeStamp
90
+ );
91
+ }
92
+
79
93
  /**
80
94
  * Returns a copy of this pointer with a new position. The screen position is determined
81
95
  * by the given `canvasPos`.
@@ -116,15 +130,14 @@ export default class Pointer {
116
130
  device = PointerDevice.Eraser;
117
131
  }
118
132
 
119
- const timeStamp = (new Date()).getTime();
133
+ const timeStamp = evt.timeStamp;
120
134
  const canvasPos = viewport.roundPoint(viewport.screenToCanvas(screenPos));
121
135
 
122
136
  if (device === PointerDevice.PrimaryButtonMouse) {
123
137
  if (evt.buttons & 0x2) {
124
138
  device = PointerDevice.RightButtonMouse;
125
139
  }
126
- // Commented out to work around a bug in old versions of Chrome:
127
- // Left mouse up events were being given type "other".
140
+ // Commented out: Mouse up events seem to not satisfy this condition on mouse up.
128
141
  // else if (!(evt.buttons & 0x1)) {
129
142
  // device = PointerDevice.Other;
130
143
  //}