js-draw 0.0.2 → 0.0.5
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 +13 -0
- package/README.md +100 -3
- package/build_tools/BundledFile.ts +167 -0
- package/build_tools/bundle.ts +11 -0
- package/dist/build_tools/BundledFile.d.ts +13 -0
- package/dist/build_tools/BundledFile.js +157 -0
- package/dist/build_tools/bundle.d.ts +1 -0
- package/dist/build_tools/bundle.js +5 -0
- package/dist/bundle.js +1 -0
- package/dist/src/Display.js +4 -1
- package/dist/src/Editor.d.ts +9 -2
- package/dist/src/Editor.js +29 -7
- package/dist/src/EditorImage.d.ts +2 -0
- package/dist/src/EditorImage.js +29 -5
- package/dist/src/Pointer.js +1 -1
- package/dist/src/Viewport.d.ts +1 -1
- package/dist/src/bundle/bundled.d.ts +4 -0
- package/dist/src/bundle/bundled.js +5 -0
- package/dist/src/components/AbstractComponent.d.ts +1 -1
- package/dist/src/components/Stroke.d.ts +1 -1
- package/dist/src/components/Stroke.js +1 -1
- package/dist/src/components/UnknownSVGObject.d.ts +1 -1
- package/dist/src/components/builders/ArrowBuilder.d.ts +17 -0
- package/dist/src/components/builders/ArrowBuilder.js +83 -0
- package/dist/src/{StrokeBuilder.d.ts → components/builders/FreehandLineBuilder.d.ts} +9 -13
- package/dist/src/{StrokeBuilder.js → components/builders/FreehandLineBuilder.js} +27 -9
- package/dist/src/components/builders/LineBuilder.d.ts +16 -0
- package/dist/src/components/builders/LineBuilder.js +57 -0
- package/dist/src/components/builders/RectangleBuilder.d.ts +18 -0
- package/dist/src/components/builders/RectangleBuilder.js +41 -0
- package/dist/src/components/builders/types.d.ts +12 -0
- package/dist/src/components/builders/types.js +1 -0
- package/dist/src/geometry/Path.d.ts +1 -0
- package/dist/src/geometry/Path.js +32 -0
- package/dist/src/geometry/Vec3.d.ts +2 -0
- package/dist/src/geometry/Vec3.js +13 -0
- package/dist/src/localization.d.ts +1 -1
- package/dist/src/localization.js +2 -2
- package/dist/src/rendering/AbstractRenderer.js +3 -25
- package/dist/src/toolbar/HTMLToolbar.d.ts +5 -3
- package/dist/src/toolbar/HTMLToolbar.js +139 -30
- package/dist/src/toolbar/localization.d.ts +20 -0
- package/dist/src/toolbar/localization.js +19 -0
- package/dist/src/toolbar/types.d.ts +0 -13
- package/dist/src/tools/Pen.d.ts +13 -3
- package/dist/src/tools/Pen.js +37 -28
- package/dist/src/tools/SelectionTool.js +2 -1
- package/dist/src/tools/ToolController.js +3 -3
- package/dist/src/types.d.ts +14 -2
- package/dist/src/types.js +1 -0
- package/dist-test/test-dist-bundle.html +35 -0
- package/package.json +15 -5
- package/src/Display.ts +3 -1
- package/src/Editor.css +0 -1
- package/src/Editor.ts +51 -12
- package/src/EditorImage.test.ts +5 -3
- package/src/EditorImage.ts +31 -3
- package/src/Pointer.ts +1 -1
- package/src/Viewport.ts +1 -1
- package/src/bundle/bundled.ts +7 -0
- package/src/components/AbstractComponent.ts +1 -1
- package/src/components/Stroke.ts +2 -2
- package/src/components/UnknownSVGObject.ts +1 -1
- package/src/components/builders/ArrowBuilder.ts +104 -0
- package/src/{StrokeBuilder.ts → components/builders/FreehandLineBuilder.ts} +36 -18
- package/src/components/builders/LineBuilder.ts +75 -0
- package/src/components/builders/RectangleBuilder.ts +59 -0
- package/src/components/builders/types.ts +15 -0
- package/src/geometry/Path.ts +43 -0
- package/src/geometry/Vec2.test.ts +1 -0
- package/src/geometry/Vec3.test.ts +14 -0
- package/src/geometry/Vec3.ts +16 -0
- package/src/localization.ts +2 -3
- package/src/rendering/AbstractRenderer.ts +3 -32
- package/src/{editorStyles.js → styles.js} +0 -0
- package/src/toolbar/HTMLToolbar.ts +167 -39
- package/src/toolbar/localization.ts +44 -0
- package/src/toolbar/toolbar.css +12 -0
- package/src/toolbar/types.ts +0 -16
- package/src/tools/Pen.ts +56 -34
- package/src/tools/SelectionTool.test.ts +1 -1
- package/src/tools/SelectionTool.ts +1 -1
- package/src/tools/ToolController.ts +3 -3
- package/src/types.ts +16 -1
package/src/toolbar/types.ts
CHANGED
@@ -2,19 +2,3 @@ export enum ToolbarButtonType {
|
|
2
2
|
ToggleButton,
|
3
3
|
ActionButton,
|
4
4
|
}
|
5
|
-
|
6
|
-
|
7
|
-
export interface ToolbarLocalization {
|
8
|
-
colorLabel: string;
|
9
|
-
pen: string;
|
10
|
-
eraser: string;
|
11
|
-
select: string;
|
12
|
-
touchDrawing: string;
|
13
|
-
thicknessLabel: string;
|
14
|
-
resizeImageToSelection: string;
|
15
|
-
undo: string;
|
16
|
-
redo: string;
|
17
|
-
|
18
|
-
dropdownShown: (toolName: string)=>string;
|
19
|
-
dropdownHidden: (toolName: string)=>string;
|
20
|
-
}
|
package/src/tools/Pen.ts
CHANGED
@@ -1,49 +1,60 @@
|
|
1
1
|
import Color4 from '../Color4';
|
2
2
|
import Editor from '../Editor';
|
3
3
|
import EditorImage from '../EditorImage';
|
4
|
-
import { Vec2 } from '../geometry/Vec2';
|
5
4
|
import Pointer, { PointerDevice } from '../Pointer';
|
6
|
-
import
|
7
|
-
import { EditorEventType, PointerEvt } from '../types';
|
5
|
+
import { makeFreehandLineBuilder } from '../components/builders/FreehandLineBuilder';
|
6
|
+
import { EditorEventType, PointerEvt, StrokeDataPoint } from '../types';
|
8
7
|
import BaseTool from './BaseTool';
|
9
8
|
import { ToolType } from './ToolController';
|
9
|
+
import { ComponentBuilder, ComponentBuilderFactory } from '../components/builders/types';
|
10
|
+
|
11
|
+
interface PenStyle {
|
12
|
+
color: Color4;
|
13
|
+
thickness: number;
|
14
|
+
}
|
10
15
|
|
11
16
|
export default class Pen extends BaseTool {
|
12
|
-
private builder:
|
17
|
+
private builder: ComponentBuilder|null = null;
|
18
|
+
private builderFactory: ComponentBuilderFactory = makeFreehandLineBuilder;
|
19
|
+
private lastPoint: StrokeDataPoint|null = null;
|
20
|
+
|
13
21
|
public readonly kind: ToolType = ToolType.Pen;
|
14
22
|
|
15
23
|
public constructor(
|
16
24
|
private editor: Editor,
|
17
25
|
description: string,
|
18
|
-
private
|
19
|
-
private thickness: number = 16.0,
|
26
|
+
private style: PenStyle,
|
20
27
|
) {
|
21
28
|
super(editor.notifier, description);
|
22
29
|
}
|
23
30
|
|
24
31
|
private getPressureMultiplier() {
|
25
|
-
return 1 / this.editor.viewport.getScaleFactor() * this.thickness;
|
32
|
+
return 1 / this.editor.viewport.getScaleFactor() * this.style.thickness;
|
26
33
|
}
|
27
34
|
|
28
|
-
private getStrokePoint(pointer: Pointer) {
|
35
|
+
private getStrokePoint(pointer: Pointer): StrokeDataPoint {
|
29
36
|
const minPressure = 0.3;
|
30
37
|
const pressure = Math.max(pointer.pressure ?? 1.0, minPressure);
|
31
38
|
return {
|
32
39
|
pos: pointer.canvasPos,
|
33
40
|
width: pressure * this.getPressureMultiplier(),
|
34
|
-
color: this.color,
|
41
|
+
color: this.style.color,
|
35
42
|
time: pointer.timeStamp,
|
36
43
|
};
|
37
44
|
}
|
38
45
|
|
39
|
-
private
|
46
|
+
private previewStroke() {
|
47
|
+
this.editor.clearWetInk();
|
48
|
+
this.builder?.preview(this.editor.display.getWetInkRenderer());
|
49
|
+
}
|
50
|
+
|
51
|
+
private addPointToStroke(point: StrokeDataPoint) {
|
40
52
|
if (!this.builder) {
|
41
53
|
throw new Error('No stroke is currently being generated.');
|
42
54
|
}
|
43
|
-
this.builder.addPoint(
|
44
|
-
|
45
|
-
this.
|
46
|
-
this.editor.drawWetInk(...this.builder.preview());
|
55
|
+
this.builder.addPoint(point);
|
56
|
+
this.lastPoint = point;
|
57
|
+
this.previewStroke();
|
47
58
|
}
|
48
59
|
|
49
60
|
public onPointerDown({ current, allPointers }: PointerEvt): boolean {
|
@@ -52,15 +63,7 @@ export default class Pen extends BaseTool {
|
|
52
63
|
}
|
53
64
|
|
54
65
|
if (allPointers.length === 1 || current.device === PointerDevice.Pen) {
|
55
|
-
|
56
|
-
// less than ± 2 px from the curve.
|
57
|
-
const canvasTransform = this.editor.viewport.screenToCanvasTransform;
|
58
|
-
const maxSmoothingDist = canvasTransform.transformVec3(Vec2.unitX).magnitude() * 7;
|
59
|
-
const minSmoothingDist = canvasTransform.transformVec3(Vec2.unitX).magnitude() * 2;
|
60
|
-
|
61
|
-
this.builder = new StrokeBuilder(
|
62
|
-
this.getStrokePoint(current), minSmoothingDist, maxSmoothingDist
|
63
|
-
);
|
66
|
+
this.builder = this.builderFactory(this.getStrokePoint(current), this.editor.viewport);
|
64
67
|
return true;
|
65
68
|
}
|
66
69
|
|
@@ -68,7 +71,7 @@ export default class Pen extends BaseTool {
|
|
68
71
|
}
|
69
72
|
|
70
73
|
public onPointerMove({ current }: PointerEvt): void {
|
71
|
-
this.addPointToStroke(current);
|
74
|
+
this.addPointToStroke(this.getStrokePoint(current));
|
72
75
|
}
|
73
76
|
|
74
77
|
public onPointerUp({ current }: PointerEvt): void {
|
@@ -76,12 +79,17 @@ export default class Pen extends BaseTool {
|
|
76
79
|
return;
|
77
80
|
}
|
78
81
|
|
79
|
-
|
82
|
+
// onPointerUp events can have zero pressure. Use the last pressure instead.
|
83
|
+
const currentPoint = this.getStrokePoint(current);
|
84
|
+
const strokePoint = {
|
85
|
+
...currentPoint,
|
86
|
+
width: this.lastPoint?.width ?? currentPoint.width,
|
87
|
+
};
|
88
|
+
|
89
|
+
this.addPointToStroke(strokePoint);
|
80
90
|
if (this.builder && current.isPrimary) {
|
81
91
|
const stroke = this.builder.build();
|
82
|
-
|
83
|
-
this.editor.clearWetInk();
|
84
|
-
this.editor.drawWetInk(...this.builder.preview());
|
92
|
+
this.previewStroke();
|
85
93
|
|
86
94
|
const canFlatten = true;
|
87
95
|
const action = new EditorImage.AddElementCommand(stroke, canFlatten);
|
@@ -103,19 +111,33 @@ export default class Pen extends BaseTool {
|
|
103
111
|
}
|
104
112
|
|
105
113
|
public setColor(color: Color4): void {
|
106
|
-
if (color.toHexString() !== this.color.toHexString()) {
|
107
|
-
this.
|
114
|
+
if (color.toHexString() !== this.style.color.toHexString()) {
|
115
|
+
this.style = {
|
116
|
+
...this.style,
|
117
|
+
color,
|
118
|
+
};
|
108
119
|
this.noteUpdated();
|
109
120
|
}
|
110
121
|
}
|
111
122
|
|
112
123
|
public setThickness(thickness: number) {
|
113
|
-
if (thickness !== this.thickness) {
|
114
|
-
this.
|
124
|
+
if (thickness !== this.style.thickness) {
|
125
|
+
this.style = {
|
126
|
+
...this.style,
|
127
|
+
thickness,
|
128
|
+
};
|
129
|
+
this.noteUpdated();
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
public setStrokeFactory(factory: ComponentBuilderFactory) {
|
134
|
+
if (factory !== this.builderFactory) {
|
135
|
+
this.builderFactory = factory;
|
115
136
|
this.noteUpdated();
|
116
137
|
}
|
117
138
|
}
|
118
139
|
|
119
|
-
public getThickness() { return this.thickness; }
|
120
|
-
public getColor() { return this.color; }
|
140
|
+
public getThickness() { return this.style.thickness; }
|
141
|
+
public getColor() { return this.style.color; }
|
142
|
+
public getStrokeFactory() { return this.builderFactory; }
|
121
143
|
}
|
@@ -15,7 +15,7 @@ const getSelectionTool = (editor: Editor): SelectionTool => {
|
|
15
15
|
return editor.toolController.getMatchingTools(ToolType.Selection)[0] as SelectionTool;
|
16
16
|
};
|
17
17
|
|
18
|
-
const createEditor = () => new Editor(document.body, RenderingMode.DummyRenderer);
|
18
|
+
const createEditor = () => new Editor(document.body, { renderingMode: RenderingMode.DummyRenderer });
|
19
19
|
|
20
20
|
const createSquareStroke = () => {
|
21
21
|
const testStroke = new Stroke([
|
@@ -24,17 +24,17 @@ export default class ToolController {
|
|
24
24
|
public constructor(editor: Editor, localization: ToolLocalization) {
|
25
25
|
const primaryToolEnabledGroup = new ToolEnabledGroup();
|
26
26
|
const touchPanZoom = new PanZoom(editor, PanZoomMode.OneFingerGestures, localization.touchPanTool);
|
27
|
-
const primaryPenTool = new Pen(editor, localization.penTool(1));
|
27
|
+
const primaryPenTool = new Pen(editor, localization.penTool(1), { color: Color4.purple, thickness: 16 });
|
28
28
|
const primaryTools = [
|
29
29
|
new SelectionTool(editor, localization.selectionTool),
|
30
30
|
new Eraser(editor, localization.eraserTool),
|
31
31
|
|
32
32
|
// Three pens
|
33
33
|
primaryPenTool,
|
34
|
-
new Pen(editor, localization.penTool(2), Color4.clay, 8),
|
34
|
+
new Pen(editor, localization.penTool(2), { color: Color4.clay, thickness: 8 }),
|
35
35
|
|
36
36
|
// Highlighter-like pen with width=64
|
37
|
-
new Pen(editor, localization.penTool(3), Color4.ofRGBA(1, 1, 0, 0.5), 64),
|
37
|
+
new Pen(editor, localization.penTool(3), { color: Color4.ofRGBA(1, 1, 0, 0.5), thickness: 64 }),
|
38
38
|
];
|
39
39
|
this.tools = [
|
40
40
|
touchPanZoom,
|
package/src/types.ts
CHANGED
@@ -8,6 +8,7 @@ import BaseTool from './tools/BaseTool';
|
|
8
8
|
import AbstractComponent from './components/AbstractComponent';
|
9
9
|
import Rect2 from './geometry/Rect2';
|
10
10
|
import Pointer from './Pointer';
|
11
|
+
import Color4 from './Color4';
|
11
12
|
|
12
13
|
|
13
14
|
export interface PointerEvtListener {
|
@@ -74,6 +75,7 @@ export type InputEvt = KeyPressEvent | WheelEvt | GestureCancelEvt | PointerEvt;
|
|
74
75
|
|
75
76
|
export type EditorNotifier = EventDispatcher<EditorEventType, EditorEventDataType>;
|
76
77
|
|
78
|
+
|
77
79
|
export enum EditorEventType {
|
78
80
|
ToolEnabled,
|
79
81
|
ToolDisabled,
|
@@ -82,6 +84,7 @@ export enum EditorEventType {
|
|
82
84
|
ObjectAdded,
|
83
85
|
ViewportChanged,
|
84
86
|
DisplayResized,
|
87
|
+
ColorPickerToggled,
|
85
88
|
}
|
86
89
|
|
87
90
|
type EditorToolEventType = EditorEventType.ToolEnabled
|
@@ -115,7 +118,12 @@ export interface EditorUndoStackUpdated {
|
|
115
118
|
readonly redoStackSize: number;
|
116
119
|
}
|
117
120
|
|
118
|
-
export
|
121
|
+
export interface ColorPickerToggled {
|
122
|
+
readonly kind: EditorEventType.ColorPickerToggled;
|
123
|
+
readonly open: boolean;
|
124
|
+
}
|
125
|
+
|
126
|
+
export type EditorEventDataType = EditorToolEvent | EditorObjectEvent | EditorViewportChangedEvent | DisplayResizedEvent | EditorUndoStackUpdated | ColorPickerToggled;
|
119
127
|
|
120
128
|
|
121
129
|
// Returns a Promise to indicate that the event source should pause until the Promise resolves.
|
@@ -131,3 +139,10 @@ export interface ImageLoader {
|
|
131
139
|
onAddComponent: ComponentAddedListener, onProgressListener: OnProgressListener
|
132
140
|
): Promise<Rect2>;
|
133
141
|
}
|
142
|
+
|
143
|
+
export interface StrokeDataPoint {
|
144
|
+
pos: Point2;
|
145
|
+
width: number;
|
146
|
+
time: number;
|
147
|
+
color: Color4;
|
148
|
+
}
|