js-draw 1.8.0 → 1.9.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/LICENSE +1 -1
- package/dist/bundle.js +2 -2
- package/dist/cjs/Editor.js +24 -13
- package/dist/cjs/SVGLoader.d.ts +1 -1
- package/dist/cjs/SVGLoader.js +11 -2
- package/dist/cjs/Viewport.d.ts +6 -0
- package/dist/cjs/Viewport.js +6 -1
- package/dist/cjs/image/EditorImage.d.ts +20 -0
- package/dist/cjs/image/EditorImage.js +40 -11
- package/dist/cjs/rendering/Display.d.ts +9 -0
- package/dist/cjs/rendering/Display.js +47 -6
- package/dist/cjs/rendering/caching/CacheRecordManager.js +3 -4
- package/dist/cjs/rendering/caching/RenderingCache.d.ts +1 -0
- package/dist/cjs/rendering/caching/RenderingCache.js +4 -0
- package/dist/cjs/rendering/caching/RenderingCacheNode.js +19 -11
- package/dist/cjs/rendering/caching/types.d.ts +1 -0
- package/dist/cjs/rendering/renderers/CanvasRenderer.js +3 -0
- package/dist/cjs/version.js +1 -1
- package/dist/mjs/Editor.mjs +24 -13
- package/dist/mjs/SVGLoader.d.ts +1 -1
- package/dist/mjs/SVGLoader.mjs +11 -2
- package/dist/mjs/Viewport.d.ts +6 -0
- package/dist/mjs/Viewport.mjs +6 -1
- package/dist/mjs/image/EditorImage.d.ts +20 -0
- package/dist/mjs/image/EditorImage.mjs +38 -10
- package/dist/mjs/rendering/Display.d.ts +9 -0
- package/dist/mjs/rendering/Display.mjs +47 -6
- package/dist/mjs/rendering/caching/CacheRecordManager.mjs +3 -4
- package/dist/mjs/rendering/caching/RenderingCache.d.ts +1 -0
- package/dist/mjs/rendering/caching/RenderingCache.mjs +4 -0
- package/dist/mjs/rendering/caching/RenderingCacheNode.mjs +20 -12
- package/dist/mjs/rendering/caching/types.d.ts +1 -0
- package/dist/mjs/rendering/renderers/CanvasRenderer.mjs +3 -0
- package/dist/mjs/version.mjs +1 -1
- package/package.json +4 -4
package/dist/mjs/Viewport.d.ts
CHANGED
@@ -50,6 +50,11 @@ export declare class Viewport {
|
|
50
50
|
private getScaleFactorToNearestPowerOf;
|
51
51
|
/** Returns the size of a grid cell (in canvas units) as used by {@link snapToGrid}. */
|
52
52
|
static getGridSize(scaleFactor: number): number;
|
53
|
+
/**
|
54
|
+
* Snaps `canvasPos` to the nearest grid cell corner.
|
55
|
+
*
|
56
|
+
* @see {@link getGridSize} and {@link getScaleFactorToNearestPowerOf}.
|
57
|
+
*/
|
53
58
|
snapToGrid(canvasPos: Point2): Vec3;
|
54
59
|
/** Returns the size of one screen pixel in canvas units. */
|
55
60
|
getSizeOfPixelOnCanvas(): number;
|
@@ -65,6 +70,7 @@ export declare class Viewport {
|
|
65
70
|
* its original location. This is useful for preparing data for base-10 conversion.
|
66
71
|
*/
|
67
72
|
static roundPoint<T extends Point2 | number>(point: T, tolerance: number): PointDataType<T>;
|
73
|
+
/** Round a point with a tolerance of ±1 screen unit. */
|
68
74
|
roundPoint(point: Point2): Point2;
|
69
75
|
static roundScaleRatio(scaleRatio: number, roundAmount?: number): number;
|
70
76
|
computeZoomToTransform(toMakeVisible: Rect2, allowZoomIn?: boolean, allowZoomOut?: boolean): Mat33;
|
package/dist/mjs/Viewport.mjs
CHANGED
@@ -97,6 +97,11 @@ export class Viewport {
|
|
97
97
|
static getGridSize(scaleFactor) {
|
98
98
|
return 50 / scaleFactor;
|
99
99
|
}
|
100
|
+
/**
|
101
|
+
* Snaps `canvasPos` to the nearest grid cell corner.
|
102
|
+
*
|
103
|
+
* @see {@link getGridSize} and {@link getScaleFactorToNearestPowerOf}.
|
104
|
+
*/
|
100
105
|
snapToGrid(canvasPos) {
|
101
106
|
const scaleFactor = this.getScaleFactorToNearestPowerOf(2);
|
102
107
|
const snapCoordinate = (coordinate) => {
|
@@ -133,7 +138,7 @@ export class Viewport {
|
|
133
138
|
}
|
134
139
|
return point.map(roundComponent);
|
135
140
|
}
|
136
|
-
|
141
|
+
/** Round a point with a tolerance of ±1 screen unit. */
|
137
142
|
roundPoint(point) {
|
138
143
|
return Viewport.roundPoint(point, 1 / this.getScaleFactor());
|
139
144
|
}
|
@@ -123,8 +123,28 @@ export default class EditorImage {
|
|
123
123
|
*/
|
124
124
|
private setExportRectDirectly;
|
125
125
|
private onExportViewportChanged;
|
126
|
+
/**
|
127
|
+
* @internal
|
128
|
+
*
|
129
|
+
* Enables debug mode for **all** `EditorImage`s.
|
130
|
+
*
|
131
|
+
* **Only use for debugging**.
|
132
|
+
*
|
133
|
+
* @internal
|
134
|
+
*/
|
135
|
+
setDebugMode(newDebugMode: boolean): void;
|
126
136
|
private static SetImportExportRectCommand;
|
127
137
|
}
|
138
|
+
/**
|
139
|
+
* Determines the first index in `sortedLeaves` that needs to be rendered
|
140
|
+
* (based on occlusion -- everything before that index can be skipped and
|
141
|
+
* produce a visually-equivalent image).
|
142
|
+
*
|
143
|
+
* Does nothing if visibleRect is not provided
|
144
|
+
*
|
145
|
+
* @internal
|
146
|
+
*/
|
147
|
+
export declare const computeFirstIndexToRender: (sortedLeaves: Array<ImageNode>, visibleRect?: Rect2) => number;
|
128
148
|
type TooSmallToRenderCheck = (rect: Rect2) => boolean;
|
129
149
|
/**
|
130
150
|
* Part of the Editor's image. Does not handle fullscreen/invisible components.
|
@@ -19,7 +19,7 @@ export var EditorImageEventType;
|
|
19
19
|
EditorImageEventType[EditorImageEventType["ExportViewportChanged"] = 0] = "ExportViewportChanged";
|
20
20
|
EditorImageEventType[EditorImageEventType["AutoresizeModeChanged"] = 1] = "AutoresizeModeChanged";
|
21
21
|
})(EditorImageEventType || (EditorImageEventType = {}));
|
22
|
-
|
22
|
+
let debugMode = false;
|
23
23
|
// Handles lookup/storage of elements in the image
|
24
24
|
class EditorImage {
|
25
25
|
// @internal
|
@@ -271,6 +271,18 @@ class EditorImage {
|
|
271
271
|
});
|
272
272
|
}
|
273
273
|
}
|
274
|
+
/**
|
275
|
+
* @internal
|
276
|
+
*
|
277
|
+
* Enables debug mode for **all** `EditorImage`s.
|
278
|
+
*
|
279
|
+
* **Only use for debugging**.
|
280
|
+
*
|
281
|
+
* @internal
|
282
|
+
*/
|
283
|
+
setDebugMode(newDebugMode) {
|
284
|
+
debugMode = newDebugMode;
|
285
|
+
}
|
274
286
|
}
|
275
287
|
_a = EditorImage;
|
276
288
|
// A Command that can access private [EditorImage] functionality
|
@@ -410,6 +422,30 @@ EditorImage.SetImportExportRectCommand = (_c = class extends SerializableCommand
|
|
410
422
|
})(),
|
411
423
|
_c);
|
412
424
|
export default EditorImage;
|
425
|
+
/**
|
426
|
+
* Determines the first index in `sortedLeaves` that needs to be rendered
|
427
|
+
* (based on occlusion -- everything before that index can be skipped and
|
428
|
+
* produce a visually-equivalent image).
|
429
|
+
*
|
430
|
+
* Does nothing if visibleRect is not provided
|
431
|
+
*
|
432
|
+
* @internal
|
433
|
+
*/
|
434
|
+
export const computeFirstIndexToRender = (sortedLeaves, visibleRect) => {
|
435
|
+
let startIndex = 0;
|
436
|
+
if (visibleRect) {
|
437
|
+
for (let i = sortedLeaves.length - 1; i >= 1; i--) {
|
438
|
+
if (
|
439
|
+
// Check for occlusion
|
440
|
+
sortedLeaves[i].getBBox().containsRect(visibleRect)
|
441
|
+
&& sortedLeaves[i].getContent()?.occludesEverythingBelowWhenRenderedInRect(visibleRect)) {
|
442
|
+
startIndex = i;
|
443
|
+
break;
|
444
|
+
}
|
445
|
+
}
|
446
|
+
}
|
447
|
+
return startIndex;
|
448
|
+
};
|
413
449
|
/**
|
414
450
|
* Part of the Editor's image. Does not handle fullscreen/invisible components.
|
415
451
|
* @internal
|
@@ -666,15 +702,7 @@ export class ImageNode {
|
|
666
702
|
// If some components hide others (and we're permitted to simplify,
|
667
703
|
// which is true in the case of visibleRect being defined), then only
|
668
704
|
// draw the non-hidden components:
|
669
|
-
|
670
|
-
if (visibleRect) {
|
671
|
-
for (let i = leaves.length - 1; i >= 1; i--) {
|
672
|
-
if (leaves[i].getContent()?.occludesEverythingBelowWhenRenderedInRect(visibleRect)) {
|
673
|
-
startIndex = i;
|
674
|
-
break;
|
675
|
-
}
|
676
|
-
}
|
677
|
-
}
|
705
|
+
const startIndex = computeFirstIndexToRender(leaves);
|
678
706
|
for (let i = startIndex; i < leaves.length; i++) {
|
679
707
|
const leaf = leaves[i];
|
680
708
|
// Leaves by definition have content
|
@@ -26,6 +26,7 @@ export default class Display {
|
|
26
26
|
private textRenderer;
|
27
27
|
private textRerenderOutput;
|
28
28
|
private cache;
|
29
|
+
private devicePixelRatio;
|
29
30
|
private resizeSurfacesCallback?;
|
30
31
|
private flattenCallback?;
|
31
32
|
/** @internal */
|
@@ -46,6 +47,14 @@ export default class Display {
|
|
46
47
|
getColorAt: (_screenPos: Point2) => Color4 | null;
|
47
48
|
private initializeCanvasRendering;
|
48
49
|
private initializeTextRendering;
|
50
|
+
/**
|
51
|
+
* Sets the device-pixel-ratio.
|
52
|
+
*
|
53
|
+
* Intended for debugging. Users do not need to call this manually.
|
54
|
+
*
|
55
|
+
* @internal
|
56
|
+
*/
|
57
|
+
setDevicePixelRatio(dpr: number): Promise<void> | undefined;
|
49
58
|
/**
|
50
59
|
* Rerenders the text-based display.
|
51
60
|
* The text-based display is intended for screen readers and can be navigated to by pressing `tab`.
|
@@ -28,6 +28,7 @@ export default class Display {
|
|
28
28
|
this.editor = editor;
|
29
29
|
this.parent = parent;
|
30
30
|
this.textRerenderOutput = null;
|
31
|
+
this.devicePixelRatio = window.devicePixelRatio ?? 1;
|
31
32
|
/**
|
32
33
|
* @returns the color at the given point on the dry ink renderer, or `null` if `screenPos`
|
33
34
|
* is not on the display.
|
@@ -112,16 +113,32 @@ export default class Display {
|
|
112
113
|
this.parent.appendChild(wetInkCanvas);
|
113
114
|
}
|
114
115
|
this.resizeSurfacesCallback = () => {
|
116
|
+
const expectedWidth = (canvas) => {
|
117
|
+
return Math.ceil(canvas.clientWidth * this.devicePixelRatio);
|
118
|
+
};
|
119
|
+
const expectedHeight = (canvas) => {
|
120
|
+
return Math.ceil(canvas.clientHeight * this.devicePixelRatio);
|
121
|
+
};
|
115
122
|
const hasSizeMismatch = (canvas) => {
|
116
|
-
return canvas
|
123
|
+
return expectedHeight(canvas) !== canvas.height || expectedWidth(canvas) !== canvas.width;
|
117
124
|
};
|
118
125
|
// Ensure that the drawing surfaces sizes match the
|
119
126
|
// canvas' sizes to prevent stretching.
|
120
127
|
if (hasSizeMismatch(dryInkCanvas) || hasSizeMismatch(wetInkCanvas)) {
|
121
|
-
dryInkCanvas.width = dryInkCanvas
|
122
|
-
dryInkCanvas.height = dryInkCanvas
|
123
|
-
wetInkCanvas.width = wetInkCanvas
|
124
|
-
wetInkCanvas.height = wetInkCanvas
|
128
|
+
dryInkCanvas.width = expectedWidth(dryInkCanvas);
|
129
|
+
dryInkCanvas.height = expectedHeight(dryInkCanvas);
|
130
|
+
wetInkCanvas.width = expectedWidth(wetInkCanvas);
|
131
|
+
wetInkCanvas.height = expectedHeight(wetInkCanvas);
|
132
|
+
// Ensure correct drawing operations on high-resolution screens.
|
133
|
+
// See
|
134
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas#scaling_for_high_resolution_displays
|
135
|
+
//
|
136
|
+
// This scaling causes the rendering contexts to automatically convert
|
137
|
+
// between screen coordinates and pixel coordinates.
|
138
|
+
wetInkCtx.resetTransform();
|
139
|
+
dryInkCtx.resetTransform();
|
140
|
+
dryInkCtx.scale(this.devicePixelRatio, this.devicePixelRatio);
|
141
|
+
wetInkCtx.scale(this.devicePixelRatio, this.devicePixelRatio);
|
125
142
|
this.editor.notifier.dispatch(EditorEventType.DisplayResized, {
|
126
143
|
kind: EditorEventType.DisplayResized,
|
127
144
|
newSize: Vec2.of(this.width, this.height),
|
@@ -130,10 +147,17 @@ export default class Display {
|
|
130
147
|
};
|
131
148
|
this.resizeSurfacesCallback();
|
132
149
|
this.flattenCallback = () => {
|
150
|
+
dryInkCtx.save();
|
151
|
+
dryInkCtx.resetTransform();
|
133
152
|
dryInkCtx.drawImage(wetInkCanvas, 0, 0);
|
153
|
+
dryInkCtx.restore();
|
134
154
|
};
|
135
155
|
this.getColorAt = (screenPos) => {
|
136
|
-
|
156
|
+
// getImageData isn't affected by a transformation matrix -- we need to
|
157
|
+
// pre-transform screenPos to convert it from screen coordinates into pixel
|
158
|
+
// coordinates.
|
159
|
+
const adjustedScreenPos = screenPos.times(this.devicePixelRatio);
|
160
|
+
const pixel = dryInkCtx.getImageData(adjustedScreenPos.x, adjustedScreenPos.y, 1, 1);
|
137
161
|
const data = pixel?.data;
|
138
162
|
if (data) {
|
139
163
|
const color = Color4.ofRGBA(data[0] / 255, data[1] / 255, data[2] / 255, data[3] / 255);
|
@@ -156,6 +180,23 @@ export default class Display {
|
|
156
180
|
textRendererOutputContainer.replaceChildren(rerenderButton, this.textRerenderOutput);
|
157
181
|
this.editor.createHTMLOverlay(textRendererOutputContainer);
|
158
182
|
}
|
183
|
+
/**
|
184
|
+
* Sets the device-pixel-ratio.
|
185
|
+
*
|
186
|
+
* Intended for debugging. Users do not need to call this manually.
|
187
|
+
*
|
188
|
+
* @internal
|
189
|
+
*/
|
190
|
+
setDevicePixelRatio(dpr) {
|
191
|
+
const minDpr = 0.001;
|
192
|
+
const maxDpr = 10;
|
193
|
+
if (isFinite(dpr) && dpr >= minDpr && dpr <= maxDpr && dpr !== this.devicePixelRatio) {
|
194
|
+
this.devicePixelRatio = dpr;
|
195
|
+
this.resizeSurfacesCallback?.();
|
196
|
+
return this.editor.queueRerender();
|
197
|
+
}
|
198
|
+
return undefined;
|
199
|
+
}
|
159
200
|
/**
|
160
201
|
* Rerenders the text-based display.
|
161
202
|
* The text-based display is intended for screen readers and can be navigated to by pressing `tab`.
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import CacheRecord from './CacheRecord.mjs';
|
2
|
-
const debugMode = false;
|
3
2
|
export class CacheRecordManager {
|
4
3
|
constructor(cacheProps) {
|
5
4
|
// Fixed-size array: Cache blocks are assigned indicies into [cachedCanvases].
|
@@ -16,19 +15,19 @@ export class CacheRecordManager {
|
|
16
15
|
const record = new CacheRecord(onDealloc, this.cacheState);
|
17
16
|
record.setRenderingRegion(drawTo);
|
18
17
|
this.cacheRecords.push(record);
|
19
|
-
if (debugMode) {
|
18
|
+
if (this.cacheState.debugMode) {
|
20
19
|
console.log('[Cache] Cache spaces used: ', this.cacheRecords.length, ' of ', this.maxCanvases);
|
21
20
|
}
|
22
21
|
return record;
|
23
22
|
}
|
24
23
|
else {
|
25
24
|
const lru = this.getLeastRecentlyUsedRecord();
|
26
|
-
if (debugMode) {
|
25
|
+
if (this.cacheState.debugMode) {
|
27
26
|
console.log('[Cache] Re-alloc. Times allocated: ', lru.allocCount, '\nLast used cycle: ', lru.getLastUsedCycle(), '\nCurrent cycle: ', this.cacheState.currentRenderingCycle);
|
28
27
|
}
|
29
28
|
lru.realloc(onDealloc);
|
30
29
|
lru.setRenderingRegion(drawTo);
|
31
|
-
if (debugMode) {
|
30
|
+
if (this.cacheState.debugMode) {
|
32
31
|
console.log('[Cache] Now re-alloc\'d. Last used cycle: ', lru.getLastUsedCycle());
|
33
32
|
console.assert(lru['cacheState'] === this.cacheState, '[Cache] Unequal cache states! cacheState should be a shared object!');
|
34
33
|
}
|
@@ -8,6 +8,7 @@ export default class RenderingCache {
|
|
8
8
|
props: cacheProps,
|
9
9
|
currentRenderingCycle: 0,
|
10
10
|
recordManager: this.recordManager,
|
11
|
+
debugMode: false,
|
11
12
|
};
|
12
13
|
this.recordManager.setSharedState(this.sharedState);
|
13
14
|
}
|
@@ -44,4 +45,7 @@ export default class RenderingCache {
|
|
44
45
|
getDebugInfo() {
|
45
46
|
return this.recordManager.getDebugInfo();
|
46
47
|
}
|
48
|
+
setIsDebugMode(debugMode) {
|
49
|
+
this.sharedState.debugMode = debugMode;
|
50
|
+
}
|
47
51
|
}
|
@@ -1,10 +1,8 @@
|
|
1
1
|
// A cache record with sub-nodes.
|
2
|
-
import { sortLeavesByZIndex } from '../../image/EditorImage.mjs';
|
2
|
+
import { computeFirstIndexToRender, sortLeavesByZIndex } from '../../image/EditorImage.mjs';
|
3
3
|
import { Rect2, Color4 } from '@js-draw/math';
|
4
4
|
// 3x3 divisions for each node.
|
5
5
|
const cacheDivisionSize = 3;
|
6
|
-
// True: Show rendering updates.
|
7
|
-
const debugMode = false;
|
8
6
|
export default class RenderingCacheNode {
|
9
7
|
constructor(region, cacheState) {
|
10
8
|
this.region = region;
|
@@ -161,8 +159,8 @@ export default class RenderingCacheNode {
|
|
161
159
|
items.forEach(item => item.render(screenRenderer, viewport.visibleRect));
|
162
160
|
return;
|
163
161
|
}
|
164
|
-
if (debugMode) {
|
165
|
-
screenRenderer.drawRect(this.region,
|
162
|
+
if (this.cacheState.debugMode) {
|
163
|
+
screenRenderer.drawRect(this.region, viewport.getSizeOfPixelOnCanvas(), { fill: Color4.yellow });
|
166
164
|
}
|
167
165
|
// Could we render direclty from [this] or do we need to recurse?
|
168
166
|
const couldRender = this.renderingWouldBeHighEnoughResolution(viewport);
|
@@ -197,7 +195,9 @@ export default class RenderingCacheNode {
|
|
197
195
|
}
|
198
196
|
let leafApproxRenderTime = 0;
|
199
197
|
for (const leaf of leavesByIds) {
|
200
|
-
|
198
|
+
if (!tooSmallToRender(leaf.getBBox())) {
|
199
|
+
leafApproxRenderTime += leaf.getContent().getProportionalRenderingTime();
|
200
|
+
}
|
201
201
|
}
|
202
202
|
// Is it worth it to render the items?
|
203
203
|
if (leafApproxRenderTime > this.cacheState.props.minProportionalRenderTimePerCache) {
|
@@ -233,26 +233,30 @@ export default class RenderingCacheNode {
|
|
233
233
|
this.renderedMaxZIndex = zIndex;
|
234
234
|
}
|
235
235
|
}
|
236
|
-
if (debugMode) {
|
237
|
-
|
236
|
+
if (this.cacheState.debugMode) {
|
237
|
+
// Clay for adding new elements
|
238
|
+
screenRenderer.drawRect(this.region, 2 * viewport.getSizeOfPixelOnCanvas(), { fill: Color4.clay });
|
238
239
|
}
|
239
240
|
}
|
240
241
|
}
|
241
|
-
else if (debugMode) {
|
242
|
+
else if (this.cacheState.debugMode) {
|
242
243
|
console.log('Decided on a full re-render. Reason: At least one of the following is false:', '\n leafIds.length > this.renderedIds.length: ', leafIds.length > this.renderedIds.length, '\n this.allRenderedIdsIn(leafIds): ', this.allRenderedIdsIn(leafIds), '\n this.renderedMaxZIndex !== null: ', this.renderedMaxZIndex !== null, '\n\nthis.rerenderedIds: ', this.renderedIds, ', leafIds: ', leafIds);
|
243
244
|
}
|
244
245
|
if (fullRerenderNeeded) {
|
245
246
|
thisRenderer = this.cachedRenderer.startRender();
|
246
247
|
thisRenderer.clear();
|
247
248
|
this.renderedMaxZIndex = null;
|
248
|
-
|
249
|
+
const startIndex = computeFirstIndexToRender(leaves, this.region);
|
250
|
+
for (let i = startIndex; i < leaves.length; i++) {
|
251
|
+
const leaf = leaves[i];
|
249
252
|
const content = leaf.getContent();
|
250
253
|
this.renderedMaxZIndex ??= content.getZIndex();
|
251
254
|
this.renderedMaxZIndex = Math.max(this.renderedMaxZIndex, content.getZIndex());
|
252
255
|
leaf.render(thisRenderer, this.region);
|
253
256
|
}
|
254
|
-
if (debugMode) {
|
255
|
-
|
257
|
+
if (this.cacheState.debugMode) {
|
258
|
+
// Red for full rerender
|
259
|
+
screenRenderer.drawRect(this.region, 3 * viewport.getSizeOfPixelOnCanvas(), { fill: Color4.red });
|
256
260
|
}
|
257
261
|
}
|
258
262
|
this.renderedIds = leafIds;
|
@@ -269,6 +273,10 @@ export default class RenderingCacheNode {
|
|
269
273
|
leaf.render(screenRenderer, this.region.intersection(viewport.visibleRect));
|
270
274
|
}
|
271
275
|
screenRenderer.endObject();
|
276
|
+
if (this.cacheState.debugMode) {
|
277
|
+
// Green for no cache needed render
|
278
|
+
screenRenderer.drawRect(this.region, 2 * viewport.getSizeOfPixelOnCanvas(), { fill: Color4.green });
|
279
|
+
}
|
272
280
|
}
|
273
281
|
}
|
274
282
|
else {
|
@@ -77,7 +77,10 @@ export default class CanvasRenderer extends AbstractRenderer {
|
|
77
77
|
return Vec2.of(this.ctx.canvas.clientWidth, this.ctx.canvas.clientHeight);
|
78
78
|
}
|
79
79
|
clear() {
|
80
|
+
this.ctx.save();
|
81
|
+
this.ctx.resetTransform();
|
80
82
|
this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
|
83
|
+
this.ctx.restore();
|
81
84
|
}
|
82
85
|
beginPath(startPoint) {
|
83
86
|
startPoint = this.canvasToScreen(startPoint);
|
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.9.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",
|
@@ -55,7 +55,7 @@
|
|
55
55
|
"license": "MIT",
|
56
56
|
"private": false,
|
57
57
|
"scripts": {
|
58
|
-
"dist-test": "
|
58
|
+
"dist-test": "cd dist-test/test_imports && npm install && npm run test",
|
59
59
|
"dist": "npm run build && npm run dist-test",
|
60
60
|
"build": "rm -rf ./dist/* && mkdir -p dist && build-tool build",
|
61
61
|
"watch": "rm -rf ./dist/* && mkdir -p dist && build-tool watch",
|
@@ -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.9.0",
|
68
68
|
"@melloware/coloris": "0.21.0"
|
69
69
|
},
|
70
70
|
"devDependencies": {
|
@@ -86,5 +86,5 @@
|
|
86
86
|
"freehand",
|
87
87
|
"svg"
|
88
88
|
],
|
89
|
-
"gitHead": "
|
89
|
+
"gitHead": "b4bae7b437b2ce4ba8378a062b8e3959dca0f26e"
|
90
90
|
}
|