js-draw 0.2.3 → 0.3.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/CHANGELOG.md +4 -0
- package/dist/bundle.js +1 -1
- package/dist/src/EditorImage.js +0 -1
- package/dist/src/components/builders/FreehandLineBuilder.js +1 -1
- 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/rendering/Display.js +2 -2
- package/dist/src/rendering/caching/RenderingCacheNode.js +2 -1
- package/dist/src/rendering/renderers/CanvasRenderer.js +6 -6
- package/dist/src/toolbar/HTMLToolbar.d.ts +4 -1
- package/dist/src/toolbar/HTMLToolbar.js +29 -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/{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 +0 -2
- 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 +8 -9
- package/dist/src/tools/Pen.js +7 -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 +7 -11
- package/dist/src/tools/ToolController.js +28 -16
- package/dist/src/tools/ToolEnabledGroup.js +1 -1
- package/dist/src/tools/UndoRedoShortcut.d.ts +0 -2
- package/dist/src/tools/UndoRedoShortcut.js +3 -2
- package/dist/src/tools/lib.d.ts +12 -0
- package/dist/src/tools/lib.js +12 -0
- package/package.json +1 -1
- package/src/EditorImage.ts +0 -1
- package/src/components/builders/FreehandLineBuilder.ts +1 -1
- package/src/components/lib.ts +3 -0
- package/src/lib.ts +5 -1
- package/src/rendering/Display.ts +2 -2
- package/src/rendering/caching/RenderingCacheNode.ts +3 -1
- package/src/rendering/renderers/CanvasRenderer.ts +6 -6
- package/src/toolbar/HTMLToolbar.ts +34 -37
- 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 +0 -4
- 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 +0 -3
- package/src/tools/Eraser.ts +0 -2
- package/src/tools/PanZoom.ts +0 -2
- package/src/tools/Pen.ts +12 -12
- 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 +34 -17
- package/src/tools/ToolEnabledGroup.ts +1 -1
- package/src/tools/UndoRedoShortcut.ts +4 -4
- package/src/tools/lib.ts +17 -0
@@ -1,11 +1,9 @@
|
|
1
1
|
// @internal @packageDocumentation
|
2
2
|
import BaseTool from './BaseTool';
|
3
|
-
import { ToolType } from './ToolController';
|
4
3
|
export default class PipetteTool extends BaseTool {
|
5
4
|
constructor(editor, description) {
|
6
5
|
super(editor.notifier, description);
|
7
6
|
this.editor = editor;
|
8
|
-
this.kind = ToolType.Pipette;
|
9
7
|
this.colorPreviewListener = null;
|
10
8
|
this.colorSelectListener = null;
|
11
9
|
}
|
@@ -5,7 +5,6 @@ import Rect2 from '../math/Rect2';
|
|
5
5
|
import { Point2, Vec2 } from '../math/Vec2';
|
6
6
|
import { KeyPressEvent, KeyUpEvent, PointerEvt } from '../types';
|
7
7
|
import BaseTool from './BaseTool';
|
8
|
-
import { ToolType } from './ToolController';
|
9
8
|
declare class Selection {
|
10
9
|
startPoint: Point2;
|
11
10
|
private editor;
|
@@ -43,7 +42,6 @@ export default class SelectionTool extends BaseTool {
|
|
43
42
|
private handleOverlay;
|
44
43
|
private prevSelectionBox;
|
45
44
|
private selectionBox;
|
46
|
-
readonly kind: ToolType;
|
47
45
|
constructor(editor: Editor, description: string);
|
48
46
|
onPointerDown(event: PointerEvt): boolean;
|
49
47
|
onPointerMove(event: PointerEvt): void;
|
@@ -1,3 +1,6 @@
|
|
1
|
+
// Allows users to select/transform portions of the `EditorImage`.
|
2
|
+
// With respect to `extend`ing, `SelectionTool` is not stable.
|
3
|
+
// @packageDocumentation
|
1
4
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
2
5
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
3
6
|
return new (P || (P = Promise))(function (resolve, reject) {
|
@@ -11,13 +14,11 @@ var _a;
|
|
11
14
|
import Duplicate from '../commands/Duplicate';
|
12
15
|
import Erase from '../commands/Erase';
|
13
16
|
import Mat33 from '../math/Mat33';
|
14
|
-
// import Mat33 from "../geometry/Mat33";
|
15
17
|
import Rect2 from '../math/Rect2';
|
16
18
|
import { Vec2 } from '../math/Vec2';
|
17
19
|
import { EditorEventType } from '../types';
|
18
20
|
import Viewport from '../Viewport';
|
19
21
|
import BaseTool from './BaseTool';
|
20
|
-
import { ToolType } from './ToolController';
|
21
22
|
import SerializableCommand from '../commands/SerializableCommand';
|
22
23
|
const handleScreenSize = 30;
|
23
24
|
const styles = `
|
@@ -409,11 +410,11 @@ Selection.ApplyTransformationCommand = class extends SerializableCommand {
|
|
409
410
|
return localizationTable.transformedElements(this.currentTransfmCommands.length);
|
410
411
|
}
|
411
412
|
};
|
413
|
+
// {@inheritDoc SelectionTool!}
|
412
414
|
export default class SelectionTool extends BaseTool {
|
413
415
|
constructor(editor, description) {
|
414
416
|
super(editor.notifier, description);
|
415
417
|
this.editor = editor;
|
416
|
-
this.kind = ToolType.Selection;
|
417
418
|
this.handleOverlay = document.createElement('div');
|
418
419
|
editor.createHTMLOverlay(this.handleOverlay);
|
419
420
|
editor.addStyleSheet(styles);
|
@@ -4,11 +4,9 @@ import Editor from '../Editor';
|
|
4
4
|
import { PointerEvt } from '../types';
|
5
5
|
import BaseTool from './BaseTool';
|
6
6
|
import { ToolLocalization } from './localization';
|
7
|
-
import { ToolType } from './ToolController';
|
8
7
|
export default class TextTool extends BaseTool {
|
9
8
|
private editor;
|
10
9
|
private localizationTable;
|
11
|
-
kind: ToolType;
|
12
10
|
private textStyle;
|
13
11
|
private textEditOverlay;
|
14
12
|
private textInputElem;
|
@@ -5,14 +5,12 @@ import Mat33 from '../math/Mat33';
|
|
5
5
|
import { PointerDevice } from '../Pointer';
|
6
6
|
import { EditorEventType } from '../types';
|
7
7
|
import BaseTool from './BaseTool';
|
8
|
-
import { ToolType } from './ToolController';
|
9
8
|
const overlayCssClass = 'textEditorOverlay';
|
10
9
|
export default class TextTool extends BaseTool {
|
11
10
|
constructor(editor, description, localizationTable) {
|
12
11
|
super(editor.notifier, description);
|
13
12
|
this.editor = editor;
|
14
13
|
this.localizationTable = localizationTable;
|
15
|
-
this.kind = ToolType.Text;
|
16
14
|
this.textInputElem = null;
|
17
15
|
this.textTargetPosition = null;
|
18
16
|
this.textMeasuringCtx = null;
|
@@ -1,21 +1,17 @@
|
|
1
1
|
import { InputEvt } from '../types';
|
2
2
|
import Editor from '../Editor';
|
3
3
|
import BaseTool from './BaseTool';
|
4
|
+
import ToolEnabledGroup from './ToolEnabledGroup';
|
4
5
|
import { ToolLocalization } from './localization';
|
5
|
-
export declare enum ToolType {
|
6
|
-
Pen = 0,
|
7
|
-
Selection = 1,
|
8
|
-
Eraser = 2,
|
9
|
-
PanZoom = 3,
|
10
|
-
Text = 4,
|
11
|
-
UndoRedoShortcut = 5,
|
12
|
-
Pipette = 6,
|
13
|
-
Other = 7
|
14
|
-
}
|
15
6
|
export default class ToolController {
|
16
7
|
private tools;
|
17
8
|
private activeTool;
|
9
|
+
private primaryToolGroup;
|
10
|
+
/** @internal */
|
18
11
|
constructor(editor: Editor, localization: ToolLocalization);
|
12
|
+
setTools(tools: BaseTool[], primaryToolGroup?: ToolEnabledGroup): void;
|
13
|
+
addPrimaryTool(tool: BaseTool): void;
|
14
|
+
addTool(tool: BaseTool): void;
|
19
15
|
dispatchInputEvent(event: InputEvt): boolean;
|
20
|
-
getMatchingTools(
|
16
|
+
getMatchingTools<Type extends BaseTool>(type: new (...args: any[]) => Type): Type[];
|
21
17
|
}
|
@@ -8,20 +8,12 @@ import Color4 from '../Color4';
|
|
8
8
|
import UndoRedoShortcut from './UndoRedoShortcut';
|
9
9
|
import TextTool from './TextTool';
|
10
10
|
import PipetteTool from './PipetteTool';
|
11
|
-
export var ToolType;
|
12
|
-
(function (ToolType) {
|
13
|
-
ToolType[ToolType["Pen"] = 0] = "Pen";
|
14
|
-
ToolType[ToolType["Selection"] = 1] = "Selection";
|
15
|
-
ToolType[ToolType["Eraser"] = 2] = "Eraser";
|
16
|
-
ToolType[ToolType["PanZoom"] = 3] = "PanZoom";
|
17
|
-
ToolType[ToolType["Text"] = 4] = "Text";
|
18
|
-
ToolType[ToolType["UndoRedoShortcut"] = 5] = "UndoRedoShortcut";
|
19
|
-
ToolType[ToolType["Pipette"] = 6] = "Pipette";
|
20
|
-
ToolType[ToolType["Other"] = 7] = "Other";
|
21
|
-
})(ToolType || (ToolType = {}));
|
22
11
|
export default class ToolController {
|
12
|
+
/** @internal */
|
23
13
|
constructor(editor, localization) {
|
24
|
-
|
14
|
+
this.activeTool = null;
|
15
|
+
const primaryToolGroup = new ToolEnabledGroup();
|
16
|
+
this.primaryToolGroup = primaryToolGroup;
|
25
17
|
const panZoomTool = new PanZoom(editor, PanZoomMode.TwoFingerTouchGestures | PanZoomMode.RightClickDrags, localization.touchPanTool);
|
26
18
|
const keyboardPanZoomTool = new PanZoom(editor, PanZoomMode.Keyboard, localization.keyboardPanZoom);
|
27
19
|
const primaryPenTool = new Pen(editor, localization.penTool(1), { color: Color4.purple, thickness: 16 });
|
@@ -30,7 +22,7 @@ export default class ToolController {
|
|
30
22
|
new Eraser(editor, localization.eraserTool),
|
31
23
|
// Three pens
|
32
24
|
primaryPenTool,
|
33
|
-
new Pen(editor, localization.penTool(2), { color: Color4.clay, thickness:
|
25
|
+
new Pen(editor, localization.penTool(2), { color: Color4.clay, thickness: 4 }),
|
34
26
|
// Highlighter-like pen with width=64
|
35
27
|
new Pen(editor, localization.penTool(3), { color: Color4.ofRGBA(1, 1, 0, 0.5), thickness: 64 }),
|
36
28
|
new TextTool(editor, localization.textTool, localization),
|
@@ -42,7 +34,7 @@ export default class ToolController {
|
|
42
34
|
keyboardPanZoomTool,
|
43
35
|
new UndoRedoShortcut(editor),
|
44
36
|
];
|
45
|
-
primaryTools.forEach(tool => tool.setToolGroup(
|
37
|
+
primaryTools.forEach(tool => tool.setToolGroup(primaryToolGroup));
|
46
38
|
panZoomTool.setEnabled(true);
|
47
39
|
primaryPenTool.setEnabled(true);
|
48
40
|
editor.notifier.on(EditorEventType.ToolEnabled, event => {
|
@@ -57,6 +49,26 @@ export default class ToolController {
|
|
57
49
|
});
|
58
50
|
this.activeTool = null;
|
59
51
|
}
|
52
|
+
// Replaces the current set of tools with `tools`. This should only be done before
|
53
|
+
// the creation of the app's toolbar (if using `HTMLToolbar`).
|
54
|
+
setTools(tools, primaryToolGroup) {
|
55
|
+
this.tools = tools;
|
56
|
+
this.primaryToolGroup = primaryToolGroup !== null && primaryToolGroup !== void 0 ? primaryToolGroup : new ToolEnabledGroup();
|
57
|
+
}
|
58
|
+
// Add a tool that acts like one of the primary tools (only one primary tool can be enabled at a time).
|
59
|
+
// This should be called before creating the app's toolbar.
|
60
|
+
addPrimaryTool(tool) {
|
61
|
+
tool.setToolGroup(this.primaryToolGroup);
|
62
|
+
if (tool.isEnabled()) {
|
63
|
+
this.primaryToolGroup.notifyEnabled(tool);
|
64
|
+
}
|
65
|
+
this.addTool(tool);
|
66
|
+
}
|
67
|
+
// Add a tool to the end of this' tool list (the added tool receives events after tools already added to this).
|
68
|
+
// This should be called before creating the app's toolbar.
|
69
|
+
addTool(tool) {
|
70
|
+
this.tools.push(tool);
|
71
|
+
}
|
60
72
|
// Returns true if the event was handled
|
61
73
|
dispatchInputEvent(event) {
|
62
74
|
var _a, _b;
|
@@ -116,7 +128,7 @@ export default class ToolController {
|
|
116
128
|
}
|
117
129
|
return handled;
|
118
130
|
}
|
119
|
-
getMatchingTools(
|
120
|
-
return this.tools.filter(tool => tool
|
131
|
+
getMatchingTools(type) {
|
132
|
+
return this.tools.filter(tool => tool instanceof type);
|
121
133
|
}
|
122
134
|
}
|
@@ -1,10 +1,8 @@
|
|
1
1
|
import Editor from '../Editor';
|
2
2
|
import { KeyPressEvent } from '../types';
|
3
3
|
import BaseTool from './BaseTool';
|
4
|
-
import { ToolType } from './ToolController';
|
5
4
|
export default class UndoRedoShortcut extends BaseTool {
|
6
5
|
private editor;
|
7
|
-
kind: ToolType.UndoRedoShortcut;
|
8
6
|
constructor(editor: Editor);
|
9
7
|
onKeyPress({ key, ctrlKey }: KeyPressEvent): boolean;
|
10
8
|
}
|
@@ -1,10 +1,11 @@
|
|
1
|
+
// Handles ctrl+Z, ctrl+Shift+Z keyboard shortcuts.
|
2
|
+
// @packageDocumentation
|
1
3
|
import BaseTool from './BaseTool';
|
2
|
-
|
4
|
+
// {@inheritDoc UndoRedoShortcut!}
|
3
5
|
export default class UndoRedoShortcut extends BaseTool {
|
4
6
|
constructor(editor) {
|
5
7
|
super(editor.notifier, editor.localization.undoRedoTool);
|
6
8
|
this.editor = editor;
|
7
|
-
this.kind = ToolType.UndoRedoShortcut;
|
8
9
|
}
|
9
10
|
// Activate undo/redo
|
10
11
|
onKeyPress({ key, ctrlKey }) {
|
@@ -0,0 +1,12 @@
|
|
1
|
+
/**
|
2
|
+
* @packageDocumentation
|
3
|
+
*/
|
4
|
+
export { default as BaseTool } from './BaseTool';
|
5
|
+
export { default as ToolController } from './ToolController';
|
6
|
+
export { default as ToolEnabledGroup } from './ToolEnabledGroup';
|
7
|
+
export { default as UndoRedoShortcut } from './UndoRedoShortcut';
|
8
|
+
export { default as PanZoomTool, PanZoomMode } from './PanZoom';
|
9
|
+
export { default as PenTool, PenStyle } from './Pen';
|
10
|
+
export { default as TextTool } from './TextTool';
|
11
|
+
export { default as SelectionTool } from './SelectionTool';
|
12
|
+
export { default as EraserTool } from './Eraser';
|
@@ -0,0 +1,12 @@
|
|
1
|
+
/**
|
2
|
+
* @packageDocumentation
|
3
|
+
*/
|
4
|
+
export { default as BaseTool } from './BaseTool';
|
5
|
+
export { default as ToolController } from './ToolController';
|
6
|
+
export { default as ToolEnabledGroup } from './ToolEnabledGroup';
|
7
|
+
export { default as UndoRedoShortcut } from './UndoRedoShortcut';
|
8
|
+
export { default as PanZoomTool, PanZoomMode } from './PanZoom';
|
9
|
+
export { default as PenTool } from './Pen';
|
10
|
+
export { default as TextTool } from './TextTool';
|
11
|
+
export { default as SelectionTool } from './SelectionTool';
|
12
|
+
export { default as EraserTool } from './Eraser';
|
package/package.json
CHANGED
package/src/EditorImage.ts
CHANGED
@@ -388,7 +388,6 @@ export class ImageNode {
|
|
388
388
|
}
|
389
389
|
|
390
390
|
public render(renderer: AbstractRenderer, visibleRect: Rect2) {
|
391
|
-
// Don't render components that are < 0.1% of the viewport.
|
392
391
|
const leaves = this.getLeavesIntersectingRegion(visibleRect, rect => renderer.isTooSmallToRender(rect));
|
393
392
|
sortLeavesByZIndex(leaves);
|
394
393
|
|
@@ -180,7 +180,7 @@ export default class FreehandLineBuilder implements ComponentBuilder {
|
|
180
180
|
}
|
181
181
|
|
182
182
|
private roundPoint(point: Point2): Point2 {
|
183
|
-
let minFit = Math.min(this.minFitAllowed, this.curveStartWidth);
|
183
|
+
let minFit = Math.min(this.minFitAllowed, this.curveStartWidth / 2);
|
184
184
|
|
185
185
|
if (minFit < 1e-10) {
|
186
186
|
minFit = this.minFitAllowed;
|
package/src/components/lib.ts
CHANGED
package/src/lib.ts
CHANGED
@@ -14,7 +14,8 @@
|
|
14
14
|
*/
|
15
15
|
|
16
16
|
import Editor from './Editor';
|
17
|
-
export {
|
17
|
+
export { default as EditorImage } from './EditorImage';
|
18
|
+
export * from './types';
|
18
19
|
export { default as getLocalizationTable } from './localizations/getLocalizationTable';
|
19
20
|
export * from './localization';
|
20
21
|
|
@@ -22,6 +23,9 @@ export { default as Color4 } from './Color4';
|
|
22
23
|
export * from './math/lib';
|
23
24
|
export * from './components/lib';
|
24
25
|
export * from './commands/lib';
|
26
|
+
export * from './tools/lib';
|
27
|
+
export * from './toolbar/lib';
|
28
|
+
export { default as Pointer, PointerDevice } from './Pointer';
|
25
29
|
export { default as HTMLToolbar } from './toolbar/HTMLToolbar';
|
26
30
|
|
27
31
|
export { Editor };
|
package/src/rendering/Display.ts
CHANGED
@@ -76,8 +76,8 @@ export default class Display {
|
|
76
76
|
return this.dryInkRenderer.canRenderFromWithoutDataLoss(renderer);
|
77
77
|
},
|
78
78
|
blockResolution: cacheBlockResolution,
|
79
|
-
cacheSize:
|
80
|
-
maxScale: 1.
|
79
|
+
cacheSize: 600 * 600 * 4 * 120,
|
80
|
+
maxScale: 1.4,
|
81
81
|
minComponentsPerCache: 45,
|
82
82
|
minComponentsToUseCache: 105,
|
83
83
|
});
|
@@ -221,11 +221,13 @@ export default class RenderingCacheNode {
|
|
221
221
|
}
|
222
222
|
} else {
|
223
223
|
// Determine whether we already have rendered the items
|
224
|
+
const tooSmallToRender = (rect: Rect2) => rect.w / this.region.w < 1 / this.cacheState.props.blockResolution.x;
|
225
|
+
|
224
226
|
const leaves = [];
|
225
227
|
for (const item of items) {
|
226
228
|
leaves.push(
|
227
229
|
...item.getLeavesIntersectingRegion(
|
228
|
-
this.region,
|
230
|
+
this.region, tooSmallToRender,
|
229
231
|
)
|
230
232
|
);
|
231
233
|
}
|
@@ -59,13 +59,13 @@ export default class CanvasRenderer extends AbstractRenderer {
|
|
59
59
|
// Set parameters for lower/higher quality rendering
|
60
60
|
public setDraftMode(draftMode: boolean) {
|
61
61
|
if (draftMode) {
|
62
|
-
this.minSquareCurveApproxDist =
|
63
|
-
this.minRenderSizeBothDimens =
|
64
|
-
this.minRenderSizeAnyDimen =
|
62
|
+
this.minSquareCurveApproxDist = 9;
|
63
|
+
this.minRenderSizeBothDimens = 2;
|
64
|
+
this.minRenderSizeAnyDimen = 0.5;
|
65
65
|
} else {
|
66
|
-
this.minSquareCurveApproxDist =
|
67
|
-
this.minRenderSizeBothDimens = 0.
|
68
|
-
this.minRenderSizeAnyDimen =
|
66
|
+
this.minSquareCurveApproxDist = 0.5;
|
67
|
+
this.minRenderSizeBothDimens = 0.3;
|
68
|
+
this.minRenderSizeAnyDimen = 1e-5;
|
69
69
|
}
|
70
70
|
}
|
71
71
|
|
@@ -1,31 +1,32 @@
|
|
1
1
|
import Editor from '../Editor';
|
2
|
-
import { ToolType } from '../tools/ToolController';
|
3
2
|
import { EditorEventType } from '../types';
|
4
3
|
|
5
4
|
import { coloris, init as colorisInit } from '@melloware/coloris';
|
6
5
|
import Color4 from '../Color4';
|
7
|
-
import Pen from '../tools/Pen';
|
8
|
-
import Eraser from '../tools/Eraser';
|
9
6
|
import SelectionTool from '../tools/SelectionTool';
|
10
7
|
import { defaultToolbarLocalization, ToolbarLocalization } from './localization';
|
11
8
|
import { ActionButtonIcon } from './types';
|
12
9
|
import { makeRedoIcon, makeUndoIcon } from './icons';
|
13
10
|
import PanZoom from '../tools/PanZoom';
|
14
11
|
import TextTool from '../tools/TextTool';
|
15
|
-
import
|
16
|
-
import EraserWidget from './widgets/
|
17
|
-
import
|
12
|
+
import PenToolWidget from './widgets/PenToolWidget';
|
13
|
+
import EraserWidget from './widgets/EraserToolWidget';
|
14
|
+
import SelectionToolWidget from './widgets/SelectionToolWidget';
|
18
15
|
import TextToolWidget from './widgets/TextToolWidget';
|
19
16
|
import HandToolWidget from './widgets/HandToolWidget';
|
17
|
+
import BaseWidget from './widgets/BaseWidget';
|
18
|
+
import { EraserTool, PenTool } from '../tools/lib';
|
20
19
|
|
21
20
|
|
22
21
|
export const toolbarCSSPrefix = 'toolbar-';
|
23
22
|
|
23
|
+
type UpdateColorisCallback = ()=>void;
|
24
24
|
|
25
25
|
export default class HTMLToolbar {
|
26
26
|
private container: HTMLElement;
|
27
27
|
|
28
28
|
private static colorisStarted: boolean = false;
|
29
|
+
private updateColoris: UpdateColorisCallback|null = null;
|
29
30
|
|
30
31
|
public constructor(
|
31
32
|
private editor: Editor, parent: HTMLElement,
|
@@ -45,6 +46,12 @@ export default class HTMLToolbar {
|
|
45
46
|
|
46
47
|
// @internal
|
47
48
|
public setupColorPickers() {
|
49
|
+
// Much of the setup only needs to be done once.
|
50
|
+
if (this.updateColoris) {
|
51
|
+
this.updateColoris();
|
52
|
+
return;
|
53
|
+
}
|
54
|
+
|
48
55
|
const closePickerOverlay = document.createElement('div');
|
49
56
|
closePickerOverlay.className = `${toolbarCSSPrefix}closeColorPickerOverlay`;
|
50
57
|
this.editor.createHTMLOverlay(closePickerOverlay);
|
@@ -73,6 +80,7 @@ export default class HTMLToolbar {
|
|
73
80
|
});
|
74
81
|
};
|
75
82
|
initColoris();
|
83
|
+
this.updateColoris = initColoris;
|
76
84
|
|
77
85
|
const addColorToSwatch = (newColor: string) => {
|
78
86
|
let alreadyPresent = false;
|
@@ -110,6 +118,13 @@ export default class HTMLToolbar {
|
|
110
118
|
});
|
111
119
|
}
|
112
120
|
|
121
|
+
// Adds an `ActionButtonWidget` or `BaseToolWidget`. The widget should not have already have a parent
|
122
|
+
// (i.e. its `addTo` method should not have been called).
|
123
|
+
public addWidget(widget: BaseWidget) {
|
124
|
+
widget.addTo(this.container);
|
125
|
+
this.setupColorPickers();
|
126
|
+
}
|
127
|
+
|
113
128
|
public addActionButton(title: string|ActionButtonIcon, command: ()=> void, parent?: Element) {
|
114
129
|
const button = document.createElement('button');
|
115
130
|
button.classList.add(`${toolbarCSSPrefix}button`);
|
@@ -134,7 +149,7 @@ export default class HTMLToolbar {
|
|
134
149
|
return button;
|
135
150
|
}
|
136
151
|
|
137
|
-
|
152
|
+
public addUndoRedoButtons() {
|
138
153
|
const undoRedoGroup = document.createElement('div');
|
139
154
|
undoRedoGroup.classList.add(`${toolbarCSSPrefix}buttonGroup`);
|
140
155
|
|
@@ -166,47 +181,29 @@ export default class HTMLToolbar {
|
|
166
181
|
|
167
182
|
public addDefaultToolWidgets() {
|
168
183
|
const toolController = this.editor.toolController;
|
169
|
-
for (const tool of toolController.getMatchingTools(
|
170
|
-
|
171
|
-
throw new Error('All `Pen` tools must have kind === ToolType.Pen');
|
172
|
-
}
|
173
|
-
|
174
|
-
const widget = new PenWidget(
|
184
|
+
for (const tool of toolController.getMatchingTools(PenTool)) {
|
185
|
+
const widget = new PenToolWidget(
|
175
186
|
this.editor, tool, this.localizationTable,
|
176
187
|
);
|
177
|
-
|
188
|
+
this.addWidget(widget);
|
178
189
|
}
|
179
190
|
|
180
|
-
for (const tool of toolController.getMatchingTools(
|
181
|
-
|
182
|
-
throw new Error('All Erasers must have kind === ToolType.Eraser!');
|
183
|
-
}
|
184
|
-
|
185
|
-
(new EraserWidget(this.editor, tool, this.localizationTable)).addTo(this.container);
|
191
|
+
for (const tool of toolController.getMatchingTools(EraserTool)) {
|
192
|
+
this.addWidget(new EraserWidget(this.editor, tool, this.localizationTable));
|
186
193
|
}
|
187
194
|
|
188
|
-
for (const tool of toolController.getMatchingTools(
|
189
|
-
|
190
|
-
throw new Error('All SelectionTools must have kind === ToolType.Selection');
|
191
|
-
}
|
192
|
-
|
193
|
-
(new SelectionWidget(this.editor, tool, this.localizationTable)).addTo(this.container);
|
195
|
+
for (const tool of toolController.getMatchingTools(SelectionTool)) {
|
196
|
+
this.addWidget(new SelectionToolWidget(this.editor, tool, this.localizationTable));
|
194
197
|
}
|
195
198
|
|
196
|
-
for (const tool of toolController.getMatchingTools(
|
197
|
-
|
198
|
-
throw new Error('All text tools must have kind === ToolType.Text');
|
199
|
-
}
|
200
|
-
|
201
|
-
(new TextToolWidget(this.editor, tool, this.localizationTable)).addTo(this.container);
|
199
|
+
for (const tool of toolController.getMatchingTools(TextTool)) {
|
200
|
+
this.addWidget(new TextToolWidget(this.editor, tool, this.localizationTable));
|
202
201
|
}
|
203
202
|
|
204
|
-
const panZoomTool = toolController.getMatchingTools(
|
205
|
-
if (panZoomTool
|
206
|
-
(new HandToolWidget(this.editor, panZoomTool, this.localizationTable))
|
203
|
+
const panZoomTool = toolController.getMatchingTools(PanZoom)[0];
|
204
|
+
if (panZoomTool) {
|
205
|
+
this.addWidget(new HandToolWidget(this.editor, panZoomTool, this.localizationTable));
|
207
206
|
}
|
208
|
-
|
209
|
-
this.setupColorPickers();
|
210
207
|
}
|
211
208
|
|
212
209
|
public addDefaultActionButtons() {
|
package/src/toolbar/icons.ts
CHANGED
@@ -287,7 +287,11 @@ export const makeTextIcon = (textStyle: TextStyle) => {
|
|
287
287
|
return icon;
|
288
288
|
};
|
289
289
|
|
290
|
-
export const makePenIcon = (tipThickness: number, color: string) => {
|
290
|
+
export const makePenIcon = (tipThickness: number, color: string|Color4) => {
|
291
|
+
if (color instanceof Color4) {
|
292
|
+
color = color.toHexString();
|
293
|
+
}
|
294
|
+
|
291
295
|
const icon = document.createElementNS(svgNamespace, 'svg');
|
292
296
|
icon.setAttribute('viewBox', '0 0 100 100');
|
293
297
|
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import Color4 from '../Color4';
|
2
2
|
import Editor from '../Editor';
|
3
3
|
import PipetteTool from '../tools/PipetteTool';
|
4
|
-
import { ToolType } from '../tools/ToolController';
|
5
4
|
import { EditorEventType } from '../types';
|
6
5
|
import { makePipetteIcon } from './icons';
|
7
6
|
|
@@ -77,7 +76,7 @@ const addPipetteTool = (editor: Editor, container: HTMLElement, onColorChange: O
|
|
77
76
|
};
|
78
77
|
updatePipetteIcon();
|
79
78
|
|
80
|
-
const pipetteTool: PipetteTool|undefined = editor.toolController.getMatchingTools(
|
79
|
+
const pipetteTool: PipetteTool|undefined = editor.toolController.getMatchingTools(PipetteTool)[0];
|
81
80
|
const endColorSelectMode = () => {
|
82
81
|
pipetteTool?.clearColorListener();
|
83
82
|
updatePipetteIcon();
|
package/src/toolbar/types.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { makeEraserIcon } from '../icons';
|
2
2
|
import BaseToolWidget from './BaseToolWidget';
|
3
3
|
|
4
|
-
export default class
|
4
|
+
export default class EraserToolWidget extends BaseToolWidget {
|
5
5
|
protected getTitle(): string {
|
6
6
|
return this.localizationTable.eraser;
|
7
7
|
}
|
@@ -1,5 +1,3 @@
|
|
1
|
-
// @internal @packageDocumentation
|
2
|
-
|
3
1
|
import { makeArrowBuilder } from '../../components/builders/ArrowBuilder';
|
4
2
|
import { makeFreehandLineBuilder } from '../../components/builders/FreehandLineBuilder';
|
5
3
|
import { makeLineBuilder } from '../../components/builders/LineBuilder';
|
@@ -15,12 +13,15 @@ import makeColorInput from '../makeColorInput';
|
|
15
13
|
import BaseToolWidget from './BaseToolWidget';
|
16
14
|
|
17
15
|
|
18
|
-
interface PenTypeRecord {
|
16
|
+
export interface PenTypeRecord {
|
17
|
+
// Description of the factory (e.g. 'Freehand line')
|
19
18
|
name: string;
|
19
|
+
|
20
|
+
// Creates an `AbstractComponent` from pen input.
|
20
21
|
factory: ComponentBuilderFactory;
|
21
22
|
}
|
22
23
|
|
23
|
-
export default class
|
24
|
+
export default class PenToolWidget extends BaseToolWidget {
|
24
25
|
private updateInputs: ()=> void = () => {};
|
25
26
|
protected penTypes: PenTypeRecord[];
|
26
27
|
|
@@ -97,8 +98,8 @@ export default class PenWidget extends BaseToolWidget {
|
|
97
98
|
const objectTypeSelect = document.createElement('select');
|
98
99
|
|
99
100
|
// Give inputs IDs so we can label them with a <label for=...>Label text</label>
|
100
|
-
thicknessInput.id = `${toolbarCSSPrefix}thicknessInput${
|
101
|
-
objectTypeSelect.id = `${toolbarCSSPrefix}builderSelect${
|
101
|
+
thicknessInput.id = `${toolbarCSSPrefix}thicknessInput${PenToolWidget.idCounter++}`;
|
102
|
+
objectTypeSelect.id = `${toolbarCSSPrefix}builderSelect${PenToolWidget.idCounter++}`;
|
102
103
|
|
103
104
|
thicknessLabel.innerText = this.localizationTable.thicknessLabel;
|
104
105
|
thicknessLabel.setAttribute('for', thicknessInput.id);
|
@@ -106,7 +107,7 @@ export default class PenWidget extends BaseToolWidget {
|
|
106
107
|
objectSelectLabel.setAttribute('for', objectTypeSelect.id);
|
107
108
|
|
108
109
|
thicknessInput.type = 'range';
|
109
|
-
thicknessInput.min = '
|
110
|
+
thicknessInput.min = '2';
|
110
111
|
thicknessInput.max = '20';
|
111
112
|
thicknessInput.step = '1';
|
112
113
|
thicknessInput.oninput = () => {
|
@@ -133,7 +134,7 @@ export default class PenWidget extends BaseToolWidget {
|
|
133
134
|
this.tool.setColor(color);
|
134
135
|
});
|
135
136
|
|
136
|
-
colorInput.id = `${toolbarCSSPrefix}colorInput${
|
137
|
+
colorInput.id = `${toolbarCSSPrefix}colorInput${PenToolWidget.idCounter++}`;
|
137
138
|
colorLabel.innerText = this.localizationTable.colorLabel;
|
138
139
|
colorLabel.setAttribute('for', colorInput.id);
|
139
140
|
|
@@ -164,4 +165,4 @@ export default class PenWidget extends BaseToolWidget {
|
|
164
165
|
dropdown.replaceChildren(container);
|
165
166
|
return true;
|
166
167
|
}
|
167
|
-
}
|
168
|
+
}
|
@@ -6,7 +6,7 @@ import { ToolbarLocalization } from '../localization';
|
|
6
6
|
import ActionButtonWidget from './ActionButtonWidget';
|
7
7
|
import BaseToolWidget from './BaseToolWidget';
|
8
8
|
|
9
|
-
export class
|
9
|
+
export default class SelectionToolWidget extends BaseToolWidget {
|
10
10
|
public constructor(
|
11
11
|
editor: Editor, private tool: SelectionTool, localization: ToolbarLocalization
|
12
12
|
) {
|
@@ -0,0 +1,10 @@
|
|
1
|
+
|
2
|
+
export { default as ActionButtonWidget } from './ActionButtonWidget';
|
3
|
+
export { default as BaseToolWidget } from './BaseToolWidget';
|
4
|
+
export { default as BaseWidget } from './BaseWidget';
|
5
|
+
|
6
|
+
export { default as PenToolWidget } from './PenToolWidget';
|
7
|
+
export { default as TextToolWidget } from './TextToolWidget';
|
8
|
+
export { default as HandToolWidget } from './HandToolWidget';
|
9
|
+
export { default as SelectionToolWidget } from './SelectionToolWidget';
|
10
|
+
export { default as EraserToolWidget } from './EraserToolWidget';
|