js-draw 1.11.2 → 1.12.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/Editor.js +13 -2
- package/dist/cjs/components/util/StrokeSmoother.d.ts +1 -0
- package/dist/cjs/components/util/StrokeSmoother.js +25 -7
- package/dist/cjs/util/mitLicenseAttribution.d.ts +2 -0
- package/dist/cjs/util/mitLicenseAttribution.js +28 -0
- package/dist/cjs/version.js +1 -1
- package/dist/mjs/Editor.mjs +13 -2
- package/dist/mjs/components/util/StrokeSmoother.d.ts +1 -0
- package/dist/mjs/components/util/StrokeSmoother.mjs +25 -7
- package/dist/mjs/util/mitLicenseAttribution.d.ts +2 -0
- package/dist/mjs/util/mitLicenseAttribution.mjs +26 -0
- package/dist/mjs/version.mjs +1 -1
- package/package.json +2 -2
package/dist/cjs/Editor.js
CHANGED
@@ -57,6 +57,7 @@ const version_1 = __importDefault(require("./version"));
|
|
57
57
|
const editorImageToSVG_1 = require("./image/export/editorImageToSVG");
|
58
58
|
const ReactiveValue_1 = require("./util/ReactiveValue");
|
59
59
|
const listenForKeyboardEventsFrom_1 = __importDefault(require("./util/listenForKeyboardEventsFrom"));
|
60
|
+
const mitLicenseAttribution_1 = __importDefault(require("./util/mitLicenseAttribution"));
|
60
61
|
/**
|
61
62
|
* The main entrypoint for the full editor.
|
62
63
|
*
|
@@ -1202,9 +1203,19 @@ class Editor {
|
|
1202
1203
|
text: [
|
1203
1204
|
`This image editor is powered by js-draw v${version_1.default.number}.`,
|
1204
1205
|
'',
|
1205
|
-
'js-draw uses
|
1206
|
+
'At runtime, js-draw uses',
|
1206
1207
|
' - The Coloris color picker: https://github.com/mdbassit/Coloris',
|
1207
|
-
' - The bezier.js Bézier curve library: https://github.com/Pomax/bezierjs'
|
1208
|
+
' - The bezier.js Bézier curve library: https://github.com/Pomax/bezierjs',
|
1209
|
+
'',
|
1210
|
+
'Both are licensed under the MIT license:',
|
1211
|
+
'',
|
1212
|
+
'',
|
1213
|
+
'== Coloris ==',
|
1214
|
+
(0, mitLicenseAttribution_1.default)('2021 Mohammed Bassit'),
|
1215
|
+
'',
|
1216
|
+
'',
|
1217
|
+
'== Bezier.js ==',
|
1218
|
+
(0, mitLicenseAttribution_1.default)('2023 Mike "Pomax" Kamermans'),
|
1208
1219
|
].join('\n'),
|
1209
1220
|
minimized: true,
|
1210
1221
|
});
|
@@ -15,6 +15,7 @@ class StrokeSmoother {
|
|
15
15
|
this.maxFitAllowed = maxFitAllowed;
|
16
16
|
this.onCurveAdded = onCurveAdded;
|
17
17
|
this.isFirstSegment = true;
|
18
|
+
this.centerOfMass = null;
|
18
19
|
this.lastExitingVec = null;
|
19
20
|
this.currentCurve = null;
|
20
21
|
this.lastPoint = this.startPoint;
|
@@ -60,6 +61,7 @@ class StrokeSmoother {
|
|
60
61
|
this.buffer[this.buffer.length - 2], lastPoint,
|
61
62
|
];
|
62
63
|
this.currentCurve = null;
|
64
|
+
this.centerOfMass = null;
|
63
65
|
this.isFirstSegment = false;
|
64
66
|
}
|
65
67
|
// Returns [upper curve, connector, lower curve]
|
@@ -107,10 +109,20 @@ class StrokeSmoother {
|
|
107
109
|
if (shouldSnapToInitial) {
|
108
110
|
return;
|
109
111
|
}
|
112
|
+
if (!this.centerOfMass) {
|
113
|
+
this.centerOfMass = newPoint.pos;
|
114
|
+
}
|
115
|
+
else {
|
116
|
+
this.centerOfMass = this.centerOfMass
|
117
|
+
.times(this.buffer.length)
|
118
|
+
.plus(newPoint.pos).times(1 / (this.buffer.length + 1));
|
119
|
+
}
|
120
|
+
const toCenterOfMass = this.centerOfMass.minus(newPoint.pos);
|
110
121
|
const deltaTimeSeconds = deltaTime / 1000;
|
111
122
|
const velocity = newPoint.pos.minus(this.lastPoint.pos).times(1 / deltaTimeSeconds);
|
112
123
|
// TODO: Do we need momentum smoothing? (this.momentum.lerp(velocity, 0.9);)
|
113
|
-
|
124
|
+
const k = 1;
|
125
|
+
this.momentum = velocity.plus(toCenterOfMass.times(k));
|
114
126
|
}
|
115
127
|
const lastPoint = this.lastPoint ?? newPoint;
|
116
128
|
this.lastPoint = newPoint;
|
@@ -147,7 +159,7 @@ class StrokeSmoother {
|
|
147
159
|
}
|
148
160
|
let exitingVec = this.computeExitingVec();
|
149
161
|
// Find the intersection between the entering vector and the exiting vector
|
150
|
-
const maxRelativeLength =
|
162
|
+
const maxRelativeLength = 1.6;
|
151
163
|
const segmentStart = this.buffer[0];
|
152
164
|
const segmentEnd = newPoint.pos;
|
153
165
|
const startEndDist = segmentEnd.minus(segmentStart).magnitude();
|
@@ -168,11 +180,17 @@ class StrokeSmoother {
|
|
168
180
|
if (intersection) {
|
169
181
|
controlPoint = intersection.point;
|
170
182
|
}
|
171
|
-
// No intersection
|
172
|
-
if (!controlPoint
|
173
|
-
//
|
174
|
-
|
175
|
-
|
183
|
+
// No intersection?
|
184
|
+
if (!controlPoint) {
|
185
|
+
// Estimate the control point position based on the entering tangent line
|
186
|
+
controlPoint = segmentStart
|
187
|
+
.lerp(segmentEnd, 0.5)
|
188
|
+
.lerp(segmentStart.plus(enteringVec.times(startEndDist)), 0.25);
|
189
|
+
}
|
190
|
+
// Equal to an endpoint?
|
191
|
+
if (segmentStart.eq(controlPoint) || segmentEnd.eq(controlPoint)) {
|
192
|
+
// Position the control point between the two end points
|
193
|
+
controlPoint = segmentStart.lerp(segmentEnd, 0.5);
|
176
194
|
}
|
177
195
|
console.assert(!segmentStart.eq(controlPoint, 1e-11), 'Start and control points are equal!');
|
178
196
|
console.assert(!controlPoint.eq(segmentEnd, 1e-11), 'Control and end points are equal!');
|
@@ -0,0 +1,28 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const mitLicenseAttribution = (copyright) => {
|
4
|
+
const removeSingleLineBreaks = (text) => text.replace(/([^\n])[\n]([^\n])/g, '$1 $2');
|
5
|
+
return removeSingleLineBreaks(`
|
6
|
+
MIT License
|
7
|
+
|
8
|
+
Copyright (c) ${copyright}
|
9
|
+
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
12
|
+
in the Software without restriction, including without limitation the rights
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
15
|
+
furnished to do so, subject to the following conditions:
|
16
|
+
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
18
|
+
copies or substantial portions of the Software.
|
19
|
+
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26
|
+
SOFTWARE.`);
|
27
|
+
};
|
28
|
+
exports.default = mitLicenseAttribution;
|
package/dist/cjs/version.js
CHANGED
package/dist/mjs/Editor.mjs
CHANGED
@@ -28,6 +28,7 @@ import version from './version.mjs';
|
|
28
28
|
import { editorImageToSVGSync, editorImageToSVGAsync } from './image/export/editorImageToSVG.mjs';
|
29
29
|
import { MutableReactiveValue } from './util/ReactiveValue.mjs';
|
30
30
|
import listenForKeyboardEventsFrom from './util/listenForKeyboardEventsFrom.mjs';
|
31
|
+
import mitLicenseAttribution from './util/mitLicenseAttribution.mjs';
|
31
32
|
/**
|
32
33
|
* The main entrypoint for the full editor.
|
33
34
|
*
|
@@ -1173,9 +1174,19 @@ export class Editor {
|
|
1173
1174
|
text: [
|
1174
1175
|
`This image editor is powered by js-draw v${version.number}.`,
|
1175
1176
|
'',
|
1176
|
-
'js-draw uses
|
1177
|
+
'At runtime, js-draw uses',
|
1177
1178
|
' - The Coloris color picker: https://github.com/mdbassit/Coloris',
|
1178
|
-
' - The bezier.js Bézier curve library: https://github.com/Pomax/bezierjs'
|
1179
|
+
' - The bezier.js Bézier curve library: https://github.com/Pomax/bezierjs',
|
1180
|
+
'',
|
1181
|
+
'Both are licensed under the MIT license:',
|
1182
|
+
'',
|
1183
|
+
'',
|
1184
|
+
'== Coloris ==',
|
1185
|
+
mitLicenseAttribution('2021 Mohammed Bassit'),
|
1186
|
+
'',
|
1187
|
+
'',
|
1188
|
+
'== Bezier.js ==',
|
1189
|
+
mitLicenseAttribution('2023 Mike "Pomax" Kamermans'),
|
1179
1190
|
].join('\n'),
|
1180
1191
|
minimized: true,
|
1181
1192
|
});
|
@@ -12,6 +12,7 @@ export class StrokeSmoother {
|
|
12
12
|
this.maxFitAllowed = maxFitAllowed;
|
13
13
|
this.onCurveAdded = onCurveAdded;
|
14
14
|
this.isFirstSegment = true;
|
15
|
+
this.centerOfMass = null;
|
15
16
|
this.lastExitingVec = null;
|
16
17
|
this.currentCurve = null;
|
17
18
|
this.lastPoint = this.startPoint;
|
@@ -57,6 +58,7 @@ export class StrokeSmoother {
|
|
57
58
|
this.buffer[this.buffer.length - 2], lastPoint,
|
58
59
|
];
|
59
60
|
this.currentCurve = null;
|
61
|
+
this.centerOfMass = null;
|
60
62
|
this.isFirstSegment = false;
|
61
63
|
}
|
62
64
|
// Returns [upper curve, connector, lower curve]
|
@@ -104,10 +106,20 @@ export class StrokeSmoother {
|
|
104
106
|
if (shouldSnapToInitial) {
|
105
107
|
return;
|
106
108
|
}
|
109
|
+
if (!this.centerOfMass) {
|
110
|
+
this.centerOfMass = newPoint.pos;
|
111
|
+
}
|
112
|
+
else {
|
113
|
+
this.centerOfMass = this.centerOfMass
|
114
|
+
.times(this.buffer.length)
|
115
|
+
.plus(newPoint.pos).times(1 / (this.buffer.length + 1));
|
116
|
+
}
|
117
|
+
const toCenterOfMass = this.centerOfMass.minus(newPoint.pos);
|
107
118
|
const deltaTimeSeconds = deltaTime / 1000;
|
108
119
|
const velocity = newPoint.pos.minus(this.lastPoint.pos).times(1 / deltaTimeSeconds);
|
109
120
|
// TODO: Do we need momentum smoothing? (this.momentum.lerp(velocity, 0.9);)
|
110
|
-
|
121
|
+
const k = 1;
|
122
|
+
this.momentum = velocity.plus(toCenterOfMass.times(k));
|
111
123
|
}
|
112
124
|
const lastPoint = this.lastPoint ?? newPoint;
|
113
125
|
this.lastPoint = newPoint;
|
@@ -144,7 +156,7 @@ export class StrokeSmoother {
|
|
144
156
|
}
|
145
157
|
let exitingVec = this.computeExitingVec();
|
146
158
|
// Find the intersection between the entering vector and the exiting vector
|
147
|
-
const maxRelativeLength =
|
159
|
+
const maxRelativeLength = 1.6;
|
148
160
|
const segmentStart = this.buffer[0];
|
149
161
|
const segmentEnd = newPoint.pos;
|
150
162
|
const startEndDist = segmentEnd.minus(segmentStart).magnitude();
|
@@ -165,11 +177,17 @@ export class StrokeSmoother {
|
|
165
177
|
if (intersection) {
|
166
178
|
controlPoint = intersection.point;
|
167
179
|
}
|
168
|
-
// No intersection
|
169
|
-
if (!controlPoint
|
170
|
-
//
|
171
|
-
|
172
|
-
|
180
|
+
// No intersection?
|
181
|
+
if (!controlPoint) {
|
182
|
+
// Estimate the control point position based on the entering tangent line
|
183
|
+
controlPoint = segmentStart
|
184
|
+
.lerp(segmentEnd, 0.5)
|
185
|
+
.lerp(segmentStart.plus(enteringVec.times(startEndDist)), 0.25);
|
186
|
+
}
|
187
|
+
// Equal to an endpoint?
|
188
|
+
if (segmentStart.eq(controlPoint) || segmentEnd.eq(controlPoint)) {
|
189
|
+
// Position the control point between the two end points
|
190
|
+
controlPoint = segmentStart.lerp(segmentEnd, 0.5);
|
173
191
|
}
|
174
192
|
console.assert(!segmentStart.eq(controlPoint, 1e-11), 'Start and control points are equal!');
|
175
193
|
console.assert(!controlPoint.eq(segmentEnd, 1e-11), 'Control and end points are equal!');
|
@@ -0,0 +1,26 @@
|
|
1
|
+
const mitLicenseAttribution = (copyright) => {
|
2
|
+
const removeSingleLineBreaks = (text) => text.replace(/([^\n])[\n]([^\n])/g, '$1 $2');
|
3
|
+
return removeSingleLineBreaks(`
|
4
|
+
MIT License
|
5
|
+
|
6
|
+
Copyright (c) ${copyright}
|
7
|
+
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
of this software and associated documentation files (the "Software"), to deal
|
10
|
+
in the Software without restriction, including without limitation the rights
|
11
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
copies of the Software, and to permit persons to whom the Software is
|
13
|
+
furnished to do so, subject to the following conditions:
|
14
|
+
|
15
|
+
The above copyright notice and this permission notice shall be included in all
|
16
|
+
copies or substantial portions of the Software.
|
17
|
+
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
24
|
+
SOFTWARE.`);
|
25
|
+
};
|
26
|
+
export default mitLicenseAttribution;
|
package/dist/mjs/version.mjs
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "js-draw",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.12.0",
|
4
4
|
"description": "Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript. ",
|
5
5
|
"types": "./dist/mjs/lib.d.ts",
|
6
6
|
"main": "./dist/cjs/lib.js",
|
@@ -86,5 +86,5 @@
|
|
86
86
|
"freehand",
|
87
87
|
"svg"
|
88
88
|
],
|
89
|
-
"gitHead": "
|
89
|
+
"gitHead": "c179c5b3ebca482dfb156527ec6631c8f5159033"
|
90
90
|
}
|