js-draw 0.9.1 → 0.9.3

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 (90) hide show
  1. package/.github/ISSUE_TEMPLATE/translation.yml +742 -0
  2. package/CHANGELOG.md +7 -0
  3. package/build_tools/buildTranslationTemplate.ts +119 -0
  4. package/dist/build_tools/buildTranslationTemplate.d.ts +1 -0
  5. package/dist/build_tools/buildTranslationTemplate.js +93 -0
  6. package/dist/bundle.js +1 -1
  7. package/dist/src/Editor.d.ts +2 -3
  8. package/dist/src/Editor.js +7 -15
  9. package/dist/src/EditorImage.d.ts +1 -1
  10. package/dist/src/EventDispatcher.d.ts +1 -1
  11. package/dist/src/SVGLoader.d.ts +2 -2
  12. package/dist/src/SVGLoader.js +1 -1
  13. package/dist/src/UndoRedoHistory.d.ts +2 -2
  14. package/dist/src/Viewport.d.ts +1 -1
  15. package/dist/src/Viewport.js +1 -3
  16. package/dist/src/commands/Command.d.ts +2 -2
  17. package/dist/src/commands/SerializableCommand.d.ts +1 -1
  18. package/dist/src/commands/uniteCommands.js +19 -10
  19. package/dist/src/components/AbstractComponent.d.ts +3 -3
  20. package/dist/src/components/SVGGlobalAttributesObject.d.ts +1 -1
  21. package/dist/src/components/{Text.d.ts → TextComponent.d.ts} +0 -0
  22. package/dist/src/components/{Text.js → TextComponent.js} +0 -0
  23. package/dist/src/components/builders/FreehandLineBuilder.d.ts +2 -0
  24. package/dist/src/components/builders/FreehandLineBuilder.js +10 -2
  25. package/dist/src/components/builders/types.d.ts +1 -1
  26. package/dist/src/components/lib.d.ts +1 -1
  27. package/dist/src/components/lib.js +1 -1
  28. package/dist/src/components/util/StrokeSmoother.d.ts +1 -1
  29. package/dist/src/math/Mat33.d.ts +1 -1
  30. package/dist/src/math/Path.d.ts +1 -1
  31. package/dist/src/math/Vec2.d.ts +2 -2
  32. package/dist/src/rendering/caching/testUtils.d.ts +1 -1
  33. package/dist/src/rendering/caching/types.d.ts +2 -2
  34. package/dist/src/rendering/renderers/AbstractRenderer.d.ts +1 -1
  35. package/dist/src/rendering/renderers/CanvasRenderer.d.ts +1 -1
  36. package/dist/src/rendering/renderers/CanvasRenderer.js +1 -1
  37. package/dist/src/rendering/renderers/DummyRenderer.d.ts +1 -1
  38. package/dist/src/rendering/renderers/SVGRenderer.d.ts +1 -1
  39. package/dist/src/rendering/renderers/SVGRenderer.js +1 -1
  40. package/dist/src/rendering/renderers/TextOnlyRenderer.d.ts +1 -1
  41. package/dist/src/rendering/renderers/TextOnlyRenderer.js +2 -2
  42. package/dist/src/toolbar/IconProvider.d.ts +2 -2
  43. package/dist/src/toolbar/localization.d.ts +1 -0
  44. package/dist/src/toolbar/localization.js +1 -0
  45. package/dist/src/toolbar/makeColorInput.d.ts +2 -2
  46. package/dist/src/toolbar/widgets/BaseWidget.d.ts +1 -1
  47. package/dist/src/toolbar/widgets/TextToolWidget.js +23 -2
  48. package/dist/src/tools/BaseTool.js +4 -4
  49. package/dist/src/tools/FindTool.d.ts +21 -0
  50. package/dist/src/tools/FindTool.js +113 -0
  51. package/dist/src/tools/PipetteTool.d.ts +1 -1
  52. package/dist/src/tools/SelectionTool/Selection.js +42 -11
  53. package/dist/src/tools/SelectionTool/SelectionHandle.d.ts +3 -3
  54. package/dist/src/tools/SelectionTool/SelectionTool.js +1 -1
  55. package/dist/src/tools/TextTool.d.ts +1 -1
  56. package/dist/src/tools/TextTool.js +9 -3
  57. package/dist/src/tools/ToolController.js +2 -0
  58. package/dist/src/tools/ToolbarShortcutHandler.d.ts +1 -1
  59. package/dist/src/tools/localization.d.ts +6 -0
  60. package/dist/src/tools/localization.js +6 -0
  61. package/dist/src/types.d.ts +8 -8
  62. package/package.json +17 -16
  63. package/src/Editor.css +1 -0
  64. package/src/Editor.toSVG.test.ts +1 -1
  65. package/src/Editor.ts +12 -22
  66. package/src/SVGLoader.ts +1 -1
  67. package/src/Viewport.ts +1 -3
  68. package/src/commands/Command.ts +2 -2
  69. package/src/commands/uniteCommands.ts +21 -10
  70. package/src/components/{Text.test.ts → TextComponent.test.ts} +1 -1
  71. package/src/components/{Text.ts → TextComponent.ts} +0 -0
  72. package/src/components/builders/FreehandLineBuilder.ts +12 -2
  73. package/src/components/lib.ts +1 -1
  74. package/src/rendering/renderers/AbstractRenderer.ts +1 -1
  75. package/src/rendering/renderers/CanvasRenderer.ts +1 -1
  76. package/src/rendering/renderers/DummyRenderer.ts +1 -1
  77. package/src/rendering/renderers/SVGRenderer.ts +2 -2
  78. package/src/rendering/renderers/TextOnlyRenderer.ts +3 -3
  79. package/src/toolbar/IconProvider.ts +1 -1
  80. package/src/toolbar/localization.ts +2 -0
  81. package/src/toolbar/widgets/TextToolWidget.ts +29 -1
  82. package/src/tools/FindTool.css +7 -0
  83. package/src/tools/FindTool.ts +151 -0
  84. package/src/tools/PasteHandler.ts +1 -1
  85. package/src/tools/SelectionTool/Selection.ts +51 -10
  86. package/src/tools/SelectionTool/SelectionTool.ts +1 -1
  87. package/src/tools/TextTool.ts +11 -3
  88. package/src/tools/ToolController.ts +2 -0
  89. package/src/tools/localization.ts +14 -0
  90. package/.github/ISSUE_TEMPLATE/translation.md +0 -100
@@ -29,8 +29,8 @@ import Pointer from './Pointer';
29
29
  import Rect2 from './math/Rect2';
30
30
  import { EditorLocalization } from './localization';
31
31
  import IconProvider from './toolbar/IconProvider';
32
- declare type HTMLPointerEventType = 'pointerdown' | 'pointermove' | 'pointerup' | 'pointercancel';
33
- declare type HTMLPointerEventFilter = (eventName: HTMLPointerEventType, event: PointerEvent) => boolean;
32
+ type HTMLPointerEventType = 'pointerdown' | 'pointermove' | 'pointerup' | 'pointercancel';
33
+ type HTMLPointerEventFilter = (eventName: HTMLPointerEventType, event: PointerEvent) => boolean;
34
34
  export interface EditorSettings {
35
35
  /** Defaults to `RenderingMode.CanvasRenderer` */
36
36
  renderingMode: RenderingMode;
@@ -199,7 +199,6 @@ export declare class Editor {
199
199
  sendPenEvent(eventType: InputEvtType.PointerDownEvt | InputEvtType.PointerMoveEvt | InputEvtType.PointerUpEvt, point: Point2, allPointers?: Pointer[]): void;
200
200
  toDataURL(format?: 'image/png' | 'image/jpeg' | 'image/webp'): string;
201
201
  toSVG(): SVGElement;
202
- private renderAllWithTransform;
203
202
  loadFrom(loader: ImageLoader): Promise<void>;
204
203
  getImportExportRect(): Rect2;
205
204
  setImportExportRect(imageRect: Rect2): Command;
@@ -639,8 +639,7 @@ export class Editor {
639
639
  canvas.height = resolution.y;
640
640
  const ctx = canvas.getContext('2d');
641
641
  const renderer = new CanvasRenderer(ctx, this.importExportViewport);
642
- // Render everything with no transform (0,0) should be (0,0) in the output image
643
- this.renderAllWithTransform(renderer, this.importExportViewport, Mat33.identity);
642
+ this.image.renderAll(renderer);
644
643
  const dataURL = canvas.toDataURL(format);
645
644
  return dataURL;
646
645
  }
@@ -649,7 +648,12 @@ export class Editor {
649
648
  const svgNameSpace = 'http://www.w3.org/2000/svg';
650
649
  const result = document.createElementNS(svgNameSpace, 'svg');
651
650
  const renderer = new SVGRenderer(result, importExportViewport);
652
- this.renderAllWithTransform(renderer, importExportViewport);
651
+ const origTransform = this.importExportViewport.canvasToScreenTransform;
652
+ // Render with (0,0) at (0,0) — we'll handle translation with
653
+ // the viewBox property.
654
+ importExportViewport.resetTransform(Mat33.identity);
655
+ this.image.renderAll(renderer);
656
+ importExportViewport.resetTransform(origTransform);
653
657
  // Just show the main region
654
658
  const rect = importExportViewport.visibleRect;
655
659
  result.setAttribute('viewBox', [rect.x, rect.y, rect.w, rect.h].map(part => toRoundedString(part)).join(' '));
@@ -662,18 +666,6 @@ export class Editor {
662
666
  result.setAttribute('xmlns', svgNameSpace);
663
667
  return result;
664
668
  }
665
- // Renders everything in this' image to `renderer`, but first transforming the given `viewport`
666
- // such that its transform is `transform`. The given `viewport`'s transform is restored before this method
667
- // returns.
668
- //
669
- // For example, rendering with `transform = Mat33.identity` *sets* `viewport`'s transform to `Mat33.identity`,
670
- // renders everything in this' image to `renderer`, then restores `viewport`'s transform to whatever it was before.
671
- renderAllWithTransform(renderer, viewport, transform = Mat33.identity) {
672
- const origTransform = this.importExportViewport.canvasToScreenTransform;
673
- viewport.resetTransform(transform);
674
- this.image.renderAll(renderer);
675
- viewport.resetTransform(origTransform);
676
- }
677
669
  loadFrom(loader) {
678
670
  return __awaiter(this, void 0, void 0, function* () {
679
671
  this.showLoadingWarning(0);
@@ -27,7 +27,7 @@ export default class EditorImage {
27
27
  static addElement(elem: AbstractComponent, applyByFlattening?: boolean): SerializableCommand;
28
28
  private static AddElementCommand;
29
29
  }
30
- declare type TooSmallToRenderCheck = (rect: Rect2) => boolean;
30
+ type TooSmallToRenderCheck = (rect: Rect2) => boolean;
31
31
  /** Part of the Editor's image. @internal */
32
32
  export declare class ImageNode {
33
33
  private parent;
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * @packageDocumentation
17
17
  */
18
- declare type CallbackHandler<EventType> = (data: EventType) => void;
18
+ type CallbackHandler<EventType> = (data: EventType) => void;
19
19
  export default class EventDispatcher<EventKeyType extends string | symbol | number, EventMessageType> {
20
20
  private listeners;
21
21
  constructor();
@@ -3,8 +3,8 @@ import { ComponentAddedListener, ImageLoader, OnDetermineExportRectListener, OnP
3
3
  export declare const defaultSVGViewRect: Rect2;
4
4
  export declare const svgAttributesDataKey = "svgAttrs";
5
5
  export declare const svgStyleAttributesDataKey = "svgStyleAttrs";
6
- export declare type SVGLoaderUnknownAttribute = [string, string];
7
- export declare type SVGLoaderUnknownStyleAttribute = {
6
+ export type SVGLoaderUnknownAttribute = [string, string];
7
+ export type SVGLoaderUnknownStyleAttribute = {
8
8
  key: string;
9
9
  value: string;
10
10
  priority?: string;
@@ -11,7 +11,7 @@ import Color4 from './Color4';
11
11
  import ImageComponent from './components/ImageComponent';
12
12
  import Stroke from './components/Stroke';
13
13
  import SVGGlobalAttributesObject from './components/SVGGlobalAttributesObject';
14
- import TextComponent from './components/Text';
14
+ import TextComponent from './components/TextComponent';
15
15
  import UnknownSVGObject from './components/UnknownSVGObject';
16
16
  import Mat33 from './math/Mat33';
17
17
  import Path from './math/Path';
@@ -1,7 +1,7 @@
1
1
  import Editor from './Editor';
2
2
  import Command from './commands/Command';
3
- declare type AnnounceRedoCallback = (command: Command) => void;
4
- declare type AnnounceUndoCallback = (command: Command) => void;
3
+ type AnnounceRedoCallback = (command: Command) => void;
4
+ type AnnounceUndoCallback = (command: Command) => void;
5
5
  declare class UndoRedoHistory {
6
6
  private readonly editor;
7
7
  private announceRedoCallback;
@@ -4,7 +4,7 @@ import Rect2 from './math/Rect2';
4
4
  import { Point2, Vec2 } from './math/Vec2';
5
5
  import { StrokeDataPoint } from './types';
6
6
  import { EditorNotifier } from './types';
7
- declare type PointDataType<T extends Point2 | StrokeDataPoint | number> = T extends Point2 ? Point2 : number;
7
+ type PointDataType<T extends Point2 | StrokeDataPoint | number> = T extends Point2 ? Point2 : number;
8
8
  export declare abstract class ViewportTransform extends Command {
9
9
  abstract readonly transform: Mat33;
10
10
  }
@@ -128,9 +128,7 @@ export class Viewport {
128
128
  // Ensure that toMakeVisible is at least 1/3rd of the visible region.
129
129
  const muchSmallerThanTarget = toMakeVisible.maxDimension / targetRect.maxDimension < 1 / 3;
130
130
  if ((largerThanTarget && allowZoomOut) || (muchSmallerThanTarget && allowZoomIn)) {
131
- // If larger than the target, ensure that the longest axis is visible.
132
- // If smaller, shrink the visible rectangle as much as possible
133
- const multiplier = (largerThanTarget ? Math.max : Math.min)(toMakeVisible.w / targetRect.w, toMakeVisible.h / targetRect.h);
131
+ const multiplier = Math.max(toMakeVisible.w / targetRect.w, toMakeVisible.h / targetRect.h);
134
132
  const visibleRectTransform = Mat33.scaling2D(multiplier, targetRect.topLeft);
135
133
  const viewportContentTransform = visibleRectTransform.inverse();
136
134
  transform = transform.rightMul(viewportContentTransform);
@@ -1,8 +1,8 @@
1
1
  import Editor from '../Editor';
2
2
  import { EditorLocalization } from '../localization';
3
3
  export declare abstract class Command {
4
- abstract apply(editor: Editor): void;
5
- abstract unapply(editor: Editor): void;
4
+ abstract apply(editor: Editor): Promise<void> | void;
5
+ abstract unapply(editor: Editor): Promise<void> | void;
6
6
  onDrop(_editor: Editor): void;
7
7
  abstract description(editor: Editor, localizationTable: EditorLocalization): string;
8
8
  static union(a: Command, b: Command): Command;
@@ -1,6 +1,6 @@
1
1
  import Editor from '../Editor';
2
2
  import Command from './Command';
3
- export declare type DeserializationCallback = (data: Record<string, any> | any[], editor: Editor) => SerializableCommand;
3
+ export type DeserializationCallback = (data: Record<string, any> | any[], editor: Editor) => SerializableCommand;
4
4
  export default abstract class SerializableCommand extends Command {
5
5
  private commandTypeId;
6
6
  constructor(commandTypeId: string);
@@ -6,24 +6,33 @@ class NonSerializableUnion extends Command {
6
6
  this.commands = commands;
7
7
  this.applyChunkSize = applyChunkSize;
8
8
  }
9
+ static waitForAll(commands) {
10
+ // If any are Promises...
11
+ if (commands.some(command => command && command['then'])) {
12
+ console.log('waiting...');
13
+ // Wait for all commands to finish.
14
+ return Promise.all(commands)
15
+ // Ensure we return a Promise<void> and not a Promise<void[]>
16
+ .then(() => { });
17
+ }
18
+ return;
19
+ }
9
20
  apply(editor) {
10
21
  if (this.applyChunkSize === undefined) {
11
- for (const command of this.commands) {
12
- command.apply(editor);
13
- }
22
+ const results = this.commands.map(cmd => cmd.apply(editor));
23
+ return NonSerializableUnion.waitForAll(results);
14
24
  }
15
25
  else {
16
- editor.asyncApplyCommands(this.commands, this.applyChunkSize);
26
+ return editor.asyncApplyCommands(this.commands, this.applyChunkSize);
17
27
  }
18
28
  }
19
29
  unapply(editor) {
20
30
  if (this.applyChunkSize === undefined) {
21
- for (const command of this.commands) {
22
- command.unapply(editor);
23
- }
31
+ const results = this.commands.map(cmd => cmd.unapply(editor));
32
+ return NonSerializableUnion.waitForAll(results);
24
33
  }
25
34
  else {
26
- editor.asyncUnapplyCommands(this.commands, this.applyChunkSize);
35
+ return editor.asyncUnapplyCommands(this.commands, this.applyChunkSize);
27
36
  }
28
37
  }
29
38
  description(editor, localizationTable) {
@@ -63,10 +72,10 @@ class SerializableUnion extends SerializableCommand {
63
72
  };
64
73
  }
65
74
  apply(editor) {
66
- this.nonserializableCommand.apply(editor);
75
+ return this.nonserializableCommand.apply(editor);
67
76
  }
68
77
  unapply(editor) {
69
- this.nonserializableCommand.unapply(editor);
78
+ return this.nonserializableCommand.unapply(editor);
70
79
  }
71
80
  description(editor, localizationTable) {
72
81
  return this.nonserializableCommand.description(editor, localizationTable);
@@ -4,9 +4,9 @@ import Mat33 from '../math/Mat33';
4
4
  import Rect2 from '../math/Rect2';
5
5
  import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
6
6
  import { ImageComponentLocalization } from './localization';
7
- export declare type LoadSaveData = (string[] | Record<symbol, string | number>);
8
- export declare type LoadSaveDataTable = Record<string, Array<LoadSaveData>>;
9
- export declare type DeserializeCallback = (data: string) => AbstractComponent;
7
+ export type LoadSaveData = (string[] | Record<symbol, string | number>);
8
+ export type LoadSaveDataTable = Record<string, Array<LoadSaveData>>;
9
+ export type DeserializeCallback = (data: string) => AbstractComponent;
10
10
  export default abstract class AbstractComponent {
11
11
  private readonly componentKind;
12
12
  protected lastChangedTime: number;
@@ -4,7 +4,7 @@ import Rect2 from '../math/Rect2';
4
4
  import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
5
5
  import AbstractComponent from './AbstractComponent';
6
6
  import { ImageComponentLocalization } from './localization';
7
- declare type GlobalAttrsList = Array<[string, string | null]>;
7
+ type GlobalAttrsList = Array<[string, string | null]>;
8
8
  export default class SVGGlobalAttributesObject extends AbstractComponent {
9
9
  private readonly attrs;
10
10
  protected contentBBox: Rect2;
@@ -24,7 +24,9 @@ export default class FreehandLineBuilder implements ComponentBuilder {
24
24
  private previewStroke;
25
25
  preview(renderer: AbstractRenderer): void;
26
26
  build(): Stroke;
27
+ private getMinFit;
27
28
  private roundPoint;
29
+ private roundDistance;
28
30
  private curveToPathCommands;
29
31
  private addCurve;
30
32
  addPoint(newPoint: StrokeDataPoint): void;
@@ -33,7 +33,7 @@ export default class FreehandLineBuilder {
33
33
  fill: Color4.transparent,
34
34
  stroke: {
35
35
  color: this.startPoint.color,
36
- width: this.averageWidth,
36
+ width: this.roundDistance(this.averageWidth),
37
37
  }
38
38
  };
39
39
  }
@@ -76,13 +76,21 @@ export default class FreehandLineBuilder {
76
76
  this.curveFitter.finalizeCurrentCurve();
77
77
  return this.previewStroke();
78
78
  }
79
- roundPoint(point) {
79
+ getMinFit() {
80
80
  let minFit = Math.min(this.minFitAllowed, this.averageWidth / 2);
81
81
  if (minFit < 1e-10) {
82
82
  minFit = this.minFitAllowed;
83
83
  }
84
+ return minFit;
85
+ }
86
+ roundPoint(point) {
87
+ const minFit = this.getMinFit();
84
88
  return Viewport.roundPoint(point, minFit);
85
89
  }
90
+ roundDistance(dist) {
91
+ const minFit = this.getMinFit();
92
+ return Viewport.roundPoint(dist, minFit);
93
+ }
86
94
  curveToPathCommands(curve) {
87
95
  // Case where no points have been added
88
96
  if (!curve) {
@@ -9,4 +9,4 @@ export interface ComponentBuilder {
9
9
  preview(renderer: AbstractRenderer): void;
10
10
  addPoint(point: StrokeDataPoint): void;
11
11
  }
12
- export declare type ComponentBuilderFactory = (startPoint: StrokeDataPoint, viewport: Viewport) => ComponentBuilder;
12
+ export type ComponentBuilderFactory = (startPoint: StrokeDataPoint, viewport: Viewport) => ComponentBuilder;
@@ -5,6 +5,6 @@ export { default as StrokeSmoother, Curve as StrokeSmootherCurve } from './util/
5
5
  export * from './AbstractComponent';
6
6
  export { default as AbstractComponent } from './AbstractComponent';
7
7
  import Stroke from './Stroke';
8
- import TextComponent from './Text';
8
+ import TextComponent from './TextComponent';
9
9
  import ImageComponent from './ImageComponent';
10
10
  export { Stroke, TextComponent as Text, TextComponent as TextComponent, Stroke as StrokeComponent, ImageComponent, };
@@ -5,6 +5,6 @@ export { default as StrokeSmoother } from './util/StrokeSmoother';
5
5
  export * from './AbstractComponent';
6
6
  export { default as AbstractComponent } from './AbstractComponent';
7
7
  import Stroke from './Stroke';
8
- import TextComponent from './Text';
8
+ import TextComponent from './TextComponent';
9
9
  import ImageComponent from './ImageComponent';
10
10
  export { Stroke, TextComponent as Text, TextComponent as TextComponent, Stroke as StrokeComponent, ImageComponent, };
@@ -8,7 +8,7 @@ export interface Curve {
8
8
  endWidth: number;
9
9
  endPoint: Vec2;
10
10
  }
11
- declare type OnCurveAddedCallback = (curve: Curve | null) => void;
11
+ type OnCurveAddedCallback = (curve: Curve | null) => void;
12
12
  export declare class StrokeSmoother {
13
13
  private startPoint;
14
14
  private minFitAllowed;
@@ -1,6 +1,6 @@
1
1
  import { Point2, Vec2 } from './Vec2';
2
2
  import Vec3 from './Vec3';
3
- export declare type Mat33Array = [
3
+ export type Mat33Array = [
4
4
  number,
5
5
  number,
6
6
  number,
@@ -30,7 +30,7 @@ export interface MoveToPathCommand {
30
30
  kind: PathCommandType.MoveTo;
31
31
  point: Point2;
32
32
  }
33
- export declare type PathCommand = CubicBezierPathCommand | LinePathCommand | QuadraticBezierPathCommand | MoveToPathCommand;
33
+ export type PathCommand = CubicBezierPathCommand | LinePathCommand | QuadraticBezierPathCommand | MoveToPathCommand;
34
34
  interface IntersectionResult {
35
35
  curve: LineSegment2 | Bezier;
36
36
  parameterValue: number;
@@ -9,5 +9,5 @@ export declare namespace Vec2 {
9
9
  const unitY: Vec3;
10
10
  const zero: Vec3;
11
11
  }
12
- export declare type Point2 = Vec3;
13
- export declare type Vec2 = Vec3;
12
+ export type Point2 = Vec3;
13
+ export type Vec2 = Vec3;
@@ -1,7 +1,7 @@
1
1
  import DummyRenderer from '../renderers/DummyRenderer';
2
2
  import RenderingCache from './RenderingCache';
3
3
  import { CacheProps } from './types';
4
- declare type RenderAllocCallback = (renderer: DummyRenderer) => void;
4
+ type RenderAllocCallback = (renderer: DummyRenderer) => void;
5
5
  export declare const createCache: (onRenderAlloc?: RenderAllocCallback, cacheOptions?: Partial<CacheProps>) => {
6
6
  cache: RenderingCache;
7
7
  editor: import("../../Editor").Editor;
@@ -1,8 +1,8 @@
1
1
  import { Vec2 } from '../../math/Vec2';
2
2
  import AbstractRenderer from '../renderers/AbstractRenderer';
3
3
  import { CacheRecordManager } from './CacheRecordManager';
4
- export declare type CacheAddress = number;
5
- export declare type BeforeDeallocCallback = () => void;
4
+ export type CacheAddress = number;
5
+ export type BeforeDeallocCallback = () => void;
6
6
  export interface CacheProps {
7
7
  createRenderer(): AbstractRenderer;
8
8
  isOfCorrectType(renderer: AbstractRenderer): boolean;
@@ -1,5 +1,5 @@
1
1
  import { LoadSaveDataTable } from '../../components/AbstractComponent';
2
- import { TextStyle } from '../../components/Text';
2
+ import { TextStyle } from '../../components/TextComponent';
3
3
  import Mat33 from '../../math/Mat33';
4
4
  import Path, { PathCommand } from '../../math/Path';
5
5
  import Rect2 from '../../math/Rect2';
@@ -1,4 +1,4 @@
1
- import { TextStyle } from '../../components/Text';
1
+ import { TextStyle } from '../../components/TextComponent';
2
2
  import Mat33 from '../../math/Mat33';
3
3
  import Rect2 from '../../math/Rect2';
4
4
  import { Point2, Vec2 } from '../../math/Vec2';
@@ -1,5 +1,5 @@
1
1
  import Color4 from '../../Color4';
2
- import TextComponent from '../../components/Text';
2
+ import TextComponent from '../../components/TextComponent';
3
3
  import { Vec2 } from '../../math/Vec2';
4
4
  import AbstractRenderer from './AbstractRenderer';
5
5
  export default class CanvasRenderer extends AbstractRenderer {
@@ -1,4 +1,4 @@
1
- import { TextStyle } from '../../components/Text';
1
+ import { TextStyle } from '../../components/TextComponent';
2
2
  import Mat33 from '../../math/Mat33';
3
3
  import Rect2 from '../../math/Rect2';
4
4
  import { Point2, Vec2 } from '../../math/Vec2';
@@ -1,5 +1,5 @@
1
1
  import { LoadSaveDataTable } from '../../components/AbstractComponent';
2
- import { TextStyle } from '../../components/Text';
2
+ import { TextStyle } from '../../components/TextComponent';
3
3
  import Mat33 from '../../math/Mat33';
4
4
  import Rect2 from '../../math/Rect2';
5
5
  import { Point2, Vec2 } from '../../math/Vec2';
@@ -87,7 +87,7 @@ export default class SVGRenderer extends AbstractRenderer {
87
87
  }
88
88
  if (style.stroke) {
89
89
  pathElem.setAttribute('stroke', style.stroke.color.toHexString());
90
- pathElem.setAttribute('stroke-width', style.stroke.width.toString());
90
+ pathElem.setAttribute('stroke-width', toRoundedString(style.stroke.width));
91
91
  }
92
92
  this.elem.appendChild(pathElem);
93
93
  (_a = this.objectElems) === null || _a === void 0 ? void 0 : _a.push(pathElem);
@@ -1,4 +1,4 @@
1
- import { TextStyle } from '../../components/Text';
1
+ import { TextStyle } from '../../components/TextComponent';
2
2
  import Mat33 from '../../math/Mat33';
3
3
  import Rect2 from '../../math/Rect2';
4
4
  import Vec3 from '../../math/Vec3';
@@ -22,8 +22,8 @@ export default class TextOnlyRenderer extends AbstractRenderer {
22
22
  getDescription() {
23
23
  return [
24
24
  this.localizationTable.pathNodeCount(this.pathCount),
25
- ...(this.textNodeCount > 0 ? this.localizationTable.textNodeCount(this.textNodeCount) : []),
26
- ...(this.imageNodeCount > 0 ? this.localizationTable.imageNodeCount(this.imageNodeCount) : []),
25
+ ...(this.textNodeCount > 0 ? [this.localizationTable.textNodeCount(this.textNodeCount)] : []),
26
+ ...(this.imageNodeCount > 0 ? [this.localizationTable.imageNodeCount(this.imageNodeCount)] : []),
27
27
  ...this.descriptionBuilder
28
28
  ].join('\n');
29
29
  }
@@ -1,8 +1,8 @@
1
1
  import Color4 from '../Color4';
2
2
  import { ComponentBuilderFactory } from '../components/builders/types';
3
- import { TextStyle } from '../components/Text';
3
+ import { TextStyle } from '../components/TextComponent';
4
4
  import Pen from '../tools/Pen';
5
- declare type IconType = SVGSVGElement | HTMLImageElement;
5
+ type IconType = SVGSVGElement | HTMLImageElement;
6
6
  export default class IconProvider {
7
7
  makeUndoIcon(): IconType;
8
8
  makeRedoIcon(mirror?: boolean): IconType;
@@ -1,5 +1,6 @@
1
1
  export interface ToolbarLocalization {
2
2
  fontLabel: string;
3
+ textSize: string;
3
4
  touchPanning: string;
4
5
  lockRotation: string;
5
6
  outlinedRectanglePen: string;
@@ -8,6 +8,7 @@ export const defaultToolbarLocalization = {
8
8
  thicknessLabel: 'Thickness: ',
9
9
  colorLabel: 'Color: ',
10
10
  fontLabel: 'Font: ',
11
+ textSize: 'Size: ',
11
12
  resizeImageToSelection: 'Resize image to selection',
12
13
  deleteSelection: 'Delete selection',
13
14
  duplicateSelection: 'Duplicate selection',
@@ -1,6 +1,6 @@
1
1
  import Color4 from '../Color4';
2
2
  import Editor from '../Editor';
3
- declare type OnColorChangeListener = (color: Color4) => void;
4
- declare type SetColorCallback = (color: Color4 | string) => void;
3
+ type OnColorChangeListener = (color: Color4) => void;
4
+ type SetColorCallback = (color: Color4 | string) => void;
5
5
  export declare const makeColorInput: (editor: Editor, onColorChange: OnColorChangeListener) => [HTMLInputElement, HTMLElement, SetColorCallback];
6
6
  export default makeColorInput;
@@ -1,7 +1,7 @@
1
1
  import Editor from '../../Editor';
2
2
  import { KeyPressEvent } from '../../types';
3
3
  import { ToolbarLocalization } from '../localization';
4
- export declare type SavedToolbuttonState = Record<string, any>;
4
+ export type SavedToolbuttonState = Record<string, any>;
5
5
  export default abstract class BaseWidget {
6
6
  #private;
7
7
  protected editor: Editor;
@@ -26,8 +26,11 @@ export default class TextToolWidget extends BaseToolWidget {
26
26
  fillDropdown(dropdown) {
27
27
  const fontRow = document.createElement('div');
28
28
  const colorRow = document.createElement('div');
29
+ const sizeRow = document.createElement('div');
29
30
  const fontInput = document.createElement('select');
30
31
  const fontLabel = document.createElement('label');
32
+ const sizeInput = document.createElement('input');
33
+ const sizeLabel = document.createElement('label');
31
34
  const [colorInput, colorInputContainer, setColorInputValue] = makeColorInput(this.editor, color => {
32
35
  this.tool.setColor(color);
33
36
  });
@@ -40,10 +43,16 @@ export default class TextToolWidget extends BaseToolWidget {
40
43
  fontInput.appendChild(option);
41
44
  fontsInInput.add(fontName);
42
45
  };
46
+ sizeInput.setAttribute('type', 'number');
47
+ sizeInput.min = '1';
48
+ sizeInput.max = '128';
43
49
  fontLabel.innerText = this.localizationTable.fontLabel;
44
50
  colorLabel.innerText = this.localizationTable.colorLabel;
51
+ sizeLabel.innerText = this.localizationTable.textSize;
45
52
  colorInput.id = `${toolbarCSSPrefix}-text-color-input-${TextToolWidget.idCounter++}`;
46
53
  colorLabel.setAttribute('for', colorInput.id);
54
+ sizeInput.id = `${toolbarCSSPrefix}-text-size-input-${TextToolWidget.idCounter++}`;
55
+ sizeLabel.setAttribute('for', sizeInput.id);
47
56
  addFontToInput('monospace');
48
57
  addFontToInput('serif');
49
58
  addFontToInput('sans-serif');
@@ -52,10 +61,18 @@ export default class TextToolWidget extends BaseToolWidget {
52
61
  fontInput.onchange = () => {
53
62
  this.tool.setFontFamily(fontInput.value);
54
63
  };
64
+ sizeInput.onchange = () => {
65
+ const size = parseInt(sizeInput.value);
66
+ if (!isNaN(size) && size > 0) {
67
+ this.tool.setFontSize(size);
68
+ }
69
+ };
55
70
  colorRow.appendChild(colorLabel);
56
71
  colorRow.appendChild(colorInputContainer);
57
72
  fontRow.appendChild(fontLabel);
58
73
  fontRow.appendChild(fontInput);
74
+ sizeRow.appendChild(sizeLabel);
75
+ sizeRow.appendChild(sizeInput);
59
76
  this.updateDropdownInputs = () => {
60
77
  const style = this.tool.getTextStyle();
61
78
  setColorInputValue(style.renderingStyle.fill);
@@ -63,14 +80,15 @@ export default class TextToolWidget extends BaseToolWidget {
63
80
  addFontToInput(style.fontFamily);
64
81
  }
65
82
  fontInput.value = style.fontFamily;
83
+ sizeInput.value = `${style.size}`;
66
84
  };
67
85
  this.updateDropdownInputs();
68
- dropdown.replaceChildren(colorRow, fontRow);
86
+ dropdown.replaceChildren(colorRow, sizeRow, fontRow);
69
87
  return true;
70
88
  }
71
89
  serializeState() {
72
90
  const textStyle = this.tool.getTextStyle();
73
- return Object.assign(Object.assign({}, super.serializeState()), { fontFamily: textStyle.fontFamily, color: textStyle.renderingStyle.fill.toHexString() });
91
+ return Object.assign(Object.assign({}, super.serializeState()), { fontFamily: textStyle.fontFamily, textSize: textStyle.size, color: textStyle.renderingStyle.fill.toHexString() });
74
92
  }
75
93
  deserializeFrom(state) {
76
94
  if (state.fontFamily && typeof (state.fontFamily) === 'string') {
@@ -79,6 +97,9 @@ export default class TextToolWidget extends BaseToolWidget {
79
97
  if (state.color && typeof (state.color) === 'string') {
80
98
  this.tool.setColor(Color4.fromHex(state.color));
81
99
  }
100
+ if (state.textSize && typeof (state.textSize) === 'number') {
101
+ this.tool.setFontSize(state.textSize);
102
+ }
82
103
  super.deserializeFrom(state);
83
104
  }
84
105
  }
@@ -1,15 +1,15 @@
1
1
  import { EditorEventType } from '../types';
2
2
  export default class BaseTool {
3
+ onPointerDown(_event) { return false; }
4
+ onPointerMove(_event) { }
5
+ onPointerUp(_event) { }
6
+ onGestureCancel() { }
3
7
  constructor(notifier, description) {
4
8
  this.notifier = notifier;
5
9
  this.description = description;
6
10
  this.enabled = true;
7
11
  this.group = null;
8
12
  }
9
- onPointerDown(_event) { return false; }
10
- onPointerMove(_event) { }
11
- onPointerUp(_event) { }
12
- onGestureCancel() { }
13
13
  onWheel(_event) {
14
14
  return false;
15
15
  }
@@ -0,0 +1,21 @@
1
+ import Editor from '../Editor';
2
+ import { KeyPressEvent } from '../types';
3
+ import BaseTool from './BaseTool';
4
+ export declare const cssPrefix = "find-tool";
5
+ export default class FindTool extends BaseTool {
6
+ private editor;
7
+ private overlay;
8
+ private searchInput;
9
+ private currentMatchIdx;
10
+ constructor(editor: Editor);
11
+ private getMatches;
12
+ private focusCurrentMatch;
13
+ private toNextMatch;
14
+ private toPrevMatch;
15
+ private fillOverlay;
16
+ private isVisible;
17
+ private setVisible;
18
+ private toggleVisible;
19
+ onKeyPress(event: KeyPressEvent): boolean;
20
+ setEnabled(enabled: boolean): void;
21
+ }