js-draw 0.1.11 → 0.2.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 (220) hide show
  1. package/.eslintrc.js +1 -0
  2. package/.firebaserc +5 -0
  3. package/.github/workflows/firebase-hosting-merge.yml +25 -0
  4. package/.github/workflows/firebase-hosting-pull-request.yml +22 -0
  5. package/.github/workflows/github-pages.yml +52 -0
  6. package/CHANGELOG.md +13 -0
  7. package/README.md +11 -6
  8. package/dist/bundle.js +1 -1
  9. package/dist/src/Color4.d.ts +19 -0
  10. package/dist/src/Color4.js +24 -3
  11. package/dist/src/Editor.d.ts +133 -4
  12. package/dist/src/Editor.js +124 -27
  13. package/dist/src/EditorImage.d.ts +8 -3
  14. package/dist/src/EditorImage.js +42 -26
  15. package/dist/src/EventDispatcher.d.ts +18 -0
  16. package/dist/src/EventDispatcher.js +19 -4
  17. package/dist/src/Pointer.d.ts +1 -1
  18. package/dist/src/Pointer.js +4 -3
  19. package/dist/src/SVGLoader.d.ts +1 -1
  20. package/dist/src/SVGLoader.js +14 -6
  21. package/dist/src/UndoRedoHistory.js +15 -2
  22. package/dist/src/Viewport.d.ts +8 -25
  23. package/dist/src/Viewport.js +18 -10
  24. package/dist/src/bundle/bundled.d.ts +1 -2
  25. package/dist/src/bundle/bundled.js +1 -2
  26. package/dist/src/commands/Command.d.ts +2 -2
  27. package/dist/src/commands/Command.js +4 -4
  28. package/dist/src/commands/Duplicate.d.ts +2 -2
  29. package/dist/src/commands/Duplicate.js +4 -5
  30. package/dist/src/commands/Erase.d.ts +2 -2
  31. package/dist/src/commands/Erase.js +7 -6
  32. package/dist/src/commands/SerializableCommand.d.ts +4 -5
  33. package/dist/src/commands/SerializableCommand.js +12 -4
  34. package/dist/src/commands/invertCommand.d.ts +4 -0
  35. package/dist/src/commands/invertCommand.js +44 -0
  36. package/dist/src/commands/lib.d.ts +6 -0
  37. package/dist/src/commands/lib.js +6 -0
  38. package/dist/src/commands/localization.d.ts +2 -1
  39. package/dist/src/commands/localization.js +1 -0
  40. package/dist/src/components/AbstractComponent.d.ts +16 -11
  41. package/dist/src/components/AbstractComponent.js +28 -17
  42. package/dist/src/components/SVGGlobalAttributesObject.d.ts +4 -4
  43. package/dist/src/components/SVGGlobalAttributesObject.js +8 -2
  44. package/dist/src/components/Stroke.d.ts +16 -6
  45. package/dist/src/components/Stroke.js +12 -9
  46. package/dist/src/components/Text.d.ts +5 -5
  47. package/dist/src/components/Text.js +9 -9
  48. package/dist/src/components/UnknownSVGObject.d.ts +4 -4
  49. package/dist/src/components/UnknownSVGObject.js +7 -2
  50. package/dist/src/components/builders/ArrowBuilder.d.ts +1 -1
  51. package/dist/src/components/builders/ArrowBuilder.js +1 -1
  52. package/dist/src/components/builders/FreehandLineBuilder.d.ts +8 -3
  53. package/dist/src/components/builders/FreehandLineBuilder.js +142 -71
  54. package/dist/src/components/builders/LineBuilder.d.ts +1 -1
  55. package/dist/src/components/builders/LineBuilder.js +1 -1
  56. package/dist/src/components/builders/RectangleBuilder.d.ts +1 -1
  57. package/dist/src/components/builders/RectangleBuilder.js +3 -3
  58. package/dist/src/components/builders/types.d.ts +1 -1
  59. package/dist/src/components/lib.d.ts +4 -0
  60. package/dist/src/components/lib.js +4 -0
  61. package/dist/src/lib.d.ts +25 -0
  62. package/dist/src/lib.js +25 -0
  63. package/dist/src/localization.d.ts +1 -0
  64. package/dist/src/localization.js +5 -1
  65. package/dist/src/localizations/es.js +1 -1
  66. package/dist/src/{geometry → math}/LineSegment2.d.ts +0 -0
  67. package/dist/src/{geometry → math}/LineSegment2.js +0 -0
  68. package/dist/src/math/Mat33.d.ts +78 -0
  69. package/dist/src/{geometry → math}/Mat33.js +48 -20
  70. package/dist/src/{geometry → math}/Path.d.ts +2 -1
  71. package/dist/src/{geometry → math}/Path.js +59 -52
  72. package/dist/src/{geometry → math}/Rect2.d.ts +2 -2
  73. package/dist/src/{geometry → math}/Rect2.js +0 -0
  74. package/dist/src/{geometry → math}/Vec2.d.ts +0 -0
  75. package/dist/src/{geometry → math}/Vec2.js +0 -0
  76. package/dist/src/math/Vec3.d.ts +96 -0
  77. package/dist/src/{geometry → math}/Vec3.js +63 -15
  78. package/dist/src/math/lib.d.ts +7 -0
  79. package/dist/src/math/lib.js +7 -0
  80. package/dist/src/math/rounding.d.ts +3 -0
  81. package/dist/src/math/rounding.js +121 -0
  82. package/dist/src/rendering/Display.d.ts +47 -1
  83. package/dist/src/rendering/Display.js +60 -15
  84. package/dist/src/rendering/caching/CacheRecord.d.ts +3 -2
  85. package/dist/src/rendering/caching/CacheRecord.js +4 -1
  86. package/dist/src/rendering/caching/CacheRecordManager.d.ts +5 -4
  87. package/dist/src/rendering/caching/CacheRecordManager.js +16 -4
  88. package/dist/src/rendering/caching/RenderingCache.d.ts +2 -3
  89. package/dist/src/rendering/caching/RenderingCache.js +10 -11
  90. package/dist/src/rendering/caching/RenderingCacheNode.d.ts +2 -1
  91. package/dist/src/rendering/caching/RenderingCacheNode.js +18 -7
  92. package/dist/src/rendering/caching/testUtils.js +1 -1
  93. package/dist/src/rendering/caching/types.d.ts +2 -4
  94. package/dist/src/rendering/localization.d.ts +2 -0
  95. package/dist/src/rendering/localization.js +2 -0
  96. package/dist/src/rendering/renderers/AbstractRenderer.d.ts +4 -4
  97. package/dist/src/rendering/renderers/AbstractRenderer.js +2 -2
  98. package/dist/src/rendering/renderers/CanvasRenderer.d.ts +4 -4
  99. package/dist/src/rendering/renderers/CanvasRenderer.js +2 -2
  100. package/dist/src/rendering/renderers/DummyRenderer.d.ts +4 -4
  101. package/dist/src/rendering/renderers/DummyRenderer.js +1 -1
  102. package/dist/src/rendering/renderers/SVGRenderer.d.ts +3 -3
  103. package/dist/src/rendering/renderers/SVGRenderer.js +8 -2
  104. package/dist/src/rendering/renderers/TextOnlyRenderer.d.ts +5 -3
  105. package/dist/src/rendering/renderers/TextOnlyRenderer.js +13 -3
  106. package/dist/src/toolbar/HTMLToolbar.js +1 -0
  107. package/dist/src/toolbar/icons.d.ts +3 -0
  108. package/dist/src/toolbar/icons.js +142 -132
  109. package/dist/src/toolbar/localization.d.ts +2 -1
  110. package/dist/src/toolbar/localization.js +2 -1
  111. package/dist/src/toolbar/makeColorInput.js +3 -2
  112. package/dist/src/toolbar/widgets/ActionButtonWidget.d.ts +13 -0
  113. package/dist/src/toolbar/widgets/ActionButtonWidget.js +21 -0
  114. package/dist/src/toolbar/widgets/BaseWidget.js +2 -0
  115. package/dist/src/toolbar/widgets/HandToolWidget.js +3 -3
  116. package/dist/src/toolbar/widgets/PenWidget.js +1 -0
  117. package/dist/src/toolbar/widgets/SelectionWidget.d.ts +0 -1
  118. package/dist/src/toolbar/widgets/SelectionWidget.js +23 -30
  119. package/dist/src/tools/Eraser.js +1 -1
  120. package/dist/src/tools/PanZoom.d.ts +1 -1
  121. package/dist/src/tools/PanZoom.js +24 -14
  122. package/dist/src/tools/Pen.d.ts +1 -2
  123. package/dist/src/tools/Pen.js +8 -1
  124. package/dist/src/tools/PipetteTool.js +1 -0
  125. package/dist/src/tools/SelectionTool.d.ts +3 -3
  126. package/dist/src/tools/SelectionTool.js +51 -28
  127. package/dist/src/tools/TextTool.js +1 -1
  128. package/dist/src/types.d.ts +21 -10
  129. package/dist/src/types.js +7 -5
  130. package/firebase.json +16 -0
  131. package/package.json +118 -101
  132. package/src/Color4.ts +23 -2
  133. package/src/Editor.ts +181 -37
  134. package/src/EditorImage.test.ts +2 -4
  135. package/src/EditorImage.ts +46 -28
  136. package/src/EventDispatcher.ts +21 -6
  137. package/src/Pointer.ts +4 -3
  138. package/src/SVGLoader.ts +14 -6
  139. package/src/UndoRedoHistory.ts +18 -2
  140. package/src/Viewport.ts +23 -18
  141. package/src/bundle/bundled.ts +1 -2
  142. package/src/commands/Command.ts +5 -5
  143. package/src/commands/Duplicate.ts +4 -5
  144. package/src/commands/Erase.ts +7 -6
  145. package/src/commands/SerializableCommand.ts +17 -9
  146. package/src/commands/invertCommand.ts +51 -0
  147. package/src/commands/lib.ts +14 -0
  148. package/src/commands/localization.ts +3 -1
  149. package/src/components/AbstractComponent.ts +35 -24
  150. package/src/components/SVGGlobalAttributesObject.ts +11 -4
  151. package/src/components/Stroke.test.ts +4 -6
  152. package/src/components/Stroke.ts +15 -11
  153. package/src/components/Text.test.ts +2 -2
  154. package/src/components/Text.ts +9 -10
  155. package/src/components/UnknownSVGObject.ts +10 -4
  156. package/src/components/builders/ArrowBuilder.ts +2 -2
  157. package/src/components/builders/FreehandLineBuilder.ts +190 -80
  158. package/src/components/builders/LineBuilder.ts +2 -2
  159. package/src/components/builders/RectangleBuilder.ts +3 -3
  160. package/src/components/builders/types.ts +1 -1
  161. package/src/components/lib.ts +9 -0
  162. package/src/lib.ts +28 -0
  163. package/src/localization.ts +6 -0
  164. package/src/localizations/es.ts +2 -1
  165. package/src/{geometry → math}/LineSegment2.test.ts +0 -0
  166. package/src/{geometry → math}/LineSegment2.ts +0 -0
  167. package/src/{geometry → math}/Mat33.test.ts +0 -0
  168. package/src/{geometry → math}/Mat33.ts +48 -20
  169. package/src/{geometry → math}/Path.fromString.test.ts +0 -0
  170. package/src/{geometry → math}/Path.test.ts +0 -0
  171. package/src/{geometry → math}/Path.toString.test.ts +11 -2
  172. package/src/{geometry → math}/Path.ts +61 -58
  173. package/src/{geometry → math}/Rect2.test.ts +0 -0
  174. package/src/{geometry → math}/Rect2.ts +2 -2
  175. package/src/{geometry → math}/Vec2.test.ts +0 -0
  176. package/src/{geometry → math}/Vec2.ts +0 -0
  177. package/src/{geometry → math}/Vec3.test.ts +0 -0
  178. package/src/{geometry → math}/Vec3.ts +64 -16
  179. package/src/math/lib.ts +15 -0
  180. package/src/math/rounding.test.ts +40 -0
  181. package/src/math/rounding.ts +147 -0
  182. package/src/rendering/Display.ts +63 -15
  183. package/src/rendering/caching/CacheRecord.test.ts +3 -3
  184. package/src/rendering/caching/CacheRecord.ts +6 -2
  185. package/src/rendering/caching/CacheRecordManager.ts +34 -8
  186. package/src/rendering/caching/RenderingCache.test.ts +3 -3
  187. package/src/rendering/caching/RenderingCache.ts +11 -16
  188. package/src/rendering/caching/RenderingCacheNode.ts +23 -7
  189. package/src/rendering/caching/testUtils.ts +1 -1
  190. package/src/rendering/caching/types.ts +2 -7
  191. package/src/rendering/localization.ts +4 -0
  192. package/src/rendering/renderers/AbstractRenderer.ts +4 -4
  193. package/src/rendering/renderers/CanvasRenderer.ts +5 -5
  194. package/src/rendering/renderers/DummyRenderer.test.ts +2 -2
  195. package/src/rendering/renderers/DummyRenderer.ts +4 -4
  196. package/src/rendering/renderers/SVGRenderer.ts +10 -4
  197. package/src/rendering/renderers/TextOnlyRenderer.ts +17 -6
  198. package/src/toolbar/HTMLToolbar.ts +1 -0
  199. package/src/toolbar/icons.ts +157 -137
  200. package/src/toolbar/localization.ts +4 -2
  201. package/src/toolbar/makeColorInput.ts +3 -2
  202. package/src/toolbar/toolbar.css +1 -1
  203. package/src/toolbar/widgets/ActionButtonWidget.ts +31 -0
  204. package/src/toolbar/widgets/BaseWidget.ts +2 -0
  205. package/src/toolbar/widgets/HandToolWidget.ts +3 -3
  206. package/src/toolbar/widgets/PenWidget.ts +2 -0
  207. package/src/toolbar/widgets/SelectionWidget.ts +46 -41
  208. package/src/tools/Eraser.ts +2 -2
  209. package/src/tools/PanZoom.ts +28 -17
  210. package/src/tools/Pen.ts +11 -2
  211. package/src/tools/PipetteTool.ts +2 -0
  212. package/src/tools/SelectionTool.test.ts +2 -4
  213. package/src/tools/SelectionTool.ts +52 -24
  214. package/src/tools/TextTool.ts +2 -2
  215. package/src/tools/UndoRedoShortcut.test.ts +1 -1
  216. package/src/types.ts +23 -7
  217. package/tsconfig.json +4 -1
  218. package/typedoc.json +20 -0
  219. package/dist/src/geometry/Mat33.d.ts +0 -32
  220. package/dist/src/geometry/Vec3.d.ts +0 -34
@@ -20,7 +20,14 @@ export default class Pen extends BaseTool {
20
20
  getStrokePoint(pointer) {
21
21
  var _a;
22
22
  const minPressure = 0.3;
23
- const pressure = Math.max((_a = pointer.pressure) !== null && _a !== void 0 ? _a : 1.0, minPressure);
23
+ let pressure = Math.max((_a = pointer.pressure) !== null && _a !== void 0 ? _a : 1.0, minPressure);
24
+ if (!isFinite(pressure)) {
25
+ console.warn('Non-finite pressure!', pointer);
26
+ pressure = minPressure;
27
+ }
28
+ console.assert(isFinite(pointer.canvasPos.length()), 'Non-finite canvas position!');
29
+ console.assert(isFinite(pointer.screenPos.length()), 'Non-finite screen position!');
30
+ console.assert(isFinite(pointer.timeStamp), 'Non-finite timeStamp on pointer!');
24
31
  return {
25
32
  pos: pointer.canvasPos,
26
33
  width: pressure * this.getPressureMultiplier(),
@@ -1,3 +1,4 @@
1
+ // @internal @packageDocumentation
1
2
  import BaseTool from './BaseTool';
2
3
  import { ToolType } from './ToolController';
3
4
  export default class PipetteTool extends BaseTool {
@@ -1,8 +1,8 @@
1
1
  import Command from '../commands/Command';
2
2
  import Editor from '../Editor';
3
- import Mat33 from '../geometry/Mat33';
4
- import Rect2 from '../geometry/Rect2';
5
- import { Point2, Vec2 } from '../geometry/Vec2';
3
+ import Mat33 from '../math/Mat33';
4
+ import Rect2 from '../math/Rect2';
5
+ import { Point2, Vec2 } from '../math/Vec2';
6
6
  import { KeyPressEvent, KeyUpEvent, PointerEvt } from '../types';
7
7
  import BaseTool from './BaseTool';
8
8
  import { ToolType } from './ToolController';
@@ -7,17 +7,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import Command from '../commands/Command';
10
+ var _a;
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';
20
20
  import { ToolType } from './ToolController';
21
+ import SerializableCommand from '../commands/SerializableCommand';
21
22
  const handleScreenSize = 30;
22
23
  const styles = `
23
24
  .handleOverlay {
@@ -118,6 +119,7 @@ const makeDraggable = (element, onDrag, onDragEnd) => {
118
119
  };
119
120
  // Maximum number of strokes to transform without a re-render.
120
121
  const updateChunkSize = 100;
122
+ // @internal
121
123
  class Selection {
122
124
  constructor(startPoint, editor) {
123
125
  this.startPoint = startPoint;
@@ -228,7 +230,7 @@ class Selection {
228
230
  this.transform = Mat33.identity;
229
231
  this.region = this.region.transformedBoundingBox(inverseTransform);
230
232
  // Make the commands undo-able
231
- this.editor.dispatch(new Selection.ApplyTransformationCommand(this, currentTransfmCommands, fullTransform, inverseTransform, deltaBoxRotation));
233
+ this.editor.dispatch(new Selection.ApplyTransformationCommand(this, currentTransfmCommands, fullTransform, deltaBoxRotation));
232
234
  }
233
235
  // Preview the effects of the current transformation on the selection
234
236
  previewTransformCmds() {
@@ -342,7 +344,7 @@ class Selection {
342
344
  if (!visibleRect.containsPoint(this.region.center)) {
343
345
  const closestPoint = visibleRect.getClosestPointOnBoundaryTo(this.region.center);
344
346
  const delta = this.region.center.minus(closestPoint);
345
- this.editor.dispatchNoAnnounce(new Viewport.ViewportTransform(Mat33.translation(delta.times(-1))), false);
347
+ this.editor.dispatchNoAnnounce(Viewport.transformBy(Mat33.translation(delta.times(-1))), false);
346
348
  }
347
349
  }
348
350
  deleteSelectedObjects() {
@@ -352,37 +354,58 @@ class Selection {
352
354
  return new Duplicate(this.selectedElems);
353
355
  }
354
356
  }
355
- Selection.ApplyTransformationCommand = class extends Command {
356
- constructor(selection, currentTransfmCommands, fullTransform, inverseTransform, deltaBoxRotation) {
357
- super();
357
+ _a = Selection;
358
+ (() => {
359
+ SerializableCommand.register('selection-tool-transform', (json, editor) => {
360
+ // The selection box is lost when serializing/deserializing. No need to store box rotation
361
+ const guiBoxRotation = 0;
362
+ const fullTransform = new Mat33(...json.transform);
363
+ const commands = json.commands.map(data => SerializableCommand.deserialize(data, editor));
364
+ return new _a.ApplyTransformationCommand(null, commands, fullTransform, guiBoxRotation);
365
+ });
366
+ })();
367
+ Selection.ApplyTransformationCommand = class extends SerializableCommand {
368
+ constructor(selection, currentTransfmCommands, fullTransform, deltaBoxRotation) {
369
+ super('selection-tool-transform');
358
370
  this.selection = selection;
359
371
  this.currentTransfmCommands = currentTransfmCommands;
360
372
  this.fullTransform = fullTransform;
361
- this.inverseTransform = inverseTransform;
362
373
  this.deltaBoxRotation = deltaBoxRotation;
363
374
  }
364
375
  apply(editor) {
376
+ var _b, _c;
365
377
  return __awaiter(this, void 0, void 0, function* () {
366
378
  // Approximate the new selection
367
- this.selection.region = this.selection.region.transformedBoundingBox(this.fullTransform);
368
- this.selection.boxRotation += this.deltaBoxRotation;
369
- this.selection.updateUI();
379
+ if (this.selection) {
380
+ this.selection.region = this.selection.region.transformedBoundingBox(this.fullTransform);
381
+ this.selection.boxRotation += this.deltaBoxRotation;
382
+ this.selection.updateUI();
383
+ }
370
384
  yield editor.asyncApplyCommands(this.currentTransfmCommands, updateChunkSize);
371
- this.selection.recomputeRegion();
372
- this.selection.updateUI();
385
+ (_b = this.selection) === null || _b === void 0 ? void 0 : _b.recomputeRegion();
386
+ (_c = this.selection) === null || _c === void 0 ? void 0 : _c.updateUI();
373
387
  });
374
388
  }
375
389
  unapply(editor) {
390
+ var _b, _c;
376
391
  return __awaiter(this, void 0, void 0, function* () {
377
- this.selection.region = this.selection.region.transformedBoundingBox(this.inverseTransform);
378
- this.selection.boxRotation -= this.deltaBoxRotation;
379
- this.selection.updateUI();
392
+ if (this.selection) {
393
+ this.selection.region = this.selection.region.transformedBoundingBox(this.fullTransform.inverse());
394
+ this.selection.boxRotation -= this.deltaBoxRotation;
395
+ this.selection.updateUI();
396
+ }
380
397
  yield editor.asyncUnapplyCommands(this.currentTransfmCommands, updateChunkSize);
381
- this.selection.recomputeRegion();
382
- this.selection.updateUI();
398
+ (_b = this.selection) === null || _b === void 0 ? void 0 : _b.recomputeRegion();
399
+ (_c = this.selection) === null || _c === void 0 ? void 0 : _c.updateUI();
383
400
  });
384
401
  }
385
- description(localizationTable) {
402
+ serializeToJSON() {
403
+ return {
404
+ commands: this.currentTransfmCommands.map(command => command.serialize()),
405
+ transform: this.fullTransform.toArray(),
406
+ };
407
+ }
408
+ description(_editor, localizationTable) {
386
409
  return localizationTable.transformedElements(this.currentTransfmCommands.length);
387
410
  }
388
411
  };
@@ -397,9 +420,9 @@ export default class SelectionTool extends BaseTool {
397
420
  this.handleOverlay.style.display = 'none';
398
421
  this.handleOverlay.classList.add('handleOverlay');
399
422
  editor.notifier.on(EditorEventType.ViewportChanged, _data => {
400
- var _a, _b;
401
- (_a = this.selectionBox) === null || _a === void 0 ? void 0 : _a.recomputeRegion();
402
- (_b = this.selectionBox) === null || _b === void 0 ? void 0 : _b.updateUI();
423
+ var _b, _c;
424
+ (_b = this.selectionBox) === null || _b === void 0 ? void 0 : _b.recomputeRegion();
425
+ (_c = this.selectionBox) === null || _c === void 0 ? void 0 : _c.updateUI();
403
426
  });
404
427
  this.editor.handleKeyEventsFrom(this.handleOverlay);
405
428
  }
@@ -447,11 +470,11 @@ export default class SelectionTool extends BaseTool {
447
470
  this.onGestureEnd();
448
471
  }
449
472
  onGestureCancel() {
450
- var _a, _b;
473
+ var _b, _c;
451
474
  // Revert to the previous selection, if any.
452
- (_a = this.selectionBox) === null || _a === void 0 ? void 0 : _a.cancelSelection();
475
+ (_b = this.selectionBox) === null || _b === void 0 ? void 0 : _b.cancelSelection();
453
476
  this.selectionBox = this.prevSelectionBox;
454
- (_b = this.selectionBox) === null || _b === void 0 ? void 0 : _b.appendBackgroundBoxTo(this.handleOverlay);
477
+ (_c = this.selectionBox) === null || _c === void 0 ? void 0 : _c.appendBackgroundBoxTo(this.handleOverlay);
455
478
  }
456
479
  onKeyPress(event) {
457
480
  let rotationSteps = 0;
@@ -535,7 +558,7 @@ export default class SelectionTool extends BaseTool {
535
558
  this.handleOverlay.style.display = enabled ? 'block' : 'none';
536
559
  if (enabled) {
537
560
  this.handleOverlay.tabIndex = 0;
538
- this.handleOverlay.ariaLabel = this.editor.localization.selectionToolKeyboardShortcuts;
561
+ this.handleOverlay.setAttribute('aria-label', this.editor.localization.selectionToolKeyboardShortcuts);
539
562
  }
540
563
  else {
541
564
  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,12 +1,13 @@
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
+ import Command from './commands/Command';
10
11
  export interface PointerEvtListener {
11
12
  onPointerDown(event: PointerEvt): boolean;
12
13
  onPointerMove(event: PointerEvt): void;
@@ -61,11 +62,13 @@ export declare enum EditorEventType {
61
62
  ToolDisabled = 1,
62
63
  ToolUpdated = 2,
63
64
  UndoRedoStackUpdated = 3,
64
- ObjectAdded = 4,
65
- ViewportChanged = 5,
66
- DisplayResized = 6,
67
- ColorPickerToggled = 7,
68
- ColorPickerColorSelected = 8
65
+ CommandDone = 4,
66
+ CommandUndone = 5,
67
+ ObjectAdded = 6,
68
+ ViewportChanged = 7,
69
+ DisplayResized = 8,
70
+ ColorPickerToggled = 9,
71
+ ColorPickerColorSelected = 10
69
72
  }
70
73
  declare type EditorToolEventType = EditorEventType.ToolEnabled | EditorEventType.ToolDisabled | EditorEventType.ToolUpdated;
71
74
  export interface EditorToolEvent {
@@ -90,6 +93,14 @@ export interface EditorUndoStackUpdated {
90
93
  readonly undoStackSize: number;
91
94
  readonly redoStackSize: number;
92
95
  }
96
+ export interface CommandDoneEvent {
97
+ readonly kind: EditorEventType.CommandDone;
98
+ readonly command: Command;
99
+ }
100
+ export interface CommandUndoneEvent {
101
+ readonly kind: EditorEventType.CommandUndone;
102
+ readonly command: Command;
103
+ }
93
104
  export interface ColorPickerToggled {
94
105
  readonly kind: EditorEventType.ColorPickerToggled;
95
106
  readonly open: boolean;
@@ -98,7 +109,7 @@ export interface ColorPickerColorSelected {
98
109
  readonly kind: EditorEventType.ColorPickerColorSelected;
99
110
  readonly color: Color4;
100
111
  }
101
- export declare type EditorEventDataType = EditorToolEvent | EditorObjectEvent | EditorViewportChangedEvent | DisplayResizedEvent | EditorUndoStackUpdated | ColorPickerToggled | ColorPickerColorSelected;
112
+ export declare type EditorEventDataType = EditorToolEvent | EditorObjectEvent | EditorViewportChangedEvent | DisplayResizedEvent | EditorUndoStackUpdated | CommandDoneEvent | CommandUndoneEvent | ColorPickerToggled | ColorPickerColorSelected;
102
113
  export declare type OnProgressListener = (amountProcessed: number, totalToProcess: number) => Promise<void> | null;
103
114
  export declare type ComponentAddedListener = (component: AbstractComponent) => void;
104
115
  export declare type OnDetermineExportRectListener = (exportRect: Rect2) => void;
package/dist/src/types.js CHANGED
@@ -15,9 +15,11 @@ export var EditorEventType;
15
15
  EditorEventType[EditorEventType["ToolDisabled"] = 1] = "ToolDisabled";
16
16
  EditorEventType[EditorEventType["ToolUpdated"] = 2] = "ToolUpdated";
17
17
  EditorEventType[EditorEventType["UndoRedoStackUpdated"] = 3] = "UndoRedoStackUpdated";
18
- EditorEventType[EditorEventType["ObjectAdded"] = 4] = "ObjectAdded";
19
- EditorEventType[EditorEventType["ViewportChanged"] = 5] = "ViewportChanged";
20
- EditorEventType[EditorEventType["DisplayResized"] = 6] = "DisplayResized";
21
- EditorEventType[EditorEventType["ColorPickerToggled"] = 7] = "ColorPickerToggled";
22
- EditorEventType[EditorEventType["ColorPickerColorSelected"] = 8] = "ColorPickerColorSelected";
18
+ EditorEventType[EditorEventType["CommandDone"] = 4] = "CommandDone";
19
+ EditorEventType[EditorEventType["CommandUndone"] = 5] = "CommandUndone";
20
+ EditorEventType[EditorEventType["ObjectAdded"] = 6] = "ObjectAdded";
21
+ EditorEventType[EditorEventType["ViewportChanged"] = 7] = "ViewportChanged";
22
+ EditorEventType[EditorEventType["DisplayResized"] = 8] = "DisplayResized";
23
+ EditorEventType[EditorEventType["ColorPickerToggled"] = 9] = "ColorPickerToggled";
24
+ EditorEventType[EditorEventType["ColorPickerColorSelected"] = 10] = "ColorPickerColorSelected";
23
25
  })(EditorEventType || (EditorEventType = {}));
package/firebase.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "hosting": {
3
+ "public": "docs",
4
+ "ignore": [
5
+ "firebase.json",
6
+ "src/**",
7
+ ".husky/**",
8
+ ".vscode/**",
9
+ "build_tools/**",
10
+ "dist/**",
11
+ "__mocks__/**",
12
+ "**/.*",
13
+ "**/node_modules/**"
14
+ ]
15
+ }
16
+ }
package/package.json CHANGED
@@ -1,103 +1,120 @@
1
1
  {
2
- "name": "js-draw",
3
- "version": "0.1.11",
4
- "description": "Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript. ",
5
- "main": "dist/src/Editor.js",
6
- "types": "dist/src/Editor.d.ts",
7
- "exports": {
8
- ".": {
9
- "types": "./dist/src/Editor.d.ts",
10
- "default": "./dist/src/Editor.js"
11
- },
12
- "./localizations/getLocalizationTable": {
13
- "types": "./dist/src/localizations/getLocalizationTable.d.ts",
14
- "default": "./dist/src/localizations/getLocalizationTable.js"
15
- },
16
- "./getLocalizationTable": {
17
- "types": "./dist/src/localizations/getLocalizationTable.d.ts",
18
- "default": "./dist/src/localizations/getLocalizationTable.js"
19
- },
20
- "./styles": {
21
- "default": "./src/styles.js"
22
- },
23
- "./Editor": {
24
- "types": "./dist/src/Editor.d.ts",
25
- "default": "./dist/src/Editor.js"
26
- },
27
- "./localization": {
28
- "types": "./dist/src/localization.d.ts",
29
- "default": "./dist/src/localization.js"
30
- },
31
- "./toolbar/HTMLToolbar": {
32
- "types": "./dist/src/toolbar/HTMLToolbar.d.ts",
33
- "default": "./dist/src/toolbar/HTMLToolbar.js"
34
- },
35
- "./Editor.css": {
36
- "default": "./src/Editor.css"
37
- },
38
- "./toolbar/toolbar.css": {
39
- "default": "./src/toolbar/toolbar.css"
40
- },
41
- "./bundle": {
42
- "default": "./dist/bundle.js"
43
- }
44
- },
45
- "repository": {
46
- "type": "git",
47
- "url": "git+https://github.com/personalizedrefrigerator/js-draw.git"
48
- },
49
- "author": "Henry Heino",
50
- "license": "MIT",
51
- "private": false,
52
- "scripts": {
53
- "test": "jest",
54
- "build": "rm -rf ./dist; mkdir dist && yarn tsc && ts-node ./build_tools/bundle.ts",
55
- "lint": "eslint .",
56
- "linter-precommit": "eslint --fix --ext .js --ext .ts",
57
- "lint-staged": "lint-staged",
58
- "_postinstall": "husky install",
59
- "prepack": "yarn build && pinst --disable",
60
- "postpack": "pinst --enable"
61
- },
62
- "dependencies": {
63
- "@melloware/coloris": "^0.16.0",
64
- "bezier-js": "^6.1.0"
65
- },
66
- "devDependencies": {
67
- "@types/bezier-js": "^4.1.0",
68
- "@types/jest": "^28.1.7",
69
- "@types/jsdom": "^20.0.0",
70
- "@types/node": "^18.7.15",
71
- "@typescript-eslint/eslint-plugin": "^5.36.2",
72
- "@typescript-eslint/parser": "^5.36.2",
73
- "css-loader": "^6.7.1",
74
- "eslint": "^8.23.0",
75
- "husky": "^8.0.1",
76
- "jest": "^28.1.3",
77
- "jest-environment-jsdom": "^29.0.2",
78
- "jsdom": "^20.0.0",
79
- "lint-staged": "^13.0.3",
80
- "pinst": "^3.0.0",
81
- "style-loader": "^3.3.1",
82
- "terser-webpack-plugin": "^5.3.5",
83
- "ts-jest": "^28.0.8",
84
- "ts-loader": "^9.3.1",
85
- "ts-node": "^10.9.1",
86
- "typescript": "^4.8.2",
87
- "webpack": "^5.74.0"
88
- },
89
- "bugs": {
90
- "url": "https://github.com/personalizedrefrigerator/js-draw/issues"
91
- },
92
- "homepage": "https://github.com/personalizedrefrigerator/js-draw#readme",
93
- "directories": {
94
- "doc": "docs"
95
- },
96
- "keywords": [
97
- "ink",
98
- "drawing",
99
- "pen",
100
- "freehand",
101
- "svg"
102
- ]
2
+ "name": "js-draw",
3
+ "version": "0.2.0",
4
+ "description": "Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript. ",
5
+ "main": "./dist/src/lib.d.ts",
6
+ "types": "./dist/src/lib.js",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/src/lib.d.ts",
10
+ "default": "./dist/src/lib.js"
11
+ },
12
+ "./getLocalizationTable": {
13
+ "types": "./dist/src/localizations/getLocalizationTable.d.ts",
14
+ "default": "./dist/src/localizations/getLocalizationTable.js"
15
+ },
16
+ "./styles": {
17
+ "default": "./src/styles.js"
18
+ },
19
+ "./Editor": {
20
+ "types": "./dist/src/Editor.d.ts",
21
+ "default": "./dist/src/Editor.js"
22
+ },
23
+ "./types": {
24
+ "types": "./dist/src/types.d.ts",
25
+ "default": "./dist/src/types.js"
26
+ },
27
+ "./localization": {
28
+ "types": "./dist/src/localization.d.ts",
29
+ "default": "./dist/src/localization.js"
30
+ },
31
+ "./toolbar/HTMLToolbar": {
32
+ "types": "./dist/src/toolbar/HTMLToolbar.d.ts",
33
+ "default": "./dist/src/toolbar/HTMLToolbar.js"
34
+ },
35
+ "./Editor.css": {
36
+ "default": "./src/Editor.css"
37
+ },
38
+ "./math": {
39
+ "types": "./dist/src/math/lib.d.ts",
40
+ "default": "./dist/src/math/lib.js"
41
+ },
42
+ "./Color4": {
43
+ "types": "./dist/src/Color4.d.ts",
44
+ "default": "./dist/src/Color4.js"
45
+ },
46
+ "./components": {
47
+ "types": "./dist/src/components/lib.d.ts",
48
+ "default": "./dist/src/components/lib.js"
49
+ },
50
+ "./commands": {
51
+ "types": "./dist/src/commands/lib.d.ts",
52
+ "default": "./dist/src/commands/lib.js"
53
+ },
54
+ "./bundle": {
55
+ "types": "./dist/src/bundle/bundled.d.ts",
56
+ "default": "./dist/bundle.js"
57
+ }
58
+ },
59
+ "repository": {
60
+ "type": "git",
61
+ "url": "git+https://github.com/personalizedrefrigerator/js-draw.git"
62
+ },
63
+ "author": "Henry Heino",
64
+ "license": "MIT",
65
+ "private": false,
66
+ "scripts": {
67
+ "test": "jest",
68
+ "build": "rm -rf ./dist; mkdir dist && yarn tsc && ts-node ./build_tools/bundle.ts",
69
+ "doc": "typedoc --options typedoc.json",
70
+ "watch-docs": "typedoc --watch --options typedoc.json",
71
+ "lint": "eslint .",
72
+ "linter-precommit": "eslint --fix --ext .js --ext .ts",
73
+ "lint-staged": "lint-staged",
74
+ "prepare": "husky install && yarn build",
75
+ "prepack": "yarn build && pinst --disable",
76
+ "postpack": "pinst --enable"
77
+ },
78
+ "dependencies": {
79
+ "@melloware/coloris": "^0.16.0",
80
+ "bezier-js": "^6.1.0"
81
+ },
82
+ "devDependencies": {
83
+ "@types/bezier-js": "^4.1.0",
84
+ "@types/jest": "^28.1.7",
85
+ "@types/jsdom": "^20.0.0",
86
+ "@types/node": "^18.7.15",
87
+ "@typescript-eslint/eslint-plugin": "^5.36.2",
88
+ "@typescript-eslint/parser": "^5.36.2",
89
+ "css-loader": "^6.7.1",
90
+ "eslint": "^8.23.0",
91
+ "husky": "^8.0.1",
92
+ "jest": "^28.1.3",
93
+ "jest-environment-jsdom": "^29.0.2",
94
+ "jsdom": "^20.0.0",
95
+ "lint-staged": "^13.0.3",
96
+ "pinst": "^3.0.0",
97
+ "style-loader": "^3.3.1",
98
+ "terser-webpack-plugin": "^5.3.5",
99
+ "ts-jest": "^28.0.8",
100
+ "ts-loader": "^9.3.1",
101
+ "ts-node": "^10.9.1",
102
+ "typedoc": "^0.23.14",
103
+ "typescript": "^4.8.2",
104
+ "webpack": "^5.74.0"
105
+ },
106
+ "bugs": {
107
+ "url": "https://github.com/personalizedrefrigerator/js-draw/issues"
108
+ },
109
+ "homepage": "https://github.com/personalizedrefrigerator/js-draw#readme",
110
+ "directories": {
111
+ "doc": "docs"
112
+ },
113
+ "keywords": [
114
+ "ink",
115
+ "drawing",
116
+ "pen",
117
+ "freehand",
118
+ "svg"
119
+ ]
103
120
  }
package/src/Color4.ts CHANGED
@@ -1,14 +1,25 @@
1
1
 
2
2
  export default class Color4 {
3
3
  private constructor(
4
+ /** Red component. Should be in the range [0, 1]. */
4
5
  public readonly r: number,
6
+
7
+ /** Green component. `g` ∈ [0, 1] */
5
8
  public readonly g: number,
9
+
10
+ /** Blue component. `b` ∈ [0, 1] */
6
11
  public readonly b: number,
12
+
13
+ /** Alpha/transparent component. `a` ∈ [0, 1] */
7
14
  public readonly a: number
8
15
  ) {
9
16
  }
10
17
 
11
- // Each component should be in the range [0, 1]
18
+ /**
19
+ * Create a color from red, green, blue components. The color is fully opaque (`a = 1.0`).
20
+ *
21
+ * Each component should be in the range [0, 1].
22
+ */
12
23
  public static ofRGB(red: number, green: number, blue: number): Color4 {
13
24
  return Color4.ofRGBA(red, green, blue, 1.0);
14
25
  }
@@ -58,7 +69,7 @@ export default class Color4 {
58
69
  return Color4.ofRGBA(components[0], components[1], components[2], components[3]);
59
70
  }
60
71
 
61
- // Like fromHex, but can handle additional colors if an HTML5Canvas is available.
72
+ /** Like fromHex, but can handle additional colors if an `HTMLCanvasElement` is available. */
62
73
  public static fromString(text: string): Color4 {
63
74
  if (text.startsWith('#')) {
64
75
  return Color4.fromHex(text);
@@ -82,6 +93,7 @@ export default class Color4 {
82
93
  }
83
94
  }
84
95
 
96
+ /** @returns true if `this` and `other` are approximately equal. */
85
97
  public eq(other: Color4|null|undefined): boolean {
86
98
  if (other == null) {
87
99
  return false;
@@ -91,6 +103,15 @@ export default class Color4 {
91
103
  }
92
104
 
93
105
  private hexString: string|null = null;
106
+
107
+ /**
108
+ * @returns a hexadecimal color string representation of `this`, in the form `#rrggbbaa`.
109
+ *
110
+ * @example
111
+ * ```
112
+ * Color4.red.toHexString(); // -> #ff0000ff
113
+ * ```
114
+ */
94
115
  public toHexString(): string {
95
116
  if (this.hexString) {
96
117
  return this.hexString;