js-draw 0.2.3 → 0.3.1
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/CHANGELOG.md +11 -0
- package/dist/bundle.js +1 -1
- package/dist/src/EditorImage.js +0 -1
- package/dist/src/components/Stroke.js +11 -6
- package/dist/src/components/builders/FreehandLineBuilder.js +6 -6
- package/dist/src/components/lib.d.ts +2 -0
- package/dist/src/components/lib.js +2 -0
- package/dist/src/lib.d.ts +5 -1
- package/dist/src/lib.js +5 -1
- package/dist/src/math/LineSegment2.d.ts +2 -0
- package/dist/src/math/LineSegment2.js +6 -0
- package/dist/src/math/Path.d.ts +5 -1
- package/dist/src/math/Path.js +89 -7
- package/dist/src/math/Rect2.js +1 -1
- package/dist/src/math/Triangle.d.ts +11 -0
- package/dist/src/math/Triangle.js +19 -0
- package/dist/src/rendering/Display.js +3 -3
- package/dist/src/rendering/caching/RenderingCacheNode.js +2 -1
- package/dist/src/rendering/renderers/AbstractRenderer.d.ts +2 -1
- package/dist/src/rendering/renderers/CanvasRenderer.js +6 -6
- package/dist/src/rendering/renderers/SVGRenderer.d.ts +10 -11
- package/dist/src/rendering/renderers/SVGRenderer.js +27 -68
- package/dist/src/toolbar/HTMLToolbar.d.ts +5 -1
- package/dist/src/toolbar/HTMLToolbar.js +30 -31
- package/dist/src/toolbar/icons.d.ts +1 -1
- package/dist/src/toolbar/icons.js +4 -0
- package/dist/src/toolbar/lib.d.ts +3 -0
- package/dist/src/toolbar/lib.js +4 -0
- package/dist/src/toolbar/makeColorInput.js +2 -2
- package/dist/src/toolbar/types.d.ts +0 -4
- package/dist/src/toolbar/types.js +1 -5
- package/dist/src/toolbar/widgets/BaseWidget.d.ts +3 -0
- package/dist/src/toolbar/widgets/BaseWidget.js +21 -1
- package/dist/src/toolbar/widgets/{EraserWidget.d.ts → EraserToolWidget.d.ts} +1 -1
- package/dist/src/toolbar/widgets/{EraserWidget.js → EraserToolWidget.js} +1 -1
- package/dist/src/toolbar/widgets/{PenWidget.d.ts → PenToolWidget.d.ts} +2 -3
- package/dist/src/toolbar/widgets/{PenWidget.js → PenToolWidget.js} +6 -7
- package/dist/src/toolbar/widgets/{SelectionWidget.d.ts → SelectionToolWidget.d.ts} +1 -1
- package/dist/src/toolbar/widgets/{SelectionWidget.js → SelectionToolWidget.js} +1 -1
- package/dist/src/toolbar/widgets/lib.d.ts +8 -0
- package/dist/src/toolbar/widgets/lib.js +8 -0
- package/dist/src/tools/BaseTool.d.ts +1 -2
- package/dist/src/tools/BaseTool.js +6 -0
- package/dist/src/tools/Eraser.d.ts +0 -2
- package/dist/src/tools/Eraser.js +0 -2
- package/dist/src/tools/PanZoom.d.ts +0 -2
- package/dist/src/tools/PanZoom.js +0 -2
- package/dist/src/tools/Pen.d.ts +9 -9
- package/dist/src/tools/Pen.js +23 -6
- package/dist/src/tools/PipetteTool.d.ts +0 -2
- package/dist/src/tools/PipetteTool.js +0 -2
- package/dist/src/tools/SelectionTool.d.ts +0 -2
- package/dist/src/tools/SelectionTool.js +4 -3
- package/dist/src/tools/TextTool.d.ts +0 -2
- package/dist/src/tools/TextTool.js +0 -2
- package/dist/src/tools/ToolController.d.ts +8 -11
- package/dist/src/tools/ToolController.js +37 -18
- package/dist/src/tools/ToolEnabledGroup.js +1 -1
- package/dist/src/tools/ToolSwitcherShortcut.d.ts +8 -0
- package/dist/src/tools/ToolSwitcherShortcut.js +26 -0
- package/dist/src/tools/UndoRedoShortcut.d.ts +0 -2
- package/dist/src/tools/UndoRedoShortcut.js +3 -2
- package/dist/src/tools/lib.d.ts +13 -0
- package/dist/src/tools/lib.js +13 -0
- package/dist/src/tools/localization.d.ts +1 -0
- package/dist/src/tools/localization.js +1 -0
- package/dist/src/types.d.ts +8 -2
- package/dist/src/types.js +1 -0
- package/package.json +2 -2
- package/src/EditorImage.ts +0 -1
- package/src/components/Stroke.test.ts +5 -0
- package/src/components/Stroke.ts +13 -7
- package/src/components/builders/FreehandLineBuilder.ts +6 -6
- package/src/components/lib.ts +3 -0
- package/src/lib.ts +5 -1
- package/src/math/LineSegment2.ts +8 -0
- package/src/math/Path.test.ts +53 -0
- package/src/math/Path.toString.test.ts +4 -2
- package/src/math/Path.ts +109 -11
- package/src/math/Rect2.ts +1 -1
- package/src/math/Triangle.ts +29 -0
- package/src/rendering/Display.ts +3 -3
- package/src/rendering/caching/RenderingCacheNode.ts +3 -1
- package/src/rendering/renderers/AbstractRenderer.ts +1 -0
- package/src/rendering/renderers/CanvasRenderer.ts +6 -6
- package/src/rendering/renderers/SVGRenderer.ts +30 -84
- package/src/toolbar/HTMLToolbar.ts +35 -38
- package/src/toolbar/icons.ts +5 -1
- package/src/toolbar/lib.ts +4 -0
- package/src/toolbar/makeColorInput.ts +1 -2
- package/src/toolbar/types.ts +1 -5
- package/src/toolbar/widgets/BaseWidget.ts +27 -1
- package/src/toolbar/widgets/{EraserWidget.ts → EraserToolWidget.ts} +1 -1
- package/src/toolbar/widgets/{PenWidget.ts → PenToolWidget.ts} +10 -9
- package/src/toolbar/widgets/{SelectionWidget.ts → SelectionToolWidget.ts} +1 -1
- package/src/toolbar/widgets/lib.ts +10 -0
- package/src/tools/BaseTool.ts +8 -3
- package/src/tools/Eraser.ts +0 -2
- package/src/tools/PanZoom.ts +0 -2
- package/src/tools/Pen.ts +32 -13
- package/src/tools/PipetteTool.ts +0 -3
- package/src/tools/SelectionTool.test.ts +1 -2
- package/src/tools/SelectionTool.ts +5 -3
- package/src/tools/TextTool.ts +0 -2
- package/src/tools/ToolController.ts +44 -20
- package/src/tools/ToolEnabledGroup.ts +1 -1
- package/src/tools/ToolSwitcherShortcut.ts +34 -0
- package/src/tools/UndoRedoShortcut.ts +4 -4
- package/src/tools/lib.ts +18 -0
- package/src/tools/localization.ts +2 -0
- package/src/types.ts +13 -1
@@ -1,16 +1,20 @@
|
|
1
1
|
import Editor from '../Editor';
|
2
2
|
import { ToolbarLocalization } from './localization';
|
3
3
|
import { ActionButtonIcon } from './types';
|
4
|
+
import BaseWidget from './widgets/BaseWidget';
|
4
5
|
export declare const toolbarCSSPrefix = "toolbar-";
|
5
6
|
export default class HTMLToolbar {
|
6
7
|
private editor;
|
7
8
|
private localizationTable;
|
8
9
|
private container;
|
9
10
|
private static colorisStarted;
|
11
|
+
private updateColoris;
|
12
|
+
/** @internal */
|
10
13
|
constructor(editor: Editor, parent: HTMLElement, localizationTable?: ToolbarLocalization);
|
11
14
|
setupColorPickers(): void;
|
15
|
+
addWidget(widget: BaseWidget): void;
|
12
16
|
addActionButton(title: string | ActionButtonIcon, command: () => void, parent?: Element): HTMLButtonElement;
|
13
|
-
|
17
|
+
addUndoRedoButtons(): void;
|
14
18
|
addDefaultToolWidgets(): void;
|
15
19
|
addDefaultActionButtons(): void;
|
16
20
|
}
|
@@ -1,24 +1,24 @@
|
|
1
|
-
import { ToolType } from '../tools/ToolController';
|
2
1
|
import { EditorEventType } from '../types';
|
3
2
|
import { coloris, init as colorisInit } from '@melloware/coloris';
|
4
3
|
import Color4 from '../Color4';
|
5
|
-
import Pen from '../tools/Pen';
|
6
|
-
import Eraser from '../tools/Eraser';
|
7
4
|
import SelectionTool from '../tools/SelectionTool';
|
8
5
|
import { defaultToolbarLocalization } from './localization';
|
9
6
|
import { makeRedoIcon, makeUndoIcon } from './icons';
|
10
7
|
import PanZoom from '../tools/PanZoom';
|
11
8
|
import TextTool from '../tools/TextTool';
|
12
|
-
import
|
13
|
-
import EraserWidget from './widgets/
|
14
|
-
import
|
9
|
+
import PenToolWidget from './widgets/PenToolWidget';
|
10
|
+
import EraserWidget from './widgets/EraserToolWidget';
|
11
|
+
import SelectionToolWidget from './widgets/SelectionToolWidget';
|
15
12
|
import TextToolWidget from './widgets/TextToolWidget';
|
16
13
|
import HandToolWidget from './widgets/HandToolWidget';
|
14
|
+
import { EraserTool, PenTool } from '../tools/lib';
|
17
15
|
export const toolbarCSSPrefix = 'toolbar-';
|
18
16
|
export default class HTMLToolbar {
|
17
|
+
/** @internal */
|
19
18
|
constructor(editor, parent, localizationTable = defaultToolbarLocalization) {
|
20
19
|
this.editor = editor;
|
21
20
|
this.localizationTable = localizationTable;
|
21
|
+
this.updateColoris = null;
|
22
22
|
this.container = document.createElement('div');
|
23
23
|
this.container.classList.add(`${toolbarCSSPrefix}root`);
|
24
24
|
this.container.setAttribute('role', 'toolbar');
|
@@ -31,6 +31,11 @@ export default class HTMLToolbar {
|
|
31
31
|
}
|
32
32
|
// @internal
|
33
33
|
setupColorPickers() {
|
34
|
+
// Much of the setup only needs to be done once.
|
35
|
+
if (this.updateColoris) {
|
36
|
+
this.updateColoris();
|
37
|
+
return;
|
38
|
+
}
|
34
39
|
const closePickerOverlay = document.createElement('div');
|
35
40
|
closePickerOverlay.className = `${toolbarCSSPrefix}closeColorPickerOverlay`;
|
36
41
|
this.editor.createHTMLOverlay(closePickerOverlay);
|
@@ -56,6 +61,7 @@ export default class HTMLToolbar {
|
|
56
61
|
});
|
57
62
|
};
|
58
63
|
initColoris();
|
64
|
+
this.updateColoris = initColoris;
|
59
65
|
const addColorToSwatch = (newColor) => {
|
60
66
|
let alreadyPresent = false;
|
61
67
|
for (const color of swatches) {
|
@@ -86,6 +92,12 @@ export default class HTMLToolbar {
|
|
86
92
|
}
|
87
93
|
});
|
88
94
|
}
|
95
|
+
// Adds an `ActionButtonWidget` or `BaseToolWidget`. The widget should not have already have a parent
|
96
|
+
// (i.e. its `addTo` method should not have been called).
|
97
|
+
addWidget(widget) {
|
98
|
+
widget.addTo(this.container);
|
99
|
+
this.setupColorPickers();
|
100
|
+
}
|
89
101
|
addActionButton(title, command, parent) {
|
90
102
|
const button = document.createElement('button');
|
91
103
|
button.classList.add(`${toolbarCSSPrefix}button`);
|
@@ -133,36 +145,23 @@ export default class HTMLToolbar {
|
|
133
145
|
}
|
134
146
|
addDefaultToolWidgets() {
|
135
147
|
const toolController = this.editor.toolController;
|
136
|
-
for (const tool of toolController.getMatchingTools(
|
137
|
-
|
138
|
-
|
139
|
-
}
|
140
|
-
const widget = new PenWidget(this.editor, tool, this.localizationTable);
|
141
|
-
widget.addTo(this.container);
|
148
|
+
for (const tool of toolController.getMatchingTools(PenTool)) {
|
149
|
+
const widget = new PenToolWidget(this.editor, tool, this.localizationTable);
|
150
|
+
this.addWidget(widget);
|
142
151
|
}
|
143
|
-
for (const tool of toolController.getMatchingTools(
|
144
|
-
|
145
|
-
throw new Error('All Erasers must have kind === ToolType.Eraser!');
|
146
|
-
}
|
147
|
-
(new EraserWidget(this.editor, tool, this.localizationTable)).addTo(this.container);
|
152
|
+
for (const tool of toolController.getMatchingTools(EraserTool)) {
|
153
|
+
this.addWidget(new EraserWidget(this.editor, tool, this.localizationTable));
|
148
154
|
}
|
149
|
-
for (const tool of toolController.getMatchingTools(
|
150
|
-
|
151
|
-
throw new Error('All SelectionTools must have kind === ToolType.Selection');
|
152
|
-
}
|
153
|
-
(new SelectionWidget(this.editor, tool, this.localizationTable)).addTo(this.container);
|
155
|
+
for (const tool of toolController.getMatchingTools(SelectionTool)) {
|
156
|
+
this.addWidget(new SelectionToolWidget(this.editor, tool, this.localizationTable));
|
154
157
|
}
|
155
|
-
for (const tool of toolController.getMatchingTools(
|
156
|
-
|
157
|
-
throw new Error('All text tools must have kind === ToolType.Text');
|
158
|
-
}
|
159
|
-
(new TextToolWidget(this.editor, tool, this.localizationTable)).addTo(this.container);
|
158
|
+
for (const tool of toolController.getMatchingTools(TextTool)) {
|
159
|
+
this.addWidget(new TextToolWidget(this.editor, tool, this.localizationTable));
|
160
160
|
}
|
161
|
-
const panZoomTool = toolController.getMatchingTools(
|
162
|
-
if (panZoomTool
|
163
|
-
(new HandToolWidget(this.editor, panZoomTool, this.localizationTable))
|
161
|
+
const panZoomTool = toolController.getMatchingTools(PanZoom)[0];
|
162
|
+
if (panZoomTool) {
|
163
|
+
this.addWidget(new HandToolWidget(this.editor, panZoomTool, this.localizationTable));
|
164
164
|
}
|
165
|
-
this.setupColorPickers();
|
166
165
|
}
|
167
166
|
addDefaultActionButtons() {
|
168
167
|
this.addUndoRedoButtons();
|
@@ -12,7 +12,7 @@ export declare const makeTouchPanningIcon: () => SVGSVGElement;
|
|
12
12
|
export declare const makeAllDevicePanningIcon: () => SVGSVGElement;
|
13
13
|
export declare const makeZoomIcon: () => SVGSVGElement;
|
14
14
|
export declare const makeTextIcon: (textStyle: TextStyle) => SVGSVGElement;
|
15
|
-
export declare const makePenIcon: (tipThickness: number, color: string) => SVGSVGElement;
|
15
|
+
export declare const makePenIcon: (tipThickness: number, color: string | Color4) => SVGSVGElement;
|
16
16
|
export declare const makeIconFromFactory: (pen: Pen, factory: ComponentBuilderFactory) => SVGSVGElement;
|
17
17
|
export declare const makePipetteIcon: (color?: Color4) => SVGSVGElement;
|
18
18
|
export declare const makeResizeViewportIcon: () => SVGSVGElement;
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import Color4 from '../Color4';
|
1
2
|
import EventDispatcher from '../EventDispatcher';
|
2
3
|
import { Vec2 } from '../math/Vec2';
|
3
4
|
import SVGRenderer from '../rendering/renderers/SVGRenderer';
|
@@ -251,6 +252,9 @@ export const makeTextIcon = (textStyle) => {
|
|
251
252
|
return icon;
|
252
253
|
};
|
253
254
|
export const makePenIcon = (tipThickness, color) => {
|
255
|
+
if (color instanceof Color4) {
|
256
|
+
color = color.toHexString();
|
257
|
+
}
|
254
258
|
const icon = document.createElementNS(svgNamespace, 'svg');
|
255
259
|
icon.setAttribute('viewBox', '0 0 100 100');
|
256
260
|
const halfThickness = tipThickness / 2;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import Color4 from '../Color4';
|
2
|
-
import
|
2
|
+
import PipetteTool from '../tools/PipetteTool';
|
3
3
|
import { EditorEventType } from '../types';
|
4
4
|
import { makePipetteIcon } from './icons';
|
5
5
|
// Returns [ color input, input container ].
|
@@ -59,7 +59,7 @@ const addPipetteTool = (editor, container, onColorChange) => {
|
|
59
59
|
pipetteButton.replaceChildren(makePipetteIcon(color));
|
60
60
|
};
|
61
61
|
updatePipetteIcon();
|
62
|
-
const pipetteTool = editor.toolController.getMatchingTools(
|
62
|
+
const pipetteTool = editor.toolController.getMatchingTools(PipetteTool)[0];
|
63
63
|
const endColorSelectMode = () => {
|
64
64
|
pipetteTool === null || pipetteTool === void 0 ? void 0 : pipetteTool.clearColorListener();
|
65
65
|
updatePipetteIcon();
|
@@ -1,5 +1 @@
|
|
1
|
-
export
|
2
|
-
(function (ToolbarButtonType) {
|
3
|
-
ToolbarButtonType[ToolbarButtonType["ToggleButton"] = 0] = "ToggleButton";
|
4
|
-
ToolbarButtonType[ToolbarButtonType["ActionButton"] = 1] = "ActionButton";
|
5
|
-
})(ToolbarButtonType || (ToolbarButtonType = {}));
|
1
|
+
export {};
|
@@ -12,6 +12,7 @@ export default abstract class BaseWidget {
|
|
12
12
|
private label;
|
13
13
|
private disabled;
|
14
14
|
private subWidgets;
|
15
|
+
private toplevel;
|
15
16
|
constructor(editor: Editor, localizationTable: ToolbarLocalization);
|
16
17
|
protected abstract getTitle(): string;
|
17
18
|
protected abstract createIcon(): Element;
|
@@ -26,6 +27,8 @@ export default abstract class BaseWidget {
|
|
26
27
|
setSelected(selected: boolean): void;
|
27
28
|
protected setDropdownVisible(visible: boolean): void;
|
28
29
|
protected repositionDropdown(): void;
|
30
|
+
/** Set whether the widget is contained within another. @internal */
|
31
|
+
protected setIsToplevel(toplevel: boolean): void;
|
29
32
|
protected isDropdownVisible(): boolean;
|
30
33
|
protected isSelected(): boolean;
|
31
34
|
private createDropdownIcon;
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
11
11
|
};
|
12
12
|
var _BaseWidget_hasDropdown;
|
13
|
-
import { InputEvtType } from '../../types';
|
13
|
+
import { EditorEventType, InputEvtType } from '../../types';
|
14
14
|
import { toolbarCSSPrefix } from '../HTMLToolbar';
|
15
15
|
import { makeDropdownIcon } from '../icons';
|
16
16
|
export default class BaseWidget {
|
@@ -20,6 +20,7 @@ export default class BaseWidget {
|
|
20
20
|
_BaseWidget_hasDropdown.set(this, void 0);
|
21
21
|
this.disabled = false;
|
22
22
|
this.subWidgets = [];
|
23
|
+
this.toplevel = true;
|
23
24
|
this.icon = null;
|
24
25
|
this.container = document.createElement('div');
|
25
26
|
this.container.classList.add(`${toolbarCSSPrefix}toolContainer`);
|
@@ -41,6 +42,7 @@ export default class BaseWidget {
|
|
41
42
|
}
|
42
43
|
for (const widget of this.subWidgets) {
|
43
44
|
widget.addTo(dropdown);
|
45
|
+
widget.setIsToplevel(false);
|
44
46
|
}
|
45
47
|
return true;
|
46
48
|
}
|
@@ -87,6 +89,7 @@ export default class BaseWidget {
|
|
87
89
|
this.subWidgets.push(widget);
|
88
90
|
}
|
89
91
|
// Adds this to [parent]. This can only be called once for each ToolbarWidget.
|
92
|
+
// @internal
|
90
93
|
addTo(parent) {
|
91
94
|
this.label.innerText = this.getTitle();
|
92
95
|
this.setupActionBtnClickListener(this.button);
|
@@ -99,6 +102,15 @@ export default class BaseWidget {
|
|
99
102
|
this.dropdownIcon = this.createDropdownIcon();
|
100
103
|
this.button.appendChild(this.dropdownIcon);
|
101
104
|
this.container.appendChild(this.dropdownContainer);
|
105
|
+
this.editor.notifier.on(EditorEventType.ToolbarDropdownShown, (evt) => {
|
106
|
+
if (evt.kind === EditorEventType.ToolbarDropdownShown
|
107
|
+
&& evt.parentWidget !== this
|
108
|
+
// Don't hide if a submenu wash shown (it might be a submenu of
|
109
|
+
// the current menu).
|
110
|
+
&& evt.parentWidget.toplevel) {
|
111
|
+
this.setDropdownVisible(false);
|
112
|
+
}
|
113
|
+
});
|
102
114
|
}
|
103
115
|
this.setDropdownVisible(false);
|
104
116
|
parent.appendChild(this.container);
|
@@ -144,6 +156,10 @@ export default class BaseWidget {
|
|
144
156
|
this.dropdownContainer.classList.remove('hidden');
|
145
157
|
this.container.classList.add('dropdownVisible');
|
146
158
|
this.editor.announceForAccessibility(this.localizationTable.dropdownShown(this.getTitle()));
|
159
|
+
this.editor.notifier.dispatch(EditorEventType.ToolbarDropdownShown, {
|
160
|
+
kind: EditorEventType.ToolbarDropdownShown,
|
161
|
+
parentWidget: this,
|
162
|
+
});
|
147
163
|
}
|
148
164
|
else {
|
149
165
|
this.dropdownContainer.classList.add('hidden');
|
@@ -164,6 +180,10 @@ export default class BaseWidget {
|
|
164
180
|
this.dropdownContainer.style.transform = '';
|
165
181
|
}
|
166
182
|
}
|
183
|
+
/** Set whether the widget is contained within another. @internal */
|
184
|
+
setIsToplevel(toplevel) {
|
185
|
+
this.toplevel = toplevel;
|
186
|
+
}
|
167
187
|
isDropdownVisible() {
|
168
188
|
return !this.dropdownContainer.classList.contains('hidden');
|
169
189
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import BaseToolWidget from './BaseToolWidget';
|
2
|
-
export default class
|
2
|
+
export default class EraserToolWidget extends BaseToolWidget {
|
3
3
|
protected getTitle(): string;
|
4
4
|
protected createIcon(): Element;
|
5
5
|
protected fillDropdown(_dropdown: HTMLElement): boolean;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { makeEraserIcon } from '../icons';
|
2
2
|
import BaseToolWidget from './BaseToolWidget';
|
3
|
-
export default class
|
3
|
+
export default class EraserToolWidget extends BaseToolWidget {
|
4
4
|
getTitle() {
|
5
5
|
return this.localizationTable.eraser;
|
6
6
|
}
|
@@ -3,11 +3,11 @@ import Editor from '../../Editor';
|
|
3
3
|
import Pen from '../../tools/Pen';
|
4
4
|
import { ToolbarLocalization } from '../localization';
|
5
5
|
import BaseToolWidget from './BaseToolWidget';
|
6
|
-
interface PenTypeRecord {
|
6
|
+
export interface PenTypeRecord {
|
7
7
|
name: string;
|
8
8
|
factory: ComponentBuilderFactory;
|
9
9
|
}
|
10
|
-
export default class
|
10
|
+
export default class PenToolWidget extends BaseToolWidget {
|
11
11
|
private tool;
|
12
12
|
private updateInputs;
|
13
13
|
protected penTypes: PenTypeRecord[];
|
@@ -17,4 +17,3 @@ export default class PenWidget extends BaseToolWidget {
|
|
17
17
|
private static idCounter;
|
18
18
|
protected fillDropdown(dropdown: HTMLElement): boolean;
|
19
19
|
}
|
20
|
-
export {};
|
@@ -1,4 +1,3 @@
|
|
1
|
-
// @internal @packageDocumentation
|
2
1
|
import { makeArrowBuilder } from '../../components/builders/ArrowBuilder';
|
3
2
|
import { makeFreehandLineBuilder } from '../../components/builders/FreehandLineBuilder';
|
4
3
|
import { makeLineBuilder } from '../../components/builders/LineBuilder';
|
@@ -8,7 +7,7 @@ import { toolbarCSSPrefix } from '../HTMLToolbar';
|
|
8
7
|
import { makeIconFromFactory, makePenIcon } from '../icons';
|
9
8
|
import makeColorInput from '../makeColorInput';
|
10
9
|
import BaseToolWidget from './BaseToolWidget';
|
11
|
-
export default class
|
10
|
+
export default class PenToolWidget extends BaseToolWidget {
|
12
11
|
constructor(editor, tool, localization) {
|
13
12
|
super(editor, tool, localization);
|
14
13
|
this.tool = tool;
|
@@ -73,14 +72,14 @@ export default class PenWidget extends BaseToolWidget {
|
|
73
72
|
const objectSelectLabel = document.createElement('label');
|
74
73
|
const objectTypeSelect = document.createElement('select');
|
75
74
|
// Give inputs IDs so we can label them with a <label for=...>Label text</label>
|
76
|
-
thicknessInput.id = `${toolbarCSSPrefix}thicknessInput${
|
77
|
-
objectTypeSelect.id = `${toolbarCSSPrefix}builderSelect${
|
75
|
+
thicknessInput.id = `${toolbarCSSPrefix}thicknessInput${PenToolWidget.idCounter++}`;
|
76
|
+
objectTypeSelect.id = `${toolbarCSSPrefix}builderSelect${PenToolWidget.idCounter++}`;
|
78
77
|
thicknessLabel.innerText = this.localizationTable.thicknessLabel;
|
79
78
|
thicknessLabel.setAttribute('for', thicknessInput.id);
|
80
79
|
objectSelectLabel.innerText = this.localizationTable.selectObjectType;
|
81
80
|
objectSelectLabel.setAttribute('for', objectTypeSelect.id);
|
82
81
|
thicknessInput.type = 'range';
|
83
|
-
thicknessInput.min = '
|
82
|
+
thicknessInput.min = '2';
|
84
83
|
thicknessInput.max = '20';
|
85
84
|
thicknessInput.step = '1';
|
86
85
|
thicknessInput.oninput = () => {
|
@@ -103,7 +102,7 @@ export default class PenWidget extends BaseToolWidget {
|
|
103
102
|
const [colorInput, colorInputContainer] = makeColorInput(this.editor, color => {
|
104
103
|
this.tool.setColor(color);
|
105
104
|
});
|
106
|
-
colorInput.id = `${toolbarCSSPrefix}colorInput${
|
105
|
+
colorInput.id = `${toolbarCSSPrefix}colorInput${PenToolWidget.idCounter++}`;
|
107
106
|
colorLabel.innerText = this.localizationTable.colorLabel;
|
108
107
|
colorLabel.setAttribute('for', colorInput.id);
|
109
108
|
colorRow.appendChild(colorLabel);
|
@@ -129,4 +128,4 @@ export default class PenWidget extends BaseToolWidget {
|
|
129
128
|
return true;
|
130
129
|
}
|
131
130
|
}
|
132
|
-
|
131
|
+
PenToolWidget.idCounter = 0;
|
@@ -2,7 +2,7 @@ import Editor from '../../Editor';
|
|
2
2
|
import SelectionTool from '../../tools/SelectionTool';
|
3
3
|
import { ToolbarLocalization } from '../localization';
|
4
4
|
import BaseToolWidget from './BaseToolWidget';
|
5
|
-
export
|
5
|
+
export default class SelectionToolWidget extends BaseToolWidget {
|
6
6
|
private tool;
|
7
7
|
constructor(editor: Editor, tool: SelectionTool, localization: ToolbarLocalization);
|
8
8
|
protected getTitle(): string;
|
@@ -2,7 +2,7 @@ import { EditorEventType } from '../../types';
|
|
2
2
|
import { makeDeleteSelectionIcon, makeDuplicateSelectionIcon, makeResizeViewportIcon, makeSelectionIcon } from '../icons';
|
3
3
|
import ActionButtonWidget from './ActionButtonWidget';
|
4
4
|
import BaseToolWidget from './BaseToolWidget';
|
5
|
-
export class
|
5
|
+
export default class SelectionToolWidget extends BaseToolWidget {
|
6
6
|
constructor(editor, tool, localization) {
|
7
7
|
super(editor, tool, localization);
|
8
8
|
this.tool = tool;
|
@@ -0,0 +1,8 @@
|
|
1
|
+
export { default as ActionButtonWidget } from './ActionButtonWidget';
|
2
|
+
export { default as BaseToolWidget } from './BaseToolWidget';
|
3
|
+
export { default as BaseWidget } from './BaseWidget';
|
4
|
+
export { default as PenToolWidget } from './PenToolWidget';
|
5
|
+
export { default as TextToolWidget } from './TextToolWidget';
|
6
|
+
export { default as HandToolWidget } from './HandToolWidget';
|
7
|
+
export { default as SelectionToolWidget } from './SelectionToolWidget';
|
8
|
+
export { default as EraserToolWidget } from './EraserToolWidget';
|
@@ -0,0 +1,8 @@
|
|
1
|
+
export { default as ActionButtonWidget } from './ActionButtonWidget';
|
2
|
+
export { default as BaseToolWidget } from './BaseToolWidget';
|
3
|
+
export { default as BaseWidget } from './BaseWidget';
|
4
|
+
export { default as PenToolWidget } from './PenToolWidget';
|
5
|
+
export { default as TextToolWidget } from './TextToolWidget';
|
6
|
+
export { default as HandToolWidget } from './HandToolWidget';
|
7
|
+
export { default as SelectionToolWidget } from './SelectionToolWidget';
|
8
|
+
export { default as EraserToolWidget } from './EraserToolWidget';
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import { PointerEvtListener, WheelEvt, PointerEvt, EditorNotifier, KeyPressEvent, KeyUpEvent } from '../types';
|
2
|
-
import { ToolType } from './ToolController';
|
3
2
|
import ToolEnabledGroup from './ToolEnabledGroup';
|
4
3
|
export default abstract class BaseTool implements PointerEvtListener {
|
5
4
|
private notifier;
|
@@ -10,7 +9,6 @@ export default abstract class BaseTool implements PointerEvtListener {
|
|
10
9
|
onPointerMove(_event: PointerEvt): void;
|
11
10
|
onPointerUp(_event: PointerEvt): void;
|
12
11
|
onGestureCancel(): void;
|
13
|
-
abstract readonly kind: ToolType;
|
14
12
|
protected constructor(notifier: EditorNotifier, description: string);
|
15
13
|
onWheel(_event: WheelEvt): boolean;
|
16
14
|
onKeyPress(_event: KeyPressEvent): boolean;
|
@@ -18,4 +16,5 @@ export default abstract class BaseTool implements PointerEvtListener {
|
|
18
16
|
setEnabled(enabled: boolean): void;
|
19
17
|
isEnabled(): boolean;
|
20
18
|
setToolGroup(group: ToolEnabledGroup): void;
|
19
|
+
getToolGroup(): ToolEnabledGroup | null;
|
21
20
|
}
|
@@ -1,12 +1,10 @@
|
|
1
1
|
import { PointerEvt } from '../types';
|
2
2
|
import BaseTool from './BaseTool';
|
3
3
|
import Editor from '../Editor';
|
4
|
-
import { ToolType } from './ToolController';
|
5
4
|
export default class Eraser extends BaseTool {
|
6
5
|
private editor;
|
7
6
|
private lastPoint;
|
8
7
|
private command;
|
9
|
-
kind: ToolType;
|
10
8
|
private toRemove;
|
11
9
|
constructor(editor: Editor, description: string);
|
12
10
|
onPointerDown(event: PointerEvt): boolean;
|
package/dist/src/tools/Eraser.js
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
import BaseTool from './BaseTool';
|
2
2
|
import LineSegment2 from '../math/LineSegment2';
|
3
3
|
import Erase from '../commands/Erase';
|
4
|
-
import { ToolType } from './ToolController';
|
5
4
|
import { PointerDevice } from '../Pointer';
|
6
5
|
export default class Eraser extends BaseTool {
|
7
6
|
constructor(editor, description) {
|
8
7
|
super(editor.notifier, description);
|
9
8
|
this.editor = editor;
|
10
9
|
this.command = null;
|
11
|
-
this.kind = ToolType.Eraser;
|
12
10
|
}
|
13
11
|
onPointerDown(event) {
|
14
12
|
if (event.allPointers.length === 1 || event.current.device === PointerDevice.Eraser) {
|
@@ -3,7 +3,6 @@ import { Point2 } from '../math/Vec2';
|
|
3
3
|
import Pointer from '../Pointer';
|
4
4
|
import { KeyPressEvent, PointerEvt, WheelEvt } from '../types';
|
5
5
|
import BaseTool from './BaseTool';
|
6
|
-
import { ToolType } from './ToolController';
|
7
6
|
interface PinchData {
|
8
7
|
canvasCenter: Point2;
|
9
8
|
screenCenter: Point2;
|
@@ -20,7 +19,6 @@ export declare enum PanZoomMode {
|
|
20
19
|
export default class PanZoom extends BaseTool {
|
21
20
|
private editor;
|
22
21
|
private mode;
|
23
|
-
readonly kind: ToolType.PanZoom;
|
24
22
|
private transform;
|
25
23
|
private lastAngle;
|
26
24
|
private lastDist;
|
@@ -5,7 +5,6 @@ import { PointerDevice } from '../Pointer';
|
|
5
5
|
import { EditorEventType } from '../types';
|
6
6
|
import { Viewport } from '../Viewport';
|
7
7
|
import BaseTool from './BaseTool';
|
8
|
-
import { ToolType } from './ToolController';
|
9
8
|
export var PanZoomMode;
|
10
9
|
(function (PanZoomMode) {
|
11
10
|
PanZoomMode[PanZoomMode["OneFingerTouchGestures"] = 1] = "OneFingerTouchGestures";
|
@@ -19,7 +18,6 @@ export default class PanZoom extends BaseTool {
|
|
19
18
|
super(editor.notifier, description);
|
20
19
|
this.editor = editor;
|
21
20
|
this.mode = mode;
|
22
|
-
this.kind = ToolType.PanZoom;
|
23
21
|
this.transform = null;
|
24
22
|
}
|
25
23
|
// Returns information about the pointers in a gesture
|
package/dist/src/tools/Pen.d.ts
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
import Color4 from '../Color4';
|
2
2
|
import Editor from '../Editor';
|
3
|
-
import
|
3
|
+
import Pointer from '../Pointer';
|
4
|
+
import { KeyPressEvent, PointerEvt, StrokeDataPoint } from '../types';
|
4
5
|
import BaseTool from './BaseTool';
|
5
|
-
import {
|
6
|
-
import { ComponentBuilderFactory } from '../components/builders/types';
|
6
|
+
import { ComponentBuilder, ComponentBuilderFactory } from '../components/builders/types';
|
7
7
|
export interface PenStyle {
|
8
8
|
color: Color4;
|
9
9
|
thickness: number;
|
@@ -11,15 +11,14 @@ export interface PenStyle {
|
|
11
11
|
export default class Pen extends BaseTool {
|
12
12
|
private editor;
|
13
13
|
private style;
|
14
|
-
|
15
|
-
|
14
|
+
protected builder: ComponentBuilder | null;
|
15
|
+
protected builderFactory: ComponentBuilderFactory;
|
16
16
|
private lastPoint;
|
17
|
-
readonly kind: ToolType;
|
18
17
|
constructor(editor: Editor, description: string, style: PenStyle);
|
19
18
|
private getPressureMultiplier;
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
protected toStrokePoint(pointer: Pointer): StrokeDataPoint;
|
20
|
+
protected previewStroke(): void;
|
21
|
+
protected addPointToStroke(point: StrokeDataPoint): void;
|
23
22
|
onPointerDown({ current, allPointers }: PointerEvt): boolean;
|
24
23
|
onPointerMove({ current }: PointerEvt): void;
|
25
24
|
onPointerUp({ current }: PointerEvt): void;
|
@@ -31,4 +30,5 @@ export default class Pen extends BaseTool {
|
|
31
30
|
getThickness(): number;
|
32
31
|
getColor(): Color4;
|
33
32
|
getStrokeFactory(): ComponentBuilderFactory;
|
33
|
+
onKeyPress({ key }: KeyPressEvent): boolean;
|
34
34
|
}
|
package/dist/src/tools/Pen.js
CHANGED
@@ -3,7 +3,6 @@ import { PointerDevice } from '../Pointer';
|
|
3
3
|
import { makeFreehandLineBuilder } from '../components/builders/FreehandLineBuilder';
|
4
4
|
import { EditorEventType } from '../types';
|
5
5
|
import BaseTool from './BaseTool';
|
6
|
-
import { ToolType } from './ToolController';
|
7
6
|
export default class Pen extends BaseTool {
|
8
7
|
constructor(editor, description, style) {
|
9
8
|
super(editor.notifier, description);
|
@@ -12,12 +11,12 @@ export default class Pen extends BaseTool {
|
|
12
11
|
this.builder = null;
|
13
12
|
this.builderFactory = makeFreehandLineBuilder;
|
14
13
|
this.lastPoint = null;
|
15
|
-
this.kind = ToolType.Pen;
|
16
14
|
}
|
17
15
|
getPressureMultiplier() {
|
18
16
|
return 1 / this.editor.viewport.getScaleFactor() * this.style.thickness;
|
19
17
|
}
|
20
|
-
|
18
|
+
// Converts a `pointer` to a `StrokeDataPoint`.
|
19
|
+
toStrokePoint(pointer) {
|
21
20
|
var _a;
|
22
21
|
const minPressure = 0.3;
|
23
22
|
let pressure = Math.max((_a = pointer.pressure) !== null && _a !== void 0 ? _a : 1.0, minPressure);
|
@@ -35,11 +34,13 @@ export default class Pen extends BaseTool {
|
|
35
34
|
time: pointer.timeStamp,
|
36
35
|
};
|
37
36
|
}
|
37
|
+
// Displays the stroke that is currently being built with the display's `wetInkRenderer`.
|
38
38
|
previewStroke() {
|
39
39
|
var _a;
|
40
40
|
this.editor.clearWetInk();
|
41
41
|
(_a = this.builder) === null || _a === void 0 ? void 0 : _a.preview(this.editor.display.getWetInkRenderer());
|
42
42
|
}
|
43
|
+
// Throws if no stroke builder exists.
|
43
44
|
addPointToStroke(point) {
|
44
45
|
if (!this.builder) {
|
45
46
|
throw new Error('No stroke is currently being generated.');
|
@@ -58,13 +59,13 @@ export default class Pen extends BaseTool {
|
|
58
59
|
}
|
59
60
|
}
|
60
61
|
if ((allPointers.length === 1 && !isEraser) || anyDeviceIsStylus) {
|
61
|
-
this.builder = this.builderFactory(this.
|
62
|
+
this.builder = this.builderFactory(this.toStrokePoint(current), this.editor.viewport);
|
62
63
|
return true;
|
63
64
|
}
|
64
65
|
return false;
|
65
66
|
}
|
66
67
|
onPointerMove({ current }) {
|
67
|
-
this.addPointToStroke(this.
|
68
|
+
this.addPointToStroke(this.toStrokePoint(current));
|
68
69
|
}
|
69
70
|
onPointerUp({ current }) {
|
70
71
|
var _a, _b;
|
@@ -72,7 +73,7 @@ export default class Pen extends BaseTool {
|
|
72
73
|
return;
|
73
74
|
}
|
74
75
|
// onPointerUp events can have zero pressure. Use the last pressure instead.
|
75
|
-
const currentPoint = this.
|
76
|
+
const currentPoint = this.toStrokePoint(current);
|
76
77
|
const strokePoint = Object.assign(Object.assign({}, currentPoint), { width: (_b = (_a = this.lastPoint) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : currentPoint.width });
|
77
78
|
this.addPointToStroke(strokePoint);
|
78
79
|
if (this.builder && current.isPrimary) {
|
@@ -120,4 +121,20 @@ export default class Pen extends BaseTool {
|
|
120
121
|
getThickness() { return this.style.thickness; }
|
121
122
|
getColor() { return this.style.color; }
|
122
123
|
getStrokeFactory() { return this.builderFactory; }
|
124
|
+
onKeyPress({ key }) {
|
125
|
+
key = key.toLowerCase();
|
126
|
+
let newThickness;
|
127
|
+
if (key === '-' || key === '_') {
|
128
|
+
newThickness = this.getThickness() * 2 / 3;
|
129
|
+
}
|
130
|
+
else if (key === '+' || key === '=') {
|
131
|
+
newThickness = this.getThickness() * 3 / 2;
|
132
|
+
}
|
133
|
+
if (newThickness !== undefined) {
|
134
|
+
newThickness = Math.min(Math.max(1, newThickness), 128);
|
135
|
+
this.setThickness(newThickness);
|
136
|
+
return true;
|
137
|
+
}
|
138
|
+
return false;
|
139
|
+
}
|
123
140
|
}
|
@@ -2,11 +2,9 @@ import Color4 from '../Color4';
|
|
2
2
|
import Editor from '../Editor';
|
3
3
|
import { PointerEvt } from '../types';
|
4
4
|
import BaseTool from './BaseTool';
|
5
|
-
import { ToolType } from './ToolController';
|
6
5
|
declare type ColorListener = (color: Color4 | null) => void;
|
7
6
|
export default class PipetteTool extends BaseTool {
|
8
7
|
private editor;
|
9
|
-
kind: ToolType;
|
10
8
|
private colorPreviewListener;
|
11
9
|
private colorSelectListener;
|
12
10
|
constructor(editor: Editor, description: string);
|