js-draw 1.3.1 → 1.4.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/README.md +1 -1
- package/dist/Editor.css +55 -13
- package/dist/bundle.js +2 -2
- package/dist/bundledStyles.js +1 -1
- package/dist/cjs/Editor.d.ts +36 -3
- package/dist/cjs/Editor.js +63 -26
- package/dist/cjs/commands/Erase.js +1 -1
- package/dist/cjs/commands/UnresolvedCommand.d.ts +1 -1
- package/dist/cjs/components/AbstractComponent.d.ts +1 -1
- package/dist/cjs/components/AbstractComponent.js +1 -1
- package/dist/cjs/components/BackgroundComponent.d.ts +1 -1
- package/dist/cjs/components/BackgroundComponent.js +1 -1
- package/dist/cjs/{EditorImage.d.ts → image/EditorImage.d.ts} +30 -8
- package/dist/cjs/{EditorImage.js → image/EditorImage.js} +51 -7
- package/dist/cjs/image/export/editorImageToSVG.d.ts +8 -0
- package/dist/cjs/image/export/editorImageToSVG.js +49 -0
- package/dist/cjs/image/export/setExportedSVGSize.d.ts +6 -0
- package/dist/cjs/image/export/setExportedSVGSize.js +25 -0
- package/dist/cjs/image/lib.d.ts +1 -0
- package/dist/cjs/image/lib.js +8 -0
- package/dist/cjs/lib.d.ts +1 -1
- package/dist/cjs/lib.js +2 -3
- package/dist/cjs/localizations/comments.d.ts +6 -0
- package/dist/cjs/localizations/comments.js +10 -0
- package/dist/cjs/localizations/es.js +68 -48
- package/dist/cjs/rendering/caching/RenderingCache.d.ts +1 -1
- package/dist/cjs/rendering/caching/RenderingCacheNode.d.ts +1 -1
- package/dist/cjs/rendering/caching/RenderingCacheNode.js +4 -3
- package/dist/cjs/toolbar/AbstractToolbar.d.ts +11 -3
- package/dist/cjs/toolbar/AbstractToolbar.js +20 -6
- package/dist/cjs/toolbar/EdgeToolbar.js +5 -6
- package/dist/cjs/toolbar/IconProvider.d.ts +1 -0
- package/dist/cjs/toolbar/IconProvider.js +43 -0
- package/dist/cjs/toolbar/widgets/ActionButtonWidget.d.ts +3 -1
- package/dist/cjs/toolbar/widgets/ActionButtonWidget.js +19 -1
- package/dist/cjs/toolbar/widgets/BaseToolWidget.d.ts +1 -0
- package/dist/cjs/toolbar/widgets/BaseToolWidget.js +3 -0
- package/dist/cjs/toolbar/widgets/BaseWidget.d.ts +5 -0
- package/dist/cjs/toolbar/widgets/BaseWidget.js +30 -2
- package/dist/cjs/toolbar/widgets/DocumentPropertiesWidget.js +1 -1
- package/dist/cjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
- package/dist/cjs/toolbar/widgets/HandToolWidget.js +6 -0
- package/dist/cjs/toolbar/widgets/InsertImageWidget.js +1 -1
- package/dist/cjs/toolbar/widgets/OverflowWidget.d.ts +1 -0
- package/dist/cjs/toolbar/widgets/OverflowWidget.js +3 -0
- package/dist/cjs/toolbar/widgets/SaveActionWidget.d.ts +1 -0
- package/dist/cjs/toolbar/widgets/SaveActionWidget.js +3 -0
- package/dist/cjs/tools/BaseTool.d.ts +3 -0
- package/dist/cjs/tools/BaseTool.js +13 -2
- package/dist/cjs/tools/FindTool.d.ts +1 -0
- package/dist/cjs/tools/FindTool.js +4 -1
- package/dist/cjs/tools/PanZoom.d.ts +1 -0
- package/dist/cjs/tools/PanZoom.js +4 -0
- package/dist/cjs/tools/Pen.d.ts +0 -1
- package/dist/cjs/tools/Pen.js +1 -4
- package/dist/cjs/tools/PipetteTool.d.ts +1 -0
- package/dist/cjs/tools/PipetteTool.js +3 -0
- package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +1 -0
- package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.js +3 -0
- package/dist/cjs/tools/SelectionTool/Selection.d.ts +2 -0
- package/dist/cjs/tools/SelectionTool/Selection.js +44 -8
- package/dist/cjs/tools/SelectionTool/SelectionHandle.d.ts +14 -6
- package/dist/cjs/tools/SelectionTool/SelectionHandle.js +26 -8
- package/dist/cjs/tools/SelectionTool/SelectionTool.js +5 -0
- package/dist/cjs/tools/SoundUITool.d.ts +1 -0
- package/dist/cjs/tools/SoundUITool.js +4 -1
- package/dist/cjs/tools/TextTool.js +2 -2
- package/dist/cjs/tools/ToolController.d.ts +2 -0
- package/dist/cjs/tools/ToolController.js +13 -2
- package/dist/cjs/tools/ToolSwitcherShortcut.d.ts +1 -0
- package/dist/cjs/tools/ToolSwitcherShortcut.js +3 -0
- package/dist/cjs/types.d.ts +9 -4
- package/dist/cjs/types.js +4 -3
- package/dist/cjs/util/ReactiveValue.d.ts +1 -1
- package/dist/cjs/util/ReactiveValue.js +2 -2
- package/dist/cjs/version.js +1 -1
- package/dist/mjs/Editor.d.ts +36 -3
- package/dist/mjs/Editor.mjs +64 -27
- package/dist/mjs/Editor.toSVGAsync.test.d.ts +1 -0
- package/dist/mjs/commands/Erase.mjs +1 -1
- package/dist/mjs/commands/UnresolvedCommand.d.ts +1 -1
- package/dist/mjs/components/AbstractComponent.d.ts +1 -1
- package/dist/mjs/components/AbstractComponent.mjs +1 -1
- package/dist/mjs/components/BackgroundComponent.d.ts +1 -1
- package/dist/mjs/components/BackgroundComponent.mjs +1 -1
- package/dist/mjs/{EditorImage.d.ts → image/EditorImage.d.ts} +30 -8
- package/dist/mjs/{EditorImage.mjs → image/EditorImage.mjs} +51 -7
- package/dist/mjs/image/EditorImage.test.d.ts +1 -0
- package/dist/mjs/image/export/editorImageToSVG.d.ts +8 -0
- package/dist/mjs/image/export/editorImageToSVG.mjs +41 -0
- package/dist/mjs/image/export/setExportedSVGSize.d.ts +6 -0
- package/dist/mjs/image/export/setExportedSVGSize.mjs +23 -0
- package/dist/mjs/image/lib.d.ts +1 -0
- package/dist/mjs/image/lib.mjs +1 -0
- package/dist/mjs/lib.d.ts +1 -1
- package/dist/mjs/lib.mjs +1 -1
- package/dist/mjs/localizations/comments.d.ts +6 -0
- package/dist/mjs/localizations/comments.mjs +8 -0
- package/dist/mjs/localizations/es.mjs +68 -48
- package/dist/mjs/rendering/caching/RenderingCache.d.ts +1 -1
- package/dist/mjs/rendering/caching/RenderingCacheNode.d.ts +1 -1
- package/dist/mjs/rendering/caching/RenderingCacheNode.mjs +4 -3
- package/dist/mjs/toolbar/AbstractToolbar.d.ts +11 -3
- package/dist/mjs/toolbar/AbstractToolbar.mjs +20 -6
- package/dist/mjs/toolbar/EdgeToolbar.mjs +5 -6
- package/dist/mjs/toolbar/IconProvider.d.ts +1 -0
- package/dist/mjs/toolbar/IconProvider.mjs +43 -0
- package/dist/mjs/toolbar/widgets/ActionButtonWidget.d.ts +3 -1
- package/dist/mjs/toolbar/widgets/ActionButtonWidget.mjs +21 -2
- package/dist/mjs/toolbar/widgets/BaseToolWidget.d.ts +1 -0
- package/dist/mjs/toolbar/widgets/BaseToolWidget.mjs +3 -0
- package/dist/mjs/toolbar/widgets/BaseWidget.d.ts +5 -0
- package/dist/mjs/toolbar/widgets/BaseWidget.mjs +30 -2
- package/dist/mjs/toolbar/widgets/DocumentPropertiesWidget.mjs +1 -1
- package/dist/mjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
- package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +6 -0
- package/dist/mjs/toolbar/widgets/InsertImageWidget.mjs +1 -1
- package/dist/mjs/toolbar/widgets/OverflowWidget.d.ts +1 -0
- package/dist/mjs/toolbar/widgets/OverflowWidget.mjs +3 -0
- package/dist/mjs/toolbar/widgets/SaveActionWidget.d.ts +1 -0
- package/dist/mjs/toolbar/widgets/SaveActionWidget.mjs +3 -0
- package/dist/mjs/tools/BaseTool.d.ts +3 -0
- package/dist/mjs/tools/BaseTool.mjs +13 -2
- package/dist/mjs/tools/FindTool.d.ts +1 -0
- package/dist/mjs/tools/FindTool.mjs +4 -1
- package/dist/mjs/tools/PanZoom.d.ts +1 -0
- package/dist/mjs/tools/PanZoom.mjs +4 -0
- package/dist/mjs/tools/Pen.d.ts +0 -1
- package/dist/mjs/tools/Pen.mjs +1 -4
- package/dist/mjs/tools/PipetteTool.d.ts +1 -0
- package/dist/mjs/tools/PipetteTool.mjs +3 -0
- package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +1 -0
- package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.mjs +3 -0
- package/dist/mjs/tools/SelectionTool/Selection.d.ts +2 -0
- package/dist/mjs/tools/SelectionTool/Selection.mjs +45 -9
- package/dist/mjs/tools/SelectionTool/SelectionHandle.d.ts +14 -6
- package/dist/mjs/tools/SelectionTool/SelectionHandle.mjs +25 -7
- package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +5 -0
- package/dist/mjs/tools/SoundUITool.d.ts +1 -0
- package/dist/mjs/tools/SoundUITool.mjs +4 -1
- package/dist/mjs/tools/TextTool.mjs +2 -2
- package/dist/mjs/tools/ToolController.d.ts +2 -0
- package/dist/mjs/tools/ToolController.mjs +13 -2
- package/dist/mjs/tools/ToolSwitcherShortcut.d.ts +1 -0
- package/dist/mjs/tools/ToolSwitcherShortcut.mjs +3 -0
- package/dist/mjs/types.d.ts +9 -4
- package/dist/mjs/types.mjs +4 -3
- package/dist/mjs/util/ReactiveValue.d.ts +1 -1
- package/dist/mjs/util/ReactiveValue.mjs +2 -2
- package/dist/mjs/version.mjs +1 -1
- package/package.json +5 -5
- package/src/Editor.scss +6 -0
- package/src/toolbar/EdgeToolbar.scss +19 -2
- package/src/tools/SelectionTool/SelectionTool.scss +74 -0
- package/src/tools/tools.scss +1 -1
- package/src/tools/SelectionTool/SelectionTool.css +0 -35
- /package/dist/cjs/{EditorImage.test.d.ts → Editor.toSVGAsync.test.d.ts} +0 -0
- /package/dist/{mjs → cjs/image}/EditorImage.test.d.ts +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.handleSize = exports.
|
3
|
+
exports.handleSize = exports.HandleAction = void 0;
|
4
4
|
const assertions_1 = require("../../util/assertions");
|
5
5
|
const math_1 = require("@js-draw/math");
|
6
6
|
const SelectionTool_1 = require("./SelectionTool");
|
@@ -8,12 +8,18 @@ var HandleShape;
|
|
8
8
|
(function (HandleShape) {
|
9
9
|
HandleShape[HandleShape["Circle"] = 0] = "Circle";
|
10
10
|
HandleShape[HandleShape["Square"] = 1] = "Square";
|
11
|
-
})(HandleShape || (
|
11
|
+
})(HandleShape || (HandleShape = {}));
|
12
|
+
var HandleAction;
|
13
|
+
(function (HandleAction) {
|
14
|
+
HandleAction["ResizeXY"] = "resize-xy";
|
15
|
+
HandleAction["Rotate"] = "rotate";
|
16
|
+
HandleAction["ResizeX"] = "resize-x";
|
17
|
+
HandleAction["ResizeY"] = "resize-y";
|
18
|
+
})(HandleAction || (exports.HandleAction = HandleAction = {}));
|
12
19
|
exports.handleSize = 30;
|
13
20
|
class SelectionHandle {
|
14
|
-
constructor(
|
15
|
-
this.
|
16
|
-
this.parentSide = parentSide;
|
21
|
+
constructor(presentation, parent, viewport, onDragStart, onDragUpdate, onDragEnd) {
|
22
|
+
this.presentation = presentation;
|
17
23
|
this.parent = parent;
|
18
24
|
this.viewport = viewport;
|
19
25
|
this.onDragStart = onDragStart;
|
@@ -21,8 +27,20 @@ class SelectionHandle {
|
|
21
27
|
this.onDragEnd = onDragEnd;
|
22
28
|
this.dragLastPos = null;
|
23
29
|
this.element = document.createElement('div');
|
24
|
-
this.element.classList.add(`${SelectionTool_1.cssPrefix}handle`);
|
25
|
-
|
30
|
+
this.element.classList.add(`${SelectionTool_1.cssPrefix}handle`, `${SelectionTool_1.cssPrefix}${presentation.action}`);
|
31
|
+
this.parentSide = presentation.side;
|
32
|
+
const icon = presentation.icon;
|
33
|
+
if (icon) {
|
34
|
+
this.element.appendChild(icon);
|
35
|
+
icon.classList.add('icon');
|
36
|
+
}
|
37
|
+
if (presentation.action === HandleAction.Rotate) {
|
38
|
+
this.shape = HandleShape.Circle;
|
39
|
+
}
|
40
|
+
else {
|
41
|
+
this.shape = HandleShape.Square;
|
42
|
+
}
|
43
|
+
switch (this.shape) {
|
26
44
|
case HandleShape.Circle:
|
27
45
|
this.element.classList.add(`${SelectionTool_1.cssPrefix}circle`);
|
28
46
|
break;
|
@@ -30,7 +48,7 @@ class SelectionHandle {
|
|
30
48
|
this.element.classList.add(`${SelectionTool_1.cssPrefix}square`);
|
31
49
|
break;
|
32
50
|
default:
|
33
|
-
(0, assertions_1.assertUnreachable)(shape);
|
51
|
+
(0, assertions_1.assertUnreachable)(this.shape);
|
34
52
|
}
|
35
53
|
this.updatePosition();
|
36
54
|
}
|
@@ -33,6 +33,11 @@ class SelectionTool extends BaseTool_1.default {
|
|
33
33
|
// The selection box could be using the wet ink display if its transformation
|
34
34
|
// hasn't been finalized yet. Clear before updating the UI.
|
35
35
|
this.editor.clearWetInk();
|
36
|
+
// If not currently selecting, ensure that the selection box
|
37
|
+
// is large enough.
|
38
|
+
if (!this.expandingSelectionBox) {
|
39
|
+
this.selectionBox?.padRegion();
|
40
|
+
}
|
36
41
|
this.selectionBox?.updateUI();
|
37
42
|
});
|
38
43
|
this.editor.handleKeyEventsFrom(this.handleOverlay);
|
@@ -14,6 +14,7 @@ export default class SoundUITool extends BaseTool {
|
|
14
14
|
private toggleButton;
|
15
15
|
private toggleButtonContainer;
|
16
16
|
constructor(editor: Editor, description: string);
|
17
|
+
canReceiveInputInReadOnlyEditor(): boolean;
|
17
18
|
private updateToggleButtonText;
|
18
19
|
setEnabled(enabled: boolean): void;
|
19
20
|
onKeyPress(event: KeyPressEvent): boolean;
|
@@ -105,6 +105,9 @@ class SoundUITool extends BaseTool_1.default {
|
|
105
105
|
this.updateToggleButtonText();
|
106
106
|
editor.createHTMLOverlay(this.toggleButtonContainer);
|
107
107
|
}
|
108
|
+
canReceiveInputInReadOnlyEditor() {
|
109
|
+
return true;
|
110
|
+
}
|
108
111
|
updateToggleButtonText() {
|
109
112
|
const containerEnabledClass = 'sound-ui-tool-enabled';
|
110
113
|
if (this.isEnabled()) {
|
@@ -118,7 +121,7 @@ class SoundUITool extends BaseTool_1.default {
|
|
118
121
|
}
|
119
122
|
setEnabled(enabled) {
|
120
123
|
super.setEnabled(enabled);
|
121
|
-
if (!
|
124
|
+
if (!this.isEnabled()) {
|
122
125
|
this.soundFeedback?.close();
|
123
126
|
this.soundFeedback = null;
|
124
127
|
}
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
6
|
const TextComponent_1 = __importDefault(require("../components/TextComponent"));
|
7
|
-
const EditorImage_1 = __importDefault(require("../EditorImage"));
|
7
|
+
const EditorImage_1 = __importDefault(require("../image/EditorImage"));
|
8
8
|
const math_1 = require("@js-draw/math");
|
9
9
|
const Pointer_1 = require("../Pointer");
|
10
10
|
const types_1 = require("../types");
|
@@ -193,7 +193,7 @@ class TextTool extends BaseTool_1.default {
|
|
193
193
|
}
|
194
194
|
setEnabled(enabled) {
|
195
195
|
super.setEnabled(enabled);
|
196
|
-
if (!
|
196
|
+
if (!this.isEnabled()) {
|
197
197
|
this.flushInput();
|
198
198
|
}
|
199
199
|
this.textEditOverlay.style.display = enabled ? 'block' : 'none';
|
@@ -9,6 +9,7 @@ export default class ToolController implements InputEventListener {
|
|
9
9
|
private activeTool;
|
10
10
|
private primaryToolGroup;
|
11
11
|
private inputPipeline;
|
12
|
+
private isEditorReadOnly;
|
12
13
|
/** @internal */
|
13
14
|
constructor(editor: Editor, localization: ToolLocalization);
|
14
15
|
setTools(tools: BaseTool[], primaryToolGroup?: ToolEnabledGroup): void;
|
@@ -29,4 +30,5 @@ export default class ToolController implements InputEventListener {
|
|
29
30
|
*/
|
30
31
|
addInputMapper(mapper: InputMapper): void;
|
31
32
|
getMatchingTools<Type extends BaseTool>(type: new (...args: any[]) => Type): Type[];
|
33
|
+
onEditorDestroyed(): void;
|
32
34
|
}
|
@@ -51,6 +51,7 @@ class ToolController {
|
|
51
51
|
/** @internal */
|
52
52
|
constructor(editor, localization) {
|
53
53
|
this.activeTool = null;
|
54
|
+
this.isEditorReadOnly = editor.isReadOnlyReactiveValue();
|
54
55
|
this.inputPipeline = new InputPipeline_1.default();
|
55
56
|
this.inputPipeline.setEmitListener(event => this.onEventInternal(event));
|
56
57
|
const primaryToolGroup = new ToolEnabledGroup_1.default();
|
@@ -135,6 +136,10 @@ class ToolController {
|
|
135
136
|
}
|
136
137
|
// @internal use `dispatchEvent` rather than calling `onEvent` directly.
|
137
138
|
onEventInternal(event) {
|
139
|
+
const isEditorReadOnly = this.isEditorReadOnly.get();
|
140
|
+
const canToolReceiveInput = (tool) => {
|
141
|
+
return tool.isEnabled() && (!isEditorReadOnly || tool.canReceiveInputInReadOnlyEditor());
|
142
|
+
};
|
138
143
|
let handled = false;
|
139
144
|
if (event.kind === inputEvents_1.InputEvtType.PointerDownEvt) {
|
140
145
|
let canOnlySendToActiveTool = false;
|
@@ -145,7 +150,7 @@ class ToolController {
|
|
145
150
|
if (canOnlySendToActiveTool && tool !== this.activeTool) {
|
146
151
|
continue;
|
147
152
|
}
|
148
|
-
if (tool
|
153
|
+
if (canToolReceiveInput(tool) && tool.onEvent(event)) {
|
149
154
|
if (this.activeTool !== tool) {
|
150
155
|
this.activeTool?.onEvent({ kind: inputEvents_1.InputEvtType.GestureCancelEvt });
|
151
156
|
}
|
@@ -179,7 +184,7 @@ class ToolController {
|
|
179
184
|
}
|
180
185
|
else {
|
181
186
|
for (const tool of this.tools) {
|
182
|
-
if (!tool
|
187
|
+
if (!canToolReceiveInput(tool)) {
|
183
188
|
continue;
|
184
189
|
}
|
185
190
|
handled = tool.onEvent(event);
|
@@ -213,5 +218,11 @@ class ToolController {
|
|
213
218
|
getMatchingTools(type) {
|
214
219
|
return this.tools.filter(tool => tool instanceof type);
|
215
220
|
}
|
221
|
+
// @internal
|
222
|
+
onEditorDestroyed() {
|
223
|
+
for (const tool of this.tools) {
|
224
|
+
tool.onDestroy();
|
225
|
+
}
|
226
|
+
}
|
216
227
|
}
|
217
228
|
exports.default = ToolController;
|
@@ -17,6 +17,9 @@ class ToolSwitcherShortcut extends BaseTool_1.default {
|
|
17
17
|
super(editor.notifier, editor.localization.changeTool);
|
18
18
|
this.editor = editor;
|
19
19
|
}
|
20
|
+
canReceiveInputInReadOnlyEditor() {
|
21
|
+
return true;
|
22
|
+
}
|
20
23
|
// @internal
|
21
24
|
onKeyPress({ key }) {
|
22
25
|
const toolController = this.editor.toolController;
|
package/dist/cjs/types.d.ts
CHANGED
@@ -16,12 +16,13 @@ export declare enum EditorEventType {
|
|
16
16
|
ViewportChanged = 7,
|
17
17
|
DisplayResized = 8,
|
18
18
|
SelectionUpdated = 9,
|
19
|
+
ReadOnlyModeToggled = 10,
|
19
20
|
/** @internal */
|
20
|
-
ColorPickerToggled =
|
21
|
+
ColorPickerToggled = 11,
|
21
22
|
/** @internal */
|
22
|
-
ColorPickerColorSelected =
|
23
|
+
ColorPickerColorSelected = 12,
|
23
24
|
/** @deprecated @internal */
|
24
|
-
ToolbarDropdownShown =
|
25
|
+
ToolbarDropdownShown = 13
|
25
26
|
}
|
26
27
|
export declare enum UndoEventType {
|
27
28
|
CommandDone = 0,
|
@@ -66,6 +67,10 @@ export interface SelectionUpdated {
|
|
66
67
|
readonly selectedComponents: AbstractComponent[];
|
67
68
|
readonly tool: BaseTool;
|
68
69
|
}
|
70
|
+
export interface ReadOnlyToggled {
|
71
|
+
readonly kind: EditorEventType.ReadOnlyModeToggled;
|
72
|
+
readonly editorIsReadOnly: boolean;
|
73
|
+
}
|
69
74
|
export interface ColorPickerToggled {
|
70
75
|
readonly kind: EditorEventType.ColorPickerToggled;
|
71
76
|
readonly open: boolean;
|
@@ -79,7 +84,7 @@ export interface ToolbarDropdownShownEvent {
|
|
79
84
|
readonly fromToplevelDropdown: boolean;
|
80
85
|
readonly layoutManager: WidgetContentLayoutManager;
|
81
86
|
}
|
82
|
-
export type EditorEventDataType = EditorToolEvent | EditorObjectEvent | EditorViewportChangedEvent | DisplayResizedEvent | EditorUndoStackUpdated | CommandDoneEvent | CommandUndoneEvent | SelectionUpdated | ColorPickerToggled | ColorPickerColorSelected | ToolbarDropdownShownEvent;
|
87
|
+
export type EditorEventDataType = EditorToolEvent | EditorObjectEvent | EditorViewportChangedEvent | DisplayResizedEvent | EditorUndoStackUpdated | CommandDoneEvent | CommandUndoneEvent | SelectionUpdated | ReadOnlyToggled | ColorPickerToggled | ColorPickerColorSelected | ToolbarDropdownShownEvent;
|
83
88
|
export type OnProgressListener = (amountProcessed: number, totalToProcess: number) => Promise<void> | null | void;
|
84
89
|
export type ComponentAddedListener = (component: AbstractComponent) => Promise<void> | void;
|
85
90
|
export type OnDetermineExportRectListener = (exportRect: Rect2, options?: {
|
package/dist/cjs/types.js
CHANGED
@@ -14,12 +14,13 @@ var EditorEventType;
|
|
14
14
|
EditorEventType[EditorEventType["ViewportChanged"] = 7] = "ViewportChanged";
|
15
15
|
EditorEventType[EditorEventType["DisplayResized"] = 8] = "DisplayResized";
|
16
16
|
EditorEventType[EditorEventType["SelectionUpdated"] = 9] = "SelectionUpdated";
|
17
|
+
EditorEventType[EditorEventType["ReadOnlyModeToggled"] = 10] = "ReadOnlyModeToggled";
|
17
18
|
/** @internal */
|
18
|
-
EditorEventType[EditorEventType["ColorPickerToggled"] =
|
19
|
+
EditorEventType[EditorEventType["ColorPickerToggled"] = 11] = "ColorPickerToggled";
|
19
20
|
/** @internal */
|
20
|
-
EditorEventType[EditorEventType["ColorPickerColorSelected"] =
|
21
|
+
EditorEventType[EditorEventType["ColorPickerColorSelected"] = 12] = "ColorPickerColorSelected";
|
21
22
|
/** @deprecated @internal */
|
22
|
-
EditorEventType[EditorEventType["ToolbarDropdownShown"] =
|
23
|
+
EditorEventType[EditorEventType["ToolbarDropdownShown"] = 13] = "ToolbarDropdownShown";
|
23
24
|
})(EditorEventType || (exports.EditorEventType = EditorEventType = {}));
|
24
25
|
// Types of `EditorUndoStackUpdated` events.
|
25
26
|
var UndoEventType;
|
@@ -55,7 +55,7 @@ export declare abstract class ReactiveValue<T> {
|
|
55
55
|
}
|
56
56
|
export declare abstract class MutableReactiveValue<T> extends ReactiveValue<T> {
|
57
57
|
/**
|
58
|
-
* Changes the value of this and fires all update listeners.
|
58
|
+
* Changes the value of this and, if different, fires all update listeners.
|
59
59
|
*
|
60
60
|
* @see {@link onUpdate}
|
61
61
|
*/
|
@@ -59,7 +59,7 @@ class ReactiveValue {
|
|
59
59
|
*/
|
60
60
|
static fromCallback(callback, sourceValues) {
|
61
61
|
const result = new ReactiveValueImpl(callback());
|
62
|
-
const resultRef = window.WeakRef ? new WeakRef(result) : { deref: () => result };
|
62
|
+
const resultRef = window.WeakRef ? new window.WeakRef(result) : { deref: () => result };
|
63
63
|
for (const value of sourceValues) {
|
64
64
|
const listener = value.onUpdate(() => {
|
65
65
|
// Use resultRef to allow `result` to be garbage collected
|
@@ -98,7 +98,7 @@ exports.ReactiveValue = ReactiveValue;
|
|
98
98
|
class MutableReactiveValue extends ReactiveValue {
|
99
99
|
static fromProperty(sourceValue, propertyName) {
|
100
100
|
const child = ReactiveValue.fromInitialValue(sourceValue.get()[propertyName]);
|
101
|
-
const childRef = window.WeakRef ? new WeakRef(child) : { deref: () => child };
|
101
|
+
const childRef = window.WeakRef ? new window.WeakRef(child) : { deref: () => child };
|
102
102
|
// When the source is updated...
|
103
103
|
const sourceListener = sourceValue.onUpdate(newValue => {
|
104
104
|
const childValue = childRef.deref();
|
package/dist/cjs/version.js
CHANGED
package/dist/mjs/Editor.d.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import EditorImage from './EditorImage';
|
1
|
+
import EditorImage from './image/EditorImage';
|
2
2
|
import ToolController from './tools/ToolController';
|
3
3
|
import { EditorNotifier, ImageLoader } from './types';
|
4
4
|
import { HTMLPointerEventFilter, InputEvtType } from './inputEvents';
|
@@ -16,6 +16,7 @@ import KeyBinding from './shortcuts/KeyBinding';
|
|
16
16
|
import AbstractToolbar from './toolbar/AbstractToolbar';
|
17
17
|
import RenderablePathSpec from './rendering/RenderablePathSpec';
|
18
18
|
import { AboutDialogEntry } from './dialogs/makeAboutDialog';
|
19
|
+
import ReactiveValue, { MutableReactiveValue } from './util/ReactiveValue';
|
19
20
|
/**
|
20
21
|
* Provides settings to an instance of an editor. See the Editor {@link Editor.constructor}.
|
21
22
|
*
|
@@ -152,6 +153,7 @@ export declare class Editor {
|
|
152
153
|
private accessibilityAnnounceArea;
|
153
154
|
private accessibilityControlArea;
|
154
155
|
private eventListenerTargets;
|
156
|
+
private readOnly;
|
155
157
|
private settings;
|
156
158
|
/**
|
157
159
|
* @example
|
@@ -269,6 +271,13 @@ export declare class Editor {
|
|
269
271
|
* passed to the editor.
|
270
272
|
*/
|
271
273
|
handleKeyEventsFrom(elem: HTMLElement, filter?: (event: KeyboardEvent) => boolean): void;
|
274
|
+
/**
|
275
|
+
* Attempts to prevent **user-triggered** events from modifying
|
276
|
+
* the content of the image.
|
277
|
+
*/
|
278
|
+
setReadOnly(readOnly: boolean): void;
|
279
|
+
isReadOnlyReactiveValue(): ReactiveValue<boolean>;
|
280
|
+
isReadOnly(): MutableReactiveValue<boolean>;
|
272
281
|
/** `apply` a command. `command` will be announced for accessibility. */
|
273
282
|
dispatch(command: Command, addToHistory?: boolean): void | Promise<void>;
|
274
283
|
/**
|
@@ -386,10 +395,31 @@ export declare class Editor {
|
|
386
395
|
/**
|
387
396
|
* Converts the editor's content into an SVG image.
|
388
397
|
*
|
398
|
+
* If the output SVG has width or height less than `options.minDimension`, its size
|
399
|
+
* will be increased.
|
400
|
+
*
|
389
401
|
* @see
|
390
402
|
* {@link SVGRenderer}
|
391
403
|
*/
|
392
|
-
toSVG(
|
404
|
+
toSVG(options?: {
|
405
|
+
minDimension?: number;
|
406
|
+
}): SVGElement;
|
407
|
+
/**
|
408
|
+
* Converts the editor's content into an SVG image in an asynchronous,
|
409
|
+
* but **potentially lossy** way.
|
410
|
+
*
|
411
|
+
* **Warning**: If the image is being edited during an async rendering, edited components
|
412
|
+
* may not be rendered.
|
413
|
+
*
|
414
|
+
* Like {@link toSVG}, but can be configured to briefly pause after processing every
|
415
|
+
* `pauseAfterCount` items. This can prevent the editor from becoming unresponsive
|
416
|
+
* when saving very large images.
|
417
|
+
*/
|
418
|
+
toSVGAsync(options?: {
|
419
|
+
minDimension?: number;
|
420
|
+
pauseAfterCount?: number;
|
421
|
+
onProgress?: (processedCountInLayer: number, totalToProcessInLayer: number) => Promise<void | boolean>;
|
422
|
+
}): Promise<SVGElement>;
|
393
423
|
/**
|
394
424
|
* Load editor data from an `ImageLoader` (e.g. an {@link SVGLoader}).
|
395
425
|
*
|
@@ -435,7 +465,10 @@ export declare class Editor {
|
|
435
465
|
* Shows an information dialog with legal notices.
|
436
466
|
*/
|
437
467
|
showAboutDialog(): void;
|
438
|
-
/**
|
468
|
+
/**
|
469
|
+
* Removes and **destroys** the editor. The editor cannot be added to a parent
|
470
|
+
* again after calling this method.
|
471
|
+
*/
|
439
472
|
remove(): void;
|
440
473
|
}
|
441
474
|
export default Editor;
|
package/dist/mjs/Editor.mjs
CHANGED
@@ -1,14 +1,13 @@
|
|
1
|
-
import EditorImage from './EditorImage.mjs';
|
1
|
+
import EditorImage from './image/EditorImage.mjs';
|
2
2
|
import ToolController from './tools/ToolController.mjs';
|
3
3
|
import { EditorEventType } from './types.mjs';
|
4
4
|
import { InputEvtType, keyUpEventFromHTMLEvent, keyPressEventFromHTMLEvent } from './inputEvents.mjs';
|
5
5
|
import UndoRedoHistory from './UndoRedoHistory.mjs';
|
6
6
|
import Viewport from './Viewport.mjs';
|
7
7
|
import EventDispatcher from './EventDispatcher.mjs';
|
8
|
-
import { Vec2, Vec3, Color4, Mat33
|
8
|
+
import { Vec2, Vec3, Color4, Mat33 } from '@js-draw/math';
|
9
9
|
import Display, { RenderingMode } from './rendering/Display.mjs';
|
10
|
-
import
|
11
|
-
import SVGLoader, { svgLoaderAutoresizeClassName } from './SVGLoader.mjs';
|
10
|
+
import SVGLoader from './SVGLoader.mjs';
|
12
11
|
import Pointer from './Pointer.mjs';
|
13
12
|
import getLocalizationTable from './localizations/getLocalizationTable.mjs';
|
14
13
|
import IconProvider from './toolbar/IconProvider.mjs';
|
@@ -26,6 +25,8 @@ import StrokeKeyboardControl from './tools/InputFilter/StrokeKeyboardControl.m
|
|
26
25
|
import guessKeyCodeFromKey from './util/guessKeyCodeFromKey.mjs';
|
27
26
|
import makeAboutDialog from './dialogs/makeAboutDialog.mjs';
|
28
27
|
import version from './version.mjs';
|
28
|
+
import { editorImageToSVGSync, editorImageToSVGAsync } from './image/export/editorImageToSVG.mjs';
|
29
|
+
import { MutableReactiveValue } from './util/ReactiveValue.mjs';
|
29
30
|
/**
|
30
31
|
* The main entrypoint for the full editor.
|
31
32
|
*
|
@@ -110,6 +111,7 @@ export class Editor {
|
|
110
111
|
if (this.settings.minZoom > this.settings.maxZoom) {
|
111
112
|
throw new Error('Minimum zoom must be lesser than maximum zoom!');
|
112
113
|
}
|
114
|
+
this.readOnly = MutableReactiveValue.fromInitialValue(false);
|
113
115
|
this.icons = this.settings.iconProvider;
|
114
116
|
this.shortcuts = new KeyboardShortcutManager(this.settings.keyboardShortcutOverrides);
|
115
117
|
this.container = document.createElement('div');
|
@@ -660,6 +662,26 @@ export class Editor {
|
|
660
662
|
};
|
661
663
|
this.eventListenerTargets.push(elem);
|
662
664
|
}
|
665
|
+
/**
|
666
|
+
* Attempts to prevent **user-triggered** events from modifying
|
667
|
+
* the content of the image.
|
668
|
+
*/
|
669
|
+
setReadOnly(readOnly) {
|
670
|
+
if (readOnly !== this.readOnly.get()) {
|
671
|
+
this.readOnly.set(readOnly);
|
672
|
+
this.notifier.dispatch(EditorEventType.ReadOnlyModeToggled, {
|
673
|
+
kind: EditorEventType.ReadOnlyModeToggled,
|
674
|
+
editorIsReadOnly: readOnly,
|
675
|
+
});
|
676
|
+
}
|
677
|
+
}
|
678
|
+
// @internal
|
679
|
+
isReadOnlyReactiveValue() {
|
680
|
+
return this.readOnly;
|
681
|
+
}
|
682
|
+
isReadOnly() {
|
683
|
+
return this.readOnly;
|
684
|
+
}
|
663
685
|
/** `apply` a command. `command` will be announced for accessibility. */
|
664
686
|
dispatch(command, addToHistory = true) {
|
665
687
|
const dispatchResult = this.dispatchNoAnnounce(command, addToHistory);
|
@@ -938,31 +960,42 @@ export class Editor {
|
|
938
960
|
/**
|
939
961
|
* Converts the editor's content into an SVG image.
|
940
962
|
*
|
963
|
+
* If the output SVG has width or height less than `options.minDimension`, its size
|
964
|
+
* will be increased.
|
965
|
+
*
|
941
966
|
* @see
|
942
967
|
* {@link SVGRenderer}
|
943
968
|
*/
|
944
|
-
toSVG() {
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
969
|
+
toSVG(options) {
|
970
|
+
return editorImageToSVGSync(this.image, options ?? {});
|
971
|
+
}
|
972
|
+
/**
|
973
|
+
* Converts the editor's content into an SVG image in an asynchronous,
|
974
|
+
* but **potentially lossy** way.
|
975
|
+
*
|
976
|
+
* **Warning**: If the image is being edited during an async rendering, edited components
|
977
|
+
* may not be rendered.
|
978
|
+
*
|
979
|
+
* Like {@link toSVG}, but can be configured to briefly pause after processing every
|
980
|
+
* `pauseAfterCount` items. This can prevent the editor from becoming unresponsive
|
981
|
+
* when saving very large images.
|
982
|
+
*/
|
983
|
+
async toSVGAsync(options = {}) {
|
984
|
+
const pauseAfterCount = options.pauseAfterCount ?? 100;
|
985
|
+
return await editorImageToSVGAsync(this.image, async (_component, processedCount, totalComponents) => {
|
986
|
+
if (options.onProgress) {
|
987
|
+
const shouldContinue = await options.onProgress(processedCount, totalComponents);
|
988
|
+
if (shouldContinue === false) {
|
989
|
+
return false;
|
990
|
+
}
|
991
|
+
}
|
992
|
+
if (processedCount % pauseAfterCount === 0) {
|
993
|
+
await untilNextAnimationFrame();
|
994
|
+
}
|
995
|
+
return true;
|
996
|
+
}, {
|
997
|
+
minDimension: options.minDimension,
|
998
|
+
});
|
966
999
|
}
|
967
1000
|
/**
|
968
1001
|
* Load editor data from an `ImageLoader` (e.g. an {@link SVGLoader}).
|
@@ -1114,10 +1147,14 @@ export class Editor {
|
|
1114
1147
|
this.closeAboutDialog?.();
|
1115
1148
|
this.closeAboutDialog = makeAboutDialog(this, notices).close;
|
1116
1149
|
}
|
1117
|
-
/**
|
1150
|
+
/**
|
1151
|
+
* Removes and **destroys** the editor. The editor cannot be added to a parent
|
1152
|
+
* again after calling this method.
|
1153
|
+
*/
|
1118
1154
|
remove() {
|
1119
1155
|
this.container.remove();
|
1120
1156
|
// TODO: Is additional cleanup necessary here?
|
1157
|
+
this.toolController.onEditorDestroyed();
|
1121
1158
|
}
|
1122
1159
|
}
|
1123
1160
|
export default Editor;
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import describeComponentList from '../components/util/describeComponentList.mjs';
|
2
|
-
import EditorImage from '../EditorImage.mjs';
|
2
|
+
import EditorImage from '../image/EditorImage.mjs';
|
3
3
|
import SerializableCommand from './SerializableCommand.mjs';
|
4
4
|
/**
|
5
5
|
* Removes the given {@link AbstractComponent}s from the image.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import EditorImage from '../EditorImage';
|
1
|
+
import EditorImage from '../image/EditorImage';
|
2
2
|
import AbstractComponent from '../components/AbstractComponent';
|
3
3
|
import SerializableCommand from './SerializableCommand';
|
4
4
|
export type ResolveFromComponentCallback = () => SerializableCommand;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import SerializableCommand from '../commands/SerializableCommand';
|
2
|
-
import EditorImage from '../EditorImage';
|
2
|
+
import EditorImage from '../image/EditorImage';
|
3
3
|
import { LineSegment2, Mat33, Rect2 } from '@js-draw/math';
|
4
4
|
import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
|
5
5
|
import { ImageComponentLocalization } from './localization';
|
@@ -4,7 +4,7 @@ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, p
|
|
4
4
|
};
|
5
5
|
var _a;
|
6
6
|
import SerializableCommand from '../commands/SerializableCommand.mjs';
|
7
|
-
import EditorImage from '../EditorImage.mjs';
|
7
|
+
import EditorImage from '../image/EditorImage.mjs';
|
8
8
|
import { Mat33 } from '@js-draw/math';
|
9
9
|
import UnresolvedSerializableCommand from '../commands/UnresolvedCommand.mjs';
|
10
10
|
export var ComponentSizingMode;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import Editor from '../Editor';
|
2
|
-
import EditorImage from '../EditorImage';
|
2
|
+
import EditorImage from '../image/EditorImage';
|
3
3
|
import SerializableCommand from '../commands/SerializableCommand';
|
4
4
|
import { LineSegment2, Mat33, Rect2, Color4 } from '@js-draw/math';
|
5
5
|
import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { EditorImageEventType } from '../EditorImage.mjs';
|
1
|
+
import { EditorImageEventType } from '../image/EditorImage.mjs';
|
2
2
|
import { Rect2, Color4, toRoundedString, Path, PathCommandType, Vec2 } from '@js-draw/math';
|
3
3
|
import AbstractComponent, { ComponentSizingMode } from './AbstractComponent.mjs';
|
4
4
|
import { createRestyleComponentCommand } from './RestylableComponent.mjs';
|
@@ -1,11 +1,11 @@
|
|
1
|
-
import AbstractRenderer from '
|
2
|
-
import Viewport from '
|
3
|
-
import AbstractComponent from '
|
1
|
+
import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
|
2
|
+
import Viewport from '../Viewport';
|
3
|
+
import AbstractComponent from '../components/AbstractComponent';
|
4
4
|
import { Rect2 } from '@js-draw/math';
|
5
|
-
import RenderingCache from '
|
6
|
-
import SerializableCommand from '
|
7
|
-
import EventDispatcher from '
|
8
|
-
import Command from '
|
5
|
+
import RenderingCache from '../rendering/caching/RenderingCache';
|
6
|
+
import SerializableCommand from '../commands/SerializableCommand';
|
7
|
+
import EventDispatcher from '../EventDispatcher';
|
8
|
+
import Command from '../commands/Command';
|
9
9
|
export declare const sortLeavesByZIndex: (leaves: Array<ImageNode>) => void;
|
10
10
|
export declare enum EditorImageEventType {
|
11
11
|
ExportViewportChanged = 0,
|
@@ -14,6 +14,13 @@ export declare enum EditorImageEventType {
|
|
14
14
|
export type EditorImageNotifier = EventDispatcher<EditorImageEventType, {
|
15
15
|
image: EditorImage;
|
16
16
|
}>;
|
17
|
+
/**
|
18
|
+
* A callback used to
|
19
|
+
* 1. pause the render process
|
20
|
+
* 2. observe progress through `componentsProcessed` and `totalComponents`
|
21
|
+
* 3. stop the render process early by returning `false`.
|
22
|
+
*/
|
23
|
+
export type PreRenderComponentCallback = (component: AbstractComponent, componentsProcessed: number, totalComponents: number) => Promise<boolean>;
|
17
24
|
export default class EditorImage {
|
18
25
|
private root;
|
19
26
|
private background;
|
@@ -36,7 +43,21 @@ export default class EditorImage {
|
|
36
43
|
* the viewport used by the `renderer` (if any).
|
37
44
|
*/
|
38
45
|
render(renderer: AbstractRenderer, viewport: Viewport | null): void;
|
39
|
-
/**
|
46
|
+
/**
|
47
|
+
* Like {@link renderAll}, but can be stopped early and paused.
|
48
|
+
*
|
49
|
+
* **Note**: If the image is being edited during an async rendering, there is no
|
50
|
+
* guarantee that all nodes will be rendered correctly (some may be missing).
|
51
|
+
*
|
52
|
+
* @internal
|
53
|
+
*/
|
54
|
+
renderAllAsync(renderer: AbstractRenderer, preRenderComponent: PreRenderComponentCallback): Promise<boolean>;
|
55
|
+
/**
|
56
|
+
* Renders all nodes, even ones not within the viewport.
|
57
|
+
*
|
58
|
+
* This can be slow for large images
|
59
|
+
* @internal
|
60
|
+
*/
|
40
61
|
renderAll(renderer: AbstractRenderer): void;
|
41
62
|
/**
|
42
63
|
* @returns all elements in the image, sorted by z-index. This can be slow for large images.
|
@@ -136,6 +157,7 @@ export declare class ImageNode {
|
|
136
157
|
private rebalance;
|
137
158
|
protected removeChild(child: ImageNode): void;
|
138
159
|
remove(): void;
|
160
|
+
renderAllAsync(renderer: AbstractRenderer, preRenderComponent: PreRenderComponentCallback): Promise<boolean>;
|
139
161
|
render(renderer: AbstractRenderer, visibleRect?: Rect2): void;
|
140
162
|
renderDebugBoundingBoxes(renderer: AbstractRenderer, visibleRect: Rect2, depth?: number): void;
|
141
163
|
}
|