js-draw 1.29.2 → 1.30.1

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 (118) hide show
  1. package/dist/bundle.js +44 -34
  2. package/dist/cjs/Editor.d.ts +2 -2
  3. package/dist/cjs/Editor.js +16 -9
  4. package/dist/cjs/components/ImageComponent.js +1 -1
  5. package/dist/cjs/components/builders/FreehandLineBuilder.d.ts +5 -1
  6. package/dist/cjs/components/builders/FreehandLineBuilder.js +7 -4
  7. package/dist/cjs/components/builders/PolylineBuilder.d.ts +5 -1
  8. package/dist/cjs/components/builders/PolylineBuilder.js +7 -4
  9. package/dist/cjs/components/builders/PressureSensitiveFreehandLineBuilder.d.ts +1 -0
  10. package/dist/cjs/components/builders/PressureSensitiveFreehandLineBuilder.js +13 -10
  11. package/dist/cjs/components/builders/autocorrect/makeShapeFitAutocorrect.js +3 -0
  12. package/dist/cjs/components/builders/autocorrect/makeSnapToGridAutocorrect.js +3 -0
  13. package/dist/cjs/components/builders/types.d.ts +6 -0
  14. package/dist/cjs/dialogs/makeMessageDialog.js +5 -3
  15. package/dist/cjs/localizations/getLocalizationTable.js +2 -0
  16. package/dist/cjs/localizations/sk.d.ts +3 -0
  17. package/dist/cjs/localizations/sk.js +182 -0
  18. package/dist/cjs/rendering/Display.d.ts +2 -0
  19. package/dist/cjs/rendering/Display.js +13 -4
  20. package/dist/cjs/rendering/renderers/AbstractRenderer.d.ts +20 -1
  21. package/dist/cjs/rendering/renderers/AbstractRenderer.js +7 -0
  22. package/dist/cjs/rendering/renderers/AcceleratedInkingCanvasRenderer.d.ts +22 -0
  23. package/dist/cjs/rendering/renderers/AcceleratedInkingCanvasRenderer.js +50 -0
  24. package/dist/cjs/toolbar/EdgeToolbar.js +3 -2
  25. package/dist/cjs/toolbar/IconProvider.js +1 -1
  26. package/dist/cjs/toolbar/utils/HelpDisplay.js +7 -6
  27. package/dist/cjs/toolbar/widgets/BaseWidget.js +1 -1
  28. package/dist/cjs/toolbar/widgets/DocumentPropertiesWidget.js +5 -3
  29. package/dist/cjs/toolbar/widgets/HandToolWidget.js +4 -3
  30. package/dist/cjs/toolbar/widgets/InsertImageWidget/InsertImageWidget.js +14 -11
  31. package/dist/cjs/toolbar/widgets/PenToolWidget.js +2 -1
  32. package/dist/cjs/toolbar/widgets/components/makeButtonGrid.js +3 -2
  33. package/dist/cjs/toolbar/widgets/components/makeColorInput.js +2 -1
  34. package/dist/cjs/toolbar/widgets/components/makeGridSelector.js +2 -2
  35. package/dist/cjs/toolbar/widgets/components/makeSnappedList.js +1 -1
  36. package/dist/cjs/tools/FindTool.js +3 -2
  37. package/dist/cjs/tools/Pen.d.ts +2 -0
  38. package/dist/cjs/tools/Pen.js +24 -12
  39. package/dist/cjs/tools/SelectionTool/SelectionMenuShortcut.js +7 -2
  40. package/dist/cjs/tools/SoundUITool.js +6 -4
  41. package/dist/cjs/tools/util/createMenuOverlay.js +9 -7
  42. package/dist/cjs/util/dom/createButton.d.ts +7 -0
  43. package/dist/cjs/util/dom/createButton.js +20 -0
  44. package/dist/cjs/util/{createElement.d.ts → dom/createElement.d.ts} +3 -0
  45. package/dist/cjs/version.js +1 -1
  46. package/dist/mjs/Editor.d.ts +2 -2
  47. package/dist/mjs/Editor.mjs +16 -9
  48. package/dist/mjs/components/ImageComponent.mjs +1 -1
  49. package/dist/mjs/components/builders/FreehandLineBuilder.d.ts +5 -1
  50. package/dist/mjs/components/builders/FreehandLineBuilder.mjs +7 -4
  51. package/dist/mjs/components/builders/PolylineBuilder.d.ts +5 -1
  52. package/dist/mjs/components/builders/PolylineBuilder.mjs +7 -4
  53. package/dist/mjs/components/builders/PressureSensitiveFreehandLineBuilder.d.ts +1 -0
  54. package/dist/mjs/components/builders/PressureSensitiveFreehandLineBuilder.mjs +13 -10
  55. package/dist/mjs/components/builders/autocorrect/makeShapeFitAutocorrect.mjs +3 -0
  56. package/dist/mjs/components/builders/autocorrect/makeSnapToGridAutocorrect.mjs +3 -0
  57. package/dist/mjs/components/builders/types.d.ts +6 -0
  58. package/dist/mjs/dialogs/makeMessageDialog.mjs +5 -3
  59. package/dist/mjs/localizations/getLocalizationTable.mjs +2 -0
  60. package/dist/mjs/localizations/sk.d.ts +3 -0
  61. package/dist/mjs/localizations/sk.mjs +180 -0
  62. package/dist/mjs/rendering/Display.d.ts +2 -0
  63. package/dist/mjs/rendering/Display.mjs +13 -4
  64. package/dist/mjs/rendering/renderers/AbstractRenderer.d.ts +20 -1
  65. package/dist/mjs/rendering/renderers/AbstractRenderer.mjs +7 -0
  66. package/dist/mjs/rendering/renderers/AcceleratedInkingCanvasRenderer.d.ts +22 -0
  67. package/dist/mjs/rendering/renderers/AcceleratedInkingCanvasRenderer.mjs +44 -0
  68. package/dist/mjs/toolbar/EdgeToolbar.mjs +3 -2
  69. package/dist/mjs/toolbar/IconProvider.mjs +1 -1
  70. package/dist/mjs/toolbar/utils/HelpDisplay.mjs +7 -6
  71. package/dist/mjs/toolbar/widgets/BaseWidget.mjs +1 -1
  72. package/dist/mjs/toolbar/widgets/DocumentPropertiesWidget.mjs +5 -3
  73. package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +4 -3
  74. package/dist/mjs/toolbar/widgets/InsertImageWidget/InsertImageWidget.mjs +14 -11
  75. package/dist/mjs/toolbar/widgets/PenToolWidget.mjs +2 -1
  76. package/dist/mjs/toolbar/widgets/components/makeButtonGrid.mjs +3 -2
  77. package/dist/mjs/toolbar/widgets/components/makeColorInput.mjs +2 -1
  78. package/dist/mjs/toolbar/widgets/components/makeGridSelector.mjs +2 -2
  79. package/dist/mjs/toolbar/widgets/components/makeSnappedList.mjs +1 -1
  80. package/dist/mjs/tools/FindTool.mjs +3 -2
  81. package/dist/mjs/tools/Pen.d.ts +2 -0
  82. package/dist/mjs/tools/Pen.mjs +24 -12
  83. package/dist/mjs/tools/SelectionTool/SelectionMenuShortcut.mjs +4 -2
  84. package/dist/mjs/tools/SoundUITool.mjs +6 -4
  85. package/dist/mjs/tools/util/createMenuOverlay.mjs +9 -7
  86. package/dist/mjs/util/dom/createButton.d.ts +7 -0
  87. package/dist/mjs/util/dom/createButton.mjs +15 -0
  88. package/dist/mjs/util/{createElement.d.ts → dom/createElement.d.ts} +3 -0
  89. package/dist/mjs/version.mjs +1 -1
  90. package/package.json +4 -4
  91. /package/dist/cjs/util/{addLongPressOrHoverCssClasses.d.ts → dom/addLongPressOrHoverCssClasses.d.ts} +0 -0
  92. /package/dist/cjs/util/{addLongPressOrHoverCssClasses.js → dom/addLongPressOrHoverCssClasses.js} +0 -0
  93. /package/dist/cjs/util/{cloneElementWithStyles.d.ts → dom/cloneElementWithStyles.d.ts} +0 -0
  94. /package/dist/cjs/util/{cloneElementWithStyles.js → dom/cloneElementWithStyles.js} +0 -0
  95. /package/dist/cjs/util/{createElement.js → dom/createElement.js} +0 -0
  96. /package/dist/cjs/util/{listenForKeyboardEventsFrom.d.ts → dom/listenForKeyboardEventsFrom.d.ts} +0 -0
  97. /package/dist/cjs/util/{listenForKeyboardEventsFrom.js → dom/listenForKeyboardEventsFrom.js} +0 -0
  98. /package/dist/cjs/util/{listenForLongPressOrHover.d.ts → dom/listenForLongPressOrHover.d.ts} +0 -0
  99. /package/dist/cjs/util/{listenForLongPressOrHover.js → dom/listenForLongPressOrHover.js} +0 -0
  100. /package/dist/cjs/util/{listenForLongPressOrHover.test.d.ts → dom/listenForLongPressOrHover.test.d.ts} +0 -0
  101. /package/dist/cjs/util/{stopPropagationOfScrollingWheelEvents.d.ts → dom/stopPropagationOfScrollingWheelEvents.d.ts} +0 -0
  102. /package/dist/cjs/util/{stopPropagationOfScrollingWheelEvents.js → dom/stopPropagationOfScrollingWheelEvents.js} +0 -0
  103. /package/dist/cjs/util/{waitForImageLoaded.d.ts → dom/waitForImageLoaded.d.ts} +0 -0
  104. /package/dist/cjs/util/{waitForImageLoaded.js → dom/waitForImageLoaded.js} +0 -0
  105. /package/dist/mjs/util/{addLongPressOrHoverCssClasses.d.ts → dom/addLongPressOrHoverCssClasses.d.ts} +0 -0
  106. /package/dist/mjs/util/{addLongPressOrHoverCssClasses.mjs → dom/addLongPressOrHoverCssClasses.mjs} +0 -0
  107. /package/dist/mjs/util/{cloneElementWithStyles.d.ts → dom/cloneElementWithStyles.d.ts} +0 -0
  108. /package/dist/mjs/util/{cloneElementWithStyles.mjs → dom/cloneElementWithStyles.mjs} +0 -0
  109. /package/dist/mjs/util/{createElement.mjs → dom/createElement.mjs} +0 -0
  110. /package/dist/mjs/util/{listenForKeyboardEventsFrom.d.ts → dom/listenForKeyboardEventsFrom.d.ts} +0 -0
  111. /package/dist/mjs/util/{listenForKeyboardEventsFrom.mjs → dom/listenForKeyboardEventsFrom.mjs} +0 -0
  112. /package/dist/mjs/util/{listenForLongPressOrHover.d.ts → dom/listenForLongPressOrHover.d.ts} +0 -0
  113. /package/dist/mjs/util/{listenForLongPressOrHover.mjs → dom/listenForLongPressOrHover.mjs} +0 -0
  114. /package/dist/mjs/util/{listenForLongPressOrHover.test.d.ts → dom/listenForLongPressOrHover.test.d.ts} +0 -0
  115. /package/dist/mjs/util/{stopPropagationOfScrollingWheelEvents.d.ts → dom/stopPropagationOfScrollingWheelEvents.d.ts} +0 -0
  116. /package/dist/mjs/util/{stopPropagationOfScrollingWheelEvents.mjs → dom/stopPropagationOfScrollingWheelEvents.mjs} +0 -0
  117. /package/dist/mjs/util/{waitForImageLoaded.d.ts → dom/waitForImageLoaded.d.ts} +0 -0
  118. /package/dist/mjs/util/{waitForImageLoaded.mjs → dom/waitForImageLoaded.mjs} +0 -0
@@ -340,9 +340,9 @@ export declare class Editor {
340
340
  * A protected method that can override setPointerCapture in environments where it may fail
341
341
  * (e.g. with synthetic events). @internal
342
342
  */
343
- protected setPointerCapture(target: HTMLElement, pointerId: number): void;
343
+ protected setPointerCapture(target: HTMLElement, pointer: PointerEvent): void;
344
344
  /** Can be overridden in a testing environment to handle synthetic events. @internal */
345
- protected releasePointerCapture(target: HTMLElement, pointerId: number): void;
345
+ protected releasePointerCapture(target: HTMLElement, pointer: PointerEvent): void;
346
346
  /**
347
347
  * Dispatches a `PointerEvent` to the editor. The target element for `evt` must have the same top left
348
348
  * as the content of the editor.
@@ -65,7 +65,7 @@ const makeAboutDialog_1 = __importDefault(require("./dialogs/makeAboutDialog"));
65
65
  const version_1 = __importDefault(require("./version"));
66
66
  const editorImageToSVG_1 = require("./image/export/editorImageToSVG");
67
67
  const ReactiveValue_1 = __importStar(require("./util/ReactiveValue"));
68
- const listenForKeyboardEventsFrom_1 = __importDefault(require("./util/listenForKeyboardEventsFrom"));
68
+ const listenForKeyboardEventsFrom_1 = __importDefault(require("./util/dom/listenForKeyboardEventsFrom"));
69
69
  const mitLicenseAttribution_1 = __importDefault(require("./util/mitLicenseAttribution"));
70
70
  const ClipboardHandler_1 = __importDefault(require("./util/ClipboardHandler"));
71
71
  const ContextMenuRecognizer_1 = __importDefault(require("./tools/InputFilter/ContextMenuRecognizer"));
@@ -424,18 +424,24 @@ class Editor {
424
424
  * A protected method that can override setPointerCapture in environments where it may fail
425
425
  * (e.g. with synthetic events). @internal
426
426
  */
427
- setPointerCapture(target, pointerId) {
427
+ setPointerCapture(target, pointer) {
428
+ // Prevent synthetic events from attempting to capture the pointer.
429
+ // Such events are sometimes created during debug/testing.
430
+ if ('__mockEvent' in pointer)
431
+ return;
428
432
  try {
429
- target.setPointerCapture(pointerId);
433
+ target.setPointerCapture(pointer.pointerId);
430
434
  }
431
435
  catch (error) {
432
436
  console.warn('Failed to setPointerCapture', error);
433
437
  }
434
438
  }
435
439
  /** Can be overridden in a testing environment to handle synthetic events. @internal */
436
- releasePointerCapture(target, pointerId) {
440
+ releasePointerCapture(target, pointer) {
441
+ if ('__mockEvent' in pointer)
442
+ return;
437
443
  try {
438
- target.releasePointerCapture(pointerId);
444
+ target.releasePointerCapture(pointer.pointerId);
439
445
  }
440
446
  catch (error) {
441
447
  console.warn('Failed to releasePointerCapture', error);
@@ -448,10 +454,11 @@ class Editor {
448
454
  handleHTMLPointerEvent(eventType, evt) {
449
455
  const eventsRelativeTo = this.renderingRegion;
450
456
  const eventTarget = evt.target ?? this.renderingRegion;
457
+ this.display.onPointerEvent(evt);
451
458
  if (eventType === 'pointerdown') {
452
459
  const pointer = Pointer_1.default.ofEvent(evt, true, this.viewport, eventsRelativeTo);
453
460
  this.pointers[pointer.id] = pointer;
454
- this.setPointerCapture(eventTarget, pointer.id);
461
+ this.setPointerCapture(eventTarget, evt);
455
462
  const event = {
456
463
  kind: inputEvents_1.InputEvtType.PointerDownEvt,
457
464
  current: pointer,
@@ -488,7 +495,7 @@ class Editor {
488
495
  return false;
489
496
  }
490
497
  this.pointers[pointer.id] = pointer;
491
- this.releasePointerCapture(eventTarget, pointer.id);
498
+ this.releasePointerCapture(eventTarget, evt);
492
499
  if (this.toolController.dispatchInputEvent({
493
500
  kind: inputEvents_1.InputEvtType.PointerUpEvt,
494
501
  current: pointer,
@@ -631,7 +638,7 @@ class Editor {
631
638
  hasMovedSignificantly: false,
632
639
  };
633
640
  // Capture the pointer so we receive future events even if the overlay is hidden.
634
- this.setPointerCapture(elem, event.pointerId);
641
+ this.setPointerCapture(elem, event);
635
642
  // Don't send to the editor.
636
643
  sendToEditor = false;
637
644
  }
@@ -665,7 +672,7 @@ class Editor {
665
672
  else if ((eventName === 'pointerup' || eventName === 'pointercancel') &&
666
673
  gestureData[pointerId] &&
667
674
  gestureData[pointerId].eventBuffer.length > 0) {
668
- this.releasePointerCapture(elem, event.pointerId);
675
+ this.releasePointerCapture(elem, event);
669
676
  // Don't send to the editor.
670
677
  sendToEditor = false;
671
678
  delete gestureData[pointerId];
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const math_1 = require("@js-draw/math");
7
7
  const assertions_1 = require("../util/assertions");
8
8
  const AbstractComponent_1 = __importDefault(require("./AbstractComponent"));
9
- const waitForImageLoaded_1 = __importDefault(require("../util/waitForImageLoaded"));
9
+ const waitForImageLoaded_1 = __importDefault(require("../util/dom/waitForImageLoaded"));
10
10
  /**
11
11
  * Represents a raster image.
12
12
  *
@@ -1,6 +1,6 @@
1
1
  import AbstractRenderer from '../../rendering/renderers/AbstractRenderer';
2
2
  import RenderablePathSpec from '../../rendering/RenderablePathSpec';
3
- import { Rect2 } from '@js-draw/math';
3
+ import { Rect2, Color4 } from '@js-draw/math';
4
4
  import Stroke from '../Stroke';
5
5
  import Viewport from '../../Viewport';
6
6
  import { StrokeDataPoint } from '../../types';
@@ -26,6 +26,10 @@ export default class FreehandLineBuilder implements ComponentBuilder {
26
26
  constructor(startPoint: StrokeDataPoint, minFitAllowed: number, maxFitAllowed: number, viewport: Viewport);
27
27
  getBBox(): Rect2;
28
28
  protected getRenderingStyle(): RenderingStyle;
29
+ inkTrailStyle(): {
30
+ color: Color4;
31
+ width: number;
32
+ };
29
33
  protected previewCurrentPath(): RenderablePathSpec | null;
30
34
  protected previewFullPath(): RenderablePathSpec[] | null;
31
35
  private previewStroke;
@@ -41,10 +41,13 @@ class FreehandLineBuilder {
41
41
  getRenderingStyle() {
42
42
  return {
43
43
  fill: math_1.Color4.transparent,
44
- stroke: {
45
- color: this.startPoint.color,
46
- width: this.roundDistance(this.averageWidth),
47
- },
44
+ stroke: this.inkTrailStyle(),
45
+ };
46
+ }
47
+ inkTrailStyle() {
48
+ return {
49
+ color: this.startPoint.color,
50
+ width: this.roundDistance(this.averageWidth),
48
51
  };
49
52
  }
50
53
  previewCurrentPath() {
@@ -1,6 +1,6 @@
1
1
  import AbstractRenderer from '../../rendering/renderers/AbstractRenderer';
2
2
  import RenderablePathSpec from '../../rendering/RenderablePathSpec';
3
- import { Rect2 } from '@js-draw/math';
3
+ import { Rect2, Color4 } from '@js-draw/math';
4
4
  import Stroke from '../Stroke';
5
5
  import Viewport from '../../Viewport';
6
6
  import { StrokeDataPoint } from '../../types';
@@ -27,6 +27,10 @@ export default class PolylineBuilder implements ComponentBuilder {
27
27
  constructor(startPoint: StrokeDataPoint, minFitAllowed: number, viewport: Viewport);
28
28
  getBBox(): Rect2;
29
29
  protected getRenderingStyle(): RenderingStyle;
30
+ inkTrailStyle(): {
31
+ color: Color4;
32
+ width: number;
33
+ };
30
34
  protected previewCurrentPath(): RenderablePathSpec;
31
35
  protected previewFullPath(): RenderablePathSpec[];
32
36
  preview(renderer: AbstractRenderer): void;
@@ -48,10 +48,13 @@ class PolylineBuilder {
48
48
  getRenderingStyle() {
49
49
  return {
50
50
  fill: math_1.Color4.transparent,
51
- stroke: {
52
- color: this.startPoint.color,
53
- width: this.roundDistance(this.averageWidth),
54
- },
51
+ stroke: this.inkTrailStyle(),
52
+ };
53
+ }
54
+ inkTrailStyle() {
55
+ return {
56
+ color: this.startPoint.color,
57
+ width: this.roundDistance(this.averageWidth),
55
58
  };
56
59
  }
57
60
  previewCurrentPath() {
@@ -30,6 +30,7 @@ export default class PressureSensitiveFreehandLineBuilder implements ComponentBu
30
30
  build(): Stroke;
31
31
  private roundPoint;
32
32
  private shouldStartNewSegment;
33
+ private getCurrentRadius;
33
34
  private addCurve;
34
35
  private segmentToPath;
35
36
  addPoint(newPoint: StrokeDataPoint): void;
@@ -190,6 +190,9 @@ class PressureSensitiveFreehandLineBuilder {
190
190
  }
191
191
  return false;
192
192
  }
193
+ getCurrentRadius() {
194
+ return Viewport_1.default.roundPoint(this.startPoint.width / 2.2, Math.min(this.minFitAllowed, this.startPoint.width / 4));
195
+ }
193
196
  addCurve(curve) {
194
197
  // Case where no points have been added
195
198
  if (!curve) {
@@ -197,35 +200,35 @@ class PressureSensitiveFreehandLineBuilder {
197
200
  if (!this.isFirstSegment) {
198
201
  return;
199
202
  }
200
- const width = Viewport_1.default.roundPoint(this.startPoint.width / 2.2, Math.min(this.minFitAllowed, this.startPoint.width / 4));
203
+ const radius = this.getCurrentRadius();
201
204
  const center = this.roundPoint(this.startPoint.pos);
202
205
  // Start on the right, cycle clockwise:
203
206
  // |
204
207
  // ----- ←
205
208
  // |
206
- const startPoint = this.startPoint.pos.plus(math_1.Vec2.of(width, 0));
209
+ const startPoint = this.startPoint.pos.plus(math_1.Vec2.of(radius, 0));
207
210
  // Draw a circle-ish shape around the start point
208
211
  this.lowerSegments.push({
209
212
  kind: math_1.PathCommandType.QuadraticBezierTo,
210
- controlPoint: center.plus(math_1.Vec2.of(width, width)),
213
+ controlPoint: center.plus(math_1.Vec2.of(radius, radius)),
211
214
  // Bottom of the circle
212
215
  // |
213
216
  // -----
214
217
  // |
215
218
  // ↑
216
- endPoint: center.plus(math_1.Vec2.of(0, width)),
219
+ endPoint: center.plus(math_1.Vec2.of(0, radius)),
217
220
  }, {
218
221
  kind: math_1.PathCommandType.QuadraticBezierTo,
219
- controlPoint: center.plus(math_1.Vec2.of(-width, width)),
220
- endPoint: center.plus(math_1.Vec2.of(-width, 0)),
222
+ controlPoint: center.plus(math_1.Vec2.of(-radius, radius)),
223
+ endPoint: center.plus(math_1.Vec2.of(-radius, 0)),
221
224
  }, {
222
225
  kind: math_1.PathCommandType.QuadraticBezierTo,
223
- controlPoint: center.plus(math_1.Vec2.of(-width, -width)),
224
- endPoint: center.plus(math_1.Vec2.of(0, -width)),
226
+ controlPoint: center.plus(math_1.Vec2.of(-radius, -radius)),
227
+ endPoint: center.plus(math_1.Vec2.of(0, -radius)),
225
228
  }, {
226
229
  kind: math_1.PathCommandType.QuadraticBezierTo,
227
- controlPoint: center.plus(math_1.Vec2.of(width, -width)),
228
- endPoint: center.plus(math_1.Vec2.of(width, 0)),
230
+ controlPoint: center.plus(math_1.Vec2.of(radius, -radius)),
231
+ endPoint: center.plus(math_1.Vec2.of(radius, 0)),
229
232
  });
230
233
  const connector = {
231
234
  kind: math_1.PathCommandType.LineTo,
@@ -21,6 +21,9 @@ class ShapeFitBuilder {
21
21
  this.viewport = viewport;
22
22
  this.builder = sourceFactory(startPoint, viewport);
23
23
  this.points = [startPoint];
24
+ if (this.builder.inkTrailStyle) {
25
+ this.inkTrailStyle = this.builder.inkTrailStyle.bind(this.builder);
26
+ }
24
27
  }
25
28
  getBBox() {
26
29
  return this.builder.getBBox();
@@ -13,6 +13,9 @@ class SnapToGridAutocompleteBuilder {
13
13
  this.viewport = viewport;
14
14
  this.builder = sourceFactory(startPoint, viewport);
15
15
  this.points = [startPoint];
16
+ if (this.builder.inkTrailStyle) {
17
+ this.inkTrailStyle = this.builder.inkTrailStyle.bind(this.builder);
18
+ }
16
19
  }
17
20
  getBBox() {
18
21
  return this.builder.getBBox();
@@ -3,10 +3,16 @@ import AbstractRenderer from '../../rendering/renderers/AbstractRenderer';
3
3
  import { StrokeDataPoint } from '../../types';
4
4
  import Viewport from '../../Viewport';
5
5
  import AbstractComponent from '../AbstractComponent';
6
+ import { StrokeStyle } from '../../rendering/RenderingStyle';
6
7
  export interface ComponentBuilder {
7
8
  getBBox(): Rect2;
8
9
  build(): AbstractComponent;
9
10
  preview(renderer: AbstractRenderer): void;
11
+ /**
12
+ * (Optional) If provided, allows js-draw to efficiently render
13
+ * an ink trail with the given style on some devices.
14
+ */
15
+ inkTrailStyle?: () => StrokeStyle;
10
16
  /**
11
17
  * Called when the pen is stationary (or the user otherwise
12
18
  * activates autocomplete). This might attempt to fit the user's
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const createButton_1 = __importDefault(require("../util/dom/createButton"));
6
7
  const waitForTimeout_1 = __importDefault(require("../util/waitForTimeout"));
7
8
  const makeAboutDialog = (editor, options) => {
8
9
  const overlay = document.createElement('div');
@@ -14,9 +15,10 @@ const makeAboutDialog = (editor, options) => {
14
15
  const heading = document.createElement('h1');
15
16
  heading.textContent = options.title;
16
17
  heading.setAttribute('autofocus', 'true');
17
- const closeButton = document.createElement('button');
18
- closeButton.innerText = editor.localization.closeDialog;
19
- closeButton.classList.add('close');
18
+ const closeButton = (0, createButton_1.default)({
19
+ text: editor.localization.closeDialog,
20
+ classList: ['close'],
21
+ });
20
22
  const scrollRegion = document.createElement('div');
21
23
  scrollRegion.classList.add('scroll');
22
24
  // Allow scrolling in the scrollable container -- don't forward wheel events.
@@ -8,10 +8,12 @@ const localization_1 = require("../localization");
8
8
  const de_1 = __importDefault(require("./de"));
9
9
  const en_1 = __importDefault(require("./en"));
10
10
  const es_1 = __importDefault(require("./es"));
11
+ const sk_1 = __importDefault(require("./sk"));
11
12
  exports.allLocales = {
12
13
  de: de_1.default,
13
14
  en: en_1.default,
14
15
  es: es_1.default,
16
+ sk: sk_1.default,
15
17
  };
16
18
  // [locale]: A string in the format languageCode_Region or just languageCode. For example, en_US.
17
19
  const languageFromLocale = (locale) => {
@@ -0,0 +1,3 @@
1
+ import { EditorLocalization } from '../localization';
2
+ declare const localization: EditorLocalization;
3
+ export default localization;
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const localization_1 = require("../localization");
4
+ // Slovak localization
5
+ const localization = {
6
+ ...localization_1.defaultEditorLocalization,
7
+ help: 'Pomoc',
8
+ helpHidden: 'Skrytá pomoc',
9
+ next: 'Ďalšie',
10
+ previous: 'Prechádzajúce',
11
+ close: 'Zavrieť',
12
+ helpScreenNavigationHelp: 'Kliknutím na ovládací prvok získate viac informácií.',
13
+ helpControlsAccessibilityLabel: 'Ovládacie prvky: Aktivujte ovládací prvok, ktorý zobrazí pomoc.',
14
+ pen: 'Pero',
15
+ eraser: 'Guma',
16
+ select: 'Vybrať',
17
+ handTool: 'Posun',
18
+ zoom: 'Priblížiť',
19
+ image: 'Obrázok',
20
+ reformatSelection: 'Výber formátu',
21
+ inputAltText: 'Alternatívny text',
22
+ decreaseImageSize: 'Zmenšiť veľkosť',
23
+ resetImage: 'Obnoviť',
24
+ chooseFile: 'Vybrať súbor',
25
+ dragAndDropHereOrBrowse: 'Presuňte sem alebo {{prehľadávať}}',
26
+ submit: 'Odoslať',
27
+ addAll: 'Pridať všetko',
28
+ cancel: 'Zrušiť',
29
+ resetView: 'Obnoviť zobrazenie',
30
+ thicknessLabel: 'Hrúbka',
31
+ colorLabel: 'Farba',
32
+ fontLabel: 'Písmo',
33
+ textSize: 'Veľkosť',
34
+ resizeImageToSelection: 'Zmena veľkosti obrázka podľa výberu',
35
+ deleteSelection: 'Vymazať výber',
36
+ duplicateSelection: 'Duplikovať výber',
37
+ exit: 'Ukončiť',
38
+ save: 'Uložiť',
39
+ undo: 'Späť',
40
+ redo: 'Opakovať',
41
+ fullStrokeEraser: 'Guma s plným ťahom',
42
+ selectPenType: 'Typ pera',
43
+ selectShape: 'Tvar',
44
+ pickColorFromScreen: 'Vybrať farbu z obrazovky',
45
+ clickToPickColorAnnouncement: 'Kliknutím na obrazovku vyberte farbu',
46
+ colorSelectionCanceledAnnouncement: 'Výber farby zrušený',
47
+ selectionTool__lassoSelect: 'Výber voľného tvaru',
48
+ selectionTool__lassoSelect__help: 'Ak je táto funkcia zapnutá, ťahanie vytvorí voľný tvar (laso) výberu.',
49
+ selectionToolKeyboardShortcuts: 'Nástroj na výber: Pomocou klávesov so šípkami môžete presunúť vybrané položky, malými/veľkými písmenami „i“ a „o“ môžete zmeniť veľkosť.',
50
+ documentProperties: 'Strana',
51
+ backgroundColor: 'Farba pozadia',
52
+ imageWidthOption: 'Šírka',
53
+ imageHeightOption: 'Výška',
54
+ useGridOption: 'Mriežka',
55
+ enableAutoresizeOption: 'Automatická zmena veľkosti',
56
+ toggleOverflow: 'Viac',
57
+ about: 'O aplikácii',
58
+ inputStabilization: 'Stabilizácia',
59
+ strokeAutocorrect: 'Automatická oprava',
60
+ pressureSensitivity: 'Tlak',
61
+ touchPanning: 'Posúvanie dotykom',
62
+ roundedTipPen: 'Okrúhle',
63
+ roundedTipPen2: 'Viacčiarové',
64
+ flatTipPen: 'Ploché',
65
+ arrowPen: 'Šípka',
66
+ linePen: 'Čiara',
67
+ outlinedRectanglePen: 'Obrys obdĺžnika',
68
+ filledRectanglePen: 'Plný obdĺžnik',
69
+ outlinedCirclePen: 'Kružnica',
70
+ lockRotation: 'Zamknúť otáčanie',
71
+ paste: 'Vložiť',
72
+ errorImageHasZeroSize: 'Chyba: Obrázok má nulovú veľkosť',
73
+ describeTheImage: 'Popis obrázku',
74
+ fileInput__loading: 'Načítavanie...',
75
+ fileInput__andNMoreFiles: (n) => `(...${n} ďalších)`,
76
+ penDropdown__baseHelpText: 'Tento nástroj kreslí tvary alebo voľné čiary.',
77
+ penDropdown__colorHelpText: 'Zmení farbu pera',
78
+ penDropdown__thicknessHelpText: 'Mení hrúbku ťahov nakreslených perom.',
79
+ penDropdown__penTypeHelpText: 'Zmení štýl pera.\n\nMôžete si vybrať buď štýl „pero“, alebo „tvar“. Výberom štýlu „pero“ sa kreslia voľné čiary. Výberom štýlu „tvar“ sa kreslia tvary.',
80
+ penDropdown__autocorrectHelpText: 'Prevedie približné voľné čiary a obdĺžniky na dokonalé.\n\nPero musí byť držané nehybne na konci ťahu, aby sa spustila oprava.',
81
+ penDropdown__stabilizationHelpText: 'Kreslí hladšie ťahy.\n\nPridáva tiež krátke oneskorenie medzi pohybom myši/stylusu a ťahom.',
82
+ penDropdown__pressureSensitivityHelpText: 'Pri použití kompatibilného zariadenia, napríklad stylusu, mení hrúbku ťahov podľa sily stlačenia.',
83
+ handDropdown__baseHelpText: 'Tento nástroj je zodpovedný za posúvanie, otáčanie a zväčšovanie editora.',
84
+ handDropdown__zoomInHelpText: 'Priblížiť.',
85
+ handDropdown__zoomOutHelpText: 'Oddialiť.',
86
+ handDropdown__resetViewHelpText: 'Obnoví úroveň priblíženia na 100 % a vynuluje posúvanie.',
87
+ handDropdown__zoomDisplayHelpText: 'Zobrazí aktuálnu úroveň priblíženia. 100 % zobrazuje obrázok v jeho skutočnej veľkosti.',
88
+ handDropdown__touchPanningHelpText: 'Keď je táto funkcia zapnutá, gestá dotykovej obrazovky posúvajú obrázok, a nevyberajú ho ani nekreslia.',
89
+ handDropdown__lockRotationHelpText: 'Ak je táto funkcia zapnutá, zabraňuje dotykovým gestám otáčať obrazovku.',
90
+ eraserDropdown__baseHelpText: 'Tento nástroj odstraňuje ťahy, obrázky a text pod kurzorom.',
91
+ eraserDropdown__thicknessHelpText: 'Zmení veľkosť gumy.',
92
+ eraserDropdown__fullStrokeEraserHelpText: '`V režime plného ťahu sa vymažú celé tvary.\n\nKeď nie je v režime plného ťahu, tvary sa môžu byť čiastočne vymazané.`',
93
+ selectionDropdown__baseHelpText: 'Vyberá obsah a manipuluje s výberom',
94
+ selectionDropdown__resizeToHelpText: 'Oreže kresbu na veľkosť toho, čo je aktuálne vybrané.\n\nAk je zapnutá automatická zmena veľkosti, bude táto funkcia vypnutá.',
95
+ selectionDropdown__deleteHelpText: 'Vymaže vybrané položky.',
96
+ selectionDropdown__duplicateHelpText: 'Vytvorí kópiu vybraných položiek.',
97
+ selectionDropdown__changeColorHelpText: 'Zmení farbu vybraných položiek.',
98
+ pageDropdown__baseHelpText: 'Ovláda farbu, vzor a veľkosť pozadia kresliaceho plátna.',
99
+ pageDropdown__backgroundColorHelpText: 'Zmení farbu pozadia kresliaceho plátna.',
100
+ pageDropdown__gridCheckboxHelpText: 'Zapne/vypne vzor mriežky na pozadí.',
101
+ pageDropdown__autoresizeCheckboxHelpText: 'Pokiaľ je označené, stránka sa zväčší tak, aby sa prispôsobila kresbe.\n\nKeď nie je označené, stránka je viditeľná a jej veľkosť sa dá nastaviť ručne.',
102
+ pageDropdown__aboutButtonHelpText: 'Zobrazí verziu, ladenie a ďalšie informácie.',
103
+ colorPickerPipetteHelpText: 'Vyberie farbu z obrazovky.',
104
+ colorPickerToggleHelpText: 'Otvorí/zatvorí výber farieb.',
105
+ closeSidebar: (toolName) => `Zatvoriť bočný panel pre ${toolName}`,
106
+ dropdownShown: (toolName) => `Ponuka pre ${toolName} zobrazená`,
107
+ dropdownHidden: (toolName) => `Ponuka pre ${toolName} skrytá`,
108
+ zoomLevel: (zoomPercent) => `Priblíženie: ${zoomPercent}%`,
109
+ colorChangedAnnouncement: (color) => `Farba zmenená na ${color}`,
110
+ imageSize: (size, units) => `Veľkosť obrázka: ${size} ${units}`,
111
+ imageLoadError: (message) => `Chyba pri načítavaní obrázka: ${message}`,
112
+ penTool: (penId) => `Pero ${penId}`,
113
+ selectionTool: 'Výber',
114
+ selectAllTool: 'Skratka pre výber všetkých',
115
+ eraserTool: 'Guma',
116
+ touchPanTool: 'Posúvanie dotykom',
117
+ twoFingerPanZoomTool: 'Posun a priblíženie',
118
+ undoRedoTool: 'Späť/Opakovať',
119
+ rightClickDragPanTool: 'Ťahanie pravým tlačidlom myši',
120
+ pipetteTool: 'Vybrať farbu z obrazovky',
121
+ keyboardPanZoom: 'Klávesové skratky pre posúvanie/priblíženie',
122
+ selectionMenu__show: 'Zobraziť ponuku výberu',
123
+ selectionMenu__copyToClipboard: 'Kopírovať do schránky',
124
+ selectionMenu__duplicate: 'Duplikovať',
125
+ selectionMenu__delete: 'Vymazať',
126
+ selectionMenu__paste: 'Vložiť',
127
+ copyPasteError__heading: 'Kopírovať/vložiť',
128
+ copyPasteError__description: 'Niečo sa pokazilo - tento nástroj nemusí mať prístup k schránke.',
129
+ copyPasteError__errorDetails: 'Zobraziť chybu',
130
+ copyPasteError__pasteRetry: 'Ak chcete opakovať pokus, vložte ho do nižšie uvedeného vstupného poľa:',
131
+ copyPasteError__copyRetry: 'Ak chcete opakovať pokus, skopírujte text do vstupného poľa nižšie:',
132
+ copyPasteError__copyMe: 'Skopíruj ma!',
133
+ autocorrectedTo: (strokeDescription) => `Automaticky opravené na ${strokeDescription}`,
134
+ autocorrectionCanceled: 'Automatická oprava zrušená',
135
+ enterTextToInsert: 'Text, ktorý sa má vložiť',
136
+ changeTool: 'Zmeniť nástroj',
137
+ findLabel: 'Hľadať',
138
+ toNextMatch: 'Ďalšie',
139
+ closeDialog: 'Zavrieť',
140
+ findDialogShown: 'Dialógové okno vyhľadávania zobrazené',
141
+ findDialogHidden: 'Dialógové okno vyhľadávania je skryté',
142
+ copied: (count) => `Skopírovaných ${count} položiek`,
143
+ pasted: (count) => `Vložených ${count} položiek`,
144
+ toolEnabledAnnouncement: (toolName) => `${toolName} zapnuté`,
145
+ toolDisabledAnnouncement: (toolName) => `${toolName} vypnuté`,
146
+ resizeOutputCommand: (newSize) => `Zmenená veľkosť obrázka na ${newSize.w}x${newSize.h}`,
147
+ enabledAutoresizeOutputCommand: 'Automatická zmena veľkosti výstupu je povolená',
148
+ disabledAutoresizeOutputCommand: 'Automatická zmena veľkosti výstupu je zakázaná',
149
+ addComponentAction: (componentDescription) => `Pridané ${componentDescription}`,
150
+ eraseAction: (componentDescription, numElems) => `Vymazané ${numElems} ${componentDescription}`,
151
+ duplicateAction: (componentDescription, numElems) => `Duplikované ${numElems} ${componentDescription}`,
152
+ elements: 'Prvky',
153
+ erasedNoElements: 'Nič sa nevymazalo.',
154
+ duplicatedNoElements: 'Nič sa neduplikovalo.',
155
+ rotatedBy: (degrees) => `Otočené o ${Math.abs(degrees)} stupňov ${degrees < 0 ? 'clockwise' : 'counter-clockwise'}`,
156
+ movedLeft: 'Presunuté doľava',
157
+ movedUp: 'Presunuté hore',
158
+ movedDown: 'Presunuté dole',
159
+ movedRight: 'Presunuté doprava',
160
+ zoomedOut: 'Oddialené',
161
+ zoomedIn: 'Priblížené',
162
+ andNMoreCommands: (count) => `A ${count} ďalších príkazov.`,
163
+ unlabeledImageNode: 'Obrázok bez označenia',
164
+ stroke: 'Ťah',
165
+ svgObject: 'Objekt SVG',
166
+ emptyBackground: 'Prázdne pozadie',
167
+ gridBackground: 'Pozadie s mriežkou',
168
+ filledBackgroundWithColor: (color) => `Vyplnené pozadie (${color})`,
169
+ text: (text) => `Textový objekt: ${text}`,
170
+ imageNode: (label) => `Obrázok: ${label}`,
171
+ pathNodeCount: (count) => `Viditeľných je ${count} objektov ciest.`,
172
+ textNodeCount: (count) => `Viditeľných je ${count} textových uzlov.`,
173
+ imageNodeCount: (nodeCount) => `Viditeľných je ${nodeCount} obrazových uzlov.`,
174
+ rerenderAsText: 'Opätovne vykresliť ako text.',
175
+ accessibilityInputInstructions: 'Pomocou tlačidla „t“ prečítate obsah zobrazovacieho okna ako text. Pomocou klávesov so šípkami pohybujte zobrazovacím oknom, kliknutím a ťahaním kreslite ťahy. Stlačením tlačidla „w“ priblížite a stlačením tlačidla „s“ oddialite pohľad.',
176
+ loading: (percentage) => `Načítava sa ${percentage}%...`,
177
+ imageEditor: 'Editor obrázkov',
178
+ doneLoading: 'Načítanie dokončené',
179
+ softwareLibraries: 'Knižnice',
180
+ developerInformation: 'Informácie pre vývojárov',
181
+ };
182
+ exports.default = localization;
@@ -58,6 +58,8 @@ export default class Display {
58
58
  setDevicePixelRatio(dpr: number): Promise<void> | undefined;
59
59
  /** @internal */
60
60
  getDevicePixelRatio(): number;
61
+ /** @internal -- used for internal performance improvements. */
62
+ onPointerEvent(event: PointerEvent): void;
61
63
  /**
62
64
  * Rerenders the text-based display.
63
65
  * The text-based display is intended for screen readers and can be navigated to by pressing `tab`.
@@ -10,6 +10,8 @@ const DummyRenderer_1 = __importDefault(require("./renderers/DummyRenderer"));
10
10
  const math_1 = require("@js-draw/math");
11
11
  const RenderingCache_1 = __importDefault(require("./caching/RenderingCache"));
12
12
  const TextOnlyRenderer_1 = __importDefault(require("./renderers/TextOnlyRenderer"));
13
+ const AcceleratedInkingCanvasRenderer_1 = __importDefault(require("./renderers/AcceleratedInkingCanvasRenderer"));
14
+ const createButton_1 = __importDefault(require("../util/dom/createButton"));
13
15
  var RenderingMode;
14
16
  (function (RenderingMode) {
15
17
  RenderingMode[RenderingMode["DummyRenderer"] = 0] = "DummyRenderer";
@@ -114,7 +116,7 @@ class Display {
114
116
  const dryInkCtx = dryInkCanvas.getContext('2d');
115
117
  const wetInkCtx = wetInkCanvas.getContext('2d');
116
118
  this.dryInkRenderer = new CanvasRenderer_1.default(dryInkCtx, this.editor.viewport);
117
- this.wetInkRenderer = new CanvasRenderer_1.default(wetInkCtx, this.editor.viewport);
119
+ this.wetInkRenderer = new AcceleratedInkingCanvasRenderer_1.default(wetInkCtx, this.editor.viewport);
118
120
  dryInkCanvas.className = 'dryInkCanvas';
119
121
  wetInkCanvas.className = 'wetInkCanvas';
120
122
  if (this.parent) {
@@ -182,9 +184,10 @@ class Display {
182
184
  initializeTextRendering() {
183
185
  const textRendererOutputContainer = document.createElement('div');
184
186
  textRendererOutputContainer.classList.add('textRendererOutputContainer');
185
- const rerenderButton = document.createElement('button');
186
- rerenderButton.classList.add('rerenderButton');
187
- rerenderButton.innerText = this.editor.localization.rerenderAsText;
187
+ const rerenderButton = (0, createButton_1.default)({
188
+ classList: ['rerenderButton'],
189
+ text: this.editor.localization.rerenderAsText,
190
+ });
188
191
  this.textRerenderOutput = document.createElement('div');
189
192
  this.textRerenderOutput.setAttribute('aria-live', 'polite');
190
193
  rerenderButton.onclick = () => {
@@ -214,6 +217,12 @@ class Display {
214
217
  getDevicePixelRatio() {
215
218
  return this.devicePixelRatio;
216
219
  }
220
+ /** @internal -- used for internal performance improvements. */
221
+ onPointerEvent(event) {
222
+ if (this.wetInkRenderer instanceof AcceleratedInkingCanvasRenderer_1.default) {
223
+ this.wetInkRenderer.onEvent(event);
224
+ }
225
+ }
217
226
  /**
218
227
  * Rerenders the text-based display.
219
228
  * The text-based display is intended for screen readers and can be navigated to by pressing `tab`.
@@ -1,7 +1,7 @@
1
1
  import { Color4, Mat33, Point2, Vec2, Rect2 } from '@js-draw/math';
2
2
  import { LoadSaveDataTable } from '../../components/AbstractComponent';
3
3
  import Viewport from '../../Viewport';
4
- import RenderingStyle from '../RenderingStyle';
4
+ import RenderingStyle, { StrokeStyle } from '../RenderingStyle';
5
5
  import TextRenderingStyle from '../TextRenderingStyle';
6
6
  import RenderablePathSpec from '../RenderablePathSpec';
7
7
  export interface RenderableImage {
@@ -10,6 +10,21 @@ export interface RenderableImage {
10
10
  base64Url: string;
11
11
  label?: string;
12
12
  }
13
+ /**
14
+ * An interface that allows renderers to provide accelerated inking.
15
+ *
16
+ * This API is intended to reduce latency by rendering a draft preview of the
17
+ * last, trailing part of a stroke.
18
+ *
19
+ * This may be implemented with, for example, [the web `Ink` API](https://developer.mozilla.org/en-US/docs/Web/API/Ink),
20
+ * or do nothing at all, depending on the renderer and platform.
21
+ */
22
+ export interface DraftInkPresenter {
23
+ /** Enables the ink presenter, if available on the current platform. */
24
+ setEnabled(pointerId: number, enabled: boolean): void;
25
+ /** Sets the color and width of the stroke trail. */
26
+ updateStyle(style: StrokeStyle): void;
27
+ }
13
28
  /**
14
29
  * Abstract base class for renderers.
15
30
  *
@@ -38,6 +53,10 @@ export default abstract class AbstractRenderer {
38
53
  abstract drawImage(image: RenderableImage): void;
39
54
  abstract isTooSmallToRender(rect: Rect2): boolean;
40
55
  setDraftMode(_draftMode: boolean): void;
56
+ /**
57
+ * Returns an API that can be used to accelerate inking.
58
+ */
59
+ getDraftInkPresenter(): DraftInkPresenter;
41
60
  protected objectLevel: number;
42
61
  private currentPaths;
43
62
  private flushPath;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const math_1 = require("@js-draw/math");
4
4
  const RenderingStyle_1 = require("../RenderingStyle");
5
5
  const RenderablePathSpec_1 = require("../RenderablePathSpec");
6
+ const defaultDraftInkPresenter = { setEnabled: () => { }, updateStyle: () => { } };
6
7
  /**
7
8
  * Abstract base class for renderers.
8
9
  *
@@ -26,6 +27,12 @@ class AbstractRenderer {
26
27
  return this.viewport;
27
28
  }
28
29
  setDraftMode(_draftMode) { }
30
+ /**
31
+ * Returns an API that can be used to accelerate inking.
32
+ */
33
+ getDraftInkPresenter() {
34
+ return defaultDraftInkPresenter;
35
+ }
29
36
  flushPath() {
30
37
  if (!this.currentPaths) {
31
38
  return;