js-draw 0.1.11 → 0.1.12

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 (167) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/bundle.js +1 -1
  3. package/dist/src/Editor.d.ts +4 -2
  4. package/dist/src/Editor.js +30 -10
  5. package/dist/src/EditorImage.d.ts +1 -1
  6. package/dist/src/EditorImage.js +2 -2
  7. package/dist/src/Pointer.d.ts +1 -1
  8. package/dist/src/Pointer.js +1 -1
  9. package/dist/src/SVGLoader.d.ts +1 -1
  10. package/dist/src/SVGLoader.js +14 -6
  11. package/dist/src/Viewport.d.ts +8 -25
  12. package/dist/src/Viewport.js +15 -10
  13. package/dist/src/commands/Command.d.ts +2 -2
  14. package/dist/src/commands/Command.js +4 -4
  15. package/dist/src/commands/Duplicate.d.ts +1 -1
  16. package/dist/src/commands/Duplicate.js +1 -1
  17. package/dist/src/commands/Erase.d.ts +1 -1
  18. package/dist/src/commands/Erase.js +1 -1
  19. package/dist/src/commands/localization.d.ts +1 -1
  20. package/dist/src/components/AbstractComponent.d.ts +3 -3
  21. package/dist/src/components/AbstractComponent.js +2 -2
  22. package/dist/src/components/SVGGlobalAttributesObject.d.ts +3 -3
  23. package/dist/src/components/SVGGlobalAttributesObject.js +1 -1
  24. package/dist/src/components/Stroke.d.ts +4 -4
  25. package/dist/src/components/Stroke.js +2 -2
  26. package/dist/src/components/Text.d.ts +3 -3
  27. package/dist/src/components/Text.js +3 -3
  28. package/dist/src/components/UnknownSVGObject.d.ts +3 -3
  29. package/dist/src/components/UnknownSVGObject.js +1 -1
  30. package/dist/src/components/builders/ArrowBuilder.d.ts +1 -1
  31. package/dist/src/components/builders/ArrowBuilder.js +1 -1
  32. package/dist/src/components/builders/FreehandLineBuilder.d.ts +8 -3
  33. package/dist/src/components/builders/FreehandLineBuilder.js +142 -71
  34. package/dist/src/components/builders/LineBuilder.d.ts +1 -1
  35. package/dist/src/components/builders/LineBuilder.js +1 -1
  36. package/dist/src/components/builders/RectangleBuilder.d.ts +1 -1
  37. package/dist/src/components/builders/RectangleBuilder.js +3 -3
  38. package/dist/src/components/builders/types.d.ts +1 -1
  39. package/dist/src/localization.d.ts +1 -0
  40. package/dist/src/localization.js +5 -1
  41. package/dist/src/localizations/es.js +1 -1
  42. package/dist/src/{geometry → math}/LineSegment2.d.ts +0 -0
  43. package/dist/src/{geometry → math}/LineSegment2.js +0 -0
  44. package/dist/src/{geometry → math}/Mat33.d.ts +0 -0
  45. package/dist/src/{geometry → math}/Mat33.js +0 -0
  46. package/dist/src/{geometry → math}/Path.d.ts +2 -1
  47. package/dist/src/{geometry → math}/Path.js +58 -51
  48. package/dist/src/{geometry → math}/Rect2.d.ts +0 -0
  49. package/dist/src/{geometry → math}/Rect2.js +0 -0
  50. package/dist/src/{geometry → math}/Vec2.d.ts +0 -0
  51. package/dist/src/{geometry → math}/Vec2.js +0 -0
  52. package/dist/src/{geometry → math}/Vec3.d.ts +1 -1
  53. package/dist/src/{geometry → math}/Vec3.js +1 -1
  54. package/dist/src/math/rounding.d.ts +3 -0
  55. package/dist/src/math/rounding.js +120 -0
  56. package/dist/src/rendering/Display.d.ts +3 -1
  57. package/dist/src/rendering/Display.js +16 -10
  58. package/dist/src/rendering/caching/CacheRecord.d.ts +2 -2
  59. package/dist/src/rendering/caching/CacheRecord.js +1 -1
  60. package/dist/src/rendering/caching/CacheRecordManager.d.ts +1 -1
  61. package/dist/src/rendering/caching/RenderingCache.js +1 -1
  62. package/dist/src/rendering/caching/RenderingCacheNode.d.ts +2 -1
  63. package/dist/src/rendering/caching/RenderingCacheNode.js +18 -7
  64. package/dist/src/rendering/caching/testUtils.js +1 -1
  65. package/dist/src/rendering/caching/types.d.ts +1 -1
  66. package/dist/src/rendering/localization.d.ts +2 -0
  67. package/dist/src/rendering/localization.js +2 -0
  68. package/dist/src/rendering/renderers/AbstractRenderer.d.ts +4 -4
  69. package/dist/src/rendering/renderers/AbstractRenderer.js +2 -2
  70. package/dist/src/rendering/renderers/CanvasRenderer.d.ts +4 -4
  71. package/dist/src/rendering/renderers/CanvasRenderer.js +1 -1
  72. package/dist/src/rendering/renderers/DummyRenderer.d.ts +4 -4
  73. package/dist/src/rendering/renderers/DummyRenderer.js +1 -1
  74. package/dist/src/rendering/renderers/SVGRenderer.d.ts +3 -3
  75. package/dist/src/rendering/renderers/SVGRenderer.js +8 -2
  76. package/dist/src/rendering/renderers/TextOnlyRenderer.d.ts +5 -3
  77. package/dist/src/rendering/renderers/TextOnlyRenderer.js +13 -3
  78. package/dist/src/toolbar/icons.d.ts +3 -0
  79. package/dist/src/toolbar/icons.js +142 -132
  80. package/dist/src/toolbar/localization.d.ts +2 -1
  81. package/dist/src/toolbar/localization.js +2 -1
  82. package/dist/src/toolbar/makeColorInput.js +2 -1
  83. package/dist/src/toolbar/widgets/ActionButtonWidget.d.ts +13 -0
  84. package/dist/src/toolbar/widgets/ActionButtonWidget.js +21 -0
  85. package/dist/src/toolbar/widgets/BaseWidget.js +2 -0
  86. package/dist/src/toolbar/widgets/HandToolWidget.js +3 -3
  87. package/dist/src/toolbar/widgets/SelectionWidget.d.ts +0 -1
  88. package/dist/src/toolbar/widgets/SelectionWidget.js +23 -30
  89. package/dist/src/tools/Eraser.js +1 -1
  90. package/dist/src/tools/PanZoom.d.ts +1 -1
  91. package/dist/src/tools/PanZoom.js +24 -14
  92. package/dist/src/tools/SelectionTool.d.ts +3 -3
  93. package/dist/src/tools/SelectionTool.js +6 -6
  94. package/dist/src/tools/TextTool.js +1 -1
  95. package/dist/src/types.d.ts +4 -4
  96. package/package.json +1 -1
  97. package/src/Editor.ts +34 -12
  98. package/src/EditorImage.test.ts +2 -4
  99. package/src/EditorImage.ts +2 -2
  100. package/src/Pointer.ts +1 -1
  101. package/src/SVGLoader.ts +14 -6
  102. package/src/Viewport.ts +19 -17
  103. package/src/commands/Command.ts +5 -5
  104. package/src/commands/Duplicate.ts +1 -1
  105. package/src/commands/Erase.ts +1 -1
  106. package/src/commands/localization.ts +1 -1
  107. package/src/components/AbstractComponent.ts +4 -4
  108. package/src/components/SVGGlobalAttributesObject.ts +3 -3
  109. package/src/components/Stroke.test.ts +3 -5
  110. package/src/components/Stroke.ts +4 -4
  111. package/src/components/Text.test.ts +2 -2
  112. package/src/components/Text.ts +3 -3
  113. package/src/components/UnknownSVGObject.ts +3 -3
  114. package/src/components/builders/ArrowBuilder.ts +2 -2
  115. package/src/components/builders/FreehandLineBuilder.ts +190 -80
  116. package/src/components/builders/LineBuilder.ts +2 -2
  117. package/src/components/builders/RectangleBuilder.ts +3 -3
  118. package/src/components/builders/types.ts +1 -1
  119. package/src/localization.ts +6 -0
  120. package/src/localizations/es.ts +2 -1
  121. package/src/{geometry → math}/LineSegment2.test.ts +0 -0
  122. package/src/{geometry → math}/LineSegment2.ts +0 -0
  123. package/src/{geometry → math}/Mat33.test.ts +0 -0
  124. package/src/{geometry → math}/Mat33.ts +0 -0
  125. package/src/{geometry → math}/Path.fromString.test.ts +0 -0
  126. package/src/{geometry → math}/Path.test.ts +0 -0
  127. package/src/{geometry → math}/Path.toString.test.ts +11 -2
  128. package/src/{geometry → math}/Path.ts +60 -57
  129. package/src/{geometry → math}/Rect2.test.ts +0 -0
  130. package/src/{geometry → math}/Rect2.ts +0 -0
  131. package/src/{geometry → math}/Vec2.test.ts +0 -0
  132. package/src/{geometry → math}/Vec2.ts +0 -0
  133. package/src/{geometry → math}/Vec3.test.ts +0 -0
  134. package/src/{geometry → math}/Vec3.ts +2 -2
  135. package/src/math/rounding.test.ts +40 -0
  136. package/src/math/rounding.ts +145 -0
  137. package/src/rendering/Display.ts +18 -10
  138. package/src/rendering/caching/CacheRecord.test.ts +2 -2
  139. package/src/rendering/caching/CacheRecord.ts +2 -2
  140. package/src/rendering/caching/CacheRecordManager.ts +1 -1
  141. package/src/rendering/caching/RenderingCache.test.ts +3 -3
  142. package/src/rendering/caching/RenderingCache.ts +1 -1
  143. package/src/rendering/caching/RenderingCacheNode.ts +23 -7
  144. package/src/rendering/caching/testUtils.ts +1 -1
  145. package/src/rendering/caching/types.ts +1 -1
  146. package/src/rendering/localization.ts +4 -0
  147. package/src/rendering/renderers/AbstractRenderer.ts +4 -4
  148. package/src/rendering/renderers/CanvasRenderer.ts +4 -4
  149. package/src/rendering/renderers/DummyRenderer.test.ts +2 -2
  150. package/src/rendering/renderers/DummyRenderer.ts +4 -4
  151. package/src/rendering/renderers/SVGRenderer.ts +10 -4
  152. package/src/rendering/renderers/TextOnlyRenderer.ts +17 -6
  153. package/src/toolbar/icons.ts +157 -137
  154. package/src/toolbar/localization.ts +4 -2
  155. package/src/toolbar/makeColorInput.ts +2 -1
  156. package/src/toolbar/toolbar.css +1 -1
  157. package/src/toolbar/widgets/ActionButtonWidget.ts +31 -0
  158. package/src/toolbar/widgets/BaseWidget.ts +2 -0
  159. package/src/toolbar/widgets/HandToolWidget.ts +3 -3
  160. package/src/toolbar/widgets/SelectionWidget.ts +46 -41
  161. package/src/tools/Eraser.ts +2 -2
  162. package/src/tools/PanZoom.ts +28 -16
  163. package/src/tools/SelectionTool.test.ts +2 -4
  164. package/src/tools/SelectionTool.ts +6 -6
  165. package/src/tools/TextTool.ts +2 -2
  166. package/src/tools/UndoRedoShortcut.test.ts +1 -1
  167. package/src/types.ts +4 -4
@@ -10,10 +10,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import Command from '../commands/Command';
11
11
  import Duplicate from '../commands/Duplicate';
12
12
  import Erase from '../commands/Erase';
13
- import Mat33 from '../geometry/Mat33';
13
+ import Mat33 from '../math/Mat33';
14
14
  // import Mat33 from "../geometry/Mat33";
15
- import Rect2 from '../geometry/Rect2';
16
- import { Vec2 } from '../geometry/Vec2';
15
+ import Rect2 from '../math/Rect2';
16
+ import { Vec2 } from '../math/Vec2';
17
17
  import { EditorEventType } from '../types';
18
18
  import Viewport from '../Viewport';
19
19
  import BaseTool from './BaseTool';
@@ -342,7 +342,7 @@ class Selection {
342
342
  if (!visibleRect.containsPoint(this.region.center)) {
343
343
  const closestPoint = visibleRect.getClosestPointOnBoundaryTo(this.region.center);
344
344
  const delta = this.region.center.minus(closestPoint);
345
- this.editor.dispatchNoAnnounce(new Viewport.ViewportTransform(Mat33.translation(delta.times(-1))), false);
345
+ this.editor.dispatchNoAnnounce(Viewport.transformBy(Mat33.translation(delta.times(-1))), false);
346
346
  }
347
347
  }
348
348
  deleteSelectedObjects() {
@@ -382,7 +382,7 @@ Selection.ApplyTransformationCommand = class extends Command {
382
382
  this.selection.updateUI();
383
383
  });
384
384
  }
385
- description(localizationTable) {
385
+ description(_editor, localizationTable) {
386
386
  return localizationTable.transformedElements(this.currentTransfmCommands.length);
387
387
  }
388
388
  };
@@ -535,7 +535,7 @@ export default class SelectionTool extends BaseTool {
535
535
  this.handleOverlay.style.display = enabled ? 'block' : 'none';
536
536
  if (enabled) {
537
537
  this.handleOverlay.tabIndex = 0;
538
- this.handleOverlay.ariaLabel = this.editor.localization.selectionToolKeyboardShortcuts;
538
+ this.handleOverlay.setAttribute('aria-label', this.editor.localization.selectionToolKeyboardShortcuts);
539
539
  }
540
540
  else {
541
541
  this.handleOverlay.tabIndex = -1;
@@ -1,7 +1,7 @@
1
1
  import Color4 from '../Color4';
2
2
  import Text from '../components/Text';
3
3
  import EditorImage from '../EditorImage';
4
- import Mat33 from '../geometry/Mat33';
4
+ import Mat33 from '../math/Mat33';
5
5
  import { PointerDevice } from '../Pointer';
6
6
  import { EditorEventType } from '../types';
7
7
  import BaseTool from './BaseTool';
@@ -1,10 +1,10 @@
1
1
  import EventDispatcher from './EventDispatcher';
2
- import Mat33 from './geometry/Mat33';
3
- import { Point2, Vec2 } from './geometry/Vec2';
4
- import Vec3 from './geometry/Vec3';
2
+ import Mat33 from './math/Mat33';
3
+ import { Point2, Vec2 } from './math/Vec2';
4
+ import Vec3 from './math/Vec3';
5
5
  import BaseTool from './tools/BaseTool';
6
6
  import AbstractComponent from './components/AbstractComponent';
7
- import Rect2 from './geometry/Rect2';
7
+ import Rect2 from './math/Rect2';
8
8
  import Pointer from './Pointer';
9
9
  import Color4 from './Color4';
10
10
  export interface PointerEvtListener {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-draw",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "description": "Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript. ",
5
5
  "main": "dist/src/Editor.js",
6
6
  "types": "dist/src/Editor.d.ts",
package/src/Editor.ts CHANGED
@@ -6,8 +6,8 @@ import Command from './commands/Command';
6
6
  import UndoRedoHistory from './UndoRedoHistory';
7
7
  import Viewport from './Viewport';
8
8
  import EventDispatcher from './EventDispatcher';
9
- import { Point2, Vec2 } from './geometry/Vec2';
10
- import Vec3 from './geometry/Vec3';
9
+ import { Point2, Vec2 } from './math/Vec2';
10
+ import Vec3 from './math/Vec3';
11
11
  import HTMLToolbar from './toolbar/HTMLToolbar';
12
12
  import { RenderablePathSpec } from './rendering/renderers/AbstractRenderer';
13
13
  import Display, { RenderingMode } from './rendering/Display';
@@ -15,8 +15,8 @@ import SVGRenderer from './rendering/renderers/SVGRenderer';
15
15
  import Color4 from './Color4';
16
16
  import SVGLoader from './SVGLoader';
17
17
  import Pointer from './Pointer';
18
- import Mat33 from './geometry/Mat33';
19
- import Rect2 from './geometry/Rect2';
18
+ import Mat33 from './math/Mat33';
19
+ import Rect2 from './math/Rect2';
20
20
  import { EditorLocalization } from './localization';
21
21
  import getLocalizationTable from './localizations/getLocalizationTable';
22
22
 
@@ -55,6 +55,7 @@ export class Editor {
55
55
 
56
56
  private loadingWarning: HTMLElement;
57
57
  private accessibilityAnnounceArea: HTMLElement;
58
+ private accessibilityControlArea: HTMLTextAreaElement;
58
59
 
59
60
  private settings: EditorSettings;
60
61
 
@@ -86,15 +87,23 @@ export class Editor {
86
87
  this.loadingWarning.ariaLive = 'polite';
87
88
  this.container.appendChild(this.loadingWarning);
88
89
 
90
+ this.accessibilityControlArea = document.createElement('textarea');
91
+ this.accessibilityControlArea.setAttribute('placeholder', this.localization.accessibilityInputInstructions);
92
+ this.accessibilityControlArea.style.opacity = '0';
93
+ this.accessibilityControlArea.style.width = '0';
94
+ this.accessibilityControlArea.style.height = '0';
95
+ this.accessibilityControlArea.style.position = 'absolute';
96
+
89
97
  this.accessibilityAnnounceArea = document.createElement('div');
90
- this.accessibilityAnnounceArea.ariaLive = 'assertive';
98
+ this.accessibilityAnnounceArea.setAttribute('aria-live', 'assertive');
91
99
  this.accessibilityAnnounceArea.className = 'accessibilityAnnouncement';
92
100
  this.container.appendChild(this.accessibilityAnnounceArea);
93
101
 
94
102
  this.renderingRegion.style.touchAction = 'none';
95
103
  this.renderingRegion.className = 'imageEditorRenderArea';
104
+ this.renderingRegion.appendChild(this.accessibilityControlArea);
96
105
  this.renderingRegion.setAttribute('tabIndex', '0');
97
- this.renderingRegion.ariaLabel = this.localization.imageEditor;
106
+ this.renderingRegion.setAttribute('alt', '');
98
107
 
99
108
  this.notifier = new EventDispatcher();
100
109
  this.importExportViewport = new Viewport(this.notifier);
@@ -156,8 +165,14 @@ export class Editor {
156
165
  this.announceForAccessibility(this.localization.doneLoading);
157
166
  }
158
167
 
168
+ private previousAccessibilityAnnouncement: string = '';
159
169
  public announceForAccessibility(message: string) {
170
+ // Force re-announcing an announcement if announced again.
171
+ if (message === this.previousAccessibilityAnnouncement) {
172
+ message = message + '. ';
173
+ }
160
174
  this.accessibilityAnnounceArea.innerText = message;
175
+ this.previousAccessibilityAnnouncement = message;
161
176
  }
162
177
 
163
178
  public addToolbar(defaultLayout: boolean = true): HTMLToolbar {
@@ -319,13 +334,20 @@ export class Editor {
319
334
  });
320
335
  this.queueRerender();
321
336
  });
337
+
338
+ this.accessibilityControlArea.addEventListener('input', () => {
339
+ this.accessibilityControlArea.value = '';
340
+ });
322
341
  }
323
342
 
324
343
  // Adds event listners for keypresses to [elem] and forwards those events to the
325
344
  // editor.
326
345
  public handleKeyEventsFrom(elem: HTMLElement) {
327
346
  elem.addEventListener('keydown', evt => {
328
- if (this.toolController.dispatchInputEvent({
347
+ if (evt.key === 't' || evt.key === 'T') {
348
+ evt.preventDefault();
349
+ this.display.rerenderAsText();
350
+ } else if (this.toolController.dispatchInputEvent({
329
351
  kind: InputEvtType.KeyPressEvent,
330
352
  key: evt.key,
331
353
  ctrlKey: evt.ctrlKey,
@@ -333,7 +355,7 @@ export class Editor {
333
355
  evt.preventDefault();
334
356
  } else if (evt.key === 'Escape') {
335
357
  this.renderingRegion.blur();
336
- }
358
+ }
337
359
  });
338
360
 
339
361
  elem.addEventListener('keyup', evt => {
@@ -356,7 +378,7 @@ export class Editor {
356
378
  command.apply(this);
357
379
  }
358
380
 
359
- this.announceForAccessibility(command.description(this.localization));
381
+ this.announceForAccessibility(command.description(this, this.localization));
360
382
  }
361
383
 
362
384
  // Dispatches a command without announcing it. By default, does not add to history.
@@ -410,11 +432,11 @@ export class Editor {
410
432
  }
411
433
 
412
434
  private announceUndoCallback = (command: Command) => {
413
- this.announceForAccessibility(this.localization.undoAnnouncement(command.description(this.localization)));
435
+ this.announceForAccessibility(this.localization.undoAnnouncement(command.description(this, this.localization)));
414
436
  };
415
437
 
416
438
  private announceRedoCallback = (command: Command) => {
417
- this.announceForAccessibility(this.localization.redoAnnouncement(command.description(this.localization)));
439
+ this.announceForAccessibility(this.localization.redoAnnouncement(command.description(this, this.localization)));
418
440
  };
419
441
 
420
442
  private rerenderQueued: boolean = false;
@@ -587,7 +609,7 @@ export class Editor {
587
609
  editor.queueRerender();
588
610
  }
589
611
 
590
- public description(localizationTable: EditorLocalization) {
612
+ public description(_editor: Editor, localizationTable: EditorLocalization) {
591
613
  return localizationTable.resizeOutputCommand(imageRect);
592
614
  }
593
615
  };
@@ -1,9 +1,7 @@
1
- /* @jest-environment jsdom */
2
-
3
1
  import EditorImage from './EditorImage';
4
2
  import Stroke from './components/Stroke';
5
- import { Vec2 } from './geometry/Vec2';
6
- import Path, { PathCommandType } from './geometry/Path';
3
+ import { Vec2 } from './math/Vec2';
4
+ import Path, { PathCommandType } from './math/Path';
7
5
  import Color4 from './Color4';
8
6
  import DummyRenderer from './rendering/renderers/DummyRenderer';
9
7
  import createEditor from './testing/createEditor';
@@ -3,7 +3,7 @@ import AbstractRenderer from './rendering/renderers/AbstractRenderer';
3
3
  import Command from './commands/Command';
4
4
  import Viewport from './Viewport';
5
5
  import AbstractComponent from './components/AbstractComponent';
6
- import Rect2 from './geometry/Rect2';
6
+ import Rect2 from './math/Rect2';
7
7
  import { EditorLocalization } from './localization';
8
8
  import RenderingCache from './rendering/caching/RenderingCache';
9
9
  import SerializableCommand from './commands/SerializableCommand';
@@ -108,7 +108,7 @@ export default class EditorImage {
108
108
  editor.queueRerender();
109
109
  }
110
110
 
111
- public description(localization: EditorLocalization) {
111
+ public description(editor: Editor, localization: EditorLocalization) {
112
112
  return localization.addElementAction(this.element.description(localization));
113
113
  }
114
114
 
package/src/Pointer.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Point2, Vec2 } from './geometry/Vec2';
1
+ import { Point2, Vec2 } from './math/Vec2';
2
2
  import Viewport from './Viewport';
3
3
 
4
4
  export enum PointerDevice {
package/src/SVGLoader.ts CHANGED
@@ -4,10 +4,10 @@ import Stroke from './components/Stroke';
4
4
  import SVGGlobalAttributesObject from './components/SVGGlobalAttributesObject';
5
5
  import Text, { TextStyle } from './components/Text';
6
6
  import UnknownSVGObject from './components/UnknownSVGObject';
7
- import Mat33 from './geometry/Mat33';
8
- import Path from './geometry/Path';
9
- import Rect2 from './geometry/Rect2';
10
- import { Vec2 } from './geometry/Vec2';
7
+ import Mat33 from './math/Mat33';
8
+ import Path from './math/Path';
9
+ import Rect2 from './math/Rect2';
10
+ import { Vec2 } from './math/Vec2';
11
11
  import { RenderablePathSpec } from './rendering/renderers/AbstractRenderer';
12
12
  import RenderingStyle from './rendering/RenderingStyle';
13
13
  import { ComponentAddedListener, ImageLoader, OnDetermineExportRectListener, OnProgressListener } from './types';
@@ -210,8 +210,16 @@ export default class SVGLoader implements ImageLoader {
210
210
  transformProperty = elem.style.transform || 'none';
211
211
  }
212
212
 
213
- // Compute transform matrix
214
- let transform = Mat33.fromCSSMatrix(transformProperty);
213
+ // Compute transform matrix. Prefer the actual .style.transform
214
+ // to the computed stylesheet -- in some browsers, the computedStyles version
215
+ // can have lower precision.
216
+ let transform;
217
+ try {
218
+ transform = Mat33.fromCSSMatrix(elem.style.transform);
219
+ } catch(_e) {
220
+ transform = Mat33.fromCSSMatrix(transformProperty);
221
+ }
222
+
215
223
  const supportedAttrs = [];
216
224
  const elemX = elem.getAttribute('x');
217
225
  const elemY = elem.getAttribute('y');
package/src/Viewport.ts CHANGED
@@ -1,19 +1,23 @@
1
1
  import Command from './commands/Command';
2
2
  import { CommandLocalization } from './commands/localization';
3
3
  import Editor from './Editor';
4
- import Mat33 from './geometry/Mat33';
5
- import Rect2 from './geometry/Rect2';
6
- import { Point2, Vec2 } from './geometry/Vec2';
7
- import Vec3 from './geometry/Vec3';
4
+ import Mat33 from './math/Mat33';
5
+ import Rect2 from './math/Rect2';
6
+ import { Point2, Vec2 } from './math/Vec2';
7
+ import Vec3 from './math/Vec3';
8
8
  import { StrokeDataPoint } from './types';
9
9
  import { EditorEventType, EditorNotifier } from './types';
10
10
 
11
11
  // Returns the base type of some type of point/number
12
12
  type PointDataType<T extends Point2|StrokeDataPoint|number> = T extends Point2 ? Point2 : number;
13
13
 
14
+ export abstract class ViewportTransform extends Command {
15
+ public abstract readonly transform: Mat33;
16
+ }
17
+
14
18
  export class Viewport {
15
19
  // Command that translates/scales the viewport.
16
- public static ViewportTransform = class extends Command {
20
+ private static ViewportTransform = class extends ViewportTransform {
17
21
  readonly #inverseTransform: Mat33;
18
22
 
19
23
  public constructor(public readonly transform: Mat33) {
@@ -33,14 +37,14 @@ export class Viewport {
33
37
  editor.queueRerender();
34
38
  }
35
39
 
36
- public description(localizationTable: CommandLocalization): string {
40
+ public description(editor: Editor, localizationTable: CommandLocalization): string {
37
41
  const result: string[] = [];
38
42
 
39
43
  // Describe the transformation's affect on the viewport (note that transformation transforms
40
44
  // the **elements** within the viewport). Assumes the transformation only does rotation/scale/translation.
41
- const origVec = Vec2.unitX;
45
+ const origVec = editor.viewport.visibleRect.center;
42
46
  const linearTransformedVec = this.transform.transformVec3(Vec2.unitX);
43
- const affineTransformedVec = this.transform.transformVec2(Vec2.unitX);
47
+ const affineTransformedVec = this.transform.transformVec2(origVec);
44
48
 
45
49
  const scale = linearTransformedVec.magnitude();
46
50
  const rotation = 180 / Math.PI * linearTransformedVec.angle();
@@ -48,8 +52,7 @@ export class Viewport {
48
52
 
49
53
  if (scale > 1.2) {
50
54
  result.push(localizationTable.zoomedIn);
51
- }
52
- else if (scale < 0.8) {
55
+ } else if (scale < 0.8) {
53
56
  result.push(localizationTable.zoomedOut);
54
57
  }
55
58
 
@@ -64,7 +67,7 @@ export class Viewport {
64
67
  result.push(localizationTable.movedRight);
65
68
  }
66
69
 
67
- if (translation.y < minTranslation) {
70
+ if (translation.y < -minTranslation) {
68
71
  result.push(localizationTable.movedDown);
69
72
  } else if (translation.y > minTranslation) {
70
73
  result.push(localizationTable.movedUp);
@@ -100,7 +103,11 @@ export class Viewport {
100
103
  return this.transform.transformVec2(canvasPoint);
101
104
  }
102
105
 
103
- // Updates the transformation directly. Using ViewportTransform is preferred.
106
+ public static transformBy(transform: Mat33): ViewportTransform {
107
+ return new Viewport.ViewportTransform(transform);
108
+ }
109
+
110
+ // Updates the transformation directly. Using transformBy is preferred.
104
111
  // [newTransform] should map from canvas coordinates to screen coordinates.
105
112
  public resetTransform(newTransform: Mat33 = Mat33.identity) {
106
113
  const oldTransform = this.transform;
@@ -231,9 +238,4 @@ export class Viewport {
231
238
  }
232
239
  }
233
240
 
234
- export namespace Viewport { // eslint-disable-line
235
- // Needed to allow accessing as a type. See https://stackoverflow.com/a/68201883
236
- export type ViewportTransform = typeof Viewport.ViewportTransform.prototype;
237
- }
238
-
239
241
  export default Viewport;
@@ -8,7 +8,7 @@ export abstract class Command {
8
8
  // Called when the command is being deleted
9
9
  public onDrop(_editor: Editor) { }
10
10
 
11
- public abstract description(localizationTable: EditorLocalization): string;
11
+ public abstract description(editor: Editor, localizationTable: EditorLocalization): string;
12
12
 
13
13
  public static union(a: Command, b: Command): Command {
14
14
  return new class extends Command {
@@ -22,9 +22,9 @@ export abstract class Command {
22
22
  a.unapply(editor);
23
23
  }
24
24
 
25
- public description(localizationTable: EditorLocalization) {
26
- const aDescription = a.description(localizationTable);
27
- const bDescription = b.description(localizationTable);
25
+ public description(editor: Editor, localizationTable: EditorLocalization) {
26
+ const aDescription = a.description(editor, localizationTable);
27
+ const bDescription = b.description(editor, localizationTable);
28
28
 
29
29
  if (aDescription === bDescription) {
30
30
  return aDescription;
@@ -36,7 +36,7 @@ export abstract class Command {
36
36
  }
37
37
 
38
38
  public static readonly empty = new class extends Command {
39
- public description(_localizationTable: EditorLocalization) { return ''; }
39
+ public description(_editor: Editor, _localizationTable: EditorLocalization) { return ''; }
40
40
  public apply(_editor: Editor) { }
41
41
  public unapply(_editor: Editor) { }
42
42
  };
@@ -24,7 +24,7 @@ export default class Duplicate extends SerializableCommand {
24
24
  this.reverse.apply(editor);
25
25
  }
26
26
 
27
- public description(localizationTable: EditorLocalization): string {
27
+ public description(_editor: Editor, localizationTable: EditorLocalization): string {
28
28
  if (this.duplicates.length === 0) {
29
29
  return localizationTable.duplicatedNoElements;
30
30
  }
@@ -49,7 +49,7 @@ export default class Erase extends SerializableCommand {
49
49
  }
50
50
  }
51
51
 
52
- public description(localizationTable: EditorLocalization): string {
52
+ public description(_editor: Editor, localizationTable: EditorLocalization): string {
53
53
  if (this.toRemove.length === 0) {
54
54
  return localizationTable.erasedNoElements;
55
55
  }
@@ -1,4 +1,4 @@
1
- import Rect2 from '../geometry/Rect2';
1
+ import Rect2 from '../math/Rect2';
2
2
 
3
3
  export interface CommandLocalization {
4
4
  movedLeft: string;
@@ -2,9 +2,9 @@ import Command from '../commands/Command';
2
2
  import SerializableCommand from '../commands/SerializableCommand';
3
3
  import Editor from '../Editor';
4
4
  import EditorImage from '../EditorImage';
5
- import LineSegment2 from '../geometry/LineSegment2';
6
- import Mat33 from '../geometry/Mat33';
7
- import Rect2 from '../geometry/Rect2';
5
+ import LineSegment2 from '../math/LineSegment2';
6
+ import Mat33 from '../math/Mat33';
7
+ import Rect2 from '../math/Rect2';
8
8
  import { EditorLocalization } from '../localization';
9
9
  import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
10
10
  import { ImageComponentLocalization } from './localization';
@@ -128,7 +128,7 @@ export default abstract class AbstractComponent {
128
128
  editor.queueRerender();
129
129
  }
130
130
 
131
- public description(localizationTable: EditorLocalization) {
131
+ public description(_editor: Editor, localizationTable: EditorLocalization) {
132
132
  return localizationTable.transformedElements(1);
133
133
  }
134
134
 
@@ -1,6 +1,6 @@
1
- import LineSegment2 from '../geometry/LineSegment2';
2
- import Mat33 from '../geometry/Mat33';
3
- import Rect2 from '../geometry/Rect2';
1
+ import LineSegment2 from '../math/LineSegment2';
2
+ import Mat33 from '../math/Mat33';
3
+ import Rect2 from '../math/Rect2';
4
4
  import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
5
5
  import SVGRenderer from '../rendering/renderers/SVGRenderer';
6
6
  import AbstractComponent from './AbstractComponent';
@@ -1,12 +1,10 @@
1
- /* @jest-environment jsdom */
2
-
3
1
  import Color4 from '../Color4';
4
- import Path from '../geometry/Path';
5
- import { Vec2 } from '../geometry/Vec2';
2
+ import Path from '../math/Path';
3
+ import { Vec2 } from '../math/Vec2';
6
4
  import Stroke from './Stroke';
7
5
  import { loadExpectExtensions } from '../testing/loadExpectExtensions';
8
6
  import createEditor from '../testing/createEditor';
9
- import Mat33 from '../geometry/Mat33';
7
+ import Mat33 from '../math/Mat33';
10
8
 
11
9
  loadExpectExtensions();
12
10
 
@@ -1,7 +1,7 @@
1
- import LineSegment2 from '../geometry/LineSegment2';
2
- import Mat33 from '../geometry/Mat33';
3
- import Path from '../geometry/Path';
4
- import Rect2 from '../geometry/Rect2';
1
+ import LineSegment2 from '../math/LineSegment2';
2
+ import Mat33 from '../math/Mat33';
3
+ import Path from '../math/Path';
4
+ import Rect2 from '../math/Rect2';
5
5
  import AbstractRenderer, { RenderablePathSpec } from '../rendering/renderers/AbstractRenderer';
6
6
  import RenderingStyle, { styleFromJSON, styleToJSON } from '../rendering/RenderingStyle';
7
7
  import AbstractComponent from './AbstractComponent';
@@ -1,6 +1,6 @@
1
1
  import Color4 from '../Color4';
2
- import Mat33 from '../geometry/Mat33';
3
- import Rect2 from '../geometry/Rect2';
2
+ import Mat33 from '../math/Mat33';
3
+ import Rect2 from '../math/Rect2';
4
4
  import AbstractComponent from './AbstractComponent';
5
5
  import Text, { TextStyle } from './Text';
6
6
  import { loadExpectExtensions } from '../testing/loadExpectExtensions';
@@ -1,6 +1,6 @@
1
- import LineSegment2 from '../geometry/LineSegment2';
2
- import Mat33 from '../geometry/Mat33';
3
- import Rect2 from '../geometry/Rect2';
1
+ import LineSegment2 from '../math/LineSegment2';
2
+ import Mat33 from '../math/Mat33';
3
+ import Rect2 from '../math/Rect2';
4
4
  import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
5
5
  import RenderingStyle, { styleFromJSON, styleToJSON } from '../rendering/RenderingStyle';
6
6
  import AbstractComponent from './AbstractComponent';
@@ -1,6 +1,6 @@
1
- import LineSegment2 from '../geometry/LineSegment2';
2
- import Mat33 from '../geometry/Mat33';
3
- import Rect2 from '../geometry/Rect2';
1
+ import LineSegment2 from '../math/LineSegment2';
2
+ import Mat33 from '../math/Mat33';
3
+ import Rect2 from '../math/Rect2';
4
4
  import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
5
5
  import SVGRenderer from '../rendering/renderers/SVGRenderer';
6
6
  import AbstractComponent from './AbstractComponent';
@@ -1,5 +1,5 @@
1
- import { PathCommandType } from '../../geometry/Path';
2
- import Rect2 from '../../geometry/Rect2';
1
+ import { PathCommandType } from '../../math/Path';
2
+ import Rect2 from '../../math/Rect2';
3
3
  import AbstractRenderer from '../../rendering/renderers/AbstractRenderer';
4
4
  import { StrokeDataPoint } from '../../types';
5
5
  import Viewport from '../../Viewport';