@lvl99dotcom/paintcanvas 0.0.0-stage → 0.3.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/LICENSE +201 -0
- package/README.md +131 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/lib/brushes/BrushTipCache/index.d.ts +32 -0
- package/dist/lib/brushes/BrushTipCache/index.js +60 -0
- package/dist/lib/brushes/StrokeEngine/index.d.ts +171 -0
- package/dist/lib/brushes/StrokeEngine/index.js +324 -0
- package/dist/lib/brushes/StrokePath/index.d.ts +53 -0
- package/dist/lib/brushes/StrokePath/index.js +161 -0
- package/dist/lib/brushes/StrokeSampler/index.d.ts +55 -0
- package/dist/lib/brushes/StrokeSampler/index.js +75 -0
- package/dist/lib/brushes/authors/index.d.ts +55 -0
- package/dist/lib/brushes/authors/index.js +60 -0
- package/dist/lib/brushes/configRanges/index.d.ts +52 -0
- package/dist/lib/brushes/configRanges/index.js +206 -0
- package/dist/lib/brushes/index.d.ts +5 -0
- package/dist/lib/brushes/index.js +19 -0
- package/dist/lib/brushes/params/index.d.ts +108 -0
- package/dist/lib/brushes/params/index.js +139 -0
- package/dist/lib/brushes/presetFile/index.d.ts +32 -0
- package/dist/lib/brushes/presetFile/index.js +55 -0
- package/dist/lib/brushes/presets/drawing/brush-pen.js +3 -0
- package/dist/lib/brushes/presets/drawing/felt-pen.js +3 -0
- package/dist/lib/brushes/presets/drawing/index.d.ts +13 -0
- package/dist/lib/brushes/presets/drawing/index.js +88 -0
- package/dist/lib/brushes/presets/drawing/pencil-2b.js +3 -0
- package/dist/lib/brushes/presets/drawing/pencil-hb.js +3 -0
- package/dist/lib/brushes/presets/painting/grass.js +3 -0
- package/dist/lib/brushes/presets/painting/hair.js +3 -0
- package/dist/lib/brushes/presets/painting/index.d.ts +18 -0
- package/dist/lib/brushes/presets/painting/index.js +118 -0
- package/dist/lib/brushes/presets/painting/splatter.js +3 -0
- package/dist/lib/brushes/presets/painting/textured-paint.js +3 -0
- package/dist/lib/brushes/presets/painting/watery-paint.js +3 -0
- package/dist/lib/brushes/presets/round/index.d.ts +9 -0
- package/dist/lib/brushes/presets/round/index.js +44 -0
- package/dist/lib/brushes/presets/round/round.js +3 -0
- package/dist/lib/brushes/presets/round/soft-round.js +3 -0
- package/dist/lib/brushes/presets/sized/index.d.ts +20 -0
- package/dist/lib/brushes/presets/sized/index.js +30 -0
- package/dist/lib/brushes/presets/sketching/index.d.ts +14 -0
- package/dist/lib/brushes/presets/sketching/index.js +107 -0
- package/dist/lib/brushes/presets/square/index.d.ts +7 -0
- package/dist/lib/brushes/presets/square/index.js +22 -0
- package/dist/lib/brushes/presets/square/square.js +3 -0
- package/dist/lib/brushes/shapeImage/index.d.ts +40 -0
- package/dist/lib/brushes/shapeImage/index.js +61 -0
- package/dist/lib/brushes/types/index.d.ts +243 -0
- package/dist/lib/brushes/types/index.js +20 -0
- package/dist/lib/classes/BackgroundWork/index.d.ts +55 -0
- package/dist/lib/classes/BackgroundWork/index.js +97 -0
- package/dist/lib/classes/BrushSettings/index.d.ts +91 -0
- package/dist/lib/classes/BrushSettings/index.js +152 -0
- package/dist/lib/classes/CustomPresets/index.d.ts +53 -0
- package/dist/lib/classes/CustomPresets/index.js +71 -0
- package/dist/lib/classes/ExternalSheets/index.d.ts +64 -0
- package/dist/lib/classes/ExternalSheets/index.js +112 -0
- package/dist/lib/classes/GestureTracker/index.d.ts +62 -0
- package/dist/lib/classes/GestureTracker/index.js +122 -0
- package/dist/lib/classes/History/index.d.ts +83 -0
- package/dist/lib/classes/History/index.js +126 -0
- package/dist/lib/classes/HistoryGuard/index.d.ts +58 -0
- package/dist/lib/classes/HistoryGuard/index.js +97 -0
- package/dist/lib/classes/InputSettings/index.d.ts +74 -0
- package/dist/lib/classes/InputSettings/index.js +101 -0
- package/dist/lib/classes/KeyboardShortcuts/index.d.ts +48 -0
- package/dist/lib/classes/KeyboardShortcuts/index.js +137 -0
- package/dist/lib/classes/Layer/index.d.ts +86 -0
- package/dist/lib/classes/Layer/index.js +111 -0
- package/dist/lib/classes/LayerAutosave/index.d.ts +180 -0
- package/dist/lib/classes/LayerAutosave/index.js +346 -0
- package/dist/lib/classes/LayerStack/index.d.ts +177 -0
- package/dist/lib/classes/LayerStack/index.js +394 -0
- package/dist/lib/classes/PaintCanvas/index.d.ts +537 -0
- package/dist/lib/classes/PaintCanvas/index.js +965 -0
- package/dist/lib/classes/StrokeLog/index.d.ts +149 -0
- package/dist/lib/classes/StrokeLog/index.js +257 -0
- package/dist/lib/classes/Viewport/index.d.ts +108 -0
- package/dist/lib/classes/Viewport/index.js +194 -0
- package/dist/lib/document/index.d.ts +17 -0
- package/dist/lib/document/index.js +25 -0
- package/dist/lib/document/schema.d.ts +132 -0
- package/dist/lib/document/schema.js +110 -0
- package/dist/lib/i18n/index.d.ts +131 -0
- package/dist/lib/i18n/index.js +277 -0
- package/dist/lib/image/index.d.ts +90 -0
- package/dist/lib/image/index.js +147 -0
- package/dist/lib/messages/PatchSender/index.d.ts +75 -0
- package/dist/lib/messages/PatchSender/index.js +125 -0
- package/dist/lib/messages/index.d.ts +26 -0
- package/dist/lib/messages/index.js +59 -0
- package/dist/lib/messages/schema.d.ts +1775 -0
- package/dist/lib/messages/schema.js +192 -0
- package/dist/lib/presets/index.d.ts +32 -0
- package/dist/lib/presets/index.js +35 -0
- package/dist/lib/presets/schema.d.ts +753 -0
- package/dist/lib/presets/schema.js +181 -0
- package/dist/lib/rendering/BrushTip/index.d.ts +63 -0
- package/dist/lib/rendering/BrushTip/index.js +112 -0
- package/dist/lib/rendering/checkerboard/index.d.ts +22 -0
- package/dist/lib/rendering/checkerboard/index.js +31 -0
- package/dist/lib/rendering/compositing/index.d.ts +64 -0
- package/dist/lib/rendering/compositing/index.js +124 -0
- package/dist/lib/rendering/cursor/index.d.ts +14 -0
- package/dist/lib/rendering/cursor/index.js +39 -0
- package/dist/lib/rendering/cursors/index.d.ts +18 -0
- package/dist/lib/rendering/cursors/index.js +23 -0
- package/dist/lib/rendering/maskOutline/index.d.ts +22 -0
- package/dist/lib/rendering/maskOutline/index.js +78 -0
- package/dist/lib/rendering/outline/index.d.ts +36 -0
- package/dist/lib/rendering/outline/index.js +120 -0
- package/dist/lib/rendering/sample/index.d.ts +55 -0
- package/dist/lib/rendering/sample/index.js +83 -0
- package/dist/lib/rendering/screenshot/index.d.ts +67 -0
- package/dist/lib/rendering/screenshot/index.js +96 -0
- package/dist/lib/rendering/transformBox/index.d.ts +10 -0
- package/dist/lib/rendering/transformBox/index.js +57 -0
- package/dist/lib/selection/Lasso/index.d.ts +70 -0
- package/dist/lib/selection/Lasso/index.js +156 -0
- package/dist/lib/selection/Selection/index.d.ts +86 -0
- package/dist/lib/selection/Selection/index.js +228 -0
- package/dist/lib/selection/geometry/index.d.ts +37 -0
- package/dist/lib/selection/geometry/index.js +57 -0
- package/dist/lib/storage/index.d.ts +63 -0
- package/dist/lib/storage/index.js +114 -0
- package/dist/lib/transform/Transformer/index.d.ts +124 -0
- package/dist/lib/transform/Transformer/index.js +286 -0
- package/dist/lib/transform/geometry/index.d.ts +95 -0
- package/dist/lib/transform/geometry/index.js +258 -0
- package/dist/lib/utils/array/index.d.ts +10 -0
- package/dist/lib/utils/array/index.js +21 -0
- package/dist/lib/utils/gestures/index.d.ts +35 -0
- package/dist/lib/utils/gestures/index.js +81 -0
- package/dist/lib/utils/navigation/index.d.ts +51 -0
- package/dist/lib/utils/navigation/index.js +59 -0
- package/dist/lib/utils/random/index.d.ts +18 -0
- package/dist/lib/utils/random/index.js +27 -0
- package/dist/lib/utils/shortcuts/index.d.ts +74 -0
- package/dist/lib/utils/shortcuts/index.js +189 -0
- package/dist/lib/validation/validators.generated.d.ts +27 -0
- package/dist/lib/validation/validators.generated.js +19826 -0
- package/dist/locales/en-GB.js +181 -0
- package/dist/locales/en-US.js +181 -0
- package/dist/locales/fr.js +181 -0
- package/dist/locales/ja.js +181 -0
- package/dist/locales/ko.js +181 -0
- package/dist/locales/zh-Hans.js +181 -0
- package/dist/locales/zh-Hant.js +181 -0
- package/dist/package.js +3 -0
- package/dist/testing/app.d.ts +7 -0
- package/dist/testing/app.js +16 -0
- package/dist/testing/elements.d.ts +42 -0
- package/dist/testing/elements.js +58 -0
- package/dist/testing/fakeCanvas.d.ts +21 -0
- package/dist/testing/fakeCanvas.js +26 -0
- package/dist/testing/layerStore.d.ts +26 -0
- package/dist/testing/layerStore.js +43 -0
- package/dist/testing/locks.d.ts +15 -0
- package/dist/testing/locks.js +41 -0
- package/dist/testing/recordingCanvas.d.ts +14 -0
- package/dist/testing/recordingCanvas.js +28 -0
- package/dist/testing/recordingContext.d.ts +10 -0
- package/dist/testing/recordingContext.js +19 -0
- package/dist/ui/ChangeController/index.d.ts +40 -0
- package/dist/ui/ChangeController/index.js +62 -0
- package/dist/ui/base/index.d.ts +69 -0
- package/dist/ui/base/index.js +94 -0
- package/dist/ui/elements/PaintCanvas/index.d.ts +249 -0
- package/dist/ui/elements/PaintCanvas/index.js +584 -0
- package/dist/ui/elements/PaintCanvas/style.js +3 -0
- package/dist/ui/elements/PcBrushConfig/index.d.ts +130 -0
- package/dist/ui/elements/PcBrushConfig/index.js +465 -0
- package/dist/ui/elements/PcBrushConfig/style.js +3 -0
- package/dist/ui/elements/PcBrushMenu/index.d.ts +121 -0
- package/dist/ui/elements/PcBrushMenu/index.js +362 -0
- package/dist/ui/elements/PcBrushMenu/style.js +3 -0
- package/dist/ui/elements/PcBrushTest/index.d.ts +71 -0
- package/dist/ui/elements/PcBrushTest/index.js +136 -0
- package/dist/ui/elements/PcBrushTest/style.js +3 -0
- package/dist/ui/elements/PcButton/index.d.ts +57 -0
- package/dist/ui/elements/PcButton/index.js +124 -0
- package/dist/ui/elements/PcButtonGroup/index.d.ts +44 -0
- package/dist/ui/elements/PcButtonGroup/index.js +93 -0
- package/dist/ui/elements/PcCanvas/index.d.ts +356 -0
- package/dist/ui/elements/PcCanvas/index.js +1004 -0
- package/dist/ui/elements/PcCanvas/style.js +3 -0
- package/dist/ui/elements/PcCanvasMap/index.d.ts +96 -0
- package/dist/ui/elements/PcCanvasMap/index.js +187 -0
- package/dist/ui/elements/PcCanvasMap/style.js +3 -0
- package/dist/ui/elements/PcContextMenu/index.d.ts +72 -0
- package/dist/ui/elements/PcContextMenu/index.js +148 -0
- package/dist/ui/elements/PcDialog/index.d.ts +63 -0
- package/dist/ui/elements/PcDialog/index.js +114 -0
- package/dist/ui/elements/PcIcon/index.d.ts +36 -0
- package/dist/ui/elements/PcIcon/index.js +43 -0
- package/dist/ui/elements/PcIconToggle/index.d.ts +46 -0
- package/dist/ui/elements/PcIconToggle/index.js +87 -0
- package/dist/ui/elements/PcInfoTip/index.d.ts +40 -0
- package/dist/ui/elements/PcInfoTip/index.js +95 -0
- package/dist/ui/elements/PcInputSettings/index.d.ts +69 -0
- package/dist/ui/elements/PcInputSettings/index.js +154 -0
- package/dist/ui/elements/PcLayerItem/index.d.ts +221 -0
- package/dist/ui/elements/PcLayerItem/index.js +561 -0
- package/dist/ui/elements/PcLayerItem/style.js +3 -0
- package/dist/ui/elements/PcLayersMenu/index.d.ts +108 -0
- package/dist/ui/elements/PcLayersMenu/index.js +208 -0
- package/dist/ui/elements/PcLayersMenu/style.js +3 -0
- package/dist/ui/elements/PcMatch/index.d.ts +31 -0
- package/dist/ui/elements/PcMatch/index.js +58 -0
- package/dist/ui/elements/PcPanel/index.d.ts +43 -0
- package/dist/ui/elements/PcPanel/index.js +51 -0
- package/dist/ui/elements/PcPopover/index.d.ts +48 -0
- package/dist/ui/elements/PcPopover/index.js +86 -0
- package/dist/ui/elements/PcSlider/index.d.ts +57 -0
- package/dist/ui/elements/PcSlider/index.js +88 -0
- package/dist/ui/elements/PcStats/index.d.ts +54 -0
- package/dist/ui/elements/PcStats/index.js +144 -0
- package/dist/ui/elements/PcThemePicker/index.d.ts +56 -0
- package/dist/ui/elements/PcThemePicker/index.js +134 -0
- package/dist/ui/elements/PcToast/index.d.ts +58 -0
- package/dist/ui/elements/PcToast/index.js +110 -0
- package/dist/ui/elements/PcToggleCheckbox/index.d.ts +37 -0
- package/dist/ui/elements/PcToggleCheckbox/index.js +105 -0
- package/dist/ui/elements/PcToolSettings/index.d.ts +128 -0
- package/dist/ui/elements/PcToolSettings/index.js +549 -0
- package/dist/ui/elements/PcToolSettings/style.js +3 -0
- package/dist/ui/elements/PcToolbar/index.d.ts +71 -0
- package/dist/ui/elements/PcToolbar/index.js +190 -0
- package/dist/ui/elements/PcToolbar/style.js +3 -0
- package/dist/ui/icons/images/brush.js +3 -0
- package/dist/ui/icons/images/circle-mask.js +3 -0
- package/dist/ui/icons/images/clipboard.js +3 -0
- package/dist/ui/icons/images/cursor.js +3 -0
- package/dist/ui/icons/images/eraser.js +3 -0
- package/dist/ui/icons/images/eyedropper.js +3 -0
- package/dist/ui/icons/images/flip-horizontal.js +3 -0
- package/dist/ui/icons/images/flip-vertical.js +3 -0
- package/dist/ui/icons/images/focus-pen.js +3 -0
- package/dist/ui/icons/images/freehand-mask.js +3 -0
- package/dist/ui/icons/images/hidden.js +3 -0
- package/dist/ui/icons/images/layers.js +3 -0
- package/dist/ui/icons/images/linked.js +3 -0
- package/dist/ui/icons/images/locked.js +3 -0
- package/dist/ui/icons/images/moon.js +3 -0
- package/dist/ui/icons/images/pan.js +3 -0
- package/dist/ui/icons/images/polygon-mask.js +3 -0
- package/dist/ui/icons/images/pressure.js +3 -0
- package/dist/ui/icons/images/randomise.js +3 -0
- package/dist/ui/icons/images/rectangle-mask.js +3 -0
- package/dist/ui/icons/images/redo.js +3 -0
- package/dist/ui/icons/images/rotate-90-left.js +3 -0
- package/dist/ui/icons/images/rotate-90-right.js +3 -0
- package/dist/ui/icons/images/smoothing-bezier-cubic.js +3 -0
- package/dist/ui/icons/images/smoothing-bezier-quad.js +3 -0
- package/dist/ui/icons/images/smoothing-linear.js +3 -0
- package/dist/ui/icons/images/star.js +3 -0
- package/dist/ui/icons/images/sun.js +3 -0
- package/dist/ui/icons/images/tilt.js +3 -0
- package/dist/ui/icons/images/undo.js +3 -0
- package/dist/ui/icons/images/unlinked.js +3 -0
- package/dist/ui/icons/images/unlocked.js +3 -0
- package/dist/ui/icons/images/visible.js +3 -0
- package/dist/ui/icons/images/zoom-in.js +3 -0
- package/dist/ui/icons/images/zoom-out.js +3 -0
- package/dist/ui/icons/images/zoom.js +3 -0
- package/dist/ui/icons/index.d.ts +42 -0
- package/dist/ui/icons/index.js +130 -0
- package/dist/ui/index.d.ts +21 -0
- package/dist/ui/index.js +22 -0
- package/dist/ui/layout/index.d.ts +88 -0
- package/dist/ui/layout/index.js +96 -0
- package/dist/ui/styles/index.d.ts +13 -0
- package/dist/ui/styles/index.js +195 -0
- package/dist/ui/tokens/index.d.ts +29 -0
- package/dist/ui/tokens/index.js +114 -0
- package/locales/en-GB.json +179 -0
- package/locales/en-US.json +179 -0
- package/locales/fr.json +179 -0
- package/locales/ja.json +179 -0
- package/locales/ko.json +179 -0
- package/locales/zh-Hans.json +179 -0
- package/locales/zh-Hant.json +179 -0
- package/package.json +97 -3
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { ImageEncoding, encodeRgbaDeflate } from "../../image/index.js";
|
|
2
|
+
import { drawLayers } from "../../rendering/compositing/index.js";
|
|
3
|
+
import { createPatchMessage } from "../index.js";
|
|
4
|
+
// src/lib/messages/PatchSender/index.ts
|
|
5
|
+
/** How long to wait after a change before sending, so quick changes go together */
|
|
6
|
+
var PATCH_DELAY_MS = 200;
|
|
7
|
+
/**
|
|
8
|
+
* The smallest box containing every pixel that differs between two images of the same size (one 32-bit value per
|
|
9
|
+
* pixel), or undefined if they are the same.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* changedArea(before, after, 100, 100); // [10, 20, 31, 45]
|
|
13
|
+
*/
|
|
14
|
+
var changedArea = (before, after, width, height) => {
|
|
15
|
+
let x1 = width;
|
|
16
|
+
let y1 = height;
|
|
17
|
+
let x2 = -1;
|
|
18
|
+
let y2 = -1;
|
|
19
|
+
for (let y = 0; y < height; y++) {
|
|
20
|
+
const row = y * width;
|
|
21
|
+
for (let x = 0; x < width; x++) {
|
|
22
|
+
if (before[row + x] === after[row + x]) continue;
|
|
23
|
+
if (x < x1) x1 = x;
|
|
24
|
+
if (x > x2) x2 = x;
|
|
25
|
+
if (y < y1) y1 = y;
|
|
26
|
+
y2 = y;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return x2 < 0 ? void 0 : [
|
|
30
|
+
x1,
|
|
31
|
+
y1,
|
|
32
|
+
x2 + 1,
|
|
33
|
+
y2 + 1
|
|
34
|
+
];
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Copy a box of RGBA pixels out of a whole image.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* cropRgba(imageData.data, imageData.width, [10, 10, 20, 20]); // 10 × 10 pixels
|
|
41
|
+
*/
|
|
42
|
+
var cropRgba = (rgba, width, [x1, y1, x2, y2]) => {
|
|
43
|
+
const rowBytes = (x2 - x1) * 4;
|
|
44
|
+
const cropped = new Uint8ClampedArray(rowBytes * (y2 - y1));
|
|
45
|
+
for (let y = y1; y < y2; y++) {
|
|
46
|
+
const start = (y * width + x1) * 4;
|
|
47
|
+
cropped.set(rgba.subarray(start, start + rowBytes), (y - y1) * rowBytes);
|
|
48
|
+
}
|
|
49
|
+
return cropped;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Sends the user's drawing as patches. Shortly after any change (and once `whenIdle` runs it), it flattens the
|
|
53
|
+
* user's own layers, compares the result with what it last sent, and sends only the area that changed. This covers every kind of change (strokes,
|
|
54
|
+
* erasing, moving pixels, layer settings and order) without each tool reporting what it changed.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* const sync = new PatchSender({ width, height, layers: () => canvas.layers.layers, send, createCanvas });
|
|
58
|
+
* app.layers.addEventListener("change", () => sync.schedule());
|
|
59
|
+
*/
|
|
60
|
+
var PatchSender = class {
|
|
61
|
+
options;
|
|
62
|
+
canvas;
|
|
63
|
+
context;
|
|
64
|
+
/** The pixels last sent (all transparent to start with) */
|
|
65
|
+
sent;
|
|
66
|
+
timer;
|
|
67
|
+
/** Whether it has stopped (a sync waiting for `whenIdle` doesn't run) */
|
|
68
|
+
stopped = false;
|
|
69
|
+
/** The sync in progress, so syncs never overlap */
|
|
70
|
+
running = Promise.resolve();
|
|
71
|
+
constructor(options) {
|
|
72
|
+
this.options = options;
|
|
73
|
+
this.canvas = options.createCanvas(options.width, options.height);
|
|
74
|
+
this.context = this.canvas.getContext("2d", { willReadFrequently: true });
|
|
75
|
+
this.sent = new Uint8ClampedArray(options.width * options.height * 4);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Send the changes soon (changes within the delay go together), once `whenIdle` runs the sync.
|
|
79
|
+
*/
|
|
80
|
+
schedule() {
|
|
81
|
+
clearTimeout(this.timer);
|
|
82
|
+
this.timer = setTimeout(() => {
|
|
83
|
+
const run = () => this.stopped ? void 0 : this.sync().catch(() => void 0);
|
|
84
|
+
if (this.options.whenIdle) this.options.whenIdle(run);
|
|
85
|
+
else run();
|
|
86
|
+
}, this.options.delayMs ?? 200);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Send what changed since the last sync now. Resolves once sent; if sending fails, the changes go with the next sync.
|
|
90
|
+
*/
|
|
91
|
+
sync() {
|
|
92
|
+
clearTimeout(this.timer);
|
|
93
|
+
this.running = this.running.catch(() => void 0).then(() => this.sendChanges());
|
|
94
|
+
return this.running;
|
|
95
|
+
}
|
|
96
|
+
/** Flatten the layers and send the changed area, if any */
|
|
97
|
+
async sendChanges() {
|
|
98
|
+
const { width, height, send } = this.options;
|
|
99
|
+
this.context.clearRect(0, 0, width, height);
|
|
100
|
+
drawLayers(this.context, this.options.layers());
|
|
101
|
+
const current = this.context.getImageData(0, 0, width, height).data;
|
|
102
|
+
const area = changedArea(new Uint32Array(this.sent.buffer), new Uint32Array(current.buffer), width, height);
|
|
103
|
+
if (!area) return;
|
|
104
|
+
const data = await encodeRgbaDeflate(cropRgba(current, width, area), area);
|
|
105
|
+
await send(createPatchMessage(area, ImageEncoding.RgbaDeflate, data));
|
|
106
|
+
this.sent = current;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Count pixels as already sent (e.g. the user's earlier work, restored from a shared drawing's history), so they aren't
|
|
110
|
+
* sent again.
|
|
111
|
+
*/
|
|
112
|
+
markSent(area, rgba) {
|
|
113
|
+
const [x1, y1, x2, y2] = area;
|
|
114
|
+
const rowBytes = (x2 - x1) * 4;
|
|
115
|
+
for (let y = y1; y < y2; y++) this.sent.set(rgba.subarray((y - y1) * rowBytes, (y - y1 + 1) * rowBytes), (y * this.options.width + x1) * 4);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Stop any pending sync.
|
|
119
|
+
*/
|
|
120
|
+
stop() {
|
|
121
|
+
this.stopped = true;
|
|
122
|
+
clearTimeout(this.timer);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
export { PATCH_DELAY_MS, changedArea, cropRgba, PatchSender as default };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { BoundingBox, ImageEncoding } from "../image";
|
|
2
|
+
import { type CanvasMessage, type PatchMessage } from "./schema";
|
|
3
|
+
export * from "./schema";
|
|
4
|
+
/** Result of checking a received message */
|
|
5
|
+
export type MessageValidationResult = {
|
|
6
|
+
valid: true;
|
|
7
|
+
value: CanvasMessage;
|
|
8
|
+
} | {
|
|
9
|
+
valid: false;
|
|
10
|
+
errors: string[];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Make a patch message.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* createPatchMessage([0, 0, 10, 10], ImageEncoding.RgbaDeflate, data);
|
|
17
|
+
*/
|
|
18
|
+
export declare const createPatchMessage: (coords: BoundingBox, encoding: ImageEncoding, data: string) => PatchMessage;
|
|
19
|
+
/**
|
|
20
|
+
* Check a received (untrusted) drawing message: its protocol version, its kind, its schema, and that a patch's area
|
|
21
|
+
* isn't empty.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* validateCanvasMessage(JSON.parse(text)); // { valid: true, value: { protocol: 1, type: "patch", … } }
|
|
25
|
+
*/
|
|
26
|
+
export declare const validateCanvasMessage: (input: unknown) => MessageValidationResult;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { formatErrors } from "../presets/index.js";
|
|
2
|
+
import { validateHistoryMessage, validatePatchMessage, validateStrokeMessage } from "../validation/validators.generated.js";
|
|
3
|
+
import { CanvasMessageType, MAX_MESSAGE_CANVAS_SIZE, MAX_PATCH_DATA_LENGTH, MAX_STROKE_POINTS, PROTOCOL_VERSION, historyMessageSchema, messageSchemas, patchMessageSchema, strokeMessageSchema, strokePresetSchema } from "./schema.js";
|
|
4
|
+
// src/lib/messages/index.ts
|
|
5
|
+
/**
|
|
6
|
+
* Make a patch message.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* createPatchMessage([0, 0, 10, 10], ImageEncoding.RgbaDeflate, data);
|
|
10
|
+
*/
|
|
11
|
+
var createPatchMessage = (coords, encoding, data) => ({
|
|
12
|
+
protocol: 1,
|
|
13
|
+
type: CanvasMessageType.Patch,
|
|
14
|
+
coords,
|
|
15
|
+
encoding,
|
|
16
|
+
data
|
|
17
|
+
});
|
|
18
|
+
/** The validator for each kind of message */
|
|
19
|
+
var VALIDATORS = {
|
|
20
|
+
[CanvasMessageType.Patch]: validatePatchMessage,
|
|
21
|
+
[CanvasMessageType.Stroke]: validateStrokeMessage,
|
|
22
|
+
[CanvasMessageType.Undo]: validateHistoryMessage,
|
|
23
|
+
[CanvasMessageType.Redo]: validateHistoryMessage
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Check a received (untrusted) drawing message: its protocol version, its kind, its schema, and that a patch's area
|
|
27
|
+
* isn't empty.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* validateCanvasMessage(JSON.parse(text)); // { valid: true, value: { protocol: 1, type: "patch", … } }
|
|
31
|
+
*/
|
|
32
|
+
var validateCanvasMessage = (input) => {
|
|
33
|
+
const record = typeof input === "object" && input !== null ? input : {};
|
|
34
|
+
if (record.protocol !== 1) return {
|
|
35
|
+
valid: false,
|
|
36
|
+
errors: [`/protocol must be 1`]
|
|
37
|
+
};
|
|
38
|
+
const validate = Object.hasOwn(VALIDATORS, record.type) ? VALIDATORS[record.type] : void 0;
|
|
39
|
+
if (!validate) return {
|
|
40
|
+
valid: false,
|
|
41
|
+
errors: ["/type is not a drawing message"]
|
|
42
|
+
};
|
|
43
|
+
if (!validate(input)) return {
|
|
44
|
+
valid: false,
|
|
45
|
+
errors: formatErrors(validate.errors)
|
|
46
|
+
};
|
|
47
|
+
if (input.type === CanvasMessageType.Patch) {
|
|
48
|
+
const [x1, y1, x2, y2] = input.coords;
|
|
49
|
+
if (x2 <= x1 || y2 <= y1) return {
|
|
50
|
+
valid: false,
|
|
51
|
+
errors: ["/coords must not be empty"]
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
valid: true,
|
|
56
|
+
value: input
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
export { CanvasMessageType, MAX_MESSAGE_CANVAS_SIZE, MAX_PATCH_DATA_LENGTH, MAX_STROKE_POINTS, PROTOCOL_VERSION, createPatchMessage, historyMessageSchema, messageSchemas, patchMessageSchema, strokeMessageSchema, strokePresetSchema, validateCanvasMessage };
|