js-draw 0.18.2 → 0.20.0

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 (269) hide show
  1. package/.eslintrc.js +1 -0
  2. package/CHANGELOG.md +10 -0
  3. package/dist/bundle.js +2 -2
  4. package/dist/bundledStyles.js +1 -0
  5. package/dist/cjs/src/Color4.d.ts +8 -0
  6. package/dist/cjs/src/Color4.js +67 -0
  7. package/dist/cjs/src/Editor.d.ts +2 -2
  8. package/dist/cjs/src/Editor.js +7 -7
  9. package/dist/cjs/src/SVGLoader.js +77 -12
  10. package/dist/cjs/src/Viewport.d.ts +2 -0
  11. package/dist/cjs/src/Viewport.js +6 -2
  12. package/dist/cjs/src/components/AbstractComponent.d.ts +2 -2
  13. package/dist/cjs/src/components/AbstractComponent.js +3 -3
  14. package/dist/cjs/src/components/{ImageBackground.d.ts → BackgroundComponent.d.ts} +23 -3
  15. package/dist/cjs/src/components/BackgroundComponent.js +309 -0
  16. package/dist/cjs/src/components/RestylableComponent.d.ts +21 -2
  17. package/dist/cjs/src/components/Stroke.d.ts +35 -0
  18. package/dist/cjs/src/components/Stroke.js +37 -3
  19. package/dist/cjs/src/components/TextComponent.d.ts +27 -17
  20. package/dist/cjs/src/components/TextComponent.js +23 -1
  21. package/dist/cjs/src/components/lib.d.ts +4 -3
  22. package/dist/cjs/src/components/lib.js +2 -2
  23. package/dist/cjs/src/components/util/StrokeSmoother.js +25 -15
  24. package/dist/cjs/src/lib.d.ts +30 -0
  25. package/dist/cjs/src/lib.js +30 -0
  26. package/dist/cjs/src/localizations/de.js +1 -1
  27. package/dist/cjs/src/localizations/es.js +1 -1
  28. package/dist/cjs/src/math/Path.js +1 -1
  29. package/dist/cjs/src/math/polynomial/QuadraticBezier.d.ts +28 -0
  30. package/dist/cjs/src/math/polynomial/QuadraticBezier.js +115 -0
  31. package/dist/cjs/src/math/polynomial/solveQuadratic.d.ts +6 -0
  32. package/dist/cjs/src/math/polynomial/solveQuadratic.js +36 -0
  33. package/dist/cjs/src/rendering/RenderingStyle.d.ts +4 -4
  34. package/dist/cjs/src/rendering/TextRenderingStyle.d.ts +10 -10
  35. package/dist/cjs/src/rendering/lib.d.ts +2 -0
  36. package/dist/cjs/src/rendering/renderers/AbstractRenderer.d.ts +2 -2
  37. package/dist/cjs/src/rendering/renderers/CanvasRenderer.d.ts +2 -2
  38. package/dist/cjs/src/rendering/renderers/CanvasRenderer.js +5 -3
  39. package/dist/cjs/src/rendering/renderers/DummyRenderer.d.ts +2 -2
  40. package/dist/cjs/src/rendering/renderers/SVGRenderer.d.ts +2 -2
  41. package/dist/cjs/src/rendering/renderers/SVGRenderer.js +15 -6
  42. package/dist/cjs/src/rendering/renderers/TextOnlyRenderer.d.ts +2 -2
  43. package/dist/cjs/src/toolbar/IconProvider.d.ts +2 -2
  44. package/dist/cjs/src/toolbar/localization.d.ts +2 -1
  45. package/dist/cjs/src/toolbar/localization.js +3 -2
  46. package/dist/cjs/src/toolbar/widgets/BaseWidget.js +1 -1
  47. package/dist/cjs/src/toolbar/widgets/DocumentPropertiesWidget.d.ts +5 -0
  48. package/dist/cjs/src/toolbar/widgets/DocumentPropertiesWidget.js +77 -2
  49. package/dist/cjs/src/toolbar/widgets/PenToolWidget.js +1 -1
  50. package/dist/cjs/src/tools/FindTool.js +1 -1
  51. package/dist/cjs/src/tools/SoundUITool.d.ts +24 -0
  52. package/dist/cjs/src/tools/SoundUITool.js +164 -0
  53. package/dist/cjs/src/tools/TextTool.d.ts +2 -2
  54. package/dist/cjs/src/tools/ToolController.js +6 -1
  55. package/dist/cjs/src/tools/lib.d.ts +1 -0
  56. package/dist/cjs/src/tools/lib.js +3 -1
  57. package/dist/cjs/src/tools/localization.d.ts +3 -0
  58. package/dist/cjs/src/tools/localization.js +3 -0
  59. package/dist/mjs/src/Color4.d.ts +8 -0
  60. package/dist/mjs/src/Color4.mjs +64 -0
  61. package/dist/mjs/src/Editor.d.ts +2 -2
  62. package/dist/mjs/src/Editor.mjs +6 -6
  63. package/dist/mjs/src/SVGLoader.mjs +76 -11
  64. package/dist/mjs/src/Viewport.d.ts +2 -0
  65. package/dist/mjs/src/Viewport.mjs +6 -2
  66. package/dist/mjs/src/components/AbstractComponent.d.ts +2 -2
  67. package/dist/mjs/src/components/AbstractComponent.mjs +3 -3
  68. package/dist/mjs/src/components/{ImageBackground.d.ts → BackgroundComponent.d.ts} +23 -3
  69. package/dist/mjs/src/components/BackgroundComponent.mjs +279 -0
  70. package/dist/mjs/src/components/RestylableComponent.d.ts +21 -2
  71. package/dist/mjs/src/components/Stroke.d.ts +35 -0
  72. package/dist/mjs/src/components/Stroke.mjs +37 -3
  73. package/dist/mjs/src/components/TextComponent.d.ts +27 -17
  74. package/dist/mjs/src/components/TextComponent.mjs +23 -1
  75. package/dist/mjs/src/components/lib.d.ts +4 -3
  76. package/dist/mjs/src/components/lib.mjs +2 -2
  77. package/dist/mjs/src/components/util/StrokeSmoother.mjs +25 -15
  78. package/dist/mjs/src/lib.d.ts +30 -0
  79. package/dist/mjs/src/lib.mjs +30 -0
  80. package/dist/mjs/src/localizations/de.mjs +1 -1
  81. package/dist/mjs/src/localizations/es.mjs +1 -1
  82. package/dist/mjs/src/math/Path.mjs +1 -1
  83. package/dist/mjs/src/math/polynomial/QuadraticBezier.d.ts +28 -0
  84. package/dist/mjs/src/math/polynomial/QuadraticBezier.mjs +109 -0
  85. package/dist/mjs/src/math/polynomial/solveQuadratic.d.ts +6 -0
  86. package/dist/mjs/src/math/polynomial/solveQuadratic.mjs +34 -0
  87. package/dist/mjs/src/rendering/RenderingStyle.d.ts +4 -4
  88. package/dist/mjs/src/rendering/TextRenderingStyle.d.ts +10 -10
  89. package/dist/mjs/src/rendering/lib.d.ts +2 -0
  90. package/dist/mjs/src/rendering/renderers/AbstractRenderer.d.ts +2 -2
  91. package/dist/mjs/src/rendering/renderers/CanvasRenderer.d.ts +2 -2
  92. package/dist/mjs/src/rendering/renderers/CanvasRenderer.mjs +5 -3
  93. package/dist/mjs/src/rendering/renderers/DummyRenderer.d.ts +2 -2
  94. package/dist/mjs/src/rendering/renderers/SVGRenderer.d.ts +2 -2
  95. package/dist/mjs/src/rendering/renderers/SVGRenderer.mjs +15 -6
  96. package/dist/mjs/src/rendering/renderers/TextOnlyRenderer.d.ts +2 -2
  97. package/dist/mjs/src/toolbar/IconProvider.d.ts +2 -2
  98. package/dist/mjs/src/toolbar/localization.d.ts +2 -1
  99. package/dist/mjs/src/toolbar/localization.mjs +3 -2
  100. package/dist/mjs/src/toolbar/widgets/BaseWidget.mjs +1 -1
  101. package/dist/mjs/src/toolbar/widgets/DocumentPropertiesWidget.d.ts +5 -0
  102. package/dist/mjs/src/toolbar/widgets/DocumentPropertiesWidget.mjs +54 -2
  103. package/dist/mjs/src/toolbar/widgets/PenToolWidget.mjs +1 -1
  104. package/dist/mjs/src/tools/FindTool.mjs +1 -1
  105. package/dist/mjs/src/tools/SoundUITool.d.ts +24 -0
  106. package/dist/mjs/src/tools/SoundUITool.mjs +158 -0
  107. package/dist/mjs/src/tools/TextTool.d.ts +2 -2
  108. package/dist/mjs/src/tools/ToolController.mjs +6 -1
  109. package/dist/mjs/src/tools/lib.d.ts +1 -0
  110. package/dist/mjs/src/tools/lib.mjs +1 -0
  111. package/dist/mjs/src/tools/localization.d.ts +3 -0
  112. package/dist/mjs/src/tools/localization.mjs +3 -0
  113. package/jest.config.js +1 -1
  114. package/package.json +19 -17
  115. package/src/Editor.css +2 -2
  116. package/src/tools/SoundUITool.css +15 -0
  117. package/src/tools/tools.css +4 -0
  118. package/dist/cjs/src/components/ImageBackground.js +0 -146
  119. package/dist/mjs/src/components/ImageBackground.mjs +0 -139
  120. package/src/Color4.test.ts +0 -40
  121. package/src/Color4.ts +0 -236
  122. package/src/Editor.loadFrom.test.ts +0 -24
  123. package/src/Editor.toSVG.test.ts +0 -111
  124. package/src/Editor.ts +0 -1122
  125. package/src/EditorImage.test.ts +0 -120
  126. package/src/EditorImage.ts +0 -603
  127. package/src/EventDispatcher.test.ts +0 -123
  128. package/src/EventDispatcher.ts +0 -71
  129. package/src/Pointer.ts +0 -127
  130. package/src/SVGLoader.test.ts +0 -114
  131. package/src/SVGLoader.ts +0 -511
  132. package/src/UndoRedoHistory.test.ts +0 -33
  133. package/src/UndoRedoHistory.ts +0 -102
  134. package/src/Viewport.ts +0 -319
  135. package/src/bundle/bundled.ts +0 -7
  136. package/src/commands/Command.ts +0 -45
  137. package/src/commands/Duplicate.ts +0 -48
  138. package/src/commands/Erase.ts +0 -74
  139. package/src/commands/SerializableCommand.ts +0 -49
  140. package/src/commands/UnresolvedCommand.ts +0 -37
  141. package/src/commands/invertCommand.ts +0 -51
  142. package/src/commands/lib.ts +0 -16
  143. package/src/commands/localization.ts +0 -47
  144. package/src/commands/uniteCommands.test.ts +0 -23
  145. package/src/commands/uniteCommands.ts +0 -135
  146. package/src/components/AbstractComponent.transformBy.test.ts +0 -22
  147. package/src/components/AbstractComponent.ts +0 -364
  148. package/src/components/ImageBackground.test.ts +0 -35
  149. package/src/components/ImageBackground.ts +0 -176
  150. package/src/components/ImageComponent.ts +0 -171
  151. package/src/components/RestylableComponent.ts +0 -142
  152. package/src/components/SVGGlobalAttributesObject.ts +0 -81
  153. package/src/components/Stroke.test.ts +0 -139
  154. package/src/components/Stroke.ts +0 -245
  155. package/src/components/TextComponent.test.ts +0 -99
  156. package/src/components/TextComponent.ts +0 -315
  157. package/src/components/UnknownSVGObject.test.ts +0 -10
  158. package/src/components/UnknownSVGObject.ts +0 -60
  159. package/src/components/builders/ArrowBuilder.ts +0 -107
  160. package/src/components/builders/FreehandLineBuilder.ts +0 -212
  161. package/src/components/builders/LineBuilder.ts +0 -77
  162. package/src/components/builders/PressureSensitiveFreehandLineBuilder.ts +0 -454
  163. package/src/components/builders/RectangleBuilder.ts +0 -74
  164. package/src/components/builders/types.ts +0 -15
  165. package/src/components/lib.ts +0 -25
  166. package/src/components/localization.ts +0 -22
  167. package/src/components/util/StrokeSmoother.ts +0 -293
  168. package/src/components/util/describeComponentList.ts +0 -18
  169. package/src/lib.ts +0 -37
  170. package/src/localization.ts +0 -34
  171. package/src/localizations/de.ts +0 -98
  172. package/src/localizations/en.ts +0 -8
  173. package/src/localizations/es.ts +0 -74
  174. package/src/localizations/getLocalizationTable.test.ts +0 -27
  175. package/src/localizations/getLocalizationTable.ts +0 -55
  176. package/src/math/LineSegment2.test.ts +0 -99
  177. package/src/math/LineSegment2.ts +0 -160
  178. package/src/math/Mat33.test.ts +0 -244
  179. package/src/math/Mat33.ts +0 -437
  180. package/src/math/Path.fromString.test.ts +0 -223
  181. package/src/math/Path.test.ts +0 -198
  182. package/src/math/Path.toString.test.ts +0 -77
  183. package/src/math/Path.ts +0 -790
  184. package/src/math/Rect2.test.ts +0 -204
  185. package/src/math/Rect2.ts +0 -315
  186. package/src/math/Triangle.ts +0 -29
  187. package/src/math/Vec2.test.ts +0 -30
  188. package/src/math/Vec2.ts +0 -18
  189. package/src/math/Vec3.test.ts +0 -44
  190. package/src/math/Vec3.ts +0 -218
  191. package/src/math/lib.ts +0 -15
  192. package/src/math/rounding.test.ts +0 -65
  193. package/src/math/rounding.ts +0 -156
  194. package/src/rendering/Display.ts +0 -249
  195. package/src/rendering/RenderingStyle.test.ts +0 -68
  196. package/src/rendering/RenderingStyle.ts +0 -55
  197. package/src/rendering/TextRenderingStyle.ts +0 -45
  198. package/src/rendering/caching/CacheRecord.test.ts +0 -49
  199. package/src/rendering/caching/CacheRecord.ts +0 -77
  200. package/src/rendering/caching/CacheRecordManager.ts +0 -71
  201. package/src/rendering/caching/RenderingCache.test.ts +0 -44
  202. package/src/rendering/caching/RenderingCache.ts +0 -66
  203. package/src/rendering/caching/RenderingCacheNode.ts +0 -405
  204. package/src/rendering/caching/testUtils.ts +0 -35
  205. package/src/rendering/caching/types.ts +0 -34
  206. package/src/rendering/lib.ts +0 -6
  207. package/src/rendering/localization.ts +0 -20
  208. package/src/rendering/renderers/AbstractRenderer.ts +0 -222
  209. package/src/rendering/renderers/CanvasRenderer.ts +0 -296
  210. package/src/rendering/renderers/DummyRenderer.test.ts +0 -42
  211. package/src/rendering/renderers/DummyRenderer.ts +0 -136
  212. package/src/rendering/renderers/SVGRenderer.ts +0 -354
  213. package/src/rendering/renderers/TextOnlyRenderer.ts +0 -70
  214. package/src/testing/beforeEachFile.ts +0 -8
  215. package/src/testing/createEditor.ts +0 -11
  216. package/src/testing/global.d.ts +0 -17
  217. package/src/testing/lib.ts +0 -3
  218. package/src/testing/loadExpectExtensions.ts +0 -25
  219. package/src/testing/sendPenEvent.ts +0 -31
  220. package/src/testing/sendTouchEvent.ts +0 -78
  221. package/src/toolbar/HTMLToolbar.ts +0 -492
  222. package/src/toolbar/IconProvider.ts +0 -736
  223. package/src/toolbar/lib.ts +0 -4
  224. package/src/toolbar/localization.ts +0 -106
  225. package/src/toolbar/makeColorInput.ts +0 -145
  226. package/src/toolbar/types.ts +0 -5
  227. package/src/toolbar/widgets/ActionButtonWidget.ts +0 -39
  228. package/src/toolbar/widgets/BaseToolWidget.ts +0 -56
  229. package/src/toolbar/widgets/BaseWidget.ts +0 -377
  230. package/src/toolbar/widgets/DocumentPropertiesWidget.ts +0 -167
  231. package/src/toolbar/widgets/EraserToolWidget.ts +0 -85
  232. package/src/toolbar/widgets/HandToolWidget.ts +0 -250
  233. package/src/toolbar/widgets/InsertImageWidget.ts +0 -223
  234. package/src/toolbar/widgets/OverflowWidget.ts +0 -92
  235. package/src/toolbar/widgets/PenToolWidget.ts +0 -288
  236. package/src/toolbar/widgets/SelectionToolWidget.ts +0 -190
  237. package/src/toolbar/widgets/TextToolWidget.ts +0 -145
  238. package/src/toolbar/widgets/lib.ts +0 -13
  239. package/src/tools/BaseTool.ts +0 -76
  240. package/src/tools/Eraser.test.ts +0 -103
  241. package/src/tools/Eraser.ts +0 -139
  242. package/src/tools/FindTool.ts +0 -152
  243. package/src/tools/PanZoom.test.ts +0 -310
  244. package/src/tools/PanZoom.ts +0 -520
  245. package/src/tools/PasteHandler.ts +0 -95
  246. package/src/tools/Pen.test.ts +0 -194
  247. package/src/tools/Pen.ts +0 -226
  248. package/src/tools/PipetteTool.ts +0 -55
  249. package/src/tools/SelectionTool/SelectAllShortcutHandler.ts +0 -28
  250. package/src/tools/SelectionTool/Selection.ts +0 -607
  251. package/src/tools/SelectionTool/SelectionHandle.ts +0 -108
  252. package/src/tools/SelectionTool/SelectionTool.test.ts +0 -261
  253. package/src/tools/SelectionTool/SelectionTool.ts +0 -480
  254. package/src/tools/SelectionTool/TransformMode.ts +0 -114
  255. package/src/tools/SelectionTool/types.ts +0 -11
  256. package/src/tools/TextTool.ts +0 -326
  257. package/src/tools/ToolController.ts +0 -178
  258. package/src/tools/ToolEnabledGroup.ts +0 -14
  259. package/src/tools/ToolSwitcherShortcut.ts +0 -39
  260. package/src/tools/ToolbarShortcutHandler.ts +0 -34
  261. package/src/tools/UndoRedoShortcut.test.ts +0 -56
  262. package/src/tools/UndoRedoShortcut.ts +0 -25
  263. package/src/tools/lib.ts +0 -21
  264. package/src/tools/localization.ts +0 -66
  265. package/src/types.ts +0 -234
  266. package/src/util/assertions.ts +0 -55
  267. package/src/util/fileToBase64.ts +0 -18
  268. package/src/util/untilNextAnimationFrame.ts +0 -9
  269. package/src/util/waitForTimeout.ts +0 -9
@@ -1,76 +0,0 @@
1
- import { PointerEvtListener, WheelEvt, PointerEvt, EditorNotifier, EditorEventType, KeyPressEvent, KeyUpEvent, PasteEvent, CopyEvent } from '../types';
2
- import ToolEnabledGroup from './ToolEnabledGroup';
3
-
4
- export default abstract class BaseTool implements PointerEvtListener {
5
- private enabled: boolean = true;
6
- private group: ToolEnabledGroup|null = null;
7
-
8
- public onPointerDown(_event: PointerEvt): boolean { return false; }
9
- public onPointerMove(_event: PointerEvt) { }
10
- public onPointerUp(_event: PointerEvt) { }
11
- public onGestureCancel() { }
12
-
13
- protected constructor(private notifier: EditorNotifier, public readonly description: string) {
14
- }
15
-
16
- public onWheel(_event: WheelEvt): boolean {
17
- return false;
18
- }
19
-
20
- public onCopy(_event: CopyEvent): boolean {
21
- return false;
22
- }
23
-
24
- public onPaste(_event: PasteEvent): boolean {
25
- return false;
26
- }
27
-
28
- public onKeyPress(_event: KeyPressEvent): boolean {
29
- return false;
30
- }
31
-
32
- public onKeyUp(_event: KeyUpEvent): boolean {
33
- return false;
34
- }
35
-
36
- public setEnabled(enabled: boolean) {
37
- this.enabled = enabled;
38
-
39
- // Ensure that at most one tool in the group is enabled.
40
- if (enabled) {
41
- this.group?.notifyEnabled(this);
42
- this.notifier.dispatch(EditorEventType.ToolEnabled, {
43
- kind: EditorEventType.ToolEnabled,
44
- tool: this,
45
- });
46
- } else {
47
- this.notifier.dispatch(EditorEventType.ToolDisabled, {
48
- kind: EditorEventType.ToolDisabled,
49
- tool: this,
50
- });
51
- }
52
- }
53
-
54
- public isEnabled(): boolean {
55
- return this.enabled;
56
- }
57
-
58
- // Connect this tool to a set of other tools, ensuring that at most one
59
- // of the tools in the group is enabled.
60
- public setToolGroup(group: ToolEnabledGroup) {
61
- if (this.isEnabled()) {
62
- group.notifyEnabled(this);
63
- }
64
-
65
- this.group = group;
66
- }
67
-
68
- public getToolGroup(): ToolEnabledGroup|null {
69
- if (this.group) {
70
- return this.group;
71
- }
72
-
73
- return null;
74
- }
75
- }
76
-
@@ -1,103 +0,0 @@
1
- import UnknownSVGObject from '../components/UnknownSVGObject';
2
- import Editor from '../Editor';
3
- import { EditorImage, Rect2, StrokeComponent } from '../lib';
4
- import { Vec2 } from '../math/Vec2';
5
- import createEditor from '../testing/createEditor';
6
- import sendPenEvent from '../testing/sendPenEvent';
7
- import { InputEvtType } from '../types';
8
- import Eraser from './Eraser';
9
-
10
- const selectEraser = (editor: Editor) => {
11
- const tools = editor.toolController;
12
- const eraser = tools.getMatchingTools(Eraser)[0];
13
- eraser.setEnabled(true);
14
-
15
- return eraser;
16
- };
17
-
18
- const getAllStrokes = (editor: Editor) => {
19
- return editor.image.getAllElements().filter(elem => elem instanceof StrokeComponent);
20
- };
21
-
22
- describe('Eraser', () => {
23
- it('should erase object between locations of events', () => {
24
- const editor = createEditor();
25
-
26
- // Draw a line
27
- sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(0, 0));
28
- jest.advanceTimersByTime(100);
29
- sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(200, 200));
30
-
31
- // Should have drawn a line
32
- const strokes = getAllStrokes(editor);
33
- expect(strokes).toHaveLength(1);
34
- expect(strokes[0].getBBox().area).toBeGreaterThanOrEqual(200 * 200);
35
-
36
- selectEraser(editor);
37
-
38
- // Erase the line.
39
- sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(200, 0));
40
- jest.advanceTimersByTime(400);
41
- sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(0, 200));
42
-
43
- // Should have erased the line
44
- expect(getAllStrokes(editor)).toHaveLength(0);
45
- });
46
-
47
- it('should erase objects within eraser.thickness of an event when not zoomed', async () => {
48
- const editor = createEditor();
49
-
50
- await editor.loadFromSVG(`
51
- <svg>
52
- <path d='m0,0 l2,0 l0,2 l-2,0 z' fill="#ff0000"/>
53
- <path d='m50,50 l2,0 l0,2 l-2,0 z' fill="#ff0000"/>
54
- </svg>
55
- `, true);
56
-
57
- editor.viewport.resetTransform();
58
-
59
- const allStrokes = getAllStrokes(editor);
60
- expect(allStrokes).toHaveLength(2);
61
- expect(allStrokes[0].getBBox()).objEq(new Rect2(0, 0, 2, 2));
62
- expect(allStrokes[1].getBBox()).objEq(new Rect2(50, 50, 2, 2));
63
-
64
- const eraser = selectEraser(editor);
65
- eraser.setThickness(10);
66
-
67
- // Erase the first stroke
68
- sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(3, 0));
69
- jest.advanceTimersByTime(100);
70
- sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(3, 0));
71
-
72
- expect(getAllStrokes(editor)).toHaveLength(1);
73
-
74
- // Erase the remaining stroke
75
- sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(47, 47));
76
- jest.advanceTimersByTime(100);
77
- sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(47, 47));
78
-
79
- expect(getAllStrokes(editor)).toHaveLength(0);
80
- });
81
-
82
- it('should not erase unselectable objects', () => {
83
- const editor = createEditor();
84
- const unerasableObj = new UnknownSVGObject(document.createElementNS('http://www.w3.org/2000/svg', 'arc'));
85
-
86
- // Add to the image
87
- expect(editor.image.getAllElements()).toHaveLength(0);
88
- editor.dispatch(EditorImage.addElement(unerasableObj));
89
- expect(editor.image.getAllElements()).toHaveLength(1);
90
-
91
-
92
- const eraser = selectEraser(editor);
93
- eraser.setThickness(100);
94
-
95
- // Try to erase it.
96
- sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(0, 0));
97
- jest.advanceTimersByTime(100);
98
- sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(3, 0));
99
-
100
- // Should not have been erased
101
- expect(editor.image.getAllElements()).toHaveLength(1);
102
- });
103
- });
@@ -1,139 +0,0 @@
1
- import { EditorEventType, PointerEvt } from '../types';
2
- import BaseTool from './BaseTool';
3
- import Editor from '../Editor';
4
- import { Point2, Vec2 } from '../math/Vec2';
5
- import LineSegment2 from '../math/LineSegment2';
6
- import Erase from '../commands/Erase';
7
- import AbstractComponent from '../components/AbstractComponent';
8
- import { PointerDevice } from '../Pointer';
9
- import Color4 from '../Color4';
10
- import Rect2 from '../math/Rect2';
11
- import RenderingStyle from '../rendering/RenderingStyle';
12
-
13
- export default class Eraser extends BaseTool {
14
- private lastPoint: Point2|null = null;
15
- private isFirstEraseEvt: boolean = true;
16
- private toRemove: AbstractComponent[];
17
- private thickness: number = 10;
18
-
19
- // Commands that each remove one element
20
- private partialCommands: Erase[] = [];
21
-
22
- public constructor(private editor: Editor, description: string) {
23
- super(editor.notifier, description);
24
- }
25
-
26
- private clearPreview() {
27
- this.editor.clearWetInk();
28
- }
29
-
30
- private getSizeOnCanvas() {
31
- return this.thickness / this.editor.viewport.getScaleFactor();
32
- }
33
-
34
- private drawPreviewAt(point: Point2) {
35
- this.clearPreview();
36
-
37
- const size = this.getSizeOnCanvas();
38
-
39
- const renderer = this.editor.display.getWetInkRenderer();
40
- const rect = this.getEraserRect(point);
41
- const fill: RenderingStyle = {
42
- fill: Color4.gray,
43
- };
44
- renderer.drawRect(rect, size / 4, fill);
45
- }
46
-
47
- private getEraserRect(centerPoint: Point2) {
48
- const size = this.getSizeOnCanvas();
49
- const halfSize = Vec2.of(size / 2, size / 2);
50
- return Rect2.fromCorners(centerPoint.minus(halfSize), centerPoint.plus(halfSize));
51
- }
52
-
53
- private eraseTo(currentPoint: Point2) {
54
- if (!this.isFirstEraseEvt && currentPoint.minus(this.lastPoint!).magnitude() === 0) {
55
- return;
56
- }
57
- this.isFirstEraseEvt = false;
58
-
59
- // Currently only objects within eraserRect or that intersect a straight line
60
- // from the center of the current rect to the previous are erased. TODO: Erase
61
- // all objects as if there were pointerMove events between the two points.
62
- const eraserRect = this.getEraserRect(currentPoint);
63
- const line = new LineSegment2(this.lastPoint!, currentPoint);
64
- const region = Rect2.union(line.bbox, eraserRect);
65
-
66
- const intersectingElems = this.editor.image.getElementsIntersectingRegion(region).filter(component => {
67
- return component.intersects(line) || component.intersectsRect(eraserRect);
68
- });
69
-
70
- // Only erase components that could be selected (and thus interacted with)
71
- // by the user.
72
- const toErase = intersectingElems.filter(elem => elem.isSelectable());
73
-
74
- // Remove any intersecting elements.
75
- this.toRemove.push(...toErase);
76
-
77
- // Create new Erase commands for the now-to-be-erased elements and apply them.
78
- const newPartialCommands = toErase.map(elem => new Erase([ elem ]));
79
- newPartialCommands.forEach(cmd => cmd.apply(this.editor));
80
-
81
- this.partialCommands.push(...newPartialCommands);
82
-
83
- this.drawPreviewAt(currentPoint);
84
- this.lastPoint = currentPoint;
85
- }
86
-
87
- public onPointerDown(event: PointerEvt): boolean {
88
- if (event.allPointers.length === 1 || event.current.device === PointerDevice.Eraser) {
89
- this.lastPoint = event.current.canvasPos;
90
- this.toRemove = [];
91
- this.isFirstEraseEvt = true;
92
-
93
- this.drawPreviewAt(event.current.canvasPos);
94
- return true;
95
- }
96
-
97
- return false;
98
- }
99
-
100
- public onPointerMove(event: PointerEvt): void {
101
- const currentPoint = event.current.canvasPos;
102
-
103
- this.eraseTo(currentPoint);
104
- }
105
-
106
- public onPointerUp(event: PointerEvt): void {
107
- this.eraseTo(event.current.canvasPos);
108
-
109
- if (this.toRemove.length > 0) {
110
- // Undo commands for each individual component and unite into a single command.
111
- this.partialCommands.forEach(cmd => cmd.unapply(this.editor));
112
- this.partialCommands = [];
113
-
114
- const command = new Erase(this.toRemove);
115
- this.editor.dispatch(command); // dispatch: Makes undo-able.
116
- }
117
-
118
- this.clearPreview();
119
- }
120
-
121
- public onGestureCancel(): void {
122
- this.partialCommands.forEach(cmd => cmd.unapply(this.editor));
123
- this.partialCommands = [];
124
- this.clearPreview();
125
- }
126
-
127
- public getThickness() {
128
- return this.thickness;
129
- }
130
-
131
- public setThickness(thickness: number) {
132
- this.thickness = thickness;
133
-
134
- this.editor.notifier.dispatch(EditorEventType.ToolUpdated, {
135
- kind: EditorEventType.ToolUpdated,
136
- tool: this,
137
- });
138
- }
139
- }
@@ -1,152 +0,0 @@
1
- // Displays a find dialog that allows the user to search for and focus text.
2
- //
3
- // @packageDocumentation
4
-
5
- import Editor from '../Editor';
6
- import TextComponent from '../components/TextComponent';
7
- import Rect2 from '../math/Rect2';
8
- import { KeyPressEvent } from '../types';
9
- import BaseTool from './BaseTool';
10
-
11
- export const cssPrefix = 'find-tool';
12
-
13
- export default class FindTool extends BaseTool {
14
- private overlay: HTMLElement;
15
- private searchInput: HTMLInputElement;
16
- private currentMatchIdx: number = 0;
17
-
18
- public constructor(private editor: Editor) {
19
- super(editor.notifier, editor.localization.findLabel);
20
-
21
- this.overlay = document.createElement('div');
22
- this.fillOverlay();
23
- editor.createHTMLOverlay(this.overlay);
24
-
25
- this.overlay.style.display = 'none';
26
- this.overlay.classList.add(`${cssPrefix}-overlay`);
27
- }
28
-
29
- private getMatches(searchFor: string): Rect2[] {
30
- searchFor = searchFor.toLocaleLowerCase();
31
- const allTextComponents = this.editor.image.getAllElements()
32
- .filter(
33
- elem => elem instanceof TextComponent
34
- ) as TextComponent[];
35
-
36
- const matches = allTextComponents.filter(
37
- text => text.getText().toLocaleLowerCase().indexOf(searchFor) !== -1
38
- );
39
-
40
- return matches.map(match => match.getBBox());
41
- }
42
-
43
- private focusCurrentMatch() {
44
- const matches = this.getMatches(this.searchInput.value);
45
- let matchIdx = this.currentMatchIdx % matches.length;
46
-
47
- if (matchIdx < 0) {
48
- matchIdx = matches.length + matchIdx;
49
- }
50
-
51
- if (matchIdx < matches.length) {
52
- const undoable = false;
53
- this.editor.dispatch(this.editor.viewport.zoomTo(matches[matchIdx], true, true), undoable);
54
- this.editor.announceForAccessibility(
55
- this.editor.localization.focusedFoundText(matchIdx + 1, matches.length)
56
- );
57
- }
58
- }
59
-
60
- private toNextMatch() {
61
- this.currentMatchIdx ++;
62
- this.focusCurrentMatch();
63
- }
64
-
65
- private toPrevMatch() {
66
- this.currentMatchIdx --;
67
- this.focusCurrentMatch();
68
- }
69
-
70
- private fillOverlay() {
71
- const label = document.createElement('label');
72
- this.searchInput = document.createElement('input');
73
- const nextBtn = document.createElement('button');
74
- const closeBtn = document.createElement('button');
75
-
76
- // Math.random() ensures that the ID is unique (to allow us to refer to it
77
- // with an htmlFor).
78
- this.searchInput.setAttribute('id', `${cssPrefix}-searchInput-${Math.random()}`);
79
- label.htmlFor = this.searchInput.getAttribute('id')!;
80
-
81
- label.innerText = this.editor.localization.findLabel;
82
- nextBtn.innerText = this.editor.localization.toNextMatch;
83
- closeBtn.innerText = this.editor.localization.closeFindDialog;
84
-
85
- this.searchInput.onkeydown = (ev: KeyboardEvent) => {
86
- if (ev.key === 'Enter') {
87
- if (ev.shiftKey) {
88
- this.toPrevMatch();
89
- } else {
90
- this.toNextMatch();
91
- }
92
- }
93
- else if (ev.key === 'Escape') {
94
- this.setVisible(false);
95
- }
96
- else if (ev.key === 'f' && ev.ctrlKey) {
97
- ev.preventDefault();
98
- this.toggleVisible();
99
- }
100
- };
101
-
102
- nextBtn.onclick = () => {
103
- this.toNextMatch();
104
- };
105
-
106
- closeBtn.onclick = () => {
107
- this.setVisible(false);
108
- };
109
-
110
- this.overlay.replaceChildren(label, this.searchInput, nextBtn, closeBtn);
111
- }
112
-
113
- private isVisible() {
114
- return this.overlay.style.display !== 'none';
115
- }
116
-
117
- private setVisible(visible: boolean) {
118
- if (visible !== this.isVisible()) {
119
- this.overlay.style.display = visible ? 'block' : 'none';
120
-
121
- if (visible) {
122
- this.searchInput.focus();
123
- this.editor.announceForAccessibility(this.editor.localization.findDialogShown);
124
- } else {
125
- this.editor.focus();
126
- this.editor.announceForAccessibility(this.editor.localization.findDialogHidden);
127
- }
128
- }
129
- }
130
-
131
- private toggleVisible() {
132
- this.setVisible(!this.isVisible());
133
- }
134
-
135
- public onKeyPress(event: KeyPressEvent): boolean {
136
- if (event.ctrlKey && event.key === 'f') {
137
- this.toggleVisible();
138
-
139
- return true;
140
- }
141
-
142
- return false;
143
- }
144
-
145
- public setEnabled(enabled: boolean) {
146
- super.setEnabled(enabled);
147
-
148
- if (enabled) {
149
- this.setVisible(false);
150
- }
151
- }
152
- }