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.
- package/.eslintrc.js +1 -0
- package/.firebaserc +5 -0
- package/.github/workflows/firebase-hosting-merge.yml +25 -0
- package/.github/workflows/firebase-hosting-pull-request.yml +22 -0
- package/.github/workflows/github-pages.yml +52 -0
- package/CHANGELOG.md +13 -0
- package/README.md +11 -6
- package/dist/bundle.js +1 -1
- package/dist/src/Color4.d.ts +19 -0
- package/dist/src/Color4.js +24 -3
- package/dist/src/Editor.d.ts +133 -4
- package/dist/src/Editor.js +124 -27
- package/dist/src/EditorImage.d.ts +8 -3
- package/dist/src/EditorImage.js +42 -26
- package/dist/src/EventDispatcher.d.ts +18 -0
- package/dist/src/EventDispatcher.js +19 -4
- package/dist/src/Pointer.d.ts +1 -1
- package/dist/src/Pointer.js +4 -3
- package/dist/src/SVGLoader.d.ts +1 -1
- package/dist/src/SVGLoader.js +14 -6
- package/dist/src/UndoRedoHistory.js +15 -2
- package/dist/src/Viewport.d.ts +8 -25
- package/dist/src/Viewport.js +18 -10
- package/dist/src/bundle/bundled.d.ts +1 -2
- package/dist/src/bundle/bundled.js +1 -2
- package/dist/src/commands/Command.d.ts +2 -2
- package/dist/src/commands/Command.js +4 -4
- package/dist/src/commands/Duplicate.d.ts +2 -2
- package/dist/src/commands/Duplicate.js +4 -5
- package/dist/src/commands/Erase.d.ts +2 -2
- package/dist/src/commands/Erase.js +7 -6
- package/dist/src/commands/SerializableCommand.d.ts +4 -5
- package/dist/src/commands/SerializableCommand.js +12 -4
- package/dist/src/commands/invertCommand.d.ts +4 -0
- package/dist/src/commands/invertCommand.js +44 -0
- package/dist/src/commands/lib.d.ts +6 -0
- package/dist/src/commands/lib.js +6 -0
- package/dist/src/commands/localization.d.ts +2 -1
- package/dist/src/commands/localization.js +1 -0
- package/dist/src/components/AbstractComponent.d.ts +16 -11
- package/dist/src/components/AbstractComponent.js +28 -17
- package/dist/src/components/SVGGlobalAttributesObject.d.ts +4 -4
- package/dist/src/components/SVGGlobalAttributesObject.js +8 -2
- package/dist/src/components/Stroke.d.ts +16 -6
- package/dist/src/components/Stroke.js +12 -9
- package/dist/src/components/Text.d.ts +5 -5
- package/dist/src/components/Text.js +9 -9
- package/dist/src/components/UnknownSVGObject.d.ts +4 -4
- package/dist/src/components/UnknownSVGObject.js +7 -2
- package/dist/src/components/builders/ArrowBuilder.d.ts +1 -1
- package/dist/src/components/builders/ArrowBuilder.js +1 -1
- package/dist/src/components/builders/FreehandLineBuilder.d.ts +8 -3
- package/dist/src/components/builders/FreehandLineBuilder.js +142 -71
- package/dist/src/components/builders/LineBuilder.d.ts +1 -1
- package/dist/src/components/builders/LineBuilder.js +1 -1
- package/dist/src/components/builders/RectangleBuilder.d.ts +1 -1
- package/dist/src/components/builders/RectangleBuilder.js +3 -3
- package/dist/src/components/builders/types.d.ts +1 -1
- package/dist/src/components/lib.d.ts +4 -0
- package/dist/src/components/lib.js +4 -0
- package/dist/src/lib.d.ts +25 -0
- package/dist/src/lib.js +25 -0
- package/dist/src/localization.d.ts +1 -0
- package/dist/src/localization.js +5 -1
- package/dist/src/localizations/es.js +1 -1
- package/dist/src/{geometry → math}/LineSegment2.d.ts +0 -0
- package/dist/src/{geometry → math}/LineSegment2.js +0 -0
- package/dist/src/math/Mat33.d.ts +78 -0
- package/dist/src/{geometry → math}/Mat33.js +48 -20
- package/dist/src/{geometry → math}/Path.d.ts +2 -1
- package/dist/src/{geometry → math}/Path.js +59 -52
- package/dist/src/{geometry → math}/Rect2.d.ts +2 -2
- package/dist/src/{geometry → math}/Rect2.js +0 -0
- package/dist/src/{geometry → math}/Vec2.d.ts +0 -0
- package/dist/src/{geometry → math}/Vec2.js +0 -0
- package/dist/src/math/Vec3.d.ts +96 -0
- package/dist/src/{geometry → math}/Vec3.js +63 -15
- package/dist/src/math/lib.d.ts +7 -0
- package/dist/src/math/lib.js +7 -0
- package/dist/src/math/rounding.d.ts +3 -0
- package/dist/src/math/rounding.js +121 -0
- package/dist/src/rendering/Display.d.ts +47 -1
- package/dist/src/rendering/Display.js +60 -15
- package/dist/src/rendering/caching/CacheRecord.d.ts +3 -2
- package/dist/src/rendering/caching/CacheRecord.js +4 -1
- package/dist/src/rendering/caching/CacheRecordManager.d.ts +5 -4
- package/dist/src/rendering/caching/CacheRecordManager.js +16 -4
- package/dist/src/rendering/caching/RenderingCache.d.ts +2 -3
- package/dist/src/rendering/caching/RenderingCache.js +10 -11
- package/dist/src/rendering/caching/RenderingCacheNode.d.ts +2 -1
- package/dist/src/rendering/caching/RenderingCacheNode.js +18 -7
- package/dist/src/rendering/caching/testUtils.js +1 -1
- package/dist/src/rendering/caching/types.d.ts +2 -4
- package/dist/src/rendering/localization.d.ts +2 -0
- package/dist/src/rendering/localization.js +2 -0
- package/dist/src/rendering/renderers/AbstractRenderer.d.ts +4 -4
- package/dist/src/rendering/renderers/AbstractRenderer.js +2 -2
- package/dist/src/rendering/renderers/CanvasRenderer.d.ts +4 -4
- package/dist/src/rendering/renderers/CanvasRenderer.js +2 -2
- package/dist/src/rendering/renderers/DummyRenderer.d.ts +4 -4
- package/dist/src/rendering/renderers/DummyRenderer.js +1 -1
- package/dist/src/rendering/renderers/SVGRenderer.d.ts +3 -3
- package/dist/src/rendering/renderers/SVGRenderer.js +8 -2
- package/dist/src/rendering/renderers/TextOnlyRenderer.d.ts +5 -3
- package/dist/src/rendering/renderers/TextOnlyRenderer.js +13 -3
- package/dist/src/toolbar/HTMLToolbar.js +1 -0
- package/dist/src/toolbar/icons.d.ts +3 -0
- package/dist/src/toolbar/icons.js +142 -132
- package/dist/src/toolbar/localization.d.ts +2 -1
- package/dist/src/toolbar/localization.js +2 -1
- package/dist/src/toolbar/makeColorInput.js +3 -2
- package/dist/src/toolbar/widgets/ActionButtonWidget.d.ts +13 -0
- package/dist/src/toolbar/widgets/ActionButtonWidget.js +21 -0
- package/dist/src/toolbar/widgets/BaseWidget.js +2 -0
- package/dist/src/toolbar/widgets/HandToolWidget.js +3 -3
- package/dist/src/toolbar/widgets/PenWidget.js +1 -0
- package/dist/src/toolbar/widgets/SelectionWidget.d.ts +0 -1
- package/dist/src/toolbar/widgets/SelectionWidget.js +23 -30
- package/dist/src/tools/Eraser.js +1 -1
- package/dist/src/tools/PanZoom.d.ts +1 -1
- package/dist/src/tools/PanZoom.js +24 -14
- package/dist/src/tools/Pen.d.ts +1 -2
- package/dist/src/tools/Pen.js +8 -1
- package/dist/src/tools/PipetteTool.js +1 -0
- package/dist/src/tools/SelectionTool.d.ts +3 -3
- package/dist/src/tools/SelectionTool.js +51 -28
- package/dist/src/tools/TextTool.js +1 -1
- package/dist/src/types.d.ts +21 -10
- package/dist/src/types.js +7 -5
- package/firebase.json +16 -0
- package/package.json +118 -101
- package/src/Color4.ts +23 -2
- package/src/Editor.ts +181 -37
- package/src/EditorImage.test.ts +2 -4
- package/src/EditorImage.ts +46 -28
- package/src/EventDispatcher.ts +21 -6
- package/src/Pointer.ts +4 -3
- package/src/SVGLoader.ts +14 -6
- package/src/UndoRedoHistory.ts +18 -2
- package/src/Viewport.ts +23 -18
- package/src/bundle/bundled.ts +1 -2
- package/src/commands/Command.ts +5 -5
- package/src/commands/Duplicate.ts +4 -5
- package/src/commands/Erase.ts +7 -6
- package/src/commands/SerializableCommand.ts +17 -9
- package/src/commands/invertCommand.ts +51 -0
- package/src/commands/lib.ts +14 -0
- package/src/commands/localization.ts +3 -1
- package/src/components/AbstractComponent.ts +35 -24
- package/src/components/SVGGlobalAttributesObject.ts +11 -4
- package/src/components/Stroke.test.ts +4 -6
- package/src/components/Stroke.ts +15 -11
- package/src/components/Text.test.ts +2 -2
- package/src/components/Text.ts +9 -10
- package/src/components/UnknownSVGObject.ts +10 -4
- package/src/components/builders/ArrowBuilder.ts +2 -2
- package/src/components/builders/FreehandLineBuilder.ts +190 -80
- package/src/components/builders/LineBuilder.ts +2 -2
- package/src/components/builders/RectangleBuilder.ts +3 -3
- package/src/components/builders/types.ts +1 -1
- package/src/components/lib.ts +9 -0
- package/src/lib.ts +28 -0
- package/src/localization.ts +6 -0
- package/src/localizations/es.ts +2 -1
- package/src/{geometry → math}/LineSegment2.test.ts +0 -0
- package/src/{geometry → math}/LineSegment2.ts +0 -0
- package/src/{geometry → math}/Mat33.test.ts +0 -0
- package/src/{geometry → math}/Mat33.ts +48 -20
- package/src/{geometry → math}/Path.fromString.test.ts +0 -0
- package/src/{geometry → math}/Path.test.ts +0 -0
- package/src/{geometry → math}/Path.toString.test.ts +11 -2
- package/src/{geometry → math}/Path.ts +61 -58
- package/src/{geometry → math}/Rect2.test.ts +0 -0
- package/src/{geometry → math}/Rect2.ts +2 -2
- package/src/{geometry → math}/Vec2.test.ts +0 -0
- package/src/{geometry → math}/Vec2.ts +0 -0
- package/src/{geometry → math}/Vec3.test.ts +0 -0
- package/src/{geometry → math}/Vec3.ts +64 -16
- package/src/math/lib.ts +15 -0
- package/src/math/rounding.test.ts +40 -0
- package/src/math/rounding.ts +147 -0
- package/src/rendering/Display.ts +63 -15
- package/src/rendering/caching/CacheRecord.test.ts +3 -3
- package/src/rendering/caching/CacheRecord.ts +6 -2
- package/src/rendering/caching/CacheRecordManager.ts +34 -8
- package/src/rendering/caching/RenderingCache.test.ts +3 -3
- package/src/rendering/caching/RenderingCache.ts +11 -16
- package/src/rendering/caching/RenderingCacheNode.ts +23 -7
- package/src/rendering/caching/testUtils.ts +1 -1
- package/src/rendering/caching/types.ts +2 -7
- package/src/rendering/localization.ts +4 -0
- package/src/rendering/renderers/AbstractRenderer.ts +4 -4
- package/src/rendering/renderers/CanvasRenderer.ts +5 -5
- package/src/rendering/renderers/DummyRenderer.test.ts +2 -2
- package/src/rendering/renderers/DummyRenderer.ts +4 -4
- package/src/rendering/renderers/SVGRenderer.ts +10 -4
- package/src/rendering/renderers/TextOnlyRenderer.ts +17 -6
- package/src/toolbar/HTMLToolbar.ts +1 -0
- package/src/toolbar/icons.ts +157 -137
- package/src/toolbar/localization.ts +4 -2
- package/src/toolbar/makeColorInput.ts +3 -2
- package/src/toolbar/toolbar.css +1 -1
- package/src/toolbar/widgets/ActionButtonWidget.ts +31 -0
- package/src/toolbar/widgets/BaseWidget.ts +2 -0
- package/src/toolbar/widgets/HandToolWidget.ts +3 -3
- package/src/toolbar/widgets/PenWidget.ts +2 -0
- package/src/toolbar/widgets/SelectionWidget.ts +46 -41
- package/src/tools/Eraser.ts +2 -2
- package/src/tools/PanZoom.ts +28 -17
- package/src/tools/Pen.ts +11 -2
- package/src/tools/PipetteTool.ts +2 -0
- package/src/tools/SelectionTool.test.ts +2 -4
- package/src/tools/SelectionTool.ts +52 -24
- package/src/tools/TextTool.ts +2 -2
- package/src/tools/UndoRedoShortcut.test.ts +1 -1
- package/src/types.ts +23 -7
- package/tsconfig.json +4 -1
- package/typedoc.json +20 -0
- package/dist/src/geometry/Mat33.d.ts +0 -32
- 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 '../
|
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
|
2
|
-
import LineSegment2 from '../
|
3
|
-
import Mat33 from '../
|
4
|
-
import Rect2 from '../
|
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
|
28
|
+
protected abstract serializeToJSON(): any[] | Record<string, any> | number | string | null;
|
29
29
|
protected abstract applyTransformation(affineTransfm: Mat33): void;
|
30
|
-
transformBy(affineTransfm: Mat33):
|
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():
|
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(
|
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 '../
|
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.
|
66
|
+
const data = this.serializeToJSON();
|
60
67
|
if (data === null) {
|
61
68
|
throw new Error(`${this} cannot be serialized.`);
|
62
69
|
}
|
63
|
-
return
|
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
|
78
|
+
// Returns true if `data` is not deserializable. May return false even if [data]
|
72
79
|
// is not deserializable.
|
73
|
-
static isNotDeserializable(
|
74
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
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
|
-
|
139
|
-
return
|
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', (
|
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 '../
|
2
|
-
import Mat33 from '../
|
3
|
-
import Rect2 from '../
|
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
|
17
|
+
protected serializeToJSON(): string | null;
|
18
18
|
static deserializeFromString(data: string): AbstractComponent;
|
19
19
|
}
|
20
20
|
export {};
|
@@ -1,4 +1,10 @@
|
|
1
|
-
|
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
|
-
|
38
|
+
serializeToJSON() {
|
33
39
|
return JSON.stringify(this.attrs);
|
34
40
|
}
|
35
41
|
static deserializeFromString(data) {
|
@@ -1,7 +1,7 @@
|
|
1
|
-
import LineSegment2 from '../
|
2
|
-
import Mat33 from '../
|
3
|
-
import Path from '../
|
4
|
-
import Rect2 from '../
|
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
|
20
|
-
|
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 '../
|
2
|
-
import Rect2 from '../
|
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
|
-
|
91
|
-
return
|
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
|
-
|
99
|
-
|
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(`${
|
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.
|
113
|
+
AbstractComponent.registerComponent('stroke', Stroke.deserializeFromJSON);
|
@@ -1,6 +1,6 @@
|
|
1
|
-
import LineSegment2 from '../
|
2
|
-
import Mat33 from '../
|
3
|
-
import Rect2 from '../
|
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
|
35
|
-
static deserializeFromString(
|
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 '../
|
2
|
-
import Mat33 from '../
|
3
|
-
import Rect2 from '../
|
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
|
-
|
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.
|
131
|
+
json: text.serializeToJSON(),
|
131
132
|
};
|
132
133
|
}
|
133
134
|
});
|
134
|
-
return
|
135
|
+
return {
|
135
136
|
textObjects,
|
136
137
|
transform: this.transform.toArray(),
|
137
138
|
style: serializableStyle,
|
138
|
-
}
|
139
|
+
};
|
139
140
|
}
|
140
|
-
static deserializeFromString(
|
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 '../
|
2
|
-
import Mat33 from '../
|
3
|
-
import Rect2 from '../
|
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
|
16
|
+
protected serializeToJSON(): string | null;
|
17
17
|
}
|
@@ -1,4 +1,9 @@
|
|
1
|
-
|
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
|
-
|
34
|
+
serializeToJSON() {
|
30
35
|
return JSON.stringify({
|
31
36
|
html: this.svgObject.outerHTML,
|
32
37
|
});
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import AbstractRenderer from '../../rendering/renderers/AbstractRenderer';
|
2
|
-
import Rect2 from '../../
|
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
|
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
|
27
|
+
private previewPath;
|
28
|
+
private previewStroke;
|
24
29
|
preview(renderer: AbstractRenderer): void;
|
25
30
|
build(): Stroke;
|
26
31
|
private roundPoint;
|