js-draw 1.15.0 → 1.16.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/dist/Editor.css +14 -0
- package/dist/bundle.js +1 -1
- package/dist/bundledStyles.js +1 -1
- package/dist/cjs/Editor.d.ts +4 -1
- package/dist/cjs/Editor.js +25 -2
- package/dist/cjs/rendering/renderers/CanvasRenderer.js +1 -1
- package/dist/cjs/tools/PanZoom.d.ts +8 -2
- package/dist/cjs/tools/PanZoom.js +29 -10
- package/dist/cjs/tools/PasteHandler.js +4 -0
- package/dist/cjs/tools/SelectionTool/Selection.js +16 -2
- package/dist/cjs/version.js +1 -1
- package/dist/mjs/Editor.d.ts +4 -1
- package/dist/mjs/Editor.mjs +25 -2
- package/dist/mjs/rendering/renderers/CanvasRenderer.mjs +1 -1
- package/dist/mjs/tools/PanZoom.d.ts +8 -2
- package/dist/mjs/tools/PanZoom.mjs +29 -10
- package/dist/mjs/tools/PasteHandler.mjs +4 -0
- package/dist/mjs/tools/SelectionTool/Selection.mjs +16 -2
- package/dist/mjs/version.mjs +1 -1
- package/package.json +3 -3
- package/src/Editor.scss +10 -0
- package/src/toolbar/EdgeToolbar.scss +2 -0
- package/src/tools/SelectionTool/SelectionTool.scss +4 -0
- package/src/tools/SoundUITool.scss +4 -1
@@ -71,9 +71,11 @@ export default class PanZoom extends BaseTool {
|
|
71
71
|
this.initialRotationSnapAngle = 0.22; // radians
|
72
72
|
this.afterRotationStartSnapAngle = 0.07; // radians
|
73
73
|
this.pinchZoomStartThreshold = 1.08; // scale factor
|
74
|
+
// Last timestamp at which a pointerdown event was received
|
74
75
|
this.lastPointerDownTimestamp = 0;
|
75
76
|
this.initialTouchAngle = 0;
|
76
77
|
this.initialViewportRotation = 0;
|
78
|
+
this.initialViewportScale = 0;
|
77
79
|
// Set to `true` only when scaling has started (if two fingers are down and have moved
|
78
80
|
// far enough).
|
79
81
|
this.isScaling = false;
|
@@ -113,11 +115,12 @@ export default class PanZoom extends BaseTool {
|
|
113
115
|
const isRightClick = this.allPointersAreOfType(pointers, PointerDevice.RightButtonMouse);
|
114
116
|
if (allAreTouch && pointers.length === 2 && this.mode & PanZoomMode.TwoFingerTouchGestures) {
|
115
117
|
const { screenCenter, angle, dist } = this.computePinchData(pointers[0], pointers[1]);
|
116
|
-
this.
|
117
|
-
this.
|
118
|
+
this.lastTouchDist = dist;
|
119
|
+
this.startTouchDist = dist;
|
118
120
|
this.lastScreenCenter = screenCenter;
|
119
121
|
this.initialTouchAngle = angle;
|
120
122
|
this.initialViewportRotation = this.editor.viewport.getRotationAngle();
|
123
|
+
this.initialViewportScale = this.editor.viewport.getScaleFactor();
|
121
124
|
this.isScaling = false;
|
122
125
|
// We're initially rotated if `initialViewportRotation` isn't near a multiple of pi/2.
|
123
126
|
// In other words, if sin(2 initialViewportRotation) is near zero.
|
@@ -193,6 +196,22 @@ export default class PanZoom extends BaseTool {
|
|
193
196
|
}
|
194
197
|
return fullRotation - this.editor.viewport.getRotationAngle();
|
195
198
|
}
|
199
|
+
/**
|
200
|
+
* Given a scale update, `scaleFactor`, returns a new scale factor snapped
|
201
|
+
* to a power of two (if within some tolerance of that scale).
|
202
|
+
*/
|
203
|
+
toSnappedScaleFactor(touchDist) {
|
204
|
+
// scaleFactor is applied to the current transformation of the viewport.
|
205
|
+
const newScale = this.initialViewportScale * touchDist / this.startTouchDist;
|
206
|
+
const currentScale = this.editor.viewport.getScaleFactor();
|
207
|
+
const logNewScale = Math.log(newScale) / Math.log(10);
|
208
|
+
const roundedLogNewScale = Math.round(logNewScale);
|
209
|
+
const logTolerance = 0.04;
|
210
|
+
if (Math.abs(roundedLogNewScale - logNewScale) < logTolerance) {
|
211
|
+
return Math.pow(10, roundedLogNewScale) / currentScale;
|
212
|
+
}
|
213
|
+
return touchDist / this.lastTouchDist;
|
214
|
+
}
|
196
215
|
handleTwoFingerMove(allPointers) {
|
197
216
|
const { screenCenter, canvasCenter, angle, dist } = this.computePinchData(allPointers[0], allPointers[1]);
|
198
217
|
const delta = this.getCenterDelta(screenCenter);
|
@@ -209,25 +228,25 @@ export default class PanZoom extends BaseTool {
|
|
209
228
|
this.isRotating = true;
|
210
229
|
}
|
211
230
|
this.updateVelocity(screenCenter);
|
212
|
-
|
213
|
-
|
214
|
-
scaleFactor = dist / this.lastDist;
|
215
|
-
}
|
216
|
-
else {
|
217
|
-
const initialScaleFactor = dist / this.startDist;
|
231
|
+
if (!this.isScaling) {
|
232
|
+
const initialScaleFactor = dist / this.startTouchDist;
|
218
233
|
// Only start scaling if scaling done so far exceeds some threshold.
|
219
234
|
const upperBound = this.pinchZoomStartThreshold;
|
220
235
|
const lowerBound = 1 / this.pinchZoomStartThreshold;
|
221
236
|
if (initialScaleFactor > upperBound || initialScaleFactor < lowerBound) {
|
222
|
-
scaleFactor = initialScaleFactor;
|
223
237
|
this.isScaling = true;
|
224
238
|
}
|
225
239
|
}
|
240
|
+
let scaleFactor = 1;
|
241
|
+
if (this.isScaling) {
|
242
|
+
scaleFactor = this.toSnappedScaleFactor(dist);
|
243
|
+
// Don't set lastDist until we start scaling --
|
244
|
+
this.lastTouchDist = dist;
|
245
|
+
}
|
226
246
|
const transformUpdate = Mat33.translation(delta)
|
227
247
|
.rightMul(Mat33.scaling2D(scaleFactor, canvasCenter))
|
228
248
|
.rightMul(Mat33.zRotation(deltaRotation, canvasCenter));
|
229
249
|
this.lastScreenCenter = screenCenter;
|
230
|
-
this.lastDist = dist;
|
231
250
|
this.transform = Viewport.transformBy(this.transform.transform.rightMul(transformUpdate));
|
232
251
|
return transformUpdate;
|
233
252
|
}
|
@@ -62,6 +62,10 @@ export default class PasteHandler extends BaseTool {
|
|
62
62
|
});
|
63
63
|
const defaultTextStyle = { size: 12, fontFamily: 'sans', renderingStyle: { fill: Color4.red } };
|
64
64
|
const pastedTextStyle = textTools[0]?.getTextStyle() ?? defaultTextStyle;
|
65
|
+
// Don't paste text that would be invisible.
|
66
|
+
if (text.trim() === '') {
|
67
|
+
return;
|
68
|
+
}
|
65
69
|
const lines = text.split('\n');
|
66
70
|
await this.addComponentsFromPaste([TextComponent.fromLines(lines, Mat33.identity, pastedTextStyle)]);
|
67
71
|
}
|
@@ -80,6 +80,7 @@ class Selection {
|
|
80
80
|
for (const handle of this.handles) {
|
81
81
|
handle.addTo(this.backgroundElem);
|
82
82
|
}
|
83
|
+
this.updateUI();
|
83
84
|
}
|
84
85
|
// @internal Intended for unit tests
|
85
86
|
getBackgroundElem() {
|
@@ -285,6 +286,13 @@ class Selection {
|
|
285
286
|
else {
|
286
287
|
this.innerContainer.classList.remove(perpendicularClassName);
|
287
288
|
}
|
289
|
+
// Hide handles when empty
|
290
|
+
if (screenRegion.width === 0 && screenRegion.height === 0) {
|
291
|
+
this.innerContainer.classList.add('-empty');
|
292
|
+
}
|
293
|
+
else {
|
294
|
+
this.innerContainer.classList.remove('-empty');
|
295
|
+
}
|
288
296
|
for (const handle of this.handles) {
|
289
297
|
handle.updatePosition();
|
290
298
|
}
|
@@ -533,7 +541,11 @@ Selection.ApplyTransformationCommand = class extends SerializableCommand {
|
|
533
541
|
this.transformCommands = this.selectedElemIds.map(id => {
|
534
542
|
const elem = editor.image.lookupElement(id);
|
535
543
|
if (!elem) {
|
536
|
-
|
544
|
+
// There may be valid reasons for an element lookup to fail:
|
545
|
+
// For example, if the element was deleted remotely and the remote deletion
|
546
|
+
// hasn't been undone.
|
547
|
+
console.warn(`Unable to find element with ID, ${id}.`);
|
548
|
+
return null;
|
537
549
|
}
|
538
550
|
let originalZIndex = elem.getZIndex();
|
539
551
|
let targetZIndex = elem.getZIndex() + this.deltaZIndex;
|
@@ -544,7 +556,9 @@ Selection.ApplyTransformationCommand = class extends SerializableCommand {
|
|
544
556
|
originalZIndex = elem.getZIndex() - this.deltaZIndex;
|
545
557
|
}
|
546
558
|
return elem.setZIndexAndTransformBy(this.fullTransform, targetZIndex, originalZIndex);
|
547
|
-
})
|
559
|
+
}).filter(// Remove all null commands
|
560
|
+
// Remove all null commands
|
561
|
+
command => command !== null);
|
548
562
|
}
|
549
563
|
async apply(editor) {
|
550
564
|
this.resolveToElems(editor, false);
|
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.16.1",
|
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",
|
@@ -64,7 +64,7 @@
|
|
64
64
|
"postpack": "ts-node tools/copyREADME.ts revert"
|
65
65
|
},
|
66
66
|
"dependencies": {
|
67
|
-
"@js-draw/math": "^1.
|
67
|
+
"@js-draw/math": "^1.16.0",
|
68
68
|
"@melloware/coloris": "0.22.0"
|
69
69
|
},
|
70
70
|
"devDependencies": {
|
@@ -86,5 +86,5 @@
|
|
86
86
|
"freehand",
|
87
87
|
"svg"
|
88
88
|
],
|
89
|
-
"gitHead": "
|
89
|
+
"gitHead": "7a1d4ea8bae0a2549494fce672b9d43ce97a68a8"
|
90
90
|
}
|
package/src/Editor.scss
CHANGED
@@ -118,6 +118,10 @@
|
|
118
118
|
max-width: inherit;
|
119
119
|
min-height: 0px;
|
120
120
|
max-height: inherit;
|
121
|
+
|
122
|
+
user-select: none;
|
123
|
+
-webkit-user-select: none;
|
124
|
+
-webkit-user-drag: none;
|
121
125
|
}
|
122
126
|
|
123
127
|
.imageEditorContainer .loadingMessage {
|
@@ -137,7 +141,10 @@
|
|
137
141
|
width: 0;
|
138
142
|
height: 0;
|
139
143
|
overflow: hidden;
|
144
|
+
|
140
145
|
pointer-events: none;
|
146
|
+
user-select: none;
|
147
|
+
-webkit-user-select: none;
|
141
148
|
}
|
142
149
|
|
143
150
|
.imageEditorContainer .textRendererOutputContainer {
|
@@ -146,6 +153,9 @@
|
|
146
153
|
width: 0.001px;
|
147
154
|
height: 0.001px;
|
148
155
|
overflow: hidden;
|
156
|
+
|
157
|
+
-webkit-user-select: none;
|
158
|
+
user-select: none;
|
149
159
|
}
|
150
160
|
|
151
161
|
.imageEditorContainer .textRendererOutputContainer:focus-within {
|
@@ -335,6 +335,7 @@
|
|
335
335
|
|
336
336
|
touch-action: none;
|
337
337
|
user-select: none;
|
338
|
+
-webkit-user-select: none;
|
338
339
|
|
339
340
|
background-color: var(--background-color-2);
|
340
341
|
color: var(--foreground-color-2);
|
@@ -356,6 +357,7 @@
|
|
356
357
|
|
357
358
|
input, textarea {
|
358
359
|
user-select: auto;
|
360
|
+
-webkit-user-select: auto;
|
359
361
|
}
|
360
362
|
|
361
363
|
.toolbar-toolContainer {
|