js-draw 1.10.0 → 1.11.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/dist/bundle.js +2 -2
- package/dist/cjs/commands/invertCommand.js +5 -0
- package/dist/cjs/components/AbstractComponent.d.ts +8 -0
- package/dist/cjs/components/AbstractComponent.js +28 -8
- package/dist/cjs/components/builders/types.d.ts +11 -0
- package/dist/cjs/toolbar/AbstractToolbar.d.ts +18 -2
- package/dist/cjs/toolbar/AbstractToolbar.js +46 -30
- package/dist/cjs/toolbar/widgets/BaseWidget.js +1 -1
- package/dist/cjs/toolbar/widgets/ExitActionWidget.d.ts +12 -0
- package/dist/cjs/toolbar/widgets/ExitActionWidget.js +32 -0
- package/dist/cjs/toolbar/widgets/HandToolWidget.d.ts +4 -3
- package/dist/cjs/toolbar/widgets/HandToolWidget.js +24 -13
- package/dist/cjs/toolbar/widgets/InsertImageWidget.js +1 -1
- package/dist/cjs/toolbar/widgets/keybindings.d.ts +1 -0
- package/dist/cjs/toolbar/widgets/keybindings.js +4 -1
- package/dist/cjs/toolbar/widgets/layout/types.d.ts +1 -1
- package/dist/cjs/tools/Pen.js +5 -0
- package/dist/cjs/tools/SelectionTool/Selection.d.ts +4 -0
- package/dist/cjs/tools/SelectionTool/Selection.js +56 -12
- package/dist/cjs/tools/SelectionTool/SelectionTool.d.ts +1 -0
- package/dist/cjs/tools/SelectionTool/SelectionTool.js +19 -1
- package/dist/cjs/tools/ToolSwitcherShortcut.d.ts +0 -1
- package/dist/cjs/tools/ToolSwitcherShortcut.js +0 -1
- package/dist/cjs/tools/keybindings.d.ts +1 -0
- package/dist/cjs/tools/keybindings.js +3 -1
- package/dist/cjs/version.js +1 -1
- package/dist/mjs/commands/invertCommand.mjs +5 -0
- package/dist/mjs/components/AbstractComponent.d.ts +8 -0
- package/dist/mjs/components/AbstractComponent.mjs +28 -8
- package/dist/mjs/components/builders/types.d.ts +11 -0
- package/dist/mjs/toolbar/AbstractToolbar.d.ts +18 -2
- package/dist/mjs/toolbar/AbstractToolbar.mjs +46 -30
- package/dist/mjs/toolbar/widgets/BaseWidget.mjs +1 -1
- package/dist/mjs/toolbar/widgets/ExitActionWidget.d.ts +12 -0
- package/dist/mjs/toolbar/widgets/ExitActionWidget.mjs +27 -0
- package/dist/mjs/toolbar/widgets/HandToolWidget.d.ts +4 -3
- package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +24 -13
- package/dist/mjs/toolbar/widgets/InsertImageWidget.mjs +1 -1
- package/dist/mjs/toolbar/widgets/keybindings.d.ts +1 -0
- package/dist/mjs/toolbar/widgets/keybindings.mjs +3 -0
- package/dist/mjs/toolbar/widgets/layout/types.d.ts +1 -1
- package/dist/mjs/tools/Pen.mjs +5 -0
- package/dist/mjs/tools/SelectionTool/Selection.d.ts +4 -0
- package/dist/mjs/tools/SelectionTool/Selection.mjs +56 -12
- package/dist/mjs/tools/SelectionTool/SelectionTool.d.ts +1 -0
- package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +20 -2
- package/dist/mjs/tools/ToolSwitcherShortcut.d.ts +0 -1
- package/dist/mjs/tools/ToolSwitcherShortcut.mjs +0 -1
- package/dist/mjs/tools/keybindings.d.ts +1 -0
- package/dist/mjs/tools/keybindings.mjs +2 -0
- package/dist/mjs/version.mjs +1 -1
- package/package.json +2 -2
@@ -11,6 +11,11 @@ const invertCommand = (command) => {
|
|
11
11
|
if (command instanceof SerializableCommand_1.default) {
|
12
12
|
// SerializableCommand that does the inverse of [command]
|
13
13
|
return new class extends SerializableCommand_1.default {
|
14
|
+
constructor() {
|
15
|
+
super(...arguments);
|
16
|
+
// For debugging
|
17
|
+
this._command = command;
|
18
|
+
}
|
14
19
|
serializeToJSON() {
|
15
20
|
return command.serialize();
|
16
21
|
}
|
@@ -116,6 +116,14 @@ export default abstract class AbstractComponent {
|
|
116
116
|
protected abstract applyTransformation(affineTransfm: Mat33): void;
|
117
117
|
transformBy(affineTransfm: Mat33): SerializableCommand;
|
118
118
|
setZIndex(newZIndex: number): SerializableCommand;
|
119
|
+
/**
|
120
|
+
* Combines {@link transformBy} and {@link setZIndex} into a single command.
|
121
|
+
*
|
122
|
+
* @param newZIndex - The z-index this component should have after applying this command.
|
123
|
+
* @param originalZIndex - @internal The z-index the component should revert to after unapplying
|
124
|
+
* this command.
|
125
|
+
*/
|
126
|
+
setZIndexAndTransformBy(affineTransfm: Mat33, newZIndex: number, originalZIndex?: number): SerializableCommand;
|
119
127
|
isSelectable(): boolean;
|
120
128
|
isBackground(): boolean;
|
121
129
|
getProportionalRenderingTime(): number;
|
@@ -144,13 +144,25 @@ class AbstractComponent {
|
|
144
144
|
}
|
145
145
|
// Returns a command that, when applied, transforms this by [affineTransfm] and
|
146
146
|
// updates the editor.
|
147
|
-
//
|
147
|
+
//
|
148
|
+
// The transformed component is also moved to the top (use {@link setZIndexAndTransformBy} to
|
149
|
+
// avoid this behavior).
|
148
150
|
transformBy(affineTransfm) {
|
149
151
|
return new AbstractComponent.TransformElementCommand(affineTransfm, this.getId(), this);
|
150
152
|
}
|
151
153
|
// Returns a command that updates this component's z-index.
|
152
154
|
setZIndex(newZIndex) {
|
153
|
-
return new AbstractComponent.TransformElementCommand(math_1.Mat33.identity, this.getId(), this, newZIndex
|
155
|
+
return new AbstractComponent.TransformElementCommand(math_1.Mat33.identity, this.getId(), this, newZIndex);
|
156
|
+
}
|
157
|
+
/**
|
158
|
+
* Combines {@link transformBy} and {@link setZIndex} into a single command.
|
159
|
+
*
|
160
|
+
* @param newZIndex - The z-index this component should have after applying this command.
|
161
|
+
* @param originalZIndex - @internal The z-index the component should revert to after unapplying
|
162
|
+
* this command.
|
163
|
+
*/
|
164
|
+
setZIndexAndTransformBy(affineTransfm, newZIndex, originalZIndex) {
|
165
|
+
return new AbstractComponent.TransformElementCommand(affineTransfm, this.getId(), this, newZIndex, originalZIndex);
|
154
166
|
}
|
155
167
|
// @returns true iff this component can be selected (e.g. by the selection tool.)
|
156
168
|
isSelectable() {
|
@@ -221,8 +233,12 @@ class AbstractComponent {
|
|
221
233
|
throw new Error(`Element with data ${json} cannot be deserialized.`);
|
222
234
|
}
|
223
235
|
const instance = this.deserializationCallbacks[json.name](json.data);
|
224
|
-
instance.zIndex = json.zIndex;
|
225
236
|
instance.id = json.id;
|
237
|
+
if (isFinite(json.zIndex)) {
|
238
|
+
instance.zIndex = json.zIndex;
|
239
|
+
// Ensure that new components will be added on top.
|
240
|
+
AbstractComponent.zIndexCounter = Math.max(AbstractComponent.zIndexCounter, instance.zIndex + 1);
|
241
|
+
}
|
226
242
|
// TODO: What should we do with json.loadSaveData?
|
227
243
|
// If we attach it to [instance], we create a potential security risk — loadSaveData
|
228
244
|
// is often used to store unrecognised attributes so they can be preserved on output.
|
@@ -231,6 +247,7 @@ class AbstractComponent {
|
|
231
247
|
}
|
232
248
|
}
|
233
249
|
// Topmost z-index
|
250
|
+
// TODO: Should be a property of the EditorImage.
|
234
251
|
AbstractComponent.zIndexCounter = 0;
|
235
252
|
AbstractComponent.deserializationCallbacks = {};
|
236
253
|
AbstractComponent.transformElementCommandId = 'transform-element';
|
@@ -258,7 +275,7 @@ AbstractComponent.TransformElementCommand = (_a = class extends UnresolvedComman
|
|
258
275
|
super.resolveComponent(image);
|
259
276
|
this.origZIndex ??= this.component.getZIndex();
|
260
277
|
}
|
261
|
-
updateTransform(editor, newTransfm) {
|
278
|
+
updateTransform(editor, newTransfm, targetZIndex) {
|
262
279
|
if (!this.component) {
|
263
280
|
throw new Error('this.component is undefined or null!');
|
264
281
|
}
|
@@ -270,7 +287,12 @@ AbstractComponent.TransformElementCommand = (_a = class extends UnresolvedComman
|
|
270
287
|
hadParent = true;
|
271
288
|
}
|
272
289
|
this.component.applyTransformation(newTransfm);
|
290
|
+
this.component.zIndex = targetZIndex;
|
273
291
|
this.component.lastChangedTime = (new Date()).getTime();
|
292
|
+
// Ensure that new components are automatically drawn above the current component.
|
293
|
+
if (targetZIndex >= AbstractComponent.zIndexCounter) {
|
294
|
+
AbstractComponent.zIndexCounter = targetZIndex + 1;
|
295
|
+
}
|
274
296
|
// Add the element back to the document.
|
275
297
|
if (hadParent) {
|
276
298
|
EditorImage_1.default.addElement(this.component).apply(editor);
|
@@ -278,14 +300,12 @@ AbstractComponent.TransformElementCommand = (_a = class extends UnresolvedComman
|
|
278
300
|
}
|
279
301
|
apply(editor) {
|
280
302
|
this.resolveComponent(editor.image);
|
281
|
-
this.
|
282
|
-
this.updateTransform(editor, this.affineTransfm);
|
303
|
+
this.updateTransform(editor, this.affineTransfm, this.targetZIndex);
|
283
304
|
editor.queueRerender();
|
284
305
|
}
|
285
306
|
unapply(editor) {
|
286
307
|
this.resolveComponent(editor.image);
|
287
|
-
this.
|
288
|
-
this.updateTransform(editor, this.affineTransfm.inverse());
|
308
|
+
this.updateTransform(editor, this.affineTransfm.inverse(), this.origZIndex);
|
289
309
|
editor.queueRerender();
|
290
310
|
}
|
291
311
|
description(_editor, localizationTable) {
|
@@ -7,6 +7,17 @@ export interface ComponentBuilder {
|
|
7
7
|
getBBox(): Rect2;
|
8
8
|
build(): AbstractComponent;
|
9
9
|
preview(renderer: AbstractRenderer): void;
|
10
|
+
/**
|
11
|
+
* Called when the pen is stationary (or the user otherwise
|
12
|
+
* activates autocomplete). This might attempt to fit the user's
|
13
|
+
* drawing to a particular shape.
|
14
|
+
*
|
15
|
+
* The shape returned by this function may be ignored if it has
|
16
|
+
* an empty bounding box.
|
17
|
+
*
|
18
|
+
* Although this returns a Promise, it should return *as fast as
|
19
|
+
* possible*.
|
20
|
+
*/
|
10
21
|
autocorrectShape?: () => Promise<AbstractComponent | null>;
|
11
22
|
addPoint(point: StrokeDataPoint): void;
|
12
23
|
}
|
@@ -3,6 +3,7 @@ import { ToolbarLocalization } from './localization';
|
|
3
3
|
import { ActionButtonIcon } from './types';
|
4
4
|
import BaseWidget, { ToolbarWidgetTag } from './widgets/BaseWidget';
|
5
5
|
import { DispatcherEventListener } from '../EventDispatcher';
|
6
|
+
import { BaseTool } from '../lib';
|
6
7
|
export interface SpacerOptions {
|
7
8
|
grow: number;
|
8
9
|
minSize: string;
|
@@ -131,7 +132,7 @@ export default abstract class AbstractToolbar {
|
|
131
132
|
/**
|
132
133
|
* Adds an "Exit" button that, when clicked, calls `exitCallback`.
|
133
134
|
*
|
134
|
-
* **Note**: This is roughly equivalent to
|
135
|
+
* **Note**: This is *roughly* equivalent to
|
135
136
|
* ```ts
|
136
137
|
* toolbar.addTaggedActionButton([ ToolbarWidgetTag.Exit ], {
|
137
138
|
* label: this.editor.localization.exit,
|
@@ -154,9 +155,24 @@ export default abstract class AbstractToolbar {
|
|
154
155
|
*/
|
155
156
|
addUndoRedoButtons(undoFirst?: boolean): void;
|
156
157
|
/**
|
157
|
-
* Adds
|
158
|
+
* Adds widgets for pen/eraser/selection/text/pan-zoom primary tools.
|
159
|
+
*
|
160
|
+
* If `filter` returns `false` for a tool, no widget is added for that tool.
|
161
|
+
* See {@link addDefaultToolWidgets}
|
162
|
+
*/
|
163
|
+
addWidgetsForPrimaryTools(filter?: (tool: BaseTool) => boolean): void;
|
164
|
+
/**
|
165
|
+
* Adds toolbar widgets based on the enabled tools, and additional tool-like
|
166
|
+
* buttons (e.g. {@link DocumentPropertiesWidget} and {@link InsertImageWidget}).
|
158
167
|
*/
|
159
168
|
addDefaultToolWidgets(): void;
|
169
|
+
/**
|
170
|
+
* Adds widgets that don't correspond to tools, but do allow the user to control
|
171
|
+
* the editor in some way.
|
172
|
+
*
|
173
|
+
* By default, this includes {@link DocumentPropertiesWidget} and {@link InsertImageWidget}.
|
174
|
+
*/
|
175
|
+
addDefaultEditorControlWidgets(): void;
|
160
176
|
addDefaultActionButtons(): void;
|
161
177
|
/**
|
162
178
|
* Adds both the default tool widgets and action buttons.
|
@@ -35,6 +35,7 @@ const DocumentPropertiesWidget_1 = __importDefault(require("./widgets/DocumentPr
|
|
35
35
|
const math_1 = require("@js-draw/math");
|
36
36
|
const constants_1 = require("./constants");
|
37
37
|
const SaveActionWidget_1 = __importDefault(require("./widgets/SaveActionWidget"));
|
38
|
+
const ExitActionWidget_1 = __importDefault(require("./widgets/ExitActionWidget"));
|
38
39
|
class AbstractToolbar {
|
39
40
|
/** @internal */
|
40
41
|
constructor(editor, localizationTable = localization_1.defaultToolbarLocalization) {
|
@@ -297,14 +298,13 @@ class AbstractToolbar {
|
|
297
298
|
*/
|
298
299
|
addSaveButton(saveCallback, labelOverride = {}) {
|
299
300
|
const widget = new SaveActionWidget_1.default(this.editor, this.localizationTable, saveCallback, labelOverride);
|
300
|
-
widget.setTags([BaseWidget_1.ToolbarWidgetTag.Save]);
|
301
301
|
this.addWidget(widget);
|
302
302
|
return widget;
|
303
303
|
}
|
304
304
|
/**
|
305
305
|
* Adds an "Exit" button that, when clicked, calls `exitCallback`.
|
306
306
|
*
|
307
|
-
* **Note**: This is roughly equivalent to
|
307
|
+
* **Note**: This is *roughly* equivalent to
|
308
308
|
* ```ts
|
309
309
|
* toolbar.addTaggedActionButton([ ToolbarWidgetTag.Exit ], {
|
310
310
|
* label: this.editor.localization.exit,
|
@@ -321,15 +321,9 @@ class AbstractToolbar {
|
|
321
321
|
* @final
|
322
322
|
*/
|
323
323
|
addExitButton(exitCallback, labelOverride = {}) {
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
...labelOverride,
|
328
|
-
}, () => {
|
329
|
-
exitCallback();
|
330
|
-
}, {
|
331
|
-
autoDisableInReadOnlyEditors: false,
|
332
|
-
});
|
324
|
+
const widget = new ExitActionWidget_1.default(this.editor, this.localizationTable, exitCallback, labelOverride);
|
325
|
+
this.addWidget(widget);
|
326
|
+
return widget;
|
333
327
|
}
|
334
328
|
/**
|
335
329
|
* Adds undo and redo buttons that trigger the editor's built-in undo and redo
|
@@ -377,27 +371,49 @@ class AbstractToolbar {
|
|
377
371
|
});
|
378
372
|
}
|
379
373
|
/**
|
380
|
-
* Adds
|
374
|
+
* Adds widgets for pen/eraser/selection/text/pan-zoom primary tools.
|
375
|
+
*
|
376
|
+
* If `filter` returns `false` for a tool, no widget is added for that tool.
|
377
|
+
* See {@link addDefaultToolWidgets}
|
381
378
|
*/
|
382
|
-
|
383
|
-
const
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
379
|
+
addWidgetsForPrimaryTools(filter) {
|
380
|
+
for (const tool of this.editor.toolController.getPrimaryTools()) {
|
381
|
+
if (filter && !filter?.(tool)) {
|
382
|
+
continue;
|
383
|
+
}
|
384
|
+
if (tool instanceof Pen_1.default) {
|
385
|
+
const widget = new PenToolWidget_1.default(this.editor, tool, this.localizationTable);
|
386
|
+
this.addWidget(widget);
|
387
|
+
}
|
388
|
+
else if (tool instanceof Eraser_1.default) {
|
389
|
+
this.addWidget(new EraserToolWidget_1.default(this.editor, tool, this.localizationTable));
|
390
|
+
}
|
391
|
+
else if (tool instanceof SelectionTool_1.default) {
|
392
|
+
this.addWidget(new SelectionToolWidget_1.default(this.editor, tool, this.localizationTable));
|
393
|
+
}
|
394
|
+
else if (tool instanceof TextTool_1.default) {
|
395
|
+
this.addWidget(new TextToolWidget_1.default(this.editor, tool, this.localizationTable));
|
396
|
+
}
|
397
|
+
else if (tool instanceof PanZoom_1.default) {
|
398
|
+
this.addWidget(new HandToolWidget_1.default(this.editor, tool, this.localizationTable));
|
399
|
+
}
|
400
400
|
}
|
401
|
+
}
|
402
|
+
/**
|
403
|
+
* Adds toolbar widgets based on the enabled tools, and additional tool-like
|
404
|
+
* buttons (e.g. {@link DocumentPropertiesWidget} and {@link InsertImageWidget}).
|
405
|
+
*/
|
406
|
+
addDefaultToolWidgets() {
|
407
|
+
this.addWidgetsForPrimaryTools();
|
408
|
+
this.addDefaultEditorControlWidgets();
|
409
|
+
}
|
410
|
+
/**
|
411
|
+
* Adds widgets that don't correspond to tools, but do allow the user to control
|
412
|
+
* the editor in some way.
|
413
|
+
*
|
414
|
+
* By default, this includes {@link DocumentPropertiesWidget} and {@link InsertImageWidget}.
|
415
|
+
*/
|
416
|
+
addDefaultEditorControlWidgets() {
|
401
417
|
this.addWidget(new DocumentPropertiesWidget_1.default(this.editor, this.localizationTable));
|
402
418
|
this.addWidget(new InsertImageWidget_1.default(this.editor, this.localizationTable));
|
403
419
|
}
|
@@ -53,7 +53,7 @@ class BaseWidget {
|
|
53
53
|
this.layoutManager = defaultLayoutManager;
|
54
54
|
this.icon = null;
|
55
55
|
this.container = document.createElement('div');
|
56
|
-
this.container.classList.add(`${constants_1.toolbarCSSPrefix}toolContainer`, `${constants_1.toolbarCSSPrefix}toolButtonContainer`);
|
56
|
+
this.container.classList.add(`${constants_1.toolbarCSSPrefix}toolContainer`, `${constants_1.toolbarCSSPrefix}toolButtonContainer`, `${constants_1.toolbarCSSPrefix}internalWidgetId--${id.replace(/[^a-zA-Z0-9_]/g, '-')}`);
|
57
57
|
this.dropdownContent = document.createElement('div');
|
58
58
|
__classPrivateFieldSet(this, _BaseWidget_hasDropdown, false, "f");
|
59
59
|
this.button = document.createElement('div');
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { KeyPressEvent } from '../../inputEvents';
|
2
|
+
import Editor from '../../Editor';
|
3
|
+
import { ToolbarLocalization } from '../localization';
|
4
|
+
import ActionButtonWidget from './ActionButtonWidget';
|
5
|
+
import { ActionButtonIcon } from '../types';
|
6
|
+
declare class ExitActionWidget extends ActionButtonWidget {
|
7
|
+
constructor(editor: Editor, localization: ToolbarLocalization, saveCallback: () => void, labelOverride?: Partial<ActionButtonIcon>);
|
8
|
+
protected shouldAutoDisableInReadOnlyEditor(): boolean;
|
9
|
+
protected onKeyPress(event: KeyPressEvent): boolean;
|
10
|
+
mustBeInToplevelMenu(): boolean;
|
11
|
+
}
|
12
|
+
export default ExitActionWidget;
|
@@ -0,0 +1,32 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const ActionButtonWidget_1 = __importDefault(require("./ActionButtonWidget"));
|
7
|
+
const BaseWidget_1 = require("./BaseWidget");
|
8
|
+
const keybindings_1 = require("./keybindings");
|
9
|
+
class ExitActionWidget extends ActionButtonWidget_1.default {
|
10
|
+
constructor(editor, localization, saveCallback, labelOverride = {}) {
|
11
|
+
super(editor, 'exit-button',
|
12
|
+
// Creates an icon
|
13
|
+
() => {
|
14
|
+
return labelOverride.icon ?? editor.icons.makeCloseIcon();
|
15
|
+
}, labelOverride.label ?? localization.exit, saveCallback);
|
16
|
+
this.setTags([BaseWidget_1.ToolbarWidgetTag.Exit]);
|
17
|
+
}
|
18
|
+
shouldAutoDisableInReadOnlyEditor() {
|
19
|
+
return false;
|
20
|
+
}
|
21
|
+
onKeyPress(event) {
|
22
|
+
if (this.editor.shortcuts.matchesShortcut(keybindings_1.exitKeyboardShortcut, event)) {
|
23
|
+
this.clickAction();
|
24
|
+
return true;
|
25
|
+
}
|
26
|
+
return super.onKeyPress(event);
|
27
|
+
}
|
28
|
+
mustBeInToplevelMenu() {
|
29
|
+
return true;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
exports.default = ExitActionWidget;
|
@@ -4,11 +4,12 @@ import { ToolbarLocalization } from '../localization';
|
|
4
4
|
import BaseToolWidget from './BaseToolWidget';
|
5
5
|
import { SavedToolbuttonState } from './BaseWidget';
|
6
6
|
export default class HandToolWidget extends BaseToolWidget {
|
7
|
-
protected overridePanZoomTool: PanZoom;
|
8
7
|
private allowTogglingBaseTool;
|
9
|
-
|
10
|
-
|
8
|
+
protected overridePanZoomTool: PanZoom;
|
9
|
+
constructor(editor: Editor, tool: PanZoom, localizationTable: ToolbarLocalization);
|
11
10
|
private static getPrimaryHandTool;
|
11
|
+
private static getOverrideHandTool;
|
12
|
+
protected shouldAutoDisableInReadOnlyEditor(): boolean;
|
12
13
|
protected getTitle(): string;
|
13
14
|
protected createIcon(): Element;
|
14
15
|
protected handleClick(): void;
|
@@ -124,34 +124,45 @@ class HandModeWidget extends BaseWidget_1.default {
|
|
124
124
|
}
|
125
125
|
class HandToolWidget extends BaseToolWidget_1.default {
|
126
126
|
constructor(editor,
|
127
|
-
//
|
128
|
-
//
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
127
|
+
// Can either be the primary pan/zoom tool (in the primary tools list) or
|
128
|
+
// the override pan/zoom tool.
|
129
|
+
// If the override pan/zoom tool, the primary will be gotten from the editor's
|
130
|
+
// tool controller.
|
131
|
+
// If the primary, the override will be gotten from the editor's tool controller.
|
132
|
+
tool, localizationTable) {
|
133
|
+
const isGivenToolPrimary = editor.toolController.getPrimaryTools().includes(tool);
|
134
|
+
const primaryTool = (isGivenToolPrimary ? tool : HandToolWidget.getPrimaryHandTool(editor.toolController))
|
135
|
+
?? tool;
|
136
|
+
super(editor, primaryTool, 'hand-tool-widget', localizationTable);
|
137
|
+
this.overridePanZoomTool =
|
138
|
+
(isGivenToolPrimary ? HandToolWidget.getOverrideHandTool(editor.toolController) : tool)
|
139
|
+
?? tool;
|
134
140
|
// Only allow toggling a hand tool if we're using the primary hand tool and not the override
|
135
141
|
// hand tool for this button.
|
136
|
-
this.allowTogglingBaseTool =
|
142
|
+
this.allowTogglingBaseTool = primaryTool !== null;
|
137
143
|
// Allow showing/hiding the dropdown, even if `overridePanZoomTool` isn't enabled.
|
138
144
|
if (!this.allowTogglingBaseTool) {
|
139
145
|
this.container.classList.add('dropdownShowable');
|
140
146
|
}
|
141
147
|
// Controls for the overriding hand tool.
|
142
|
-
const touchPanningWidget = new HandModeWidget(editor, overridePanZoomTool, PanZoom_1.PanZoomMode.OneFingerTouchGestures, () => this.editor.icons.makeTouchPanningIcon(), localizationTable.touchPanning, localizationTable);
|
143
|
-
const rotationLockWidget = new HandModeWidget(editor, overridePanZoomTool, PanZoom_1.PanZoomMode.RotationLocked, () => this.editor.icons.makeRotationLockIcon(), localizationTable.lockRotation, localizationTable);
|
148
|
+
const touchPanningWidget = new HandModeWidget(editor, this.overridePanZoomTool, PanZoom_1.PanZoomMode.OneFingerTouchGestures, () => this.editor.icons.makeTouchPanningIcon(), localizationTable.touchPanning, localizationTable);
|
149
|
+
const rotationLockWidget = new HandModeWidget(editor, this.overridePanZoomTool, PanZoom_1.PanZoomMode.RotationLocked, () => this.editor.icons.makeRotationLockIcon(), localizationTable.lockRotation, localizationTable);
|
144
150
|
this.addSubWidget(touchPanningWidget);
|
145
151
|
this.addSubWidget(rotationLockWidget);
|
146
152
|
}
|
147
|
-
shouldAutoDisableInReadOnlyEditor() {
|
148
|
-
return false;
|
149
|
-
}
|
150
153
|
static getPrimaryHandTool(toolController) {
|
151
154
|
const primaryPanZoomToolList = toolController.getPrimaryTools().filter(tool => tool instanceof PanZoom_1.default);
|
152
155
|
const primaryPanZoomTool = primaryPanZoomToolList[0];
|
153
156
|
return primaryPanZoomTool;
|
154
157
|
}
|
158
|
+
static getOverrideHandTool(toolController) {
|
159
|
+
const panZoomToolList = toolController.getMatchingTools(PanZoom_1.default);
|
160
|
+
const panZoomTool = panZoomToolList[0];
|
161
|
+
return panZoomTool;
|
162
|
+
}
|
163
|
+
shouldAutoDisableInReadOnlyEditor() {
|
164
|
+
return false;
|
165
|
+
}
|
155
166
|
getTitle() {
|
156
167
|
return this.localizationTable.handTool;
|
157
168
|
}
|
@@ -174,7 +174,7 @@ class InsertImageWidget extends BaseWidget_1.default {
|
|
174
174
|
this.image?.reset();
|
175
175
|
};
|
176
176
|
this.statusView.replaceChildren(sizeText);
|
177
|
-
const largeImageThreshold = 0.
|
177
|
+
const largeImageThreshold = 0.12; // MiB
|
178
178
|
if (sizeInMiB > largeImageThreshold) {
|
179
179
|
this.statusView.appendChild(decreaseSizeButton);
|
180
180
|
}
|
@@ -1,3 +1,4 @@
|
|
1
1
|
export declare const resizeImageToSelectionKeyboardShortcut = "jsdraw.toolbar.SelectionTool.resizeImageToSelection";
|
2
2
|
export declare const selectStrokeTypeKeyboardShortcutIds: string[];
|
3
3
|
export declare const saveKeyboardShortcut = "jsdraw.toolbar.SaveActionWidget.save";
|
4
|
+
export declare const exitKeyboardShortcut = "jsdraw.toolbar.ExitActionWidget.exit";
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.saveKeyboardShortcut = exports.selectStrokeTypeKeyboardShortcutIds = exports.resizeImageToSelectionKeyboardShortcut = void 0;
|
6
|
+
exports.exitKeyboardShortcut = exports.saveKeyboardShortcut = exports.selectStrokeTypeKeyboardShortcutIds = exports.resizeImageToSelectionKeyboardShortcut = void 0;
|
7
7
|
const KeyboardShortcutManager_1 = __importDefault(require("../../shortcuts/KeyboardShortcutManager"));
|
8
8
|
// Selection
|
9
9
|
exports.resizeImageToSelectionKeyboardShortcut = 'jsdraw.toolbar.SelectionTool.resizeImageToSelection';
|
@@ -17,3 +17,6 @@ for (let i = 0; i < exports.selectStrokeTypeKeyboardShortcutIds.length; i++) {
|
|
17
17
|
// Save
|
18
18
|
exports.saveKeyboardShortcut = 'jsdraw.toolbar.SaveActionWidget.save';
|
19
19
|
KeyboardShortcutManager_1.default.registerDefaultKeyboardShortcut(exports.saveKeyboardShortcut, ['ctrlOrMeta+KeyS'], 'Save');
|
20
|
+
// Exit
|
21
|
+
exports.exitKeyboardShortcut = 'jsdraw.toolbar.ExitActionWidget.exit';
|
22
|
+
KeyboardShortcutManager_1.default.registerDefaultKeyboardShortcut(exports.exitKeyboardShortcut, ['Alt+KeyQ'], 'Exit');
|
package/dist/cjs/tools/Pen.js
CHANGED
@@ -192,6 +192,11 @@ class Pen extends BaseTool_1.default {
|
|
192
192
|
if (!this.builder || !correctedShape) {
|
193
193
|
return;
|
194
194
|
}
|
195
|
+
// Don't complete to empty shapes.
|
196
|
+
const bboxArea = correctedShape.getBBox().area;
|
197
|
+
if (bboxArea === 0 || !isFinite(bboxArea)) {
|
198
|
+
return;
|
199
|
+
}
|
195
200
|
this.autocorrectedShape = correctedShape;
|
196
201
|
this.lastAutocorrectedShape = correctedShape;
|
197
202
|
this.previewStroke();
|
@@ -2,6 +2,7 @@
|
|
2
2
|
* @internal
|
3
3
|
* @packageDocumentation
|
4
4
|
*/
|
5
|
+
import SerializableCommand from '../../commands/SerializableCommand';
|
5
6
|
import Editor from '../../Editor';
|
6
7
|
import { Mat33, Rect2, Point2 } from '@js-draw/math';
|
7
8
|
import Pointer from '../../Pointer';
|
@@ -36,7 +37,10 @@ export default class Selection {
|
|
36
37
|
getScreenRegion(): Rect2;
|
37
38
|
get screenRegionRotation(): number;
|
38
39
|
setTransform(transform: Mat33, preview?: boolean): void;
|
40
|
+
private getDeltaZIndexToMoveSelectionToTop;
|
39
41
|
finalizeTransform(): void | Promise<void>;
|
42
|
+
/** Sends all selected elements to the bottom of the visible image. */
|
43
|
+
sendToBack(): SerializableCommand | null;
|
40
44
|
private static ApplyTransformationCommand;
|
41
45
|
private previewTransformCmds;
|
42
46
|
resolveToObjects(): boolean;
|