js-draw 1.20.3 → 1.21.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (245) hide show
  1. package/LICENSE +1 -1
  2. package/dist/Editor.css +136 -26
  3. package/dist/bundle.js +2 -2
  4. package/dist/bundledStyles.js +1 -1
  5. package/dist/cjs/Editor.d.ts +27 -6
  6. package/dist/cjs/Editor.js +30 -8
  7. package/dist/cjs/SVGLoader/SVGLoader.js +2 -2
  8. package/dist/cjs/Viewport.d.ts +2 -2
  9. package/dist/cjs/commands/Command.d.ts +5 -0
  10. package/dist/cjs/commands/Command.js +5 -0
  11. package/dist/cjs/commands/SerializableCommand.d.ts +7 -0
  12. package/dist/cjs/commands/SerializableCommand.js +9 -0
  13. package/dist/cjs/dialogs/makeAboutDialog.d.ts +1 -1
  14. package/dist/cjs/dialogs/makeAboutDialog.js +10 -25
  15. package/dist/cjs/dialogs/makeMessageDialog.d.ts +11 -0
  16. package/dist/cjs/dialogs/makeMessageDialog.js +56 -0
  17. package/dist/cjs/image/EditorImage.d.ts +15 -1
  18. package/dist/cjs/image/EditorImage.js +15 -5
  19. package/dist/cjs/inputEvents.d.ts +10 -2
  20. package/dist/cjs/inputEvents.js +1 -0
  21. package/dist/cjs/localizations/es.js +3 -0
  22. package/dist/cjs/rendering/Display.d.ts +1 -0
  23. package/dist/cjs/rendering/Display.js +1 -0
  24. package/dist/cjs/rendering/TextRenderingStyle.d.ts +7 -6
  25. package/dist/cjs/rendering/TextRenderingStyle.js +1 -0
  26. package/dist/cjs/rendering/renderers/CanvasRenderer.d.ts +12 -3
  27. package/dist/cjs/rendering/renderers/CanvasRenderer.js +15 -2
  28. package/dist/cjs/rendering/renderers/DummyRenderer.d.ts +1 -1
  29. package/dist/cjs/testing/firstElementAncestorOfNode.d.ts +1 -1
  30. package/dist/cjs/testing/firstElementAncestorOfNode.js +1 -1
  31. package/dist/cjs/testing/sendPenEvent.d.ts +2 -2
  32. package/dist/cjs/testing/sendTouchEvent.d.ts +2 -2
  33. package/dist/cjs/toolbar/AbstractToolbar.d.ts +6 -1
  34. package/dist/cjs/toolbar/AbstractToolbar.js +6 -1
  35. package/dist/cjs/toolbar/IconProvider.d.ts +1 -1
  36. package/dist/cjs/toolbar/IconProvider.js +6 -1
  37. package/dist/cjs/toolbar/widgets/BaseWidget.d.ts +8 -0
  38. package/dist/cjs/toolbar/widgets/BaseWidget.js +8 -0
  39. package/dist/cjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
  40. package/dist/cjs/toolbar/widgets/HandToolWidget.js +1 -0
  41. package/dist/cjs/toolbar/widgets/InsertImageWidget/ImageWrapper.d.ts +1 -1
  42. package/dist/cjs/toolbar/widgets/PenToolWidget.d.ts +6 -0
  43. package/dist/cjs/toolbar/widgets/PenToolWidget.js +5 -0
  44. package/dist/cjs/types.d.ts +5 -0
  45. package/dist/cjs/types.js +1 -0
  46. package/dist/cjs/util/ClipboardHandler.d.ts +9 -1
  47. package/dist/cjs/util/ClipboardHandler.js +82 -24
  48. package/dist/cjs/version.js +1 -1
  49. package/dist/mjs/Editor.d.ts +27 -6
  50. package/dist/mjs/Editor.mjs +31 -9
  51. package/dist/mjs/SVGLoader/SVGLoader.mjs +2 -2
  52. package/dist/mjs/Viewport.d.ts +2 -2
  53. package/dist/mjs/commands/Command.d.ts +5 -0
  54. package/dist/mjs/commands/Command.mjs +5 -0
  55. package/dist/mjs/commands/SerializableCommand.d.ts +7 -0
  56. package/dist/mjs/commands/SerializableCommand.mjs +9 -0
  57. package/dist/mjs/dialogs/makeAboutDialog.d.ts +1 -1
  58. package/dist/mjs/dialogs/makeAboutDialog.mjs +7 -25
  59. package/dist/mjs/dialogs/makeMessageDialog.d.ts +11 -0
  60. package/dist/mjs/dialogs/makeMessageDialog.mjs +51 -0
  61. package/dist/mjs/image/EditorImage.d.ts +15 -1
  62. package/dist/mjs/image/EditorImage.mjs +15 -5
  63. package/dist/mjs/inputEvents.d.ts +10 -2
  64. package/dist/mjs/inputEvents.mjs +1 -0
  65. package/dist/mjs/localizations/es.mjs +3 -0
  66. package/dist/mjs/rendering/Display.d.ts +1 -0
  67. package/dist/mjs/rendering/Display.mjs +1 -0
  68. package/dist/mjs/rendering/TextRenderingStyle.d.ts +7 -6
  69. package/dist/mjs/rendering/TextRenderingStyle.mjs +1 -0
  70. package/dist/mjs/rendering/renderers/CanvasRenderer.d.ts +12 -3
  71. package/dist/mjs/rendering/renderers/CanvasRenderer.mjs +15 -2
  72. package/dist/mjs/rendering/renderers/DummyRenderer.d.ts +1 -1
  73. package/dist/mjs/testing/firstElementAncestorOfNode.d.ts +1 -1
  74. package/dist/mjs/testing/firstElementAncestorOfNode.mjs +1 -1
  75. package/dist/mjs/testing/sendPenEvent.d.ts +2 -2
  76. package/dist/mjs/testing/sendTouchEvent.d.ts +2 -2
  77. package/dist/mjs/toolbar/AbstractToolbar.d.ts +6 -1
  78. package/dist/mjs/toolbar/AbstractToolbar.mjs +6 -1
  79. package/dist/mjs/toolbar/IconProvider.d.ts +1 -1
  80. package/dist/mjs/toolbar/IconProvider.mjs +6 -1
  81. package/dist/mjs/toolbar/widgets/BaseWidget.d.ts +8 -0
  82. package/dist/mjs/toolbar/widgets/BaseWidget.mjs +8 -0
  83. package/dist/mjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
  84. package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +1 -0
  85. package/dist/mjs/toolbar/widgets/InsertImageWidget/ImageWrapper.d.ts +1 -1
  86. package/dist/mjs/toolbar/widgets/PenToolWidget.d.ts +6 -0
  87. package/dist/mjs/toolbar/widgets/PenToolWidget.mjs +5 -0
  88. package/dist/mjs/types.d.ts +5 -0
  89. package/dist/mjs/types.mjs +1 -0
  90. package/dist/mjs/util/ClipboardHandler.d.ts +9 -1
  91. package/dist/mjs/util/ClipboardHandler.mjs +82 -24
  92. package/dist/mjs/version.mjs +1 -1
  93. package/package.json +8 -9
  94. package/src/dialogs/dialogs.scss +9 -21
  95. package/src/dialogs/makeAboutDialog.scss +13 -33
  96. package/src/dialogs/makeMessageDialog.scss +46 -0
  97. package/dist/cjs/tools/BaseTool.d.ts +0 -60
  98. package/dist/cjs/tools/BaseTool.js +0 -174
  99. package/dist/cjs/tools/Eraser.d.ts +0 -56
  100. package/dist/cjs/tools/Eraser.js +0 -295
  101. package/dist/cjs/tools/Eraser.test.d.ts +0 -1
  102. package/dist/cjs/tools/FindTool.d.ts +0 -21
  103. package/dist/cjs/tools/FindTool.js +0 -137
  104. package/dist/cjs/tools/FindTool.test.d.ts +0 -1
  105. package/dist/cjs/tools/InputFilter/FunctionMapper.d.ts +0 -12
  106. package/dist/cjs/tools/InputFilter/FunctionMapper.js +0 -21
  107. package/dist/cjs/tools/InputFilter/InputMapper.d.ts +0 -23
  108. package/dist/cjs/tools/InputFilter/InputMapper.js +0 -38
  109. package/dist/cjs/tools/InputFilter/InputPipeline.d.ts +0 -15
  110. package/dist/cjs/tools/InputFilter/InputPipeline.js +0 -54
  111. package/dist/cjs/tools/InputFilter/InputPipeline.test.d.ts +0 -1
  112. package/dist/cjs/tools/InputFilter/InputStabilizer.d.ts +0 -29
  113. package/dist/cjs/tools/InputFilter/InputStabilizer.js +0 -181
  114. package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.d.ts +0 -21
  115. package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.js +0 -84
  116. package/dist/cjs/tools/PanZoom.d.ts +0 -119
  117. package/dist/cjs/tools/PanZoom.js +0 -508
  118. package/dist/cjs/tools/PanZoom.test.d.ts +0 -1
  119. package/dist/cjs/tools/PasteHandler.d.ts +0 -23
  120. package/dist/cjs/tools/PasteHandler.js +0 -109
  121. package/dist/cjs/tools/Pen.d.ts +0 -53
  122. package/dist/cjs/tools/Pen.js +0 -318
  123. package/dist/cjs/tools/Pen.test.d.ts +0 -1
  124. package/dist/cjs/tools/PipetteTool.d.ts +0 -28
  125. package/dist/cjs/tools/PipetteTool.js +0 -69
  126. package/dist/cjs/tools/ScrollbarTool.d.ts +0 -18
  127. package/dist/cjs/tools/ScrollbarTool.js +0 -85
  128. package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +0 -9
  129. package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.js +0 -32
  130. package/dist/cjs/tools/SelectionTool/Selection.d.ts +0 -71
  131. package/dist/cjs/tools/SelectionTool/Selection.js +0 -620
  132. package/dist/cjs/tools/SelectionTool/SelectionHandle.d.ts +0 -62
  133. package/dist/cjs/tools/SelectionTool/SelectionHandle.js +0 -141
  134. package/dist/cjs/tools/SelectionTool/SelectionTool.d.ts +0 -40
  135. package/dist/cjs/tools/SelectionTool/SelectionTool.js +0 -494
  136. package/dist/cjs/tools/SelectionTool/SelectionTool.selecting.test.d.ts +0 -1
  137. package/dist/cjs/tools/SelectionTool/SelectionTool.test.d.ts +0 -1
  138. package/dist/cjs/tools/SelectionTool/ToPointerAutoscroller.d.ts +0 -23
  139. package/dist/cjs/tools/SelectionTool/ToPointerAutoscroller.js +0 -83
  140. package/dist/cjs/tools/SelectionTool/TransformMode.d.ts +0 -42
  141. package/dist/cjs/tools/SelectionTool/TransformMode.js +0 -155
  142. package/dist/cjs/tools/SelectionTool/types.d.ts +0 -28
  143. package/dist/cjs/tools/SelectionTool/types.js +0 -14
  144. package/dist/cjs/tools/SoundUITool.d.ts +0 -26
  145. package/dist/cjs/tools/SoundUITool.js +0 -171
  146. package/dist/cjs/tools/TextTool.d.ts +0 -36
  147. package/dist/cjs/tools/TextTool.js +0 -285
  148. package/dist/cjs/tools/TextTool.test.d.ts +0 -1
  149. package/dist/cjs/tools/ToolController.d.ts +0 -73
  150. package/dist/cjs/tools/ToolController.js +0 -304
  151. package/dist/cjs/tools/ToolController.test.d.ts +0 -1
  152. package/dist/cjs/tools/ToolEnabledGroup.d.ts +0 -6
  153. package/dist/cjs/tools/ToolEnabledGroup.js +0 -13
  154. package/dist/cjs/tools/ToolSwitcherShortcut.d.ts +0 -16
  155. package/dist/cjs/tools/ToolSwitcherShortcut.js +0 -40
  156. package/dist/cjs/tools/ToolbarShortcutHandler.d.ts +0 -12
  157. package/dist/cjs/tools/ToolbarShortcutHandler.js +0 -34
  158. package/dist/cjs/tools/UndoRedoShortcut.d.ts +0 -8
  159. package/dist/cjs/tools/UndoRedoShortcut.js +0 -27
  160. package/dist/cjs/tools/UndoRedoShortcut.test.d.ts +0 -1
  161. package/dist/cjs/tools/keybindings.d.ts +0 -18
  162. package/dist/cjs/tools/keybindings.js +0 -49
  163. package/dist/cjs/tools/lib.d.ts +0 -14
  164. package/dist/cjs/tools/lib.js +0 -36
  165. package/dist/cjs/tools/localization.d.ts +0 -34
  166. package/dist/cjs/tools/localization.js +0 -36
  167. package/dist/cjs/tools/util/StationaryPenDetector.d.ts +0 -22
  168. package/dist/cjs/tools/util/StationaryPenDetector.js +0 -95
  169. package/dist/mjs/tools/BaseTool.d.ts +0 -60
  170. package/dist/mjs/tools/BaseTool.mjs +0 -172
  171. package/dist/mjs/tools/Eraser.d.ts +0 -56
  172. package/dist/mjs/tools/Eraser.mjs +0 -288
  173. package/dist/mjs/tools/Eraser.test.d.ts +0 -1
  174. package/dist/mjs/tools/FindTool.d.ts +0 -21
  175. package/dist/mjs/tools/FindTool.mjs +0 -131
  176. package/dist/mjs/tools/FindTool.test.d.ts +0 -1
  177. package/dist/mjs/tools/InputFilter/FunctionMapper.d.ts +0 -12
  178. package/dist/mjs/tools/InputFilter/FunctionMapper.mjs +0 -15
  179. package/dist/mjs/tools/InputFilter/InputMapper.d.ts +0 -23
  180. package/dist/mjs/tools/InputFilter/InputMapper.mjs +0 -36
  181. package/dist/mjs/tools/InputFilter/InputPipeline.d.ts +0 -15
  182. package/dist/mjs/tools/InputFilter/InputPipeline.mjs +0 -49
  183. package/dist/mjs/tools/InputFilter/InputPipeline.test.d.ts +0 -1
  184. package/dist/mjs/tools/InputFilter/InputStabilizer.d.ts +0 -29
  185. package/dist/mjs/tools/InputFilter/InputStabilizer.mjs +0 -175
  186. package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.d.ts +0 -21
  187. package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.mjs +0 -78
  188. package/dist/mjs/tools/PanZoom.d.ts +0 -119
  189. package/dist/mjs/tools/PanZoom.mjs +0 -501
  190. package/dist/mjs/tools/PanZoom.test.d.ts +0 -1
  191. package/dist/mjs/tools/PasteHandler.d.ts +0 -23
  192. package/dist/mjs/tools/PasteHandler.mjs +0 -103
  193. package/dist/mjs/tools/Pen.d.ts +0 -53
  194. package/dist/mjs/tools/Pen.mjs +0 -312
  195. package/dist/mjs/tools/Pen.test.d.ts +0 -1
  196. package/dist/mjs/tools/PipetteTool.d.ts +0 -28
  197. package/dist/mjs/tools/PipetteTool.mjs +0 -63
  198. package/dist/mjs/tools/ScrollbarTool.d.ts +0 -18
  199. package/dist/mjs/tools/ScrollbarTool.mjs +0 -79
  200. package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +0 -9
  201. package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.mjs +0 -26
  202. package/dist/mjs/tools/SelectionTool/Selection.d.ts +0 -71
  203. package/dist/mjs/tools/SelectionTool/Selection.mjs +0 -592
  204. package/dist/mjs/tools/SelectionTool/SelectionHandle.d.ts +0 -62
  205. package/dist/mjs/tools/SelectionTool/SelectionHandle.mjs +0 -137
  206. package/dist/mjs/tools/SelectionTool/SelectionTool.d.ts +0 -40
  207. package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +0 -488
  208. package/dist/mjs/tools/SelectionTool/SelectionTool.selecting.test.d.ts +0 -1
  209. package/dist/mjs/tools/SelectionTool/SelectionTool.test.d.ts +0 -1
  210. package/dist/mjs/tools/SelectionTool/ToPointerAutoscroller.d.ts +0 -23
  211. package/dist/mjs/tools/SelectionTool/ToPointerAutoscroller.mjs +0 -77
  212. package/dist/mjs/tools/SelectionTool/TransformMode.d.ts +0 -42
  213. package/dist/mjs/tools/SelectionTool/TransformMode.mjs +0 -146
  214. package/dist/mjs/tools/SelectionTool/types.d.ts +0 -28
  215. package/dist/mjs/tools/SelectionTool/types.mjs +0 -11
  216. package/dist/mjs/tools/SoundUITool.d.ts +0 -26
  217. package/dist/mjs/tools/SoundUITool.mjs +0 -165
  218. package/dist/mjs/tools/TextTool.d.ts +0 -36
  219. package/dist/mjs/tools/TextTool.mjs +0 -279
  220. package/dist/mjs/tools/TextTool.test.d.ts +0 -1
  221. package/dist/mjs/tools/ToolController.d.ts +0 -73
  222. package/dist/mjs/tools/ToolController.mjs +0 -275
  223. package/dist/mjs/tools/ToolController.test.d.ts +0 -1
  224. package/dist/mjs/tools/ToolEnabledGroup.d.ts +0 -6
  225. package/dist/mjs/tools/ToolEnabledGroup.mjs +0 -10
  226. package/dist/mjs/tools/ToolSwitcherShortcut.d.ts +0 -16
  227. package/dist/mjs/tools/ToolSwitcherShortcut.mjs +0 -34
  228. package/dist/mjs/tools/ToolbarShortcutHandler.d.ts +0 -12
  229. package/dist/mjs/tools/ToolbarShortcutHandler.mjs +0 -28
  230. package/dist/mjs/tools/UndoRedoShortcut.d.ts +0 -8
  231. package/dist/mjs/tools/UndoRedoShortcut.mjs +0 -21
  232. package/dist/mjs/tools/UndoRedoShortcut.test.d.ts +0 -1
  233. package/dist/mjs/tools/keybindings.d.ts +0 -18
  234. package/dist/mjs/tools/keybindings.mjs +0 -43
  235. package/dist/mjs/tools/lib.d.ts +0 -14
  236. package/dist/mjs/tools/lib.mjs +0 -14
  237. package/dist/mjs/tools/localization.d.ts +0 -34
  238. package/dist/mjs/tools/localization.mjs +0 -33
  239. package/dist/mjs/tools/util/StationaryPenDetector.d.ts +0 -22
  240. package/dist/mjs/tools/util/StationaryPenDetector.mjs +0 -92
  241. package/src/tools/FindTool.css +0 -7
  242. package/src/tools/ScrollbarTool.scss +0 -57
  243. package/src/tools/SelectionTool/SelectionTool.scss +0 -137
  244. package/src/tools/SoundUITool.scss +0 -22
  245. package/src/tools/tools.scss +0 -5
@@ -1,295 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.EraserMode = void 0;
7
- const types_1 = require("../types");
8
- const BaseTool_1 = __importDefault(require("./BaseTool"));
9
- const math_1 = require("@js-draw/math");
10
- const Erase_1 = __importDefault(require("../commands/Erase"));
11
- const Pointer_1 = require("../Pointer");
12
- const keybindings_1 = require("./keybindings");
13
- const ReactiveValue_1 = require("../util/ReactiveValue");
14
- const EditorImage_1 = __importDefault(require("../image/EditorImage"));
15
- const uniteCommands_1 = __importDefault(require("../commands/uniteCommands"));
16
- const RenderablePathSpec_1 = require("../rendering/RenderablePathSpec");
17
- var EraserMode;
18
- (function (EraserMode) {
19
- EraserMode["PartialStroke"] = "partial-stroke";
20
- EraserMode["FullStroke"] = "full-stroke";
21
- })(EraserMode || (exports.EraserMode = EraserMode = {}));
22
- /** Handles switching from other primary tools to the eraser and back */
23
- class EraserSwitcher extends BaseTool_1.default {
24
- constructor(editor, eraser) {
25
- super(editor.notifier, editor.localization.changeTool);
26
- this.editor = editor;
27
- this.eraser = eraser;
28
- }
29
- onPointerDown(event) {
30
- if (event.allPointers.length === 1 && event.current.device === Pointer_1.PointerDevice.Eraser) {
31
- const toolController = this.editor.toolController;
32
- const enabledPrimaryTools = toolController.getPrimaryTools().filter(tool => tool.isEnabled());
33
- if (enabledPrimaryTools.length) {
34
- this.previousEnabledTool = enabledPrimaryTools[0];
35
- }
36
- else {
37
- this.previousEnabledTool = null;
38
- }
39
- this.previousEraserEnabledState = this.eraser.isEnabled();
40
- this.eraser.setEnabled(true);
41
- if (this.eraser.onPointerDown(event)) {
42
- return true;
43
- }
44
- else {
45
- this.restoreOriginalTool();
46
- }
47
- }
48
- return false;
49
- }
50
- onPointerMove(event) {
51
- this.eraser.onPointerMove(event);
52
- }
53
- restoreOriginalTool() {
54
- this.eraser.setEnabled(this.previousEraserEnabledState);
55
- if (this.previousEnabledTool) {
56
- this.previousEnabledTool.setEnabled(true);
57
- }
58
- }
59
- onPointerUp(event) {
60
- this.eraser.onPointerUp(event);
61
- this.restoreOriginalTool();
62
- }
63
- onGestureCancel(event) {
64
- this.eraser.onGestureCancel(event);
65
- this.restoreOriginalTool();
66
- }
67
- }
68
- class Eraser extends BaseTool_1.default {
69
- constructor(editor, description, options) {
70
- super(editor.notifier, description);
71
- this.editor = editor;
72
- this.lastPoint = null;
73
- this.isFirstEraseEvt = true;
74
- this.toAdd = new Set();
75
- // Commands that each remove one element
76
- this.eraseCommands = [];
77
- this.addCommands = [];
78
- this.thickness = options?.thickness ?? 10;
79
- this.thicknessValue = ReactiveValue_1.ReactiveValue.fromInitialValue(this.thickness);
80
- this.thicknessValue.onUpdate(value => {
81
- this.thickness = value;
82
- this.editor.notifier.dispatch(types_1.EditorEventType.ToolUpdated, {
83
- kind: types_1.EditorEventType.ToolUpdated,
84
- tool: this,
85
- });
86
- });
87
- this.modeValue = ReactiveValue_1.ReactiveValue.fromInitialValue(options?.mode ?? EraserMode.FullStroke);
88
- this.modeValue.onUpdate(_value => {
89
- this.editor.notifier.dispatch(types_1.EditorEventType.ToolUpdated, {
90
- kind: types_1.EditorEventType.ToolUpdated,
91
- tool: this,
92
- });
93
- });
94
- }
95
- /**
96
- * @returns a tool that briefly enables the eraser when a physical eraser is used.
97
- * This tool should be added to the tool list after the primary tools.
98
- */
99
- makeEraserSwitcherTool() {
100
- return new EraserSwitcher(this.editor, this);
101
- }
102
- clearPreview() {
103
- this.editor.clearWetInk();
104
- }
105
- getSizeOnCanvas() {
106
- return this.thickness / this.editor.viewport.getScaleFactor();
107
- }
108
- drawPreviewAt(point) {
109
- this.clearPreview();
110
- const size = this.getSizeOnCanvas();
111
- const renderer = this.editor.display.getWetInkRenderer();
112
- const rect = this.getEraserRect(point);
113
- const rect2 = this.getEraserRect(this.lastPoint ?? point);
114
- const fill = {
115
- fill: math_1.Color4.transparent,
116
- stroke: { width: size / 10, color: math_1.Color4.gray },
117
- };
118
- renderer.drawPath((0, RenderablePathSpec_1.pathToRenderable)(math_1.Path.fromConvexHullOf([...rect.corners, ...rect2.corners]), fill));
119
- }
120
- /**
121
- * @returns the eraser rectangle in canvas coordinates.
122
- *
123
- * For now, all erasers are rectangles or points.
124
- */
125
- getEraserRect(centerPoint) {
126
- const size = this.getSizeOnCanvas();
127
- const halfSize = math_1.Vec2.of(size / 2, size / 2);
128
- return math_1.Rect2.fromCorners(centerPoint.minus(halfSize), centerPoint.plus(halfSize));
129
- }
130
- /** Erases in a line from the last point to the current. */
131
- eraseTo(currentPoint) {
132
- if (!this.isFirstEraseEvt && currentPoint.distanceTo(this.lastPoint) === 0) {
133
- return;
134
- }
135
- this.isFirstEraseEvt = false;
136
- // Currently only objects within eraserRect or that intersect a straight line
137
- // from the center of the current rect to the previous are erased. TODO: Erase
138
- // all objects as if there were pointerMove events between the two points.
139
- const eraserRect = this.getEraserRect(currentPoint);
140
- const line = new math_1.LineSegment2(this.lastPoint, currentPoint);
141
- const region = math_1.Rect2.union(line.bbox, eraserRect);
142
- const intersectingElems = this.editor.image.getElementsIntersectingRegion(region).filter(component => {
143
- return component.intersects(line) || component.intersectsRect(eraserRect);
144
- });
145
- // Only erase components that could be selected (and thus interacted with)
146
- // by the user.
147
- const eraseableElems = intersectingElems.filter(elem => elem.isSelectable());
148
- if (this.modeValue.get() === EraserMode.FullStroke) {
149
- // Remove any intersecting elements.
150
- this.toRemove.push(...eraseableElems);
151
- // Create new Erase commands for the now-to-be-erased elements and apply them.
152
- const newPartialCommands = eraseableElems.map(elem => new Erase_1.default([elem]));
153
- newPartialCommands.forEach(cmd => cmd.apply(this.editor));
154
- this.eraseCommands.push(...newPartialCommands);
155
- }
156
- else {
157
- const toErase = [];
158
- const toAdd = [];
159
- for (const targetElem of eraseableElems) {
160
- toErase.push(targetElem);
161
- // Completely delete items that can't be divided.
162
- if (!targetElem.withRegionErased) {
163
- continue;
164
- }
165
- // Completely delete items that are completely or almost completely
166
- // contained within the eraser.
167
- const grownRect = eraserRect.grownBy(eraserRect.maxDimension / 3);
168
- if (grownRect.containsRect(targetElem.getExactBBox())) {
169
- continue;
170
- }
171
- // Join the current and previous rectangles so that points between events are also
172
- // erased.
173
- const erasePath = math_1.Path.fromConvexHullOf([
174
- ...eraserRect.corners, ...this.getEraserRect(this.lastPoint ?? currentPoint).corners
175
- ].map(p => this.editor.viewport.roundPoint(p)));
176
- toAdd.push(...targetElem.withRegionErased(erasePath, this.editor.viewport));
177
- }
178
- const eraseCommand = new Erase_1.default(toErase);
179
- const newAddCommands = toAdd.map(elem => EditorImage_1.default.addElement(elem));
180
- eraseCommand.apply(this.editor);
181
- newAddCommands.forEach(command => command.apply(this.editor));
182
- const finalToErase = [];
183
- for (const item of toErase) {
184
- if (this.toAdd.has(item)) {
185
- this.toAdd.delete(item);
186
- }
187
- else {
188
- finalToErase.push(item);
189
- }
190
- }
191
- this.toRemove.push(...finalToErase);
192
- for (const item of toAdd) {
193
- this.toAdd.add(item);
194
- }
195
- this.eraseCommands.push(new Erase_1.default(finalToErase));
196
- this.addCommands.push(...newAddCommands);
197
- }
198
- this.drawPreviewAt(currentPoint);
199
- this.lastPoint = currentPoint;
200
- }
201
- onPointerDown(event) {
202
- if (event.allPointers.length === 1 || event.current.device === Pointer_1.PointerDevice.Eraser) {
203
- this.lastPoint = event.current.canvasPos;
204
- this.toRemove = [];
205
- this.toAdd.clear();
206
- this.isFirstEraseEvt = true;
207
- this.drawPreviewAt(event.current.canvasPos);
208
- return true;
209
- }
210
- return false;
211
- }
212
- onPointerMove(event) {
213
- const currentPoint = event.current.canvasPos;
214
- this.eraseTo(currentPoint);
215
- }
216
- onPointerUp(event) {
217
- this.eraseTo(event.current.canvasPos);
218
- const commands = [];
219
- if (this.addCommands.length > 0) {
220
- this.addCommands.forEach(cmd => cmd.unapply(this.editor));
221
- // Remove items from toAdd that are also present in toRemove -- adding, then
222
- // removing these does nothing, and can break undo/redo.
223
- for (const item of this.toAdd) {
224
- if (this.toRemove.includes(item)) {
225
- this.toAdd.delete(item);
226
- this.toRemove = this.toRemove.filter(other => other !== item);
227
- }
228
- }
229
- for (const item of this.toRemove) {
230
- if (this.toAdd.has(item)) {
231
- this.toAdd.delete(item);
232
- this.toRemove = this.toRemove.filter(other => other !== item);
233
- }
234
- }
235
- commands.push(...[...this.toAdd].map(a => EditorImage_1.default.addElement(a)));
236
- this.addCommands = [];
237
- }
238
- if (this.eraseCommands.length > 0) {
239
- // Undo commands for each individual component and unite into a single command.
240
- this.eraseCommands.forEach(cmd => cmd.unapply(this.editor));
241
- this.eraseCommands = [];
242
- const command = new Erase_1.default(this.toRemove);
243
- commands.push(command);
244
- }
245
- if (commands.length === 1) {
246
- this.editor.dispatch(commands[0]); // dispatch: Makes undo-able.
247
- }
248
- else {
249
- this.editor.dispatch((0, uniteCommands_1.default)(commands));
250
- }
251
- this.clearPreview();
252
- }
253
- onGestureCancel(_event) {
254
- this.addCommands.forEach(cmd => cmd.unapply(this.editor));
255
- this.eraseCommands.forEach(cmd => cmd.unapply(this.editor));
256
- this.eraseCommands = [];
257
- this.addCommands = [];
258
- this.clearPreview();
259
- }
260
- onKeyPress(event) {
261
- const shortcuts = this.editor.shortcuts;
262
- let newThickness;
263
- if (shortcuts.matchesShortcut(keybindings_1.decreaseSizeKeyboardShortcutId, event)) {
264
- newThickness = this.getThickness() * 2 / 3;
265
- }
266
- else if (shortcuts.matchesShortcut(keybindings_1.increaseSizeKeyboardShortcutId, event)) {
267
- newThickness = this.getThickness() * 3 / 2;
268
- }
269
- if (newThickness !== undefined) {
270
- newThickness = Math.min(Math.max(1, newThickness), 200);
271
- this.setThickness(newThickness);
272
- return true;
273
- }
274
- return false;
275
- }
276
- /** Returns the side-length of the tip of this eraser. */
277
- getThickness() {
278
- return this.thickness;
279
- }
280
- /** Sets the side-length of this' tip. */
281
- setThickness(thickness) {
282
- this.thicknessValue.set(thickness);
283
- }
284
- /**
285
- * Returns a {@link MutableReactiveValue} that can be used to watch
286
- * this tool's thickness.
287
- */
288
- getThicknessValue() {
289
- return this.thicknessValue;
290
- }
291
- getModeValue() {
292
- return this.modeValue;
293
- }
294
- }
295
- exports.default = Eraser;
@@ -1 +0,0 @@
1
- export {};
@@ -1,21 +0,0 @@
1
- import Editor from '../Editor';
2
- import { KeyPressEvent } from '../inputEvents';
3
- import BaseTool from './BaseTool';
4
- export default class FindTool extends BaseTool {
5
- private editor;
6
- private overlay;
7
- private searchInput;
8
- private currentMatchIdx;
9
- constructor(editor: Editor);
10
- canReceiveInputInReadOnlyEditor(): boolean;
11
- private getMatches;
12
- private focusCurrentMatch;
13
- private toNextMatch;
14
- private toPrevMatch;
15
- private fillOverlay;
16
- private isVisible;
17
- private setVisible;
18
- private toggleVisible;
19
- onKeyPress(event: KeyPressEvent): boolean;
20
- setEnabled(enabled: boolean): void;
21
- }
@@ -1,137 +0,0 @@
1
- "use strict";
2
- // Displays a find dialog that allows the user to search for and focus text.
3
- //
4
- // @packageDocumentation
5
- var __importDefault = (this && this.__importDefault) || function (mod) {
6
- return (mod && mod.__esModule) ? mod : { "default": mod };
7
- };
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- const TextComponent_1 = __importDefault(require("../components/TextComponent"));
10
- const ImageComponent_1 = __importDefault(require("../components/ImageComponent"));
11
- const BaseTool_1 = __importDefault(require("./BaseTool"));
12
- const keybindings_1 = require("./keybindings");
13
- const cssPrefix = 'find-tool';
14
- class FindTool extends BaseTool_1.default {
15
- constructor(editor) {
16
- super(editor.notifier, editor.localization.findLabel);
17
- this.editor = editor;
18
- this.currentMatchIdx = 0;
19
- this.overlay = document.createElement('div');
20
- this.fillOverlay();
21
- editor.createHTMLOverlay(this.overlay);
22
- this.overlay.style.display = 'none';
23
- this.overlay.classList.add(`${cssPrefix}-overlay`);
24
- }
25
- canReceiveInputInReadOnlyEditor() {
26
- return true;
27
- }
28
- getMatches(searchFor) {
29
- const lowerSearchFor = searchFor.toLocaleLowerCase();
30
- const matchingComponents = this.editor.image.getAllElements().filter(component => {
31
- let text = '';
32
- if (component instanceof TextComponent_1.default) {
33
- text = component.getText();
34
- }
35
- else if (component instanceof ImageComponent_1.default) {
36
- text = component.getAltText() ?? '';
37
- }
38
- else {
39
- return false;
40
- }
41
- const hasLowercaseMatch = text.toLocaleLowerCase().indexOf(lowerSearchFor) !== -1;
42
- const hasSameCaseMatch = text.indexOf(searchFor) !== -1;
43
- return hasLowercaseMatch || hasSameCaseMatch;
44
- });
45
- return matchingComponents.map(match => match.getBBox());
46
- }
47
- focusCurrentMatch() {
48
- const matches = this.getMatches(this.searchInput.value);
49
- let matchIdx = this.currentMatchIdx % matches.length;
50
- if (matchIdx < 0) {
51
- matchIdx = matches.length + matchIdx;
52
- }
53
- if (matchIdx < matches.length) {
54
- const undoable = false;
55
- void this.editor.dispatch(this.editor.viewport.zoomTo(matches[matchIdx], true, true), undoable);
56
- this.editor.announceForAccessibility(this.editor.localization.focusedFoundText(matchIdx + 1, matches.length));
57
- }
58
- }
59
- toNextMatch() {
60
- this.currentMatchIdx++;
61
- this.focusCurrentMatch();
62
- }
63
- toPrevMatch() {
64
- this.currentMatchIdx--;
65
- this.focusCurrentMatch();
66
- }
67
- fillOverlay() {
68
- const label = document.createElement('label');
69
- this.searchInput = document.createElement('input');
70
- const nextBtn = document.createElement('button');
71
- const closeBtn = document.createElement('button');
72
- // Math.random() ensures that the ID is unique (to allow us to refer to it
73
- // with an htmlFor).
74
- this.searchInput.setAttribute('id', `${cssPrefix}-searchInput-${Math.random()}`);
75
- label.htmlFor = this.searchInput.getAttribute('id');
76
- label.innerText = this.editor.localization.findLabel;
77
- nextBtn.innerText = this.editor.localization.toNextMatch;
78
- closeBtn.innerText = this.editor.localization.closeDialog;
79
- this.searchInput.onkeydown = (ev) => {
80
- if (ev.key === 'Enter') {
81
- if (ev.shiftKey) {
82
- this.toPrevMatch();
83
- }
84
- else {
85
- this.toNextMatch();
86
- }
87
- }
88
- else if (ev.key === 'Escape') {
89
- this.setVisible(false);
90
- }
91
- else if (this.editor.shortcuts.matchesShortcut(keybindings_1.toggleFindVisibleShortcutId, ev)) {
92
- ev.preventDefault();
93
- this.toggleVisible();
94
- }
95
- };
96
- nextBtn.onclick = () => {
97
- this.toNextMatch();
98
- };
99
- closeBtn.onclick = () => {
100
- this.setVisible(false);
101
- };
102
- this.overlay.replaceChildren(label, this.searchInput, nextBtn, closeBtn);
103
- }
104
- isVisible() {
105
- return this.overlay.style.display !== 'none';
106
- }
107
- setVisible(visible) {
108
- if (visible !== this.isVisible()) {
109
- this.overlay.style.display = visible ? 'block' : 'none';
110
- if (visible) {
111
- this.searchInput.focus();
112
- this.editor.announceForAccessibility(this.editor.localization.findDialogShown);
113
- }
114
- else {
115
- this.editor.focus();
116
- this.editor.announceForAccessibility(this.editor.localization.findDialogHidden);
117
- }
118
- }
119
- }
120
- toggleVisible() {
121
- this.setVisible(!this.isVisible());
122
- }
123
- onKeyPress(event) {
124
- if (this.editor.shortcuts.matchesShortcut(keybindings_1.toggleFindVisibleShortcutId, event)) {
125
- this.toggleVisible();
126
- return true;
127
- }
128
- return false;
129
- }
130
- setEnabled(enabled) {
131
- super.setEnabled(enabled);
132
- if (this.isEnabled()) {
133
- this.setVisible(false);
134
- }
135
- }
136
- }
137
- exports.default = FindTool;
@@ -1 +0,0 @@
1
- export {};
@@ -1,12 +0,0 @@
1
- import { InputEvt } from '../../inputEvents';
2
- import InputMapper from './InputMapper';
3
- /**
4
- * An `InputMapper` that applies a function to all events it receives.
5
- *
6
- * Useful for automated testing.
7
- */
8
- export default class FunctionMapper extends InputMapper {
9
- private fn;
10
- constructor(fn: (event: InputEvt) => InputEvt);
11
- onEvent(event: InputEvt): boolean;
12
- }
@@ -1,21 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const InputMapper_1 = __importDefault(require("./InputMapper"));
7
- /**
8
- * An `InputMapper` that applies a function to all events it receives.
9
- *
10
- * Useful for automated testing.
11
- */
12
- class FunctionMapper extends InputMapper_1.default {
13
- constructor(fn) {
14
- super();
15
- this.fn = fn;
16
- }
17
- onEvent(event) {
18
- return this.emit(this.fn(event));
19
- }
20
- }
21
- exports.default = FunctionMapper;
@@ -1,23 +0,0 @@
1
- import { InputEvt } from '../../inputEvents';
2
- type OnEventCallback = (event: InputEvt) => boolean;
3
- export interface InputEventListener {
4
- onEvent: OnEventCallback;
5
- }
6
- /**
7
- * Accepts input events and emits input events.
8
- */
9
- export default abstract class InputMapper implements InputEventListener {
10
- #private;
11
- constructor();
12
- setEmitListener(listener: InputEventListener | OnEventCallback | null): void;
13
- protected emit(event: InputEvt): boolean;
14
- /**
15
- * @returns true if the given `event` should be considered "handled" by the app and thus not
16
- * forwarded to other targets. For example, returning "true" for a touchpad pinch event prevents
17
- * the pinch event from zooming the webpage.
18
- *
19
- * Generally, this should return the result of calling `this.emit` with some event.
20
- */
21
- abstract onEvent(event: InputEvt): boolean;
22
- }
23
- export {};
@@ -1,38 +0,0 @@
1
- "use strict";
2
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
- if (kind === "m") throw new TypeError("Private method is not writable");
4
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
- };
8
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
- };
13
- var _InputMapper_listener;
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- /**
16
- * Accepts input events and emits input events.
17
- */
18
- class InputMapper {
19
- constructor() {
20
- _InputMapper_listener.set(this, null);
21
- }
22
- // @internal
23
- setEmitListener(listener) {
24
- if (listener && typeof (listener) === 'object') {
25
- __classPrivateFieldSet(this, _InputMapper_listener, (event) => {
26
- return listener.onEvent(event) ?? false;
27
- }, "f");
28
- }
29
- else {
30
- __classPrivateFieldSet(this, _InputMapper_listener, listener, "f");
31
- }
32
- }
33
- emit(event) {
34
- return __classPrivateFieldGet(this, _InputMapper_listener, "f")?.call(this, event) ?? false;
35
- }
36
- }
37
- _InputMapper_listener = new WeakMap();
38
- exports.default = InputMapper;
@@ -1,15 +0,0 @@
1
- import { InputEvt } from '../../inputEvents';
2
- import InputMapper from './InputMapper';
3
- /**
4
- * The composition of multiple `InputMapper`s.
5
- */
6
- export default class InputPipeline extends InputMapper {
7
- #private;
8
- onEvent(event: InputEvt): boolean;
9
- /**
10
- * Adds a new `InputMapper` to the *tail* of this pipeline.
11
- * Note that an instance of an `InputMapper` can only be used in a single
12
- * pipeline.
13
- */
14
- addToTail(mapper: InputMapper): void;
15
- }
@@ -1,54 +0,0 @@
1
- "use strict";
2
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
- };
7
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
8
- if (kind === "m") throw new TypeError("Private method is not writable");
9
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
10
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
- };
13
- var __importDefault = (this && this.__importDefault) || function (mod) {
14
- return (mod && mod.__esModule) ? mod : { "default": mod };
15
- };
16
- var _InputPipeline_head, _InputPipeline_tail;
17
- Object.defineProperty(exports, "__esModule", { value: true });
18
- const InputMapper_1 = __importDefault(require("./InputMapper"));
19
- /**
20
- * The composition of multiple `InputMapper`s.
21
- */
22
- class InputPipeline extends InputMapper_1.default {
23
- constructor() {
24
- super(...arguments);
25
- _InputPipeline_head.set(this, null);
26
- _InputPipeline_tail.set(this, null);
27
- }
28
- onEvent(event) {
29
- if (__classPrivateFieldGet(this, _InputPipeline_head, "f") === null) {
30
- return this.emit(event);
31
- }
32
- else {
33
- return __classPrivateFieldGet(this, _InputPipeline_head, "f").onEvent(event);
34
- }
35
- }
36
- /**
37
- * Adds a new `InputMapper` to the *tail* of this pipeline.
38
- * Note that an instance of an `InputMapper` can only be used in a single
39
- * pipeline.
40
- */
41
- addToTail(mapper) {
42
- if (!__classPrivateFieldGet(this, _InputPipeline_tail, "f")) {
43
- __classPrivateFieldSet(this, _InputPipeline_head, mapper, "f");
44
- __classPrivateFieldSet(this, _InputPipeline_tail, __classPrivateFieldGet(this, _InputPipeline_head, "f"), "f");
45
- }
46
- else {
47
- __classPrivateFieldGet(this, _InputPipeline_tail, "f").setEmitListener(mapper);
48
- __classPrivateFieldSet(this, _InputPipeline_tail, mapper, "f");
49
- }
50
- __classPrivateFieldGet(this, _InputPipeline_tail, "f").setEmitListener(event => this.emit(event));
51
- }
52
- }
53
- _InputPipeline_head = new WeakMap(), _InputPipeline_tail = new WeakMap();
54
- exports.default = InputPipeline;
@@ -1 +0,0 @@
1
- export {};
@@ -1,29 +0,0 @@
1
- import { InputEvt } from '../../inputEvents';
2
- import InputMapper from './InputMapper';
3
- import Viewport from '../../Viewport';
4
- import Editor from '../../Editor';
5
- declare enum StabilizerType {
6
- IntertialStabilizer = 0
7
- }
8
- interface InputStabilizerOptions {
9
- kind: StabilizerType.IntertialStabilizer;
10
- mass: number;
11
- springConstant: number;
12
- frictionCoefficient: number;
13
- maxPointDist: number;
14
- minSimilarityToFinalize: number;
15
- inertiaFraction: number;
16
- velocityDecayFactor: number;
17
- }
18
- export default class InputStabilizer extends InputMapper {
19
- private viewport;
20
- private readonly options;
21
- private stabilizer;
22
- private lastPointerEvent;
23
- constructor(viewport: Viewport, options?: InputStabilizerOptions);
24
- private mapPointerEvent;
25
- private emitPointerMove;
26
- onEvent(event: InputEvt): boolean;
27
- static fromEditor(editor: Editor): InputStabilizer;
28
- }
29
- export {};