js-draw 0.17.3 → 0.17.4

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 (47) hide show
  1. package/CHANGELOG.md +6 -1
  2. package/README.md +17 -8
  3. package/dist/bundle.js +1 -1
  4. package/dist/src/Editor.d.ts +57 -1
  5. package/dist/src/Editor.js +61 -24
  6. package/dist/src/EditorImage.d.ts +4 -2
  7. package/dist/src/EditorImage.js +4 -2
  8. package/dist/src/SVGLoader.d.ts +4 -0
  9. package/dist/src/SVGLoader.js +4 -0
  10. package/dist/src/lib.d.ts +2 -1
  11. package/dist/src/lib.js +2 -1
  12. package/dist/src/rendering/lib.d.ts +2 -0
  13. package/dist/src/rendering/lib.js +2 -0
  14. package/dist/src/rendering/renderers/CanvasRenderer.d.ts +25 -0
  15. package/dist/src/rendering/renderers/CanvasRenderer.js +27 -0
  16. package/dist/src/rendering/renderers/SVGRenderer.d.ts +15 -0
  17. package/dist/src/rendering/renderers/SVGRenderer.js +27 -1
  18. package/dist/src/testing/lib.d.ts +2 -0
  19. package/dist/src/testing/lib.js +2 -0
  20. package/dist/src/testing/sendPenEvent.d.ts +12 -0
  21. package/dist/src/testing/sendPenEvent.js +19 -0
  22. package/dist/src/testing/sendTouchEvent.d.ts +36 -0
  23. package/dist/src/testing/sendTouchEvent.js +36 -0
  24. package/dist/src/toolbar/widgets/DocumentPropertiesWidget.js +4 -2
  25. package/dist/src/toolbar/widgets/PenToolWidget.js +1 -0
  26. package/dist/src/toolbar/widgets/TextToolWidget.js +4 -1
  27. package/dist/src/tools/SelectionTool/SelectionTool.js +5 -6
  28. package/package.json +1 -1
  29. package/src/Editor.ts +62 -28
  30. package/src/EditorImage.ts +4 -2
  31. package/src/SVGLoader.ts +4 -0
  32. package/src/lib.ts +2 -1
  33. package/src/rendering/lib.ts +2 -0
  34. package/src/rendering/renderers/CanvasRenderer.ts +27 -0
  35. package/src/rendering/renderers/SVGRenderer.ts +32 -1
  36. package/src/testing/lib.ts +3 -0
  37. package/src/testing/sendPenEvent.ts +31 -0
  38. package/src/testing/sendTouchEvent.ts +36 -1
  39. package/src/toolbar/toolbar.css +5 -0
  40. package/src/toolbar/widgets/DocumentPropertiesWidget.ts +4 -2
  41. package/src/toolbar/widgets/PenToolWidget.ts +1 -0
  42. package/src/toolbar/widgets/TextToolWidget.ts +4 -1
  43. package/src/tools/Eraser.test.ts +11 -10
  44. package/src/tools/PanZoom.test.ts +1 -1
  45. package/src/tools/Pen.test.ts +63 -62
  46. package/src/tools/SelectionTool/SelectionTool.test.ts +15 -14
  47. package/src/tools/SelectionTool/SelectionTool.ts +5 -7
@@ -3,6 +3,7 @@ import Editor from '../Editor';
3
3
  import { EditorImage, Rect2, StrokeComponent } from '../lib';
4
4
  import { Vec2 } from '../math/Vec2';
5
5
  import createEditor from '../testing/createEditor';
6
+ import sendPenEvent from '../testing/sendPenEvent';
6
7
  import { InputEvtType } from '../types';
7
8
  import Eraser from './Eraser';
8
9
 
@@ -23,9 +24,9 @@ describe('Eraser', () => {
23
24
  const editor = createEditor();
24
25
 
25
26
  // Draw a line
26
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(0, 0));
27
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(0, 0));
27
28
  jest.advanceTimersByTime(100);
28
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(200, 200));
29
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(200, 200));
29
30
 
30
31
  // Should have drawn a line
31
32
  const strokes = getAllStrokes(editor);
@@ -35,9 +36,9 @@ describe('Eraser', () => {
35
36
  selectEraser(editor);
36
37
 
37
38
  // Erase the line.
38
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(200, 0));
39
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(200, 0));
39
40
  jest.advanceTimersByTime(400);
40
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(0, 200));
41
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(0, 200));
41
42
 
42
43
  // Should have erased the line
43
44
  expect(getAllStrokes(editor)).toHaveLength(0);
@@ -64,16 +65,16 @@ describe('Eraser', () => {
64
65
  eraser.setThickness(10);
65
66
 
66
67
  // Erase the first stroke
67
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(3, 0));
68
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(3, 0));
68
69
  jest.advanceTimersByTime(100);
69
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(3, 0));
70
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(3, 0));
70
71
 
71
72
  expect(getAllStrokes(editor)).toHaveLength(1);
72
73
 
73
74
  // Erase the remaining stroke
74
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(47, 47));
75
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(47, 47));
75
76
  jest.advanceTimersByTime(100);
76
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(47, 47));
77
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(47, 47));
77
78
 
78
79
  expect(getAllStrokes(editor)).toHaveLength(0);
79
80
  });
@@ -92,9 +93,9 @@ describe('Eraser', () => {
92
93
  eraser.setThickness(100);
93
94
 
94
95
  // Try to erase it.
95
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(0, 0));
96
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(0, 0));
96
97
  jest.advanceTimersByTime(100);
97
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(3, 0));
98
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(3, 0));
98
99
 
99
100
  // Should not have been erased
100
101
  expect(editor.image.getAllElements()).toHaveLength(1);
@@ -68,7 +68,7 @@ describe('PanZoom', () => {
68
68
  firstPointer = sendTouchEvent(editor, eventType, point1, [ secondPointer ]);
69
69
  secondPointer = sendTouchEvent(editor, eventType, point2, [ firstPointer ]);
70
70
  expectedScale = point1.minus(point2).magnitude() / 100;
71
- Vec2.zero;
71
+
72
72
  if (i === maxIterations - 1) {
73
73
  jest.advanceTimersByTime(10);
74
74
 
@@ -7,16 +7,17 @@ import Rect2 from '../math/Rect2';
7
7
  import StrokeComponent from '../components/Stroke';
8
8
  import Mat33 from '../math/Mat33';
9
9
  import { makeFreehandLineBuilder } from '../components/builders/FreehandLineBuilder';
10
+ import sendPenEvent from '../testing/sendPenEvent';
10
11
 
11
12
  describe('Pen', () => {
12
13
  it('should draw horizontal lines', () => {
13
14
  const editor = createEditor();
14
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(0, 0));
15
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(0, 0));
15
16
  for (let i = 0; i < 10; i++) {
16
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(i, 0));
17
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(i, 0));
17
18
  jest.advanceTimersByTime(200);
18
19
  }
19
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(200, 0));
20
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(200, 0));
20
21
 
21
22
  const elems = editor.image.getElementsIntersectingRegion(new Rect2(0, 10, 10, -10));
22
23
  expect(elems).toHaveLength(1);
@@ -29,12 +30,12 @@ describe('Pen', () => {
29
30
 
30
31
  it('should draw vertical line', () => {
31
32
  const editor = createEditor();
32
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(0, 0));
33
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(0, 0));
33
34
  for (let i = 0; i < 10; i++) {
34
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(0, i * 20));
35
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(0, i * 20));
35
36
  jest.advanceTimersByTime(200);
36
37
  }
37
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(0, 150));
38
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(0, 150));
38
39
 
39
40
  const elems = editor.image.getElementsIntersectingRegion(Rect2.unitSquare);
40
41
  expect(elems).toHaveLength(1);
@@ -46,104 +47,104 @@ describe('Pen', () => {
46
47
  it('should draw vertical line with slight bend', () => {
47
48
  const editor = createEditor();
48
49
 
49
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(417, 24));
50
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(417, 24));
50
51
  jest.advanceTimersByTime(245);
51
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 197));
52
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 197));
52
53
  jest.advanceTimersByTime(20);
53
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 199));
54
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 199));
54
55
  jest.advanceTimersByTime(12);
55
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 201));
56
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 201));
56
57
  jest.advanceTimersByTime(40);
57
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 203));
58
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 203));
58
59
  jest.advanceTimersByTime(14);
59
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 206));
60
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 206));
60
61
  jest.advanceTimersByTime(35);
61
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 208));
62
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 208));
62
63
  jest.advanceTimersByTime(16);
63
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 211));
64
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 211));
64
65
  jest.advanceTimersByTime(51);
65
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 215));
66
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 215));
66
67
  jest.advanceTimersByTime(32);
67
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 218));
68
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 218));
68
69
  jest.advanceTimersByTime(30);
69
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 220));
70
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 220));
70
71
  jest.advanceTimersByTime(24);
71
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 222));
72
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 222));
72
73
  jest.advanceTimersByTime(14);
73
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 224));
74
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 224));
74
75
  jest.advanceTimersByTime(32);
75
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 227));
76
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 227));
76
77
  jest.advanceTimersByTime(17);
77
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 229));
78
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 229));
78
79
  jest.advanceTimersByTime(53);
79
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 234));
80
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 234));
80
81
  jest.advanceTimersByTime(34);
81
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 236));
82
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 236));
82
83
  jest.advanceTimersByTime(17);
83
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 238));
84
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 238));
84
85
  jest.advanceTimersByTime(39);
85
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 240));
86
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 240));
86
87
  jest.advanceTimersByTime(10);
87
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 243));
88
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 243));
88
89
  jest.advanceTimersByTime(34);
89
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 250));
90
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 250));
90
91
  jest.advanceTimersByTime(57);
91
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(423, 252));
92
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(423, 252));
92
93
  jest.advanceTimersByTime(8);
93
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(422, 256));
94
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(422, 256));
94
95
  jest.advanceTimersByTime(28);
95
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(422, 258));
96
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(422, 258));
96
97
  jest.advanceTimersByTime(21);
97
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(421, 262));
98
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(421, 262));
98
99
  jest.advanceTimersByTime(34);
99
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(420, 264));
100
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(420, 264));
100
101
  jest.advanceTimersByTime(5);
101
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(420, 266));
102
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(420, 266));
102
103
  jest.advanceTimersByTime(22);
103
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(420, 268));
104
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(420, 268));
104
105
  jest.advanceTimersByTime(22);
105
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(420, 271));
106
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(420, 271));
106
107
  jest.advanceTimersByTime(18);
107
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(420, 274));
108
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(420, 274));
108
109
  jest.advanceTimersByTime(33);
109
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(420, 277));
110
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(420, 277));
110
111
  jest.advanceTimersByTime(16);
111
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 279));
112
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 279));
112
113
  jest.advanceTimersByTime(36);
113
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 282));
114
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 282));
114
115
  jest.advanceTimersByTime(15);
115
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 284));
116
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 284));
116
117
  jest.advanceTimersByTime(48);
117
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 289));
118
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 289));
118
119
  jest.advanceTimersByTime(16);
119
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 291));
120
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 291));
120
121
  jest.advanceTimersByTime(31);
121
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 295));
122
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 295));
122
123
  jest.advanceTimersByTime(23);
123
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 301));
124
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 301));
124
125
  jest.advanceTimersByTime(31);
125
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 306));
126
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 306));
126
127
  jest.advanceTimersByTime(18);
127
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 308));
128
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 308));
128
129
  jest.advanceTimersByTime(20);
129
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 310));
130
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 310));
130
131
  jest.advanceTimersByTime(13);
131
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 313));
132
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 313));
132
133
  jest.advanceTimersByTime(17);
133
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 317));
134
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 317));
134
135
  jest.advanceTimersByTime(33);
135
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 321));
136
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 321));
136
137
  jest.advanceTimersByTime(15);
137
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 324));
138
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 324));
138
139
  jest.advanceTimersByTime(23);
139
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 326));
140
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 326));
140
141
  jest.advanceTimersByTime(14);
141
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(419, 329));
142
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(419, 329));
142
143
  jest.advanceTimersByTime(36);
143
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(420, 333));
144
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(420, 333));
144
145
  jest.advanceTimersByTime(8);
145
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(420, 340));
146
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(420, 340));
146
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(420, 340));
147
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(420, 340));
147
148
 
148
149
  const elems = editor.image.getElementsIntersectingRegion(new Rect2(0, 0, 1000, 1000));
149
150
  expect(elems).toHaveLength(1);
@@ -157,9 +158,9 @@ describe('Pen', () => {
157
158
 
158
159
  expect(editor.history.undoStackSize).toBe(0);
159
160
 
160
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(10, 10));
161
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(10, 10));
161
162
  jest.advanceTimersByTime(100);
162
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(20, 10));
163
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(20, 10));
163
164
 
164
165
  const ctrlKeyDown = true;
165
166
  editor.sendKeyboardEvent(InputEvtType.KeyPressEvent, 'z', ctrlKeyDown);
@@ -168,7 +169,7 @@ describe('Pen', () => {
168
169
  expect(editor.history.redoStackSize).toBe(1);
169
170
 
170
171
  // Lifting the pointer up shouldn't clear the redo stack.
171
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(420, 340));
172
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(420, 340));
172
173
  expect(editor.history.redoStackSize).toBe(1);
173
174
  });
174
175
 
@@ -179,10 +180,10 @@ describe('Pen', () => {
179
180
  const penTool = editor.toolController.getMatchingTools(PenTool)[0];
180
181
  penTool.setStrokeFactory(makeFreehandLineBuilder);
181
182
 
182
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(0.1, 0.1));
183
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(0.1, 0.1));
183
184
  jest.advanceTimersByTime(100);
184
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(10.1, 10.1));
185
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(10.1, 10.1));
185
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(10.1, 10.1));
186
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(10.1, 10.1));
186
187
 
187
188
  const allElems = editor.image.getAllElements();
188
189
  expect(allElems).toHaveLength(1);
@@ -10,6 +10,7 @@ import SelectionTool from './SelectionTool';
10
10
  import createEditor from '../../testing/createEditor';
11
11
  import Pointer from '../../Pointer';
12
12
  import { Rect2 } from '../../lib';
13
+ import sendPenEvent from '../../testing/sendPenEvent';
13
14
 
14
15
  const getSelectionTool = (editor: Editor): SelectionTool => {
15
16
  return editor.toolController.getMatchingTools(SelectionTool)[0];
@@ -33,9 +34,9 @@ const createEditorWithSingleObjectSelection = (objectSize: number = 50) => {
33
34
  // Select the object
34
35
  const selectionTool = getSelectionTool(editor);
35
36
  selectionTool.setEnabled(true);
36
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(0, 0));
37
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(10, 10));
38
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(5, 5));
37
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(0, 0));
38
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(10, 10));
39
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(5, 5));
39
40
 
40
41
  return { editor, testStroke, selectionTool };
41
42
  };
@@ -61,9 +62,9 @@ describe('SelectionTool', () => {
61
62
 
62
63
  const selectionTool = getSelectionTool(editor);
63
64
  selectionTool.setEnabled(true);
64
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(0, 0));
65
- editor.sendPenEvent(InputEvtType.PointerMoveEvt, Vec2.of(0.1, 0.1));
66
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(0.1, 0.1));
65
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(0, 0));
66
+ sendPenEvent(editor, InputEvtType.PointerMoveEvt, Vec2.of(0.1, 0.1));
67
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(0.1, 0.1));
67
68
 
68
69
  // Should surround the selected object (which has bbox = (0, 0, 1, 1))
69
70
  // with extra space.
@@ -125,8 +126,8 @@ describe('SelectionTool', () => {
125
126
  selectionTool.setEnabled(true);
126
127
 
127
128
  // Select the smaller rectangle
128
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(40, 40));
129
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(100, 100));
129
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(40, 40));
130
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(100, 100));
130
131
 
131
132
  expect(selectionTool.getSelectedObjects()).toHaveLength(1);
132
133
 
@@ -134,21 +135,21 @@ describe('SelectionTool', () => {
134
135
  editor.sendKeyboardEvent(InputEvtType.KeyPressEvent, 'Shift');
135
136
 
136
137
  // Select the larger stroke.
137
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(200, 200));
138
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(600, 600));
138
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(200, 200));
139
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(600, 600));
139
140
 
140
141
  expect(selectionTool.getSelectedObjects()).toHaveLength(2);
141
142
 
142
143
  editor.sendKeyboardEvent(InputEvtType.KeyUpEvent, 'Shift');
143
144
 
144
145
  // Select the larger stroke without shift pressed
145
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(200, 200));
146
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(600, 600));
146
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(200, 200));
147
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(600, 600));
147
148
  expect(selectionTool.getSelectedObjects()).toHaveLength(1);
148
149
 
149
150
  // Select nothing
150
- editor.sendPenEvent(InputEvtType.PointerDownEvt, Vec2.of(200, 200));
151
- editor.sendPenEvent(InputEvtType.PointerUpEvt, Vec2.of(201, 201));
151
+ sendPenEvent(editor, InputEvtType.PointerDownEvt, Vec2.of(200, 200));
152
+ sendPenEvent(editor, InputEvtType.PointerUpEvt, Vec2.of(201, 201));
152
153
  expect(selectionTool.getSelectedObjects()).toHaveLength(0);
153
154
  });
154
155
 
@@ -379,24 +379,22 @@ export default class SelectionTool extends BaseTool {
379
379
 
380
380
  const exportViewport = new Viewport(() => {});
381
381
  exportViewport.updateScreenSize(Vec2.of(bbox.w, bbox.h));
382
- exportViewport.resetTransform(Mat33.translation(bbox.topLeft));
383
-
384
- const svgNameSpace = 'http://www.w3.org/2000/svg';
385
- const exportElem = document.createElementNS(svgNameSpace, 'svg');
382
+ exportViewport.resetTransform(Mat33.translation(bbox.topLeft.times(-1)));
386
383
 
387
384
  const sanitize = true;
388
- const renderer = new SVGRenderer(exportElem, exportViewport, sanitize);
385
+ const { element: svgExportElem, renderer: svgRenderer } = SVGRenderer.fromViewport(exportViewport, sanitize);
389
386
 
390
387
  const text: string[] = [];
391
388
  for (const elem of selectedElems) {
392
- elem.render(renderer);
389
+ elem.render(svgRenderer);
393
390
 
394
391
  if (elem instanceof TextComponent) {
395
392
  text.push(elem.getText());
396
393
  }
397
394
  }
398
395
 
399
- event.setData('image/svg+xml', exportElem.outerHTML);
396
+ event.setData('image/svg+xml', svgExportElem.outerHTML);
397
+ event.setData('text/html', svgExportElem.outerHTML);
400
398
  if (text.length > 0) {
401
399
  event.setData('text/plain', text.join('\n'));
402
400
  }