js-draw 1.11.0 → 1.11.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 +6 -2
- package/dist/bundle.js +3 -3
- package/dist/bundledStyles.js +1 -1
- package/dist/cjs/Editor.d.ts +7 -0
- package/dist/cjs/Editor.js +18 -4
- package/dist/cjs/components/BackgroundComponent.d.ts +1 -1
- package/dist/cjs/components/ImageComponent.d.ts +1 -1
- package/dist/cjs/components/SVGGlobalAttributesObject.d.ts +1 -1
- package/dist/cjs/components/Stroke.d.ts +1 -1
- package/dist/cjs/rendering/Display.js +3 -1
- package/dist/cjs/rendering/renderers/DummyRenderer.d.ts +1 -0
- package/dist/cjs/rendering/renderers/DummyRenderer.js +3 -0
- package/dist/cjs/tools/FindTool.js +1 -1
- package/dist/cjs/tools/Pen.js +8 -2
- package/dist/cjs/tools/SelectionTool/SelectionTool.js +16 -2
- package/dist/cjs/tools/localization.d.ts +2 -0
- package/dist/cjs/tools/localization.js +2 -0
- package/dist/cjs/util/listenForKeyboardEventsFrom.d.ts +5 -0
- package/dist/cjs/util/listenForKeyboardEventsFrom.js +5 -1
- package/dist/cjs/version.js +1 -1
- package/dist/mjs/Editor.d.ts +7 -0
- package/dist/mjs/Editor.mjs +18 -4
- package/dist/mjs/components/BackgroundComponent.d.ts +1 -1
- package/dist/mjs/components/ImageComponent.d.ts +1 -1
- package/dist/mjs/components/SVGGlobalAttributesObject.d.ts +1 -1
- package/dist/mjs/components/Stroke.d.ts +1 -1
- package/dist/mjs/rendering/Display.mjs +3 -1
- package/dist/mjs/rendering/renderers/DummyRenderer.d.ts +1 -0
- package/dist/mjs/rendering/renderers/DummyRenderer.mjs +3 -0
- package/dist/mjs/tools/FindTool.mjs +1 -1
- package/dist/mjs/tools/Pen.mjs +8 -2
- package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +16 -2
- package/dist/mjs/tools/localization.d.ts +2 -0
- package/dist/mjs/tools/localization.mjs +2 -0
- package/dist/mjs/util/listenForKeyboardEventsFrom.d.ts +5 -0
- package/dist/mjs/util/listenForKeyboardEventsFrom.mjs +5 -1
- package/dist/mjs/version.mjs +1 -1
- package/package.json +5 -5
- package/src/toolbar/AbstractToolbar.scss +3 -2
- package/src/toolbar/widgets/components/makeColorInput.scss +8 -0
@@ -70,7 +70,9 @@ export default class Display {
|
|
70
70
|
},
|
71
71
|
blockResolution: cacheBlockResolution,
|
72
72
|
cacheSize: 600 * 600 * 4 * 90,
|
73
|
-
|
73
|
+
// On higher resolution displays, don't scale cache blocks as much to decrease blurriness.
|
74
|
+
// TODO: Decrease the minimum cache scale as well.
|
75
|
+
maxScale: Math.max(1, 1.3 / window.devicePixelRatio),
|
74
76
|
// Require about 20 strokes with 4 parts each to cache an image in one of the
|
75
77
|
// parts of the cache grid.
|
76
78
|
minProportionalRenderTimePerCache: 20 * 4,
|
@@ -29,4 +29,5 @@ export default class DummyRenderer extends AbstractRenderer {
|
|
29
29
|
isTooSmallToRender(_rect: Rect2): boolean;
|
30
30
|
canRenderFromWithoutDataLoss(other: AbstractRenderer): boolean;
|
31
31
|
renderFromOtherOfSameType(transform: Mat33, other: AbstractRenderer): void;
|
32
|
+
toString(): string;
|
32
33
|
}
|
@@ -34,7 +34,7 @@ export default class FindTool extends BaseTool {
|
|
34
34
|
}
|
35
35
|
if (matchIdx < matches.length) {
|
36
36
|
const undoable = false;
|
37
|
-
this.editor.dispatch(this.editor.viewport.zoomTo(matches[matchIdx], true, true), undoable);
|
37
|
+
void this.editor.dispatch(this.editor.viewport.zoomTo(matches[matchIdx], true, true), undoable);
|
38
38
|
this.editor.announceForAccessibility(this.editor.localization.focusedFoundText(matchIdx + 1, matches.length));
|
39
39
|
}
|
40
40
|
}
|
package/dist/mjs/tools/Pen.mjs
CHANGED
@@ -97,8 +97,8 @@ export default class Pen extends BaseTool {
|
|
97
97
|
this.currentDeviceType = current.device;
|
98
98
|
if (this.shapeAutocompletionEnabled) {
|
99
99
|
const stationaryDetectionConfig = {
|
100
|
-
maxSpeed: 5,
|
101
|
-
maxRadius:
|
100
|
+
maxSpeed: 8.5,
|
101
|
+
maxRadius: 11,
|
102
102
|
minTimeSeconds: 0.5, // s
|
103
103
|
};
|
104
104
|
this.stationaryDetector = new StationaryPenDetector(current, stationaryDetectionConfig, pointer => this.autocorrectShape(pointer));
|
@@ -141,6 +141,7 @@ export default class Pen extends BaseTool {
|
|
141
141
|
if (this.autocorrectedShape) {
|
142
142
|
this.removedAutocorrectedShapeTime = performance.now();
|
143
143
|
this.autocorrectedShape = null;
|
144
|
+
this.editor.announceForAccessibility(this.editor.localization.autocorrectionCanceled);
|
144
145
|
}
|
145
146
|
}
|
146
147
|
}
|
@@ -192,6 +193,8 @@ export default class Pen extends BaseTool {
|
|
192
193
|
if (bboxArea === 0 || !isFinite(bboxArea)) {
|
193
194
|
return;
|
194
195
|
}
|
196
|
+
const shapeDescription = correctedShape.description(this.editor.localization);
|
197
|
+
this.editor.announceForAccessibility(this.editor.localization.autocorrectedTo(shapeDescription));
|
195
198
|
this.autocorrectedShape = correctedShape;
|
196
199
|
this.lastAutocorrectedShape = correctedShape;
|
197
200
|
this.previewStroke();
|
@@ -206,6 +209,9 @@ export default class Pen extends BaseTool {
|
|
206
209
|
const stroke = this.autocorrectedShape ?? this.builder.build();
|
207
210
|
this.previewStroke();
|
208
211
|
if (stroke.getBBox().area > 0) {
|
212
|
+
if (stroke === this.autocorrectedShape) {
|
213
|
+
this.editor.announceForAccessibility(this.editor.localization.autocorrectedTo(stroke.description(this.editor.localization)));
|
214
|
+
}
|
209
215
|
const canFlatten = true;
|
210
216
|
const action = EditorImage.addElement(stroke, canFlatten);
|
211
217
|
this.editor.dispatch(action);
|
@@ -231,9 +231,11 @@ class SelectionTool extends BaseTool {
|
|
231
231
|
// Pass it to another tool, if apliccable.
|
232
232
|
return false;
|
233
233
|
}
|
234
|
-
else if (event.key === 'Shift') {
|
234
|
+
else if (event.shiftKey || event.key === 'Shift') {
|
235
235
|
this.shiftKeyPressed = true;
|
236
|
-
|
236
|
+
if (event.key === 'Shift') {
|
237
|
+
return true;
|
238
|
+
}
|
237
239
|
}
|
238
240
|
let rotationSteps = 0;
|
239
241
|
let xTranslateSteps = 0;
|
@@ -335,6 +337,14 @@ class SelectionTool extends BaseTool {
|
|
335
337
|
}
|
336
338
|
return true;
|
337
339
|
}
|
340
|
+
// Here, we check if shiftKey === false because, as of this writing,
|
341
|
+
// evt.shiftKey is an optional property. Being falsey could just mean
|
342
|
+
// that it wasn't set.
|
343
|
+
if (evt.shiftKey === false) {
|
344
|
+
this.shiftKeyPressed = false;
|
345
|
+
// Don't return immediately -- event may be otherwise handled
|
346
|
+
}
|
347
|
+
// Also check for key === 'Shift' (for the case where shiftKey is undefined)
|
338
348
|
if (evt.key === 'Shift') {
|
339
349
|
this.shiftKeyPressed = false;
|
340
350
|
return true;
|
@@ -379,7 +389,11 @@ class SelectionTool extends BaseTool {
|
|
379
389
|
return true;
|
380
390
|
}
|
381
391
|
setEnabled(enabled) {
|
392
|
+
const wasEnabled = this.isEnabled();
|
382
393
|
super.setEnabled(enabled);
|
394
|
+
if (wasEnabled === enabled) {
|
395
|
+
return;
|
396
|
+
}
|
383
397
|
// Clear the selection
|
384
398
|
this.selectionBox?.cancelSelection();
|
385
399
|
this.onSelectionUpdated();
|
@@ -9,6 +9,8 @@ export interface ToolLocalization {
|
|
9
9
|
undoRedoTool: string;
|
10
10
|
pipetteTool: string;
|
11
11
|
rightClickDragPanTool: string;
|
12
|
+
autocorrectedTo: (description: string) => string;
|
13
|
+
autocorrectionCanceled: string;
|
12
14
|
textTool: string;
|
13
15
|
enterTextToInsert: string;
|
14
16
|
changeTool: string;
|
@@ -9,6 +9,8 @@ export const defaultToolLocalization = {
|
|
9
9
|
rightClickDragPanTool: 'Right-click drag',
|
10
10
|
pipetteTool: 'Pick color from screen',
|
11
11
|
keyboardPanZoom: 'Keyboard pan/zoom shortcuts',
|
12
|
+
autocorrectedTo: (strokeDescription) => `Autocorrected to ${strokeDescription}`,
|
13
|
+
autocorrectionCanceled: 'Autocorrect cancelled',
|
12
14
|
textTool: 'Text',
|
13
15
|
enterTextToInsert: 'Text to insert',
|
14
16
|
changeTool: 'Change tool',
|
@@ -2,6 +2,11 @@ interface Callbacks {
|
|
2
2
|
filter(event: KeyboardEvent): boolean;
|
3
3
|
handleKeyDown(event: KeyboardEvent): void;
|
4
4
|
handleKeyUp(event: KeyboardEvent): void;
|
5
|
+
/**
|
6
|
+
* Should return `true` iff `source` is also registered as an event listener source.
|
7
|
+
* If `false` and focus leaves the original source, keyup events are fired.
|
8
|
+
*/
|
9
|
+
getHandlesKeyEventsFrom(source: Node): boolean;
|
5
10
|
}
|
6
11
|
/**
|
7
12
|
* Calls `callbacks` when different keys are known to be pressed.
|
@@ -65,7 +65,11 @@ const listenForKeyboardEventsFrom = (elem, callbacks) => {
|
|
65
65
|
handleKeyEvent(htmlEvent);
|
66
66
|
});
|
67
67
|
elem.addEventListener('focusout', (focusEvent) => {
|
68
|
-
|
68
|
+
let stillHasFocus = false;
|
69
|
+
if (focusEvent.relatedTarget) {
|
70
|
+
const relatedTarget = focusEvent.relatedTarget;
|
71
|
+
stillHasFocus = elem.contains(relatedTarget) || callbacks.getHandlesKeyEventsFrom(relatedTarget);
|
72
|
+
}
|
69
73
|
if (!stillHasFocus) {
|
70
74
|
for (const event of keysDown) {
|
71
75
|
callbacks.handleKeyUp(new KeyboardEvent('keyup', {
|
package/dist/mjs/version.mjs
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "js-draw",
|
3
|
-
"version": "1.11.
|
3
|
+
"version": "1.11.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,11 +64,11 @@
|
|
64
64
|
"postpack": "ts-node tools/copyREADME.ts revert"
|
65
65
|
},
|
66
66
|
"dependencies": {
|
67
|
-
"@js-draw/math": "^1.
|
68
|
-
"@melloware/coloris": "0.
|
67
|
+
"@js-draw/math": "^1.11.1",
|
68
|
+
"@melloware/coloris": "0.22.0"
|
69
69
|
},
|
70
70
|
"devDependencies": {
|
71
|
-
"@js-draw/build-tool": "^1.
|
71
|
+
"@js-draw/build-tool": "^1.11.1",
|
72
72
|
"@types/jest": "29.5.5",
|
73
73
|
"@types/jsdom": "21.1.3"
|
74
74
|
},
|
@@ -86,5 +86,5 @@
|
|
86
86
|
"freehand",
|
87
87
|
"svg"
|
88
88
|
],
|
89
|
-
"gitHead": "
|
89
|
+
"gitHead": "695cfe01116839842668233a14fa858ad4ae0bac"
|
90
90
|
}
|
@@ -45,7 +45,8 @@
|
|
45
45
|
}
|
46
46
|
|
47
47
|
.toolbar-button.disabled {
|
48
|
-
filter:
|
48
|
+
filter: sepia(0.2);
|
49
|
+
opacity: 0.45;
|
49
50
|
cursor: unset;
|
50
51
|
}
|
51
52
|
|
@@ -103,7 +104,7 @@
|
|
103
104
|
|
104
105
|
.toolbar-root button:disabled {
|
105
106
|
cursor: inherit;
|
106
|
-
|
107
|
+
opacity: 0.5;
|
107
108
|
}
|
108
109
|
|
109
110
|
.toolbar-root .toolbar-icon {
|
@@ -29,6 +29,14 @@
|
|
29
29
|
display: inline-flex;
|
30
30
|
flex-direction: row;
|
31
31
|
|
32
|
+
.coloris_input {
|
33
|
+
// Ensure that the region that can be clicked to open the input is roughly
|
34
|
+
// the full height of the container.
|
35
|
+
// Because the color picker is always shown below or above the input, 5px is
|
36
|
+
// subtracted to make the picker better align with the input's container.
|
37
|
+
height: calc(100% - 6px);
|
38
|
+
}
|
39
|
+
|
32
40
|
&.picker-open .clr-field {
|
33
41
|
// Work around what seems to be a Coloris bug -- clicking on the input button
|
34
42
|
// keeps the color picker open (while clicking anywhere else closes the picker).
|