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
@@ -0,0 +1,44 @@
1
+ import Command from './Command';
2
+ import SerializableCommand from './SerializableCommand';
3
+ // Returns a command taht does the opposite of the given command --- `result.apply()` calls
4
+ // `command.unapply()` and `result.unapply()` calls `command.apply()`.
5
+ const invertCommand = (command) => {
6
+ if (command instanceof SerializableCommand) {
7
+ // SerializableCommand that does the inverse of [command]
8
+ return new class extends SerializableCommand {
9
+ serializeToJSON() {
10
+ return command.serialize();
11
+ }
12
+ apply(editor) {
13
+ command.unapply(editor);
14
+ }
15
+ unapply(editor) {
16
+ command.unapply(editor);
17
+ }
18
+ description(editor, localizationTable) {
19
+ return localizationTable.inverseOf(command.description(editor, localizationTable));
20
+ }
21
+ }('inverse');
22
+ }
23
+ else {
24
+ // Command that does the inverse of [command].
25
+ const result = new class extends Command {
26
+ apply(editor) {
27
+ command.unapply(editor);
28
+ }
29
+ unapply(editor) {
30
+ command.apply(editor);
31
+ }
32
+ description(editor, localizationTable) {
33
+ return localizationTable.inverseOf(command.description(editor, localizationTable));
34
+ }
35
+ };
36
+ // We know that T does not extend SerializableCommand, and thus returning a Command
37
+ // is appropriate.
38
+ return result;
39
+ }
40
+ };
41
+ SerializableCommand.register('inverse', (data, editor) => {
42
+ return invertCommand(SerializableCommand.deserialize(data, editor));
43
+ });
44
+ export default invertCommand;
@@ -0,0 +1,6 @@
1
+ import Command from './Command';
2
+ import Duplicate from './Duplicate';
3
+ import Erase from './Erase';
4
+ import invertCommand from './invertCommand';
5
+ import SerializableCommand from './SerializableCommand';
6
+ export { Command, Duplicate, Erase, SerializableCommand, invertCommand, };
@@ -0,0 +1,6 @@
1
+ import Command from './Command';
2
+ import Duplicate from './Duplicate';
3
+ import Erase from './Erase';
4
+ import invertCommand from './invertCommand';
5
+ import SerializableCommand from './SerializableCommand';
6
+ export { Command, Duplicate, Erase, SerializableCommand, invertCommand, };
@@ -1,4 +1,4 @@
1
- import Rect2 from '../geometry/Rect2';
1
+ import Rect2 from '../math/Rect2';
2
2
  export interface CommandLocalization {
3
3
  movedLeft: string;
4
4
  movedUp: string;
@@ -16,6 +16,7 @@ export interface CommandLocalization {
16
16
  addElementAction: (elemDescription: string) => string;
17
17
  eraseAction: (elemDescription: string, numElems: number) => string;
18
18
  duplicateAction: (elemDescription: string, count: number) => string;
19
+ inverseOf: (actionDescription: string) => string;
19
20
  selectedElements: (count: number) => string;
20
21
  }
21
22
  export declare const defaultCommandLocalization: CommandLocalization;
@@ -5,6 +5,7 @@ export const defaultCommandLocalization = {
5
5
  addElementAction: (componentDescription) => `Added ${componentDescription}`,
6
6
  eraseAction: (componentDescription, numElems) => `Erased ${numElems} ${componentDescription}`,
7
7
  duplicateAction: (componentDescription, numElems) => `Duplicated ${numElems} ${componentDescription}`,
8
+ inverseOf: (actionDescription) => `Inverse of ${actionDescription}`,
8
9
  elements: 'Elements',
9
10
  erasedNoElements: 'Erased nothing',
10
11
  duplicatedNoElements: 'Duplicated nothing',
@@ -1,12 +1,12 @@
1
- import Command from '../commands/Command';
2
- import LineSegment2 from '../geometry/LineSegment2';
3
- import Mat33 from '../geometry/Mat33';
4
- import Rect2 from '../geometry/Rect2';
1
+ import SerializableCommand from '../commands/SerializableCommand';
2
+ import LineSegment2 from '../math/LineSegment2';
3
+ import Mat33 from '../math/Mat33';
4
+ import Rect2 from '../math/Rect2';
5
5
  import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
6
6
  import { ImageComponentLocalization } from './localization';
7
- declare type LoadSaveData = (string[] | Record<symbol, string | number>);
7
+ export declare type LoadSaveData = (string[] | Record<symbol, string | number>);
8
8
  export declare type LoadSaveDataTable = Record<string, Array<LoadSaveData>>;
9
- declare type DeserializeCallback = (data: string) => AbstractComponent;
9
+ export declare type DeserializeCallback = (data: string) => AbstractComponent;
10
10
  export default abstract class AbstractComponent {
11
11
  private readonly componentKind;
12
12
  protected lastChangedTime: number;
@@ -25,15 +25,20 @@ export default abstract class AbstractComponent {
25
25
  getBBox(): Rect2;
26
26
  abstract render(canvas: AbstractRenderer, visibleRect?: Rect2): void;
27
27
  abstract intersects(lineSegment: LineSegment2): boolean;
28
- protected abstract serializeToString(): string | null;
28
+ protected abstract serializeToJSON(): any[] | Record<string, any> | number | string | null;
29
29
  protected abstract applyTransformation(affineTransfm: Mat33): void;
30
- transformBy(affineTransfm: Mat33): Command;
30
+ transformBy(affineTransfm: Mat33): SerializableCommand;
31
31
  private static TransformElementCommand;
32
32
  abstract description(localizationTable: ImageComponentLocalization): string;
33
33
  protected abstract createClone(): AbstractComponent;
34
34
  clone(): AbstractComponent;
35
- serialize(): string;
35
+ serialize(): {
36
+ name: string;
37
+ zIndex: number;
38
+ id: string;
39
+ loadSaveData: LoadSaveDataTable;
40
+ data: string | number | any[] | Record<string, any>;
41
+ };
36
42
  private static isNotDeserializable;
37
- static deserialize(data: string): AbstractComponent;
43
+ static deserialize(json: string | any): AbstractComponent;
38
44
  }
39
- export {};
@@ -1,7 +1,7 @@
1
1
  var _a;
2
2
  import SerializableCommand from '../commands/SerializableCommand';
3
3
  import EditorImage from '../EditorImage';
4
- import Mat33 from '../geometry/Mat33';
4
+ import Mat33 from '../math/Mat33';
5
5
  export default class AbstractComponent {
6
6
  constructor(
7
7
  // A unique identifier for the type of component
@@ -17,6 +17,8 @@ export default class AbstractComponent {
17
17
  throw new Error(`Component ${componentKind} has not been registered using AbstractComponent.registerComponent`);
18
18
  }
19
19
  }
20
+ // Returns a unique ID for this element.
21
+ // @see { @link EditorImage!default.lookupElement }
20
22
  getId() {
21
23
  return this.id;
22
24
  }
@@ -55,23 +57,30 @@ export default class AbstractComponent {
55
57
  }
56
58
  return clone;
57
59
  }
60
+ // Convert the component to an object that can be passed to
61
+ // `JSON.stringify`.
62
+ //
63
+ // Do not rely on the output of this function to take a particular form —
64
+ // this function's output can change form without a major version increase.
58
65
  serialize() {
59
- const data = this.serializeToString();
66
+ const data = this.serializeToJSON();
60
67
  if (data === null) {
61
68
  throw new Error(`${this} cannot be serialized.`);
62
69
  }
63
- return JSON.stringify({
70
+ return {
64
71
  name: this.componentKind,
65
72
  zIndex: this.zIndex,
66
73
  id: this.id,
67
74
  loadSaveData: this.loadSaveData,
68
75
  data,
69
- });
76
+ };
70
77
  }
71
- // Returns true if [data] is not deserializable. May return false even if [data]
78
+ // Returns true if `data` is not deserializable. May return false even if [data]
72
79
  // is not deserializable.
73
- static isNotDeserializable(data) {
74
- const json = JSON.parse(data);
80
+ static isNotDeserializable(json) {
81
+ if (typeof json === 'string') {
82
+ json = JSON.parse(json);
83
+ }
75
84
  if (typeof json !== 'object') {
76
85
  return true;
77
86
  }
@@ -83,11 +92,14 @@ export default class AbstractComponent {
83
92
  }
84
93
  return false;
85
94
  }
86
- static deserialize(data) {
87
- if (AbstractComponent.isNotDeserializable(data)) {
88
- throw new Error(`Element with data ${data} cannot be deserialized.`);
95
+ // Convert a string or an object produced by `JSON.parse` into an `AbstractComponent`.
96
+ static deserialize(json) {
97
+ if (typeof json === 'string') {
98
+ json = JSON.parse(json);
99
+ }
100
+ if (AbstractComponent.isNotDeserializable(json)) {
101
+ throw new Error(`Element with data ${json} cannot be deserialized.`);
89
102
  }
90
- const json = JSON.parse(data);
91
103
  const instance = this.deserializationCallbacks[json.name](json.data);
92
104
  instance.zIndex = json.zIndex;
93
105
  instance.id = json.id;
@@ -132,19 +144,18 @@ AbstractComponent.TransformElementCommand = (_a = class extends SerializableComm
132
144
  this.updateTransform(editor, this.affineTransfm.inverse());
133
145
  editor.queueRerender();
134
146
  }
135
- description(localizationTable) {
147
+ description(_editor, localizationTable) {
136
148
  return localizationTable.transformedElements(1);
137
149
  }
138
- serializeToString() {
139
- return JSON.stringify({
150
+ serializeToJSON() {
151
+ return {
140
152
  id: this.component.getId(),
141
153
  transfm: this.affineTransfm.toArray(),
142
- });
154
+ };
143
155
  }
144
156
  },
145
157
  (() => {
146
- SerializableCommand.register('transform-element', (data, editor) => {
147
- const json = JSON.parse(data);
158
+ SerializableCommand.register('transform-element', (json, editor) => {
148
159
  const elem = editor.image.lookupElement(json.id);
149
160
  if (!elem) {
150
161
  throw new Error(`Unable to retrieve non-existent element, ${elem}`);
@@ -1,6 +1,6 @@
1
- import LineSegment2 from '../geometry/LineSegment2';
2
- import Mat33 from '../geometry/Mat33';
3
- import Rect2 from '../geometry/Rect2';
1
+ import LineSegment2 from '../math/LineSegment2';
2
+ import Mat33 from '../math/Mat33';
3
+ import Rect2 from '../math/Rect2';
4
4
  import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
5
5
  import AbstractComponent from './AbstractComponent';
6
6
  import { ImageComponentLocalization } from './localization';
@@ -14,7 +14,7 @@ export default class SVGGlobalAttributesObject extends AbstractComponent {
14
14
  protected applyTransformation(_affineTransfm: Mat33): void;
15
15
  protected createClone(): SVGGlobalAttributesObject;
16
16
  description(localization: ImageComponentLocalization): string;
17
- protected serializeToString(): string | null;
17
+ protected serializeToJSON(): string | null;
18
18
  static deserializeFromString(data: string): AbstractComponent;
19
19
  }
20
20
  export {};
@@ -1,4 +1,10 @@
1
- import Rect2 from '../geometry/Rect2';
1
+ //
2
+ // Used by `SVGLoader`s to store unrecognised global attributes
3
+ // (e.g. unrecognised XML namespace declarations).
4
+ // @internal
5
+ // @packageDocumentation
6
+ //
7
+ import Rect2 from '../math/Rect2';
2
8
  import SVGRenderer from '../rendering/renderers/SVGRenderer';
3
9
  import AbstractComponent from './AbstractComponent';
4
10
  const componentKind = 'svg-global-attributes';
@@ -29,7 +35,7 @@ export default class SVGGlobalAttributesObject extends AbstractComponent {
29
35
  description(localization) {
30
36
  return localization.svgObject;
31
37
  }
32
- serializeToString() {
38
+ serializeToJSON() {
33
39
  return JSON.stringify(this.attrs);
34
40
  }
35
41
  static deserializeFromString(data) {
@@ -1,7 +1,7 @@
1
- import LineSegment2 from '../geometry/LineSegment2';
2
- import Mat33 from '../geometry/Mat33';
3
- import Path from '../geometry/Path';
4
- import Rect2 from '../geometry/Rect2';
1
+ import LineSegment2 from '../math/LineSegment2';
2
+ import Mat33 from '../math/Mat33';
3
+ import Path from '../math/Path';
4
+ import Rect2 from '../math/Rect2';
5
5
  import AbstractRenderer, { RenderablePathSpec } from '../rendering/renderers/AbstractRenderer';
6
6
  import AbstractComponent from './AbstractComponent';
7
7
  import { ImageComponentLocalization } from './localization';
@@ -16,6 +16,16 @@ export default class Stroke extends AbstractComponent {
16
16
  getPath(): Path;
17
17
  description(localization: ImageComponentLocalization): string;
18
18
  protected createClone(): AbstractComponent;
19
- protected serializeToString(): string | null;
20
- static deserializeFromString(data: string): Stroke;
19
+ protected serializeToJSON(): {
20
+ style: {
21
+ fill: string;
22
+ stroke: {
23
+ color: string;
24
+ width: number;
25
+ } | undefined;
26
+ };
27
+ path: string;
28
+ }[];
29
+ /** @internal */
30
+ static deserializeFromJSON(json: any): Stroke;
21
31
  }
@@ -1,5 +1,5 @@
1
- import Path from '../geometry/Path';
2
- import Rect2 from '../geometry/Rect2';
1
+ import Path from '../math/Path';
2
+ import Rect2 from '../math/Rect2';
3
3
  import { styleFromJSON, styleToJSON } from '../rendering/RenderingStyle';
4
4
  import AbstractComponent from './AbstractComponent';
5
5
  export default class Stroke extends AbstractComponent {
@@ -87,18 +87,21 @@ export default class Stroke extends AbstractComponent {
87
87
  createClone() {
88
88
  return new Stroke(this.parts);
89
89
  }
90
- serializeToString() {
91
- return JSON.stringify(this.parts.map(part => {
90
+ serializeToJSON() {
91
+ return this.parts.map(part => {
92
92
  return {
93
93
  style: styleToJSON(part.style),
94
94
  path: part.path.serialize(),
95
95
  };
96
- }));
96
+ });
97
97
  }
98
- static deserializeFromString(data) {
99
- const json = JSON.parse(data);
98
+ /** @internal */
99
+ static deserializeFromJSON(json) {
100
+ if (typeof json === 'string') {
101
+ json = JSON.parse(json);
102
+ }
100
103
  if (typeof json !== 'object' || typeof json.length !== 'number') {
101
- throw new Error(`${data} is missing required field, parts, or parts is of the wrong type.`);
104
+ throw new Error(`${json} is missing required field, parts, or parts is of the wrong type.`);
102
105
  }
103
106
  const pathSpec = json.map((part) => {
104
107
  const style = styleFromJSON(part.style);
@@ -107,4 +110,4 @@ export default class Stroke extends AbstractComponent {
107
110
  return new Stroke(pathSpec);
108
111
  }
109
112
  }
110
- AbstractComponent.registerComponent('stroke', Stroke.deserializeFromString);
113
+ AbstractComponent.registerComponent('stroke', Stroke.deserializeFromJSON);
@@ -1,6 +1,6 @@
1
- import LineSegment2 from '../geometry/LineSegment2';
2
- import Mat33 from '../geometry/Mat33';
3
- import Rect2 from '../geometry/Rect2';
1
+ import LineSegment2 from '../math/LineSegment2';
2
+ import Mat33 from '../math/Mat33';
3
+ import Rect2 from '../math/Rect2';
4
4
  import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
5
5
  import RenderingStyle from '../rendering/RenderingStyle';
6
6
  import AbstractComponent from './AbstractComponent';
@@ -31,7 +31,7 @@ export default class Text extends AbstractComponent {
31
31
  protected createClone(): AbstractComponent;
32
32
  private getText;
33
33
  description(localizationTable: ImageComponentLocalization): string;
34
- protected serializeToString(): string;
35
- static deserializeFromString(data: string, getTextDimens?: GetTextDimensCallback): Text;
34
+ protected serializeToJSON(): Record<string, any>;
35
+ static deserializeFromString(json: any, getTextDimens?: GetTextDimensCallback): Text;
36
36
  }
37
37
  export {};
@@ -1,12 +1,13 @@
1
- import LineSegment2 from '../geometry/LineSegment2';
2
- import Mat33 from '../geometry/Mat33';
3
- import Rect2 from '../geometry/Rect2';
1
+ import LineSegment2 from '../math/LineSegment2';
2
+ import Mat33 from '../math/Mat33';
3
+ import Rect2 from '../math/Rect2';
4
4
  import { styleFromJSON, styleToJSON } from '../rendering/RenderingStyle';
5
5
  import AbstractComponent from './AbstractComponent';
6
6
  const componentTypeId = 'text';
7
7
  export default class Text extends AbstractComponent {
8
8
  constructor(textObjects, transform, style,
9
9
  // If not given, an HtmlCanvasElement is used to determine text boundaries.
10
+ // @internal
10
11
  getTextDimens = Text.getTextDimens) {
11
12
  super(componentTypeId);
12
13
  this.textObjects = textObjects;
@@ -117,7 +118,7 @@ export default class Text extends AbstractComponent {
117
118
  description(localizationTable) {
118
119
  return localizationTable.text(this.getText());
119
120
  }
120
- serializeToString() {
121
+ serializeToJSON() {
121
122
  const serializableStyle = Object.assign(Object.assign({}, this.style), { renderingStyle: styleToJSON(this.style.renderingStyle) });
122
123
  const textObjects = this.textObjects.map(text => {
123
124
  if (typeof text === 'string') {
@@ -127,18 +128,17 @@ export default class Text extends AbstractComponent {
127
128
  }
128
129
  else {
129
130
  return {
130
- json: text.serializeToString(),
131
+ json: text.serializeToJSON(),
131
132
  };
132
133
  }
133
134
  });
134
- return JSON.stringify({
135
+ return {
135
136
  textObjects,
136
137
  transform: this.transform.toArray(),
137
138
  style: serializableStyle,
138
- });
139
+ };
139
140
  }
140
- static deserializeFromString(data, getTextDimens = Text.getTextDimens) {
141
- const json = JSON.parse(data);
141
+ static deserializeFromString(json, getTextDimens = Text.getTextDimens) {
142
142
  const style = {
143
143
  renderingStyle: styleFromJSON(json.style.renderingStyle),
144
144
  size: json.style.size,
@@ -1,6 +1,6 @@
1
- import LineSegment2 from '../geometry/LineSegment2';
2
- import Mat33 from '../geometry/Mat33';
3
- import Rect2 from '../geometry/Rect2';
1
+ import LineSegment2 from '../math/LineSegment2';
2
+ import Mat33 from '../math/Mat33';
3
+ import Rect2 from '../math/Rect2';
4
4
  import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
5
5
  import AbstractComponent from './AbstractComponent';
6
6
  import { ImageComponentLocalization } from './localization';
@@ -13,5 +13,5 @@ export default class UnknownSVGObject extends AbstractComponent {
13
13
  protected applyTransformation(_affineTransfm: Mat33): void;
14
14
  protected createClone(): AbstractComponent;
15
15
  description(localization: ImageComponentLocalization): string;
16
- protected serializeToString(): string | null;
16
+ protected serializeToJSON(): string | null;
17
17
  }
@@ -1,4 +1,9 @@
1
- import Rect2 from '../geometry/Rect2';
1
+ //
2
+ // Stores objects loaded from an SVG that aren't recognised by the editor.
3
+ // @internal
4
+ // @packageDocumentation
5
+ //
6
+ import Rect2 from '../math/Rect2';
2
7
  import SVGRenderer from '../rendering/renderers/SVGRenderer';
3
8
  import AbstractComponent from './AbstractComponent';
4
9
  const componentId = 'unknown-svg-object';
@@ -26,7 +31,7 @@ export default class UnknownSVGObject extends AbstractComponent {
26
31
  description(localization) {
27
32
  return localization.svgObject;
28
33
  }
29
- serializeToString() {
34
+ serializeToJSON() {
30
35
  return JSON.stringify({
31
36
  html: this.svgObject.outerHTML,
32
37
  });
@@ -1,4 +1,4 @@
1
- import Rect2 from '../../geometry/Rect2';
1
+ import Rect2 from '../../math/Rect2';
2
2
  import AbstractRenderer from '../../rendering/renderers/AbstractRenderer';
3
3
  import { StrokeDataPoint } from '../../types';
4
4
  import AbstractComponent from '../AbstractComponent';
@@ -1,4 +1,4 @@
1
- import { PathCommandType } from '../../geometry/Path';
1
+ import { PathCommandType } from '../../math/Path';
2
2
  import Stroke from '../Stroke';
3
3
  export const makeArrowBuilder = (initialPoint, _viewport) => {
4
4
  return new ArrowBuilder(initialPoint);
@@ -1,5 +1,5 @@
1
1
  import AbstractRenderer from '../../rendering/renderers/AbstractRenderer';
2
- import Rect2 from '../../geometry/Rect2';
2
+ import Rect2 from '../../math/Rect2';
3
3
  import Stroke from '../Stroke';
4
4
  import { StrokeDataPoint } from '../../types';
5
5
  import { ComponentBuilder, ComponentBuilderFactory } from './types';
@@ -8,7 +8,11 @@ export default class FreehandLineBuilder implements ComponentBuilder {
8
8
  private startPoint;
9
9
  private minFitAllowed;
10
10
  private maxFitAllowed;
11
- private segments;
11
+ private isFirstSegment;
12
+ private pathStartConnector;
13
+ private mostRecentConnector;
14
+ private upperSegments;
15
+ private lowerSegments;
12
16
  private buffer;
13
17
  private lastPoint;
14
18
  private lastExitingVec;
@@ -20,7 +24,8 @@ export default class FreehandLineBuilder implements ComponentBuilder {
20
24
  constructor(startPoint: StrokeDataPoint, minFitAllowed: number, maxFitAllowed: number);
21
25
  getBBox(): Rect2;
22
26
  private getRenderingStyle;
23
- private getPreview;
27
+ private previewPath;
28
+ private previewStroke;
24
29
  preview(renderer: AbstractRenderer): void;
25
30
  build(): Stroke;
26
31
  private roundPoint;