@scrawl-board/board 0.1.0-beta.1 → 0.1.0-beta.2
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/browser.d.ts +25 -14
- package/dist/browser.js +135 -93
- package/dist/core.js +19 -19
- package/dist/index.d.ts +63 -14
- package/dist/index.js +175 -106
- package/dist/react.d.ts +63 -14
- package/dist/react.js +174 -105
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
2
2
|
import { createPortal } from "react-dom";
|
|
3
3
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
-
//#region src/core
|
|
4
|
+
//#region src/core/shapes/assets.ts
|
|
5
5
|
var ASSET_REF_PATTERN = /^asset:[a-z0-9](?:[a-z0-9.-]{0,61}[a-z0-9])?:[A-Za-z0-9._~-]+$/;
|
|
6
6
|
/** Hard ceiling on a reference's own wire length — independent of any resource limit below. */
|
|
7
7
|
var ASSET_REF_MAX_BYTES = 512;
|
|
@@ -41,7 +41,7 @@ function clampAssetCacheBytes(value) {
|
|
|
41
41
|
return Math.min(ASSET_CACHE_BYTES_MAX, Math.max(ASSET_CACHE_BYTES_MIN, Math.floor(value)));
|
|
42
42
|
}
|
|
43
43
|
//#endregion
|
|
44
|
-
//#region src/core
|
|
44
|
+
//#region src/core/document/identifiers.ts
|
|
45
45
|
function documentId(value) {
|
|
46
46
|
if (!value) throw new TypeError("DocumentId cannot be empty");
|
|
47
47
|
return value;
|
|
@@ -51,7 +51,7 @@ function strokeId(value) {
|
|
|
51
51
|
return value;
|
|
52
52
|
}
|
|
53
53
|
//#endregion
|
|
54
|
-
//#region src/document-schema.ts
|
|
54
|
+
//#region src/core/document/document-schema.ts
|
|
55
55
|
var CURRENT_DOCUMENT_SCHEMA_VERSION = 1;
|
|
56
56
|
var DocumentRecoveryError = class extends Error {
|
|
57
57
|
constructor(code, message, originalBytes, path) {
|
|
@@ -259,7 +259,7 @@ function validation(message, path) {
|
|
|
259
259
|
return new DocumentRecoveryError("DOCUMENT_VALIDATION_FAILED", message, void 0, path);
|
|
260
260
|
}
|
|
261
261
|
//#endregion
|
|
262
|
-
//#region src/core
|
|
262
|
+
//#region src/core/shapes/affine2d.ts
|
|
263
263
|
var IDENTITY = [
|
|
264
264
|
1,
|
|
265
265
|
0,
|
|
@@ -343,7 +343,7 @@ function avgScale(m) {
|
|
|
343
343
|
return (Math.hypot(m[0], m[1]) + Math.hypot(m[2], m[3])) / 2;
|
|
344
344
|
}
|
|
345
345
|
//#endregion
|
|
346
|
-
//#region src/core
|
|
346
|
+
//#region src/core/document/boardSearch.ts
|
|
347
347
|
function hay(s) {
|
|
348
348
|
return s.toLowerCase();
|
|
349
349
|
}
|
|
@@ -408,7 +408,7 @@ function searchBoard(query, board) {
|
|
|
408
408
|
return hits;
|
|
409
409
|
}
|
|
410
410
|
//#endregion
|
|
411
|
-
//#region src/core
|
|
411
|
+
//#region src/core/shapes/types.ts
|
|
412
412
|
/** Erasure level at which a point counts as fully erased. */
|
|
413
413
|
var ERASE_THRESHOLD = .95;
|
|
414
414
|
function cloneStroke(stroke) {
|
|
@@ -484,7 +484,7 @@ function cloneImage(img) {
|
|
|
484
484
|
return { ...img };
|
|
485
485
|
}
|
|
486
486
|
//#endregion
|
|
487
|
-
//#region src/core
|
|
487
|
+
//#region src/core/document/clusterStore.ts
|
|
488
488
|
/** A stroke joins a cluster last written to within this window at full reach. */
|
|
489
489
|
var RECENT_MS = 8e3;
|
|
490
490
|
/** Older clusters are still joinable, at half the gap threshold. */
|
|
@@ -655,7 +655,7 @@ function clamp$3(v, lo, hi) {
|
|
|
655
655
|
return Math.min(hi, Math.max(lo, v));
|
|
656
656
|
}
|
|
657
657
|
//#endregion
|
|
658
|
-
//#region src/core
|
|
658
|
+
//#region src/core/shapes/extensionTypes.ts
|
|
659
659
|
function cloneCustomObject(object) {
|
|
660
660
|
return {
|
|
661
661
|
...object,
|
|
@@ -665,7 +665,7 @@ function cloneCustomObject(object) {
|
|
|
665
665
|
};
|
|
666
666
|
}
|
|
667
667
|
//#endregion
|
|
668
|
-
//#region src/core
|
|
668
|
+
//#region src/core/shapes/kitchenTimer.ts
|
|
669
669
|
var TIMER_DEFAULT_SIZE = 12;
|
|
670
670
|
var TIMER_DEFAULT_DURATION_MS = 300 * 1e3;
|
|
671
671
|
var TIMER_PRESETS_MS = [
|
|
@@ -722,7 +722,7 @@ function formatTimer(ms) {
|
|
|
722
722
|
return `${Math.floor(total / 60)}:${(total % 60).toString().padStart(2, "0")}`;
|
|
723
723
|
}
|
|
724
724
|
//#endregion
|
|
725
|
-
//#region src/core
|
|
725
|
+
//#region src/core/shapes/itemLock.ts
|
|
726
726
|
/**
|
|
727
727
|
* Apply or clear a lock in place. Unlock always drops the holder so a stale
|
|
728
728
|
* name cannot linger on an unlocked item.
|
|
@@ -759,7 +759,7 @@ function serializeLock(item) {
|
|
|
759
759
|
};
|
|
760
760
|
}
|
|
761
761
|
//#endregion
|
|
762
|
-
//#region src/core
|
|
762
|
+
//#region src/core/document/document.ts
|
|
763
763
|
/**
|
|
764
764
|
* The one place a live Stroke becomes its wire representation — in
|
|
765
765
|
* particular, points collapse from {x,y,pressure,erase?} objects into
|
|
@@ -1318,7 +1318,7 @@ function computeBBox(stroke) {
|
|
|
1318
1318
|
return world;
|
|
1319
1319
|
}
|
|
1320
1320
|
//#endregion
|
|
1321
|
-
//#region src/core
|
|
1321
|
+
//#region src/core/commands/commands.ts
|
|
1322
1322
|
/** One drawing action — a marker stroke, or a shape's strokes as one unit. */
|
|
1323
1323
|
var AddStrokesCommand = class {
|
|
1324
1324
|
constructor(strokes) {
|
|
@@ -1660,7 +1660,7 @@ var LockItemsCommand = class {
|
|
|
1660
1660
|
}
|
|
1661
1661
|
};
|
|
1662
1662
|
//#endregion
|
|
1663
|
-
//#region src/core
|
|
1663
|
+
//#region src/core/history/history.ts
|
|
1664
1664
|
var LIMIT = 200;
|
|
1665
1665
|
var History = class {
|
|
1666
1666
|
constructor(doc) {
|
|
@@ -1721,7 +1721,7 @@ var History = class {
|
|
|
1721
1721
|
}
|
|
1722
1722
|
};
|
|
1723
1723
|
//#endregion
|
|
1724
|
-
//#region src/core
|
|
1724
|
+
//#region src/core/events/ops.ts
|
|
1725
1725
|
var ADDED = [
|
|
1726
1726
|
["added", "strokes"],
|
|
1727
1727
|
["notesAdded", "notes"],
|
|
@@ -1775,7 +1775,7 @@ function changeToOps(change, restoring = false) {
|
|
|
1775
1775
|
return ops;
|
|
1776
1776
|
}
|
|
1777
1777
|
//#endregion
|
|
1778
|
-
//#region src/core
|
|
1778
|
+
//#region src/core/shapes/ribbonEdges.ts
|
|
1779
1779
|
var MIN_WIDTH_FACTOR = .35;
|
|
1780
1780
|
var END_TAPER = .55;
|
|
1781
1781
|
function ribbonEdges(points, baseWidth) {
|
|
@@ -1807,7 +1807,7 @@ function ribbonEdges(points, baseWidth) {
|
|
|
1807
1807
|
return out;
|
|
1808
1808
|
}
|
|
1809
1809
|
//#endregion
|
|
1810
|
-
//#region src/core
|
|
1810
|
+
//#region src/core/document/spatialIndex.ts
|
|
1811
1811
|
var CELL = 8;
|
|
1812
1812
|
var SpatialIndex = class {
|
|
1813
1813
|
constructor(doc) {
|
|
@@ -1880,7 +1880,7 @@ function cellsOf(box) {
|
|
|
1880
1880
|
return keys;
|
|
1881
1881
|
}
|
|
1882
1882
|
//#endregion
|
|
1883
|
-
//#region src/core
|
|
1883
|
+
//#region src/core/shapes/stamps.ts
|
|
1884
1884
|
var STAMP_SIZE = 6;
|
|
1885
1885
|
var STAMPS = [
|
|
1886
1886
|
{
|
|
@@ -1929,7 +1929,7 @@ function isStampKind(value) {
|
|
|
1929
1929
|
return typeof value === "string" && STAMPS.some((s) => s.kind === value);
|
|
1930
1930
|
}
|
|
1931
1931
|
//#endregion
|
|
1932
|
-
//#region src/
|
|
1932
|
+
//#region src/collaboration/presence/presence.ts
|
|
1933
1933
|
/** Keep beacons clear of typical chrome at the top and bottom of the Board. */
|
|
1934
1934
|
var BEACON_INSET = {
|
|
1935
1935
|
top: 72,
|
|
@@ -1965,7 +1965,7 @@ function clamp$2(value, min, max) {
|
|
|
1965
1965
|
return Math.min(max, Math.max(min, value));
|
|
1966
1966
|
}
|
|
1967
1967
|
//#endregion
|
|
1968
|
-
//#region src/
|
|
1968
|
+
//#region src/persistence/serialization/svg.ts
|
|
1969
1969
|
/** Matches the key light used by the board shader and note shadows. */
|
|
1970
1970
|
var LIGHT = {
|
|
1971
1971
|
x: -.25,
|
|
@@ -2336,7 +2336,7 @@ function fmt(n) {
|
|
|
2336
2336
|
var SDK_PACKAGE_NAME = "@scrawl-board/board";
|
|
2337
2337
|
var SDK_DEVELOPMENT_VERSION = "0.0.0-development";
|
|
2338
2338
|
//#endregion
|
|
2339
|
-
//#region src/core
|
|
2339
|
+
//#region src/core/shapes/sceneGeometry.ts
|
|
2340
2340
|
var EMPTY_BOUNDS = {
|
|
2341
2341
|
x: 0,
|
|
2342
2342
|
y: 0,
|
|
@@ -2400,7 +2400,7 @@ function textCorners(x, y, text, fontSize, align, m) {
|
|
|
2400
2400
|
return rectCorners(x + (align === "center" ? -width / 2 : align === "end" ? -width : 0), y, width, height, m);
|
|
2401
2401
|
}
|
|
2402
2402
|
//#endregion
|
|
2403
|
-
//#region src/core
|
|
2403
|
+
//#region src/core/shapes/customObjects.ts
|
|
2404
2404
|
var FALLBACK_LABEL_MAX_LENGTH = 80;
|
|
2405
2405
|
function toReadonly(object) {
|
|
2406
2406
|
return object;
|
|
@@ -2529,7 +2529,7 @@ function extensionIdFromType(type) {
|
|
|
2529
2529
|
return slash === -1 ? type : type.slice(0, slash);
|
|
2530
2530
|
}
|
|
2531
2531
|
//#endregion
|
|
2532
|
-
//#region src/core
|
|
2532
|
+
//#region src/core/shapes/extensionRegistry.ts
|
|
2533
2533
|
function buildExtensionRegistry(extensions) {
|
|
2534
2534
|
const list = extensions ?? [];
|
|
2535
2535
|
const diagnostics = [];
|
|
@@ -2626,7 +2626,7 @@ function isWellFormedNamespacedId(id) {
|
|
|
2626
2626
|
return isWellFormedId(id) && id.includes("/") && !id.startsWith("/") && !id.endsWith("/");
|
|
2627
2627
|
}
|
|
2628
2628
|
//#endregion
|
|
2629
|
-
//#region src/
|
|
2629
|
+
//#region src/persistence/adapters/assetValidation.ts
|
|
2630
2630
|
function sniffImageMediaType(bytes) {
|
|
2631
2631
|
if (bytes.length >= 8 && bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71 && bytes[4] === 13 && bytes[5] === 10 && bytes[6] === 26 && bytes[7] === 10) return "image/png";
|
|
2632
2632
|
if (bytes.length >= 3 && bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) return "image/jpeg";
|
|
@@ -2713,7 +2713,7 @@ function validateDecodedDimensions(width, height) {
|
|
|
2713
2713
|
};
|
|
2714
2714
|
}
|
|
2715
2715
|
//#endregion
|
|
2716
|
-
//#region src/assetController.ts
|
|
2716
|
+
//#region src/persistence/adapters/assetController.ts
|
|
2717
2717
|
var FAILURE_COALESCE_MS = 4e3;
|
|
2718
2718
|
var AssetController = class {
|
|
2719
2719
|
constructor(resolver, options) {
|
|
@@ -2892,7 +2892,7 @@ function toAssetResolutionError(cause, ref) {
|
|
|
2892
2892
|
return new AssetResolutionError("unknown", true, cause instanceof Error ? cause.message : String(cause), ref);
|
|
2893
2893
|
}
|
|
2894
2894
|
//#endregion
|
|
2895
|
-
//#region src/
|
|
2895
|
+
//#region src/persistence/serialization/assetRefCollector.ts
|
|
2896
2896
|
/** Every unique Asset reference in the document, and which object(s) use it. */
|
|
2897
2897
|
function collectDocumentAssetRefs(doc, registry) {
|
|
2898
2898
|
const refs = /* @__PURE__ */ new Map();
|
|
@@ -2919,7 +2919,7 @@ function collectSceneAssetRefs(node, objectId, add) {
|
|
|
2919
2919
|
if (node.kind === "group") for (const child of node.children) collectSceneAssetRefs(child, objectId, add);
|
|
2920
2920
|
}
|
|
2921
2921
|
//#endregion
|
|
2922
|
-
//#region src/assetExport.ts
|
|
2922
|
+
//#region src/persistence/serialization/assetExport.ts
|
|
2923
2923
|
/** Strict mode's rejection — never contains credentials, a fetchable location, or a raw resolver message. */
|
|
2924
2924
|
var SvgAssetExportError = class extends Error {
|
|
2925
2925
|
constructor(missingAssets) {
|
|
@@ -2975,7 +2975,7 @@ function toDataUri(bytes, mediaType) {
|
|
|
2975
2975
|
return `data:${mediaType};base64,${btoa(binary)}`;
|
|
2976
2976
|
}
|
|
2977
2977
|
//#endregion
|
|
2978
|
-
//#region src/assetIngestion.ts
|
|
2978
|
+
//#region src/persistence/adapters/assetIngestion.ts
|
|
2979
2979
|
async function decodeDimensionsWithImageBitmap(bytes, mediaType) {
|
|
2980
2980
|
const blob = new Blob([bytes], { type: mediaType });
|
|
2981
2981
|
let bitmap;
|
|
@@ -35621,7 +35621,7 @@ var WebGLRenderer = class {
|
|
|
35621
35621
|
}
|
|
35622
35622
|
};
|
|
35623
35623
|
//#endregion
|
|
35624
|
-
//#region
|
|
35624
|
+
//#region src/core/events/auditEvents.ts
|
|
35625
35625
|
var BY_LABEL = {
|
|
35626
35626
|
draw: {
|
|
35627
35627
|
action: "create",
|
|
@@ -35741,7 +35741,7 @@ function lowerFirst(s) {
|
|
|
35741
35741
|
return s.charAt(0).toLowerCase() + s.slice(1);
|
|
35742
35742
|
}
|
|
35743
35743
|
//#endregion
|
|
35744
|
-
//#region
|
|
35744
|
+
//#region src/renderer/shapes/AssetTextureCache.ts
|
|
35745
35745
|
var AssetTextureCache = class {
|
|
35746
35746
|
constructor(assetController) {
|
|
35747
35747
|
this.assetController = assetController;
|
|
@@ -35832,7 +35832,7 @@ function toDecodeError(cause, ref) {
|
|
|
35832
35832
|
return new AssetResolutionError("decode-failed", false, cause instanceof Error ? cause.message : String(cause), ref);
|
|
35833
35833
|
}
|
|
35834
35834
|
//#endregion
|
|
35835
|
-
//#region
|
|
35835
|
+
//#region src/renderer/canvas/raycast.ts
|
|
35836
35836
|
var origin$1 = new Vector3();
|
|
35837
35837
|
var target = new Vector3();
|
|
35838
35838
|
function pointerToBoard(clientX, clientY, canvas, camera) {
|
|
@@ -35863,7 +35863,7 @@ function pointerToPlane(clientX, clientY, canvas, camera, z) {
|
|
|
35863
35863
|
};
|
|
35864
35864
|
}
|
|
35865
35865
|
//#endregion
|
|
35866
|
-
//#region
|
|
35866
|
+
//#region src/renderer/canvas/fog.ts
|
|
35867
35867
|
function createFogUniforms(color) {
|
|
35868
35868
|
return {
|
|
35869
35869
|
uFogColor: { value: new Color(color) },
|
|
@@ -35884,18 +35884,24 @@ var FOG_GLSL = `
|
|
|
35884
35884
|
}
|
|
35885
35885
|
`;
|
|
35886
35886
|
//#endregion
|
|
35887
|
-
//#region
|
|
35887
|
+
//#region src/renderer/canvas/boardSurface.ts
|
|
35888
35888
|
var GRID_MODE_CODE = {
|
|
35889
35889
|
none: 0,
|
|
35890
35890
|
line: 1,
|
|
35891
35891
|
dot: 2
|
|
35892
35892
|
};
|
|
35893
|
+
var TEXTURE_CODE = {
|
|
35894
|
+
flat: 0,
|
|
35895
|
+
textured: 1
|
|
35896
|
+
};
|
|
35893
35897
|
/** Used when a caller doesn't supply one (e.g. ScrawlEngine constructed without a Host theme). */
|
|
35894
35898
|
var DEFAULT_BOARD_SURFACE_THEME = {
|
|
35895
35899
|
color: "#f5f5f3",
|
|
35896
35900
|
gridMode: "none",
|
|
35897
35901
|
gridColor: "#deded8",
|
|
35898
|
-
gridSpacing: 5
|
|
35902
|
+
gridSpacing: 5,
|
|
35903
|
+
gridLineWidth: 1,
|
|
35904
|
+
surfaceTexture: "flat"
|
|
35899
35905
|
};
|
|
35900
35906
|
/** Grid alpha fades out below this on-screen spacing (px) — otherwise it aliases into a solid wash when zoomed out. */
|
|
35901
35907
|
var GRID_FADE_MIN_PX = 3;
|
|
@@ -35916,8 +35922,10 @@ var FRAGMENT = `
|
|
|
35916
35922
|
uniform float uGridMode;
|
|
35917
35923
|
uniform vec3 uGridColor;
|
|
35918
35924
|
uniform float uGridSpacing;
|
|
35919
|
-
uniform float
|
|
35925
|
+
uniform float uWorldPerPixel;
|
|
35926
|
+
uniform float uGridLineWidthPx;
|
|
35920
35927
|
uniform float uGridFade;
|
|
35928
|
+
uniform float uSurfaceTexture;
|
|
35921
35929
|
varying vec3 vWorldPos;
|
|
35922
35930
|
|
|
35923
35931
|
float hash(vec2 p) {
|
|
@@ -35937,37 +35945,45 @@ var FRAGMENT = `
|
|
|
35937
35945
|
${FOG_GLSL}
|
|
35938
35946
|
|
|
35939
35947
|
// Distance from p's nearest axis-aligned grid line, in world units.
|
|
35948
|
+
// A crisp, ~uGridLineWidthPx-wide line: full alpha to its half-width, a
|
|
35949
|
+
// ~1px anti-aliased falloff beyond that — not a wide, soft-edged band.
|
|
35940
35950
|
float gridLineAlpha(vec2 p) {
|
|
35941
35951
|
vec2 cell = mod(p, uGridSpacing);
|
|
35942
35952
|
vec2 distToLine = min(cell, uGridSpacing - cell);
|
|
35943
|
-
|
|
35953
|
+
float halfWidth = 0.5 * uGridLineWidthPx * uWorldPerPixel;
|
|
35954
|
+
float aa = uWorldPerPixel;
|
|
35955
|
+
vec2 lineAlpha2 = 1.0 - smoothstep(halfWidth - aa * 0.5, halfWidth + aa * 0.5, distToLine);
|
|
35944
35956
|
return max(lineAlpha2.x, lineAlpha2.y);
|
|
35945
35957
|
}
|
|
35946
35958
|
|
|
35947
|
-
// Distance from p's nearest grid intersection, in world units.
|
|
35959
|
+
// Distance from p's nearest grid intersection, in world units. Dot radius
|
|
35960
|
+
// matches the configured line width in pixels, same anti-aliasing.
|
|
35948
35961
|
float gridDotAlpha(vec2 p) {
|
|
35949
35962
|
vec2 cell = mod(p, uGridSpacing) - uGridSpacing * 0.5;
|
|
35950
35963
|
float dist = length(cell);
|
|
35951
|
-
float radius =
|
|
35952
|
-
|
|
35964
|
+
float radius = uGridLineWidthPx * uWorldPerPixel;
|
|
35965
|
+
float aa = uWorldPerPixel;
|
|
35966
|
+
return 1.0 - smoothstep(radius - aa * 0.5, radius + aa * 0.5, dist);
|
|
35953
35967
|
}
|
|
35954
35968
|
|
|
35955
35969
|
void main() {
|
|
35956
35970
|
vec3 col = uColor;
|
|
35957
35971
|
|
|
35958
|
-
|
|
35959
|
-
|
|
35960
|
-
|
|
35972
|
+
if (uSurfaceTexture > 0.5) {
|
|
35973
|
+
// Melamine micro-texture: two octaves of value noise, +-1.75% brightness.
|
|
35974
|
+
float n = vnoise(vWorldPos.xy * 2.3) * 0.6 + vnoise(vWorldPos.xy * 9.7) * 0.4;
|
|
35975
|
+
col *= 1.0 + (n - 0.5) * 0.035;
|
|
35961
35976
|
|
|
35962
|
-
|
|
35963
|
-
|
|
35964
|
-
|
|
35965
|
-
|
|
35966
|
-
|
|
35967
|
-
|
|
35968
|
-
|
|
35969
|
-
|
|
35970
|
-
|
|
35977
|
+
// Satin sheen: Fresnel rim + a specular band from the key light. Both
|
|
35978
|
+
// are ~zero in the straight-on working view and bloom as the camera tilts.
|
|
35979
|
+
vec3 V = normalize(cameraPosition - vWorldPos);
|
|
35980
|
+
vec3 N = vec3(0.0, 0.0, 1.0);
|
|
35981
|
+
float fres = pow(1.0 - max(dot(N, V), 0.0), 3.0);
|
|
35982
|
+
vec3 L = normalize(vec3(-0.25, 0.4, 0.88));
|
|
35983
|
+
vec3 H = normalize(L + V);
|
|
35984
|
+
float spec = pow(max(dot(N, H), 0.0), 90.0);
|
|
35985
|
+
col += (fres * 0.18 + spec * 0.06) * vec3(1.0);
|
|
35986
|
+
}
|
|
35971
35987
|
|
|
35972
35988
|
if (uGridMode > 0.5 && uGridFade > 0.001) {
|
|
35973
35989
|
float gridAlpha = (uGridMode < 1.5 ? gridLineAlpha(vWorldPos.xy) : gridDotAlpha(vWorldPos.xy)) * uGridFade;
|
|
@@ -35987,8 +36003,10 @@ function createBoardSurface(fog, theme) {
|
|
|
35987
36003
|
uGridMode: { value: GRID_MODE_CODE[theme.gridMode] },
|
|
35988
36004
|
uGridColor: { value: new Color(theme.gridColor) },
|
|
35989
36005
|
uGridSpacing: { value: Math.max(.001, theme.gridSpacing) },
|
|
35990
|
-
|
|
36006
|
+
uGridLineWidthPx: { value: Math.max(.1, theme.gridLineWidth) },
|
|
36007
|
+
uWorldPerPixel: { value: .05 },
|
|
35991
36008
|
uGridFade: { value: 0 },
|
|
36009
|
+
uSurfaceTexture: { value: TEXTURE_CODE[theme.surfaceTexture] },
|
|
35992
36010
|
...fog
|
|
35993
36011
|
}
|
|
35994
36012
|
});
|
|
@@ -35996,13 +36014,15 @@ function createBoardSurface(fog, theme) {
|
|
|
35996
36014
|
mesh.name = "board-surface";
|
|
35997
36015
|
return mesh;
|
|
35998
36016
|
}
|
|
35999
|
-
/** Applies a theme change (initial or live) — everything except the per-frame fade/
|
|
36017
|
+
/** Applies a theme change (initial or live) — everything except the per-frame fade/pixel-ratio. */
|
|
36000
36018
|
function setBoardSurfaceTheme(mesh, theme) {
|
|
36001
36019
|
const uniforms = mesh.material.uniforms;
|
|
36002
36020
|
uniforms.uColor.value.set(theme.color);
|
|
36003
36021
|
uniforms.uGridMode.value = GRID_MODE_CODE[theme.gridMode];
|
|
36004
36022
|
uniforms.uGridColor.value.set(theme.gridColor);
|
|
36005
36023
|
uniforms.uGridSpacing.value = Math.max(.001, theme.gridSpacing);
|
|
36024
|
+
uniforms.uGridLineWidthPx.value = Math.max(.1, theme.gridLineWidth);
|
|
36025
|
+
uniforms.uSurfaceTexture.value = TEXTURE_CODE[theme.surfaceTexture];
|
|
36006
36026
|
}
|
|
36007
36027
|
/** Keep the plane centered under the view, larger than the fog horizon, and the grid's on-screen weight/fade current. */
|
|
36008
36028
|
function updateBoardSurface(mesh, centerX, centerY, fogFar, worldPerPixel) {
|
|
@@ -36010,7 +36030,7 @@ function updateBoardSurface(mesh, centerX, centerY, fogFar, worldPerPixel) {
|
|
|
36010
36030
|
const size = fogFar * 2.5;
|
|
36011
36031
|
mesh.scale.set(size, size, 1);
|
|
36012
36032
|
const uniforms = mesh.material.uniforms;
|
|
36013
|
-
uniforms.
|
|
36033
|
+
uniforms.uWorldPerPixel.value = worldPerPixel;
|
|
36014
36034
|
const t = (uniforms.uGridSpacing.value / Math.max(1e-6, worldPerPixel) - GRID_FADE_MIN_PX) / (GRID_FADE_MAX_PX - GRID_FADE_MIN_PX);
|
|
36015
36035
|
uniforms.uGridFade.value = MathUtils.clamp(t, 0, 1);
|
|
36016
36036
|
}
|
|
@@ -36183,7 +36203,7 @@ var CameraRig = class {
|
|
|
36183
36203
|
}
|
|
36184
36204
|
};
|
|
36185
36205
|
//#endregion
|
|
36186
|
-
//#region
|
|
36206
|
+
//#region src/renderer/canvas/scene.ts
|
|
36187
36207
|
var SceneRig = class {
|
|
36188
36208
|
constructor(canvas, boardTheme) {
|
|
36189
36209
|
this.renderer = new WebGLRenderer({
|
|
@@ -36230,7 +36250,7 @@ var SceneRig = class {
|
|
|
36230
36250
|
}
|
|
36231
36251
|
};
|
|
36232
36252
|
//#endregion
|
|
36233
|
-
//#region
|
|
36253
|
+
//#region src/renderer/shapes/inkMaterial.ts
|
|
36234
36254
|
var VERTEX = `
|
|
36235
36255
|
attribute float aAlpha;
|
|
36236
36256
|
varying vec2 vUv;
|
|
@@ -36361,7 +36381,7 @@ var InkMaterials = class {
|
|
|
36361
36381
|
}
|
|
36362
36382
|
};
|
|
36363
36383
|
//#endregion
|
|
36364
|
-
//#region
|
|
36384
|
+
//#region src/renderer/shapes/ribbonGeometry.ts
|
|
36365
36385
|
/** Ink floats a hair above the board to avoid z-fighting with the surface. */
|
|
36366
36386
|
var INK_Z = .02;
|
|
36367
36387
|
/** Highlighter always renders under opaque ink (build prompt §4.1). */
|
|
@@ -36412,7 +36432,7 @@ function buildRibbonGeometry(points, baseWidth, z = INK_Z) {
|
|
|
36412
36432
|
return geometry;
|
|
36413
36433
|
}
|
|
36414
36434
|
//#endregion
|
|
36415
|
-
//#region
|
|
36435
|
+
//#region src/renderer/shapes/strokeRenderer.ts
|
|
36416
36436
|
var strokeZ = (stroke) => stroke.tool === "highlighter" ? HIGHLIGHT_Z : INK_Z;
|
|
36417
36437
|
/**
|
|
36418
36438
|
* Derives ink meshes from the document by subscription — the document never
|
|
@@ -36545,7 +36565,7 @@ function syncMatrix(mesh, stroke) {
|
|
|
36545
36565
|
mesh.matrixWorldNeedsUpdate = true;
|
|
36546
36566
|
}
|
|
36547
36567
|
//#endregion
|
|
36548
|
-
//#region
|
|
36568
|
+
//#region src/renderer/shapes/markerProp.ts
|
|
36549
36569
|
var BODY_LENGTH = 11;
|
|
36550
36570
|
var BODY_RADIUS = .85;
|
|
36551
36571
|
var TIP_LENGTH = 1.6;
|
|
@@ -36641,7 +36661,7 @@ var MarkerProp = class {
|
|
|
36641
36661
|
}
|
|
36642
36662
|
};
|
|
36643
36663
|
//#endregion
|
|
36644
|
-
//#region
|
|
36664
|
+
//#region src/renderer/shapes/noteGeometry.ts
|
|
36645
36665
|
/**
|
|
36646
36666
|
* Height of the sheet above the board at (u, v) ∈ [0,1]².
|
|
36647
36667
|
* v = 1 is the adhesive edge (always 0); u = 1 is the peel corner side.
|
|
@@ -36685,7 +36705,7 @@ function applyCurl(geometry, curl, peel) {
|
|
|
36685
36705
|
color.needsUpdate = true;
|
|
36686
36706
|
}
|
|
36687
36707
|
//#endregion
|
|
36688
|
-
//#region
|
|
36708
|
+
//#region src/renderer/shapes/stickyNotes.ts
|
|
36689
36709
|
var TEXTURE_SIZE = 512;
|
|
36690
36710
|
var FOCUS_COLOR$4 = 2450411;
|
|
36691
36711
|
var CURL = .3;
|
|
@@ -43261,7 +43281,7 @@ SYNCABLE_PROPS.forEach((prop) => {
|
|
|
43261
43281
|
new Box3();
|
|
43262
43282
|
new Color();
|
|
43263
43283
|
//#endregion
|
|
43264
|
-
//#region
|
|
43284
|
+
//#region src/renderer/shapes/tables.ts
|
|
43265
43285
|
var FONT_URL$2 = "/fonts/inter-medium.woff";
|
|
43266
43286
|
var TABLE_Z = .012;
|
|
43267
43287
|
var HEADER_Z = .014;
|
|
@@ -43610,7 +43630,7 @@ var TablesRenderer = class {
|
|
|
43610
43630
|
}
|
|
43611
43631
|
};
|
|
43612
43632
|
//#endregion
|
|
43613
|
-
//#region
|
|
43633
|
+
//#region src/renderer/text/textBlocks.ts
|
|
43614
43634
|
var FONT_URL$1 = "/fonts/inter-medium.woff";
|
|
43615
43635
|
var TEXT_Z = .02;
|
|
43616
43636
|
var FOCUS_COLOR$2 = 2450411;
|
|
@@ -43714,7 +43734,7 @@ var TextBlocksRenderer = class {
|
|
|
43714
43734
|
}
|
|
43715
43735
|
};
|
|
43716
43736
|
//#endregion
|
|
43717
|
-
//#region
|
|
43737
|
+
//#region src/renderer/shapes/comments.ts
|
|
43718
43738
|
var PIN_Z = .04;
|
|
43719
43739
|
var PIN_WIDTH = 3.6;
|
|
43720
43740
|
var PIN_HEIGHT = 3.6;
|
|
@@ -43882,7 +43902,7 @@ function drawBubblePath(ctx, x, y, w, h, r, tailX, tailY, tailW) {
|
|
|
43882
43902
|
ctx.closePath();
|
|
43883
43903
|
}
|
|
43884
43904
|
//#endregion
|
|
43885
|
-
//#region
|
|
43905
|
+
//#region src/renderer/shapes/images.ts
|
|
43886
43906
|
var IMAGE_Z = .015;
|
|
43887
43907
|
var FRAME_BORDER = .4;
|
|
43888
43908
|
var FOCUS_COLOR$1 = 2450411;
|
|
@@ -44092,7 +44112,7 @@ function applyPlaceholderTexture(visual, label) {
|
|
|
44092
44112
|
visual.imageMesh.material.needsUpdate = true;
|
|
44093
44113
|
}
|
|
44094
44114
|
//#endregion
|
|
44095
|
-
//#region
|
|
44115
|
+
//#region src/renderer/shapes/kitchenTimers.ts
|
|
44096
44116
|
var FACE_SIZE = 256;
|
|
44097
44117
|
var BODY_COLOR = 14753096;
|
|
44098
44118
|
var KNOB_COLOR = 16448250;
|
|
@@ -44290,7 +44310,7 @@ function renderTimerFace(timer, canvas, now = Date.now()) {
|
|
|
44290
44310
|
return c;
|
|
44291
44311
|
}
|
|
44292
44312
|
//#endregion
|
|
44293
|
-
//#region
|
|
44313
|
+
//#region src/renderer/shapes/customObjects.ts
|
|
44294
44314
|
var FONT_URL = "/fonts/inter-medium.woff";
|
|
44295
44315
|
var CUSTOM_Z = .02;
|
|
44296
44316
|
var FOCUS_COLOR = 2450411;
|
|
@@ -44652,7 +44672,7 @@ function disposeObject3D(obj) {
|
|
|
44652
44672
|
});
|
|
44653
44673
|
}
|
|
44654
44674
|
//#endregion
|
|
44655
|
-
//#region
|
|
44675
|
+
//#region src/interaction/pointer/hitTest.ts
|
|
44656
44676
|
/** Topmost (most recently added) stroke under the point, or null. */
|
|
44657
44677
|
function hitStroke(doc, index, p, slop) {
|
|
44658
44678
|
const candidates = index.query(p.x - slop, p.y - slop, p.x + slop, p.y + slop);
|
|
@@ -44693,7 +44713,7 @@ function distToSegmentSq(p, a, b) {
|
|
|
44693
44713
|
return dx * dx + dy * dy;
|
|
44694
44714
|
}
|
|
44695
44715
|
//#endregion
|
|
44696
|
-
//#region
|
|
44716
|
+
//#region src/interaction/tools/eraserTool.ts
|
|
44697
44717
|
var DECAY_PER_PASS = .4;
|
|
44698
44718
|
/** A point can take another decay pass after this long — rubbing works. */
|
|
44699
44719
|
var REARM_MS = 250;
|
|
@@ -44821,7 +44841,7 @@ function partitionByErasure(points) {
|
|
|
44821
44841
|
return runs;
|
|
44822
44842
|
}
|
|
44823
44843
|
//#endregion
|
|
44824
|
-
//#region
|
|
44844
|
+
//#region src/interaction/tools/noteDrag.ts
|
|
44825
44845
|
/**
|
|
44826
44846
|
* Drag the focused note in X/Y. The grab is resolved on the note's own
|
|
44827
44847
|
* z-plane, not the board, so the note doesn't jump under a tilted ray.
|
|
@@ -44888,7 +44908,7 @@ var NoteDragState = class {
|
|
|
44888
44908
|
}
|
|
44889
44909
|
};
|
|
44890
44910
|
//#endregion
|
|
44891
|
-
//#region
|
|
44911
|
+
//#region src/interaction/tools/imageDrag.ts
|
|
44892
44912
|
/** Drag the focused image in X/Y; one command per drag. */
|
|
44893
44913
|
var ImageDragState = class {
|
|
44894
44914
|
constructor(ctx) {
|
|
@@ -44940,7 +44960,7 @@ var ImageDragState = class {
|
|
|
44940
44960
|
}
|
|
44941
44961
|
};
|
|
44942
44962
|
//#endregion
|
|
44943
|
-
//#region
|
|
44963
|
+
//#region src/interaction/tools/timerDrag.ts
|
|
44944
44964
|
/** Drag the focused timer in X/Y; one command per drag. */
|
|
44945
44965
|
var TimerDragState = class {
|
|
44946
44966
|
constructor(ctx) {
|
|
@@ -44992,7 +45012,7 @@ var TimerDragState = class {
|
|
|
44992
45012
|
}
|
|
44993
45013
|
};
|
|
44994
45014
|
//#endregion
|
|
44995
|
-
//#region
|
|
45015
|
+
//#region src/interaction/tools/shapeGeometry.ts
|
|
44996
45016
|
/** Uniform synthetic pressure; the ink shader supplies the hand-drawn feel. */
|
|
44997
45017
|
var PRESSURE = .7;
|
|
44998
45018
|
var MIN_ELLIPSE_SEGMENTS = 24;
|
|
@@ -45181,7 +45201,7 @@ function snappedEnd(a, b) {
|
|
|
45181
45201
|
};
|
|
45182
45202
|
}
|
|
45183
45203
|
//#endregion
|
|
45184
|
-
//#region
|
|
45204
|
+
//#region src/interaction/tools/shapeTool.ts
|
|
45185
45205
|
var MIN_DRAG_PX$1 = 4;
|
|
45186
45206
|
/** Drag out a shape; live preview through the real ink material. */
|
|
45187
45207
|
var ShapeTool = class {
|
|
@@ -45212,7 +45232,7 @@ var ShapeTool = class {
|
|
|
45212
45232
|
const strokes = this.polylines.map((points) => ({
|
|
45213
45233
|
id: crypto.randomUUID(),
|
|
45214
45234
|
color: this.ctx.inkColor(),
|
|
45215
|
-
baseWidth: this.ctx.
|
|
45235
|
+
baseWidth: this.ctx.shapeStrokeWidth(),
|
|
45216
45236
|
points
|
|
45217
45237
|
}));
|
|
45218
45238
|
this.ctx.clusters.assign(strokes[0]);
|
|
@@ -45246,13 +45266,13 @@ var ShapeTool = class {
|
|
|
45246
45266
|
this.previews[i].visible = polyline !== void 0;
|
|
45247
45267
|
if (polyline) {
|
|
45248
45268
|
this.previews[i].geometry.dispose();
|
|
45249
|
-
this.previews[i].geometry = buildRibbonGeometry(polyline, this.ctx.
|
|
45269
|
+
this.previews[i].geometry = buildRibbonGeometry(polyline, this.ctx.shapeStrokeWidth());
|
|
45250
45270
|
}
|
|
45251
45271
|
}
|
|
45252
45272
|
}
|
|
45253
45273
|
};
|
|
45254
45274
|
//#endregion
|
|
45255
|
-
//#region
|
|
45275
|
+
//#region src/interaction/tools/tableDrag.ts
|
|
45256
45276
|
function getHandleCursor(handle) {
|
|
45257
45277
|
switch (handle) {
|
|
45258
45278
|
case "nw":
|
|
@@ -45372,7 +45392,7 @@ var TableDragState = class {
|
|
|
45372
45392
|
}
|
|
45373
45393
|
};
|
|
45374
45394
|
//#endregion
|
|
45375
|
-
//#region
|
|
45395
|
+
//#region src/interaction/tools/tableTool.ts
|
|
45376
45396
|
var MIN_DRAG_PX = 6;
|
|
45377
45397
|
var TableTool = class {
|
|
45378
45398
|
constructor(ctx) {
|
|
@@ -45503,7 +45523,7 @@ var TableTool = class {
|
|
|
45503
45523
|
}
|
|
45504
45524
|
};
|
|
45505
45525
|
//#endregion
|
|
45506
|
-
//#region
|
|
45526
|
+
//#region src/interaction/tools/commentTool.ts
|
|
45507
45527
|
/** Click on the board to drop a new comment pin or open an existing one. */
|
|
45508
45528
|
var CommentTool = class {
|
|
45509
45529
|
constructor(ctx) {
|
|
@@ -45538,7 +45558,7 @@ var CommentTool = class {
|
|
|
45538
45558
|
}
|
|
45539
45559
|
};
|
|
45540
45560
|
//#endregion
|
|
45541
|
-
//#region
|
|
45561
|
+
//#region src/interaction/tools/textDrag.ts
|
|
45542
45562
|
/** Drag the focused text block in X/Y; one command per drag. */
|
|
45543
45563
|
var TextDragState = class {
|
|
45544
45564
|
constructor(ctx) {
|
|
@@ -45590,7 +45610,7 @@ var TextDragState = class {
|
|
|
45590
45610
|
}
|
|
45591
45611
|
};
|
|
45592
45612
|
//#endregion
|
|
45593
|
-
//#region
|
|
45613
|
+
//#region src/interaction/tools/fsm.ts
|
|
45594
45614
|
var ToolStateMachine = class {
|
|
45595
45615
|
constructor() {
|
|
45596
45616
|
this.states = /* @__PURE__ */ new Map();
|
|
@@ -45792,7 +45812,7 @@ var IdleState = class {
|
|
|
45792
45812
|
}
|
|
45793
45813
|
};
|
|
45794
45814
|
//#endregion
|
|
45795
|
-
//#region
|
|
45815
|
+
//#region src/renderer/selection/gizmo.ts
|
|
45796
45816
|
var GIZMO_Z = .05;
|
|
45797
45817
|
var HANDLE_PX = 9;
|
|
45798
45818
|
var HANDLE_HIT_PX = 12;
|
|
@@ -46023,7 +46043,7 @@ function boxesEqual(a, b) {
|
|
|
46023
46043
|
return a.minX === b.minX && a.minY === b.minY && a.maxX === b.maxX && a.maxY === b.maxY;
|
|
46024
46044
|
}
|
|
46025
46045
|
//#endregion
|
|
46026
|
-
//#region
|
|
46046
|
+
//#region src/interaction/tools/pressure.ts
|
|
46027
46047
|
var SIM_MAX = 1;
|
|
46028
46048
|
var SIM_MIN = .3;
|
|
46029
46049
|
var SMOOTHING = .25;
|
|
@@ -46045,7 +46065,7 @@ function clamp(v, lo, hi) {
|
|
|
46045
46065
|
return Math.min(hi, Math.max(lo, v));
|
|
46046
46066
|
}
|
|
46047
46067
|
//#endregion
|
|
46048
|
-
//#region
|
|
46068
|
+
//#region src/interaction/tools/strokeBuilder.ts
|
|
46049
46069
|
var StrokeBuilder = class {
|
|
46050
46070
|
constructor() {
|
|
46051
46071
|
this.points = [];
|
|
@@ -46095,7 +46115,7 @@ function catmullRom(v0, v1, v2, v3, t) {
|
|
|
46095
46115
|
return .5 * (2 * v1 + (-v0 + v2) * t + (2 * v0 - 5 * v1 + 4 * v2 - v3) * t2 + (-v0 + 3 * v1 - 3 * v2 + v3) * t3);
|
|
46096
46116
|
}
|
|
46097
46117
|
//#endregion
|
|
46098
|
-
//#region
|
|
46118
|
+
//#region src/interaction/tools/markerTool.ts
|
|
46099
46119
|
/** Sample spacing while drawing, in screen pixels. */
|
|
46100
46120
|
var MIN_SAMPLE_PX = 1.5;
|
|
46101
46121
|
/** A highlighter is a chisel tip: near-constant width, little pressure play. */
|
|
@@ -46198,7 +46218,7 @@ var MarkerTool = class {
|
|
|
46198
46218
|
}
|
|
46199
46219
|
};
|
|
46200
46220
|
//#endregion
|
|
46201
|
-
//#region
|
|
46221
|
+
//#region src/interaction/tools/orbitTool.ts
|
|
46202
46222
|
/**
|
|
46203
46223
|
* Orbit-preview (build prompt §4.2): alt-drag tilts the camera off-axis to
|
|
46204
46224
|
* read the board's material and depth; releasing eases back to the working
|
|
@@ -46233,7 +46253,7 @@ var OrbitTool = class {
|
|
|
46233
46253
|
}
|
|
46234
46254
|
};
|
|
46235
46255
|
//#endregion
|
|
46236
|
-
//#region
|
|
46256
|
+
//#region src/interaction/tools/panTool.ts
|
|
46237
46257
|
/** Grab-pan: content follows the pointer. */
|
|
46238
46258
|
var PanTool = class {
|
|
46239
46259
|
constructor(ctx) {
|
|
@@ -46263,7 +46283,7 @@ var PanTool = class {
|
|
|
46263
46283
|
}
|
|
46264
46284
|
};
|
|
46265
46285
|
//#endregion
|
|
46266
|
-
//#region
|
|
46286
|
+
//#region src/renderer/selection/selection.ts
|
|
46267
46287
|
/** The set of selected stroke ids. Drops ids the document no longer has. */
|
|
46268
46288
|
var SelectionManager = class {
|
|
46269
46289
|
constructor(doc) {
|
|
@@ -46314,7 +46334,7 @@ var SelectionManager = class {
|
|
|
46314
46334
|
}
|
|
46315
46335
|
};
|
|
46316
46336
|
//#endregion
|
|
46317
|
-
//#region
|
|
46337
|
+
//#region src/interaction/tools/selectTool.ts
|
|
46318
46338
|
var HIT_SLOP_PX = 4;
|
|
46319
46339
|
var CLICK_TOLERANCE_PX = 3;
|
|
46320
46340
|
var MIN_SCALE = .05;
|
|
@@ -46530,7 +46550,7 @@ function safeRatio(numerator, denominator) {
|
|
|
46530
46550
|
return raw;
|
|
46531
46551
|
}
|
|
46532
46552
|
//#endregion
|
|
46533
|
-
//#region
|
|
46553
|
+
//#region src/interaction/tools/customTool.ts
|
|
46534
46554
|
function extensionIdFromToolId(toolId) {
|
|
46535
46555
|
const slash = toolId.indexOf("/");
|
|
46536
46556
|
return slash === -1 ? toolId : toolId.slice(0, slash);
|
|
@@ -46645,12 +46665,19 @@ var ExtensionCommandBatch = class {
|
|
|
46645
46665
|
}
|
|
46646
46666
|
};
|
|
46647
46667
|
//#endregion
|
|
46648
|
-
//#region
|
|
46668
|
+
//#region src/composition/ScrawlEngine.ts
|
|
46649
46669
|
/** Marker stroke width in board units (~1% of the default view height). */
|
|
46650
46670
|
var BASE_WIDTH = .5;
|
|
46651
46671
|
/** Highlighter chisel width — wide enough to cover a line of handwriting. */
|
|
46652
46672
|
var HIGHLIGHT_WIDTH = 2.2;
|
|
46653
46673
|
/**
|
|
46674
|
+
* Shape (rectangle, ellipse, arrow, ...) border width in board units.
|
|
46675
|
+
* Deliberately thinner than BASE_WIDTH: a shape border reads as a crisp,
|
|
46676
|
+
* structural line, not an expressive marker stroke — this is also the
|
|
46677
|
+
* fallback when no Host theme configures ScrawlTheme.shapeStrokeWidth.
|
|
46678
|
+
*/
|
|
46679
|
+
var DEFAULT_SHAPE_STROKE_WIDTH = .15;
|
|
46680
|
+
/**
|
|
46654
46681
|
* Identity of a rendered selection badge: which item, its lock state, and
|
|
46655
46682
|
* where it sits on screen (rounded to the pixel, so sub-pixel camera drift
|
|
46656
46683
|
* does not churn React).
|
|
@@ -46671,10 +46698,11 @@ function emptyExtensionRegistry() {
|
|
|
46671
46698
|
* React never reaches past this class.
|
|
46672
46699
|
*/
|
|
46673
46700
|
var ScrawlEngine = class {
|
|
46674
|
-
constructor(canvas, documentId$1, extensionRegistry = emptyExtensionRegistry(), assetController = new AssetController(void 0), boardTheme = DEFAULT_BOARD_SURFACE_THEME) {
|
|
46701
|
+
constructor(canvas, documentId$1, extensionRegistry = emptyExtensionRegistry(), assetController = new AssetController(void 0), boardTheme = DEFAULT_BOARD_SURFACE_THEME, shapeStrokeWidth = DEFAULT_SHAPE_STROKE_WIDTH) {
|
|
46675
46702
|
this.canvas = canvas;
|
|
46676
46703
|
this.extensionRegistry = extensionRegistry;
|
|
46677
46704
|
this.boardTheme = boardTheme;
|
|
46705
|
+
this.shapeStrokeWidth = shapeStrokeWidth;
|
|
46678
46706
|
this.onToolChange = null;
|
|
46679
46707
|
this.onZoomChange = null;
|
|
46680
46708
|
this.onAuditEvent = null;
|
|
@@ -46769,6 +46797,7 @@ var ScrawlEngine = class {
|
|
|
46769
46797
|
setTool: (t) => this.setTool(t),
|
|
46770
46798
|
inkColor: () => this.tool === "highlighter" ? this.highlightColor : this.color,
|
|
46771
46799
|
baseWidth: () => this.tool === "highlighter" ? HIGHLIGHT_WIDTH : BASE_WIDTH,
|
|
46800
|
+
shapeStrokeWidth: () => this.shapeStrokeWidth,
|
|
46772
46801
|
activeTool: () => this.tool,
|
|
46773
46802
|
isSpaceHeld: () => this.spaceHeld,
|
|
46774
46803
|
pointerToBoard: (e) => pointerToBoard(e.clientX, e.clientY, canvas, this.scene.cameraRig.camera),
|
|
@@ -47033,6 +47062,10 @@ var ScrawlEngine = class {
|
|
|
47033
47062
|
this.boardTheme = theme;
|
|
47034
47063
|
this.scene.applyBoardTheme(theme);
|
|
47035
47064
|
}
|
|
47065
|
+
/** Live update of the shape tool's border width (board units). Already-drawn shapes keep the width they were drawn with. */
|
|
47066
|
+
setShapeStrokeWidth(width) {
|
|
47067
|
+
this.shapeStrokeWidth = width;
|
|
47068
|
+
}
|
|
47036
47069
|
/**
|
|
47037
47070
|
* Snap to a peer's camera. No-op while drawing so pointer-to-board
|
|
47038
47071
|
* mapping does not warp the in-progress stroke.
|
|
@@ -48094,7 +48127,7 @@ var ScrawlEngine = class {
|
|
|
48094
48127
|
}
|
|
48095
48128
|
};
|
|
48096
48129
|
//#endregion
|
|
48097
|
-
//#region src/controller-internal.ts
|
|
48130
|
+
//#region src/composition/controller-internal.ts
|
|
48098
48131
|
function createBoardController(options) {
|
|
48099
48132
|
return createBoardControllerWithEngine(options);
|
|
48100
48133
|
}
|
|
@@ -48112,9 +48145,12 @@ function createBoardControllerWithEngine(options, existingEngine) {
|
|
|
48112
48145
|
color: options.boardTheme?.surface ?? DEFAULT_BOARD_SURFACE_THEME.color,
|
|
48113
48146
|
gridMode: options.boardTheme?.gridMode ?? DEFAULT_BOARD_SURFACE_THEME.gridMode,
|
|
48114
48147
|
gridColor: options.boardTheme?.gridColor ?? DEFAULT_BOARD_SURFACE_THEME.gridColor,
|
|
48115
|
-
gridSpacing: options.boardTheme?.gridSpacing ?? DEFAULT_BOARD_SURFACE_THEME.gridSpacing
|
|
48148
|
+
gridSpacing: options.boardTheme?.gridSpacing ?? DEFAULT_BOARD_SURFACE_THEME.gridSpacing,
|
|
48149
|
+
gridLineWidth: options.boardTheme?.gridLineWidth ?? DEFAULT_BOARD_SURFACE_THEME.gridLineWidth,
|
|
48150
|
+
surfaceTexture: options.boardTheme?.surfaceTexture ?? DEFAULT_BOARD_SURFACE_THEME.surfaceTexture
|
|
48116
48151
|
};
|
|
48117
|
-
|
|
48152
|
+
let currentShapeStrokeWidth = options.boardTheme?.shapeStrokeWidth ?? .15;
|
|
48153
|
+
const engine = existingEngine ?? (options.canvas ? new ScrawlEngine(options.canvas, options.document.id, extensionRegistry, assetController, currentBoardTheme, currentShapeStrokeWidth) : null);
|
|
48118
48154
|
const document = engine?.document ?? new BoardDocument(documentId(options.document.id));
|
|
48119
48155
|
const history = engine?.history ?? new History(document);
|
|
48120
48156
|
const createId = options.createId ?? (() => crypto.randomUUID());
|
|
@@ -48603,9 +48639,15 @@ function createBoardControllerWithEngine(options, existingEngine) {
|
|
|
48603
48639
|
color: theme.surface ?? currentBoardTheme.color,
|
|
48604
48640
|
gridMode: theme.gridMode ?? currentBoardTheme.gridMode,
|
|
48605
48641
|
gridColor: theme.gridColor ?? currentBoardTheme.gridColor,
|
|
48606
|
-
gridSpacing: theme.gridSpacing ?? currentBoardTheme.gridSpacing
|
|
48642
|
+
gridSpacing: theme.gridSpacing ?? currentBoardTheme.gridSpacing,
|
|
48643
|
+
gridLineWidth: theme.gridLineWidth ?? currentBoardTheme.gridLineWidth,
|
|
48644
|
+
surfaceTexture: theme.surfaceTexture ?? currentBoardTheme.surfaceTexture
|
|
48607
48645
|
};
|
|
48608
48646
|
engine?.applyBoardTheme(currentBoardTheme);
|
|
48647
|
+
if (theme.shapeStrokeWidth !== void 0) {
|
|
48648
|
+
currentShapeStrokeWidth = theme.shapeStrokeWidth;
|
|
48649
|
+
engine?.setShapeStrokeWidth(currentShapeStrokeWidth);
|
|
48650
|
+
}
|
|
48609
48651
|
} },
|
|
48610
48652
|
view: {
|
|
48611
48653
|
fit() {
|
|
@@ -49376,7 +49418,7 @@ function createLocalBoard(options) {
|
|
|
49376
49418
|
};
|
|
49377
49419
|
}
|
|
49378
49420
|
//#endregion
|
|
49379
|
-
//#region src/theme.ts
|
|
49421
|
+
//#region src/ui/theme.ts
|
|
49380
49422
|
var scrawlThemePresets = Object.freeze({
|
|
49381
49423
|
light: Object.freeze({
|
|
49382
49424
|
surface: "#ffffff",
|
|
@@ -49403,9 +49445,12 @@ var scrawlThemePresets = Object.freeze({
|
|
|
49403
49445
|
motionEasing: "cubic-bezier(0.2, 0, 0, 1)",
|
|
49404
49446
|
density: "comfortable",
|
|
49405
49447
|
boardSurface: "#f5f5f3",
|
|
49448
|
+
boardSurfaceTexture: "flat",
|
|
49406
49449
|
gridMode: "none",
|
|
49407
49450
|
gridColor: "#deded8",
|
|
49408
|
-
gridSpacing: 5
|
|
49451
|
+
gridSpacing: 5,
|
|
49452
|
+
gridLineWidth: 1,
|
|
49453
|
+
shapeStrokeWidth: .15
|
|
49409
49454
|
}),
|
|
49410
49455
|
dark: Object.freeze({
|
|
49411
49456
|
surface: "#171816",
|
|
@@ -49432,9 +49477,12 @@ var scrawlThemePresets = Object.freeze({
|
|
|
49432
49477
|
motionEasing: "cubic-bezier(0.2, 0, 0, 1)",
|
|
49433
49478
|
density: "comfortable",
|
|
49434
49479
|
boardSurface: "#232420",
|
|
49480
|
+
boardSurfaceTexture: "flat",
|
|
49435
49481
|
gridMode: "none",
|
|
49436
49482
|
gridColor: "#33352f",
|
|
49437
|
-
gridSpacing: 5
|
|
49483
|
+
gridSpacing: 5,
|
|
49484
|
+
gridLineWidth: 1,
|
|
49485
|
+
shapeStrokeWidth: .15
|
|
49438
49486
|
})
|
|
49439
49487
|
});
|
|
49440
49488
|
var variableNames = {
|
|
@@ -49462,9 +49510,12 @@ var variableNames = {
|
|
|
49462
49510
|
motionEasing: "--scrawl-motion-easing",
|
|
49463
49511
|
density: "--scrawl-density",
|
|
49464
49512
|
boardSurface: "--scrawl-board-surface",
|
|
49513
|
+
boardSurfaceTexture: "--scrawl-board-surface-texture",
|
|
49465
49514
|
gridMode: "--scrawl-grid-mode",
|
|
49466
49515
|
gridColor: "--scrawl-grid-color",
|
|
49467
|
-
gridSpacing: "--scrawl-grid-spacing"
|
|
49516
|
+
gridSpacing: "--scrawl-grid-spacing",
|
|
49517
|
+
gridLineWidth: "--scrawl-grid-line-width",
|
|
49518
|
+
shapeStrokeWidth: "--scrawl-shape-stroke-width"
|
|
49468
49519
|
};
|
|
49469
49520
|
var colorTokens = /* @__PURE__ */ new Set([
|
|
49470
49521
|
"surface",
|
|
@@ -49520,10 +49571,22 @@ function validateScrawlTheme(theme) {
|
|
|
49520
49571
|
token,
|
|
49521
49572
|
message: "Expected none, line, or dot"
|
|
49522
49573
|
});
|
|
49574
|
+
else if (token === "boardSurfaceTexture" && value !== "flat" && value !== "textured") diagnostics.push({
|
|
49575
|
+
token,
|
|
49576
|
+
message: "Expected flat or textured"
|
|
49577
|
+
});
|
|
49523
49578
|
else if (token === "gridSpacing" && (!finiteNumber(value) || value < .5 || value > 50)) diagnostics.push({
|
|
49524
49579
|
token,
|
|
49525
49580
|
message: "Expected spacing 0.5-50 board units"
|
|
49526
49581
|
});
|
|
49582
|
+
else if (token === "gridLineWidth" && (!finiteNumber(value) || value < .5 || value > 8)) diagnostics.push({
|
|
49583
|
+
token,
|
|
49584
|
+
message: "Expected line width 0.5-8px"
|
|
49585
|
+
});
|
|
49586
|
+
else if (token === "shapeStrokeWidth" && (!finiteNumber(value) || value < .01 || value > 5)) diagnostics.push({
|
|
49587
|
+
token,
|
|
49588
|
+
message: "Expected stroke width 0.01-5 board units"
|
|
49589
|
+
});
|
|
49527
49590
|
else if ((token.endsWith("Family") || token.startsWith("elevation") || token === "motionEasing") && (typeof value !== "string" || !value.trim() || /[;{}]/.test(value))) diagnostics.push({
|
|
49528
49591
|
token,
|
|
49529
49592
|
message: "Expected a safe CSS value"
|
|
@@ -49594,12 +49657,12 @@ function luminance(color) {
|
|
|
49594
49657
|
return channels[0] * .2126 + channels[1] * .7152 + channels[2] * .0722;
|
|
49595
49658
|
}
|
|
49596
49659
|
function formatValue(token, value) {
|
|
49597
|
-
if (token === "baseFontSize" || token === "controlRadius" || token === "panelRadius") return `${value}px`;
|
|
49660
|
+
if (token === "baseFontSize" || token === "controlRadius" || token === "panelRadius" || token === "gridLineWidth") return `${value}px`;
|
|
49598
49661
|
if (token === "motionDuration") return `${value}ms`;
|
|
49599
49662
|
return String(value);
|
|
49600
49663
|
}
|
|
49601
49664
|
//#endregion
|
|
49602
|
-
//#region src/inline-editing.tsx
|
|
49665
|
+
//#region src/ui/dialogs/inline-editing.tsx
|
|
49603
49666
|
/** Inline note, text, and table-cell editors — driven entirely by public controller events and commands. */
|
|
49604
49667
|
function InlineEditors({ controller, renderPortal }) {
|
|
49605
49668
|
const [editor, setEditor] = useState(null);
|
|
@@ -49830,7 +49893,7 @@ function InlineEditors({ controller, renderPortal }) {
|
|
|
49830
49893
|
}))] });
|
|
49831
49894
|
}
|
|
49832
49895
|
//#endregion
|
|
49833
|
-
//#region src/style-shelf.tsx
|
|
49896
|
+
//#region src/ui/toolbar/style-shelf.tsx
|
|
49834
49897
|
var ERASER_RADII = [
|
|
49835
49898
|
["Fine", 1],
|
|
49836
49899
|
["Medium", 2],
|
|
@@ -49993,7 +50056,7 @@ function StyleShelf({ controller, snapshot }) {
|
|
|
49993
50056
|
});
|
|
49994
50057
|
}
|
|
49995
50058
|
//#endregion
|
|
49996
|
-
//#region src/default-ui.tsx
|
|
50059
|
+
//#region src/ui/default-ui.tsx
|
|
49997
50060
|
var PRIMARY_TOOLS = [
|
|
49998
50061
|
{
|
|
49999
50062
|
tool: "select",
|
|
@@ -50522,7 +50585,7 @@ function download(blob, name) {
|
|
|
50522
50585
|
URL.revokeObjectURL(url);
|
|
50523
50586
|
}
|
|
50524
50587
|
//#endregion
|
|
50525
|
-
//#region src/presence.tsx
|
|
50588
|
+
//#region src/ui/panels/presence.tsx
|
|
50526
50589
|
var labelStyle = {
|
|
50527
50590
|
borderRadius: 999,
|
|
50528
50591
|
color: "#fff",
|
|
@@ -50682,9 +50745,12 @@ function ScrawlProvider({ controller, children, preset = "light", theme, portalC
|
|
|
50682
50745
|
useEffect(() => {
|
|
50683
50746
|
controller.boardTheme.set({
|
|
50684
50747
|
surface: resolved.values.boardSurface,
|
|
50748
|
+
surfaceTexture: resolved.values.boardSurfaceTexture,
|
|
50685
50749
|
gridMode: resolved.values.gridMode,
|
|
50686
50750
|
gridColor: resolved.values.gridColor,
|
|
50687
|
-
gridSpacing: resolved.values.gridSpacing
|
|
50751
|
+
gridSpacing: resolved.values.gridSpacing,
|
|
50752
|
+
gridLineWidth: resolved.values.gridLineWidth,
|
|
50753
|
+
shapeStrokeWidth: resolved.values.shapeStrokeWidth
|
|
50688
50754
|
});
|
|
50689
50755
|
}, [controller, resolved]);
|
|
50690
50756
|
useDeferredDisposal(controller, disposeOnUnmount);
|
|
@@ -50737,9 +50803,12 @@ function Scrawl({ children, preset, theme, portalContainer, className, style, on
|
|
|
50737
50803
|
const resolved = resolveScrawlTheme(preset, theme);
|
|
50738
50804
|
const boardTheme = {
|
|
50739
50805
|
surface: resolved.values.boardSurface,
|
|
50806
|
+
surfaceTexture: resolved.values.boardSurfaceTexture,
|
|
50740
50807
|
gridMode: resolved.values.gridMode,
|
|
50741
50808
|
gridColor: resolved.values.gridColor,
|
|
50742
|
-
gridSpacing: resolved.values.gridSpacing
|
|
50809
|
+
gridSpacing: resolved.values.gridSpacing,
|
|
50810
|
+
gridLineWidth: resolved.values.gridLineWidth,
|
|
50811
|
+
shapeStrokeWidth: resolved.values.shapeStrokeWidth
|
|
50743
50812
|
};
|
|
50744
50813
|
controller = createBoardController({
|
|
50745
50814
|
...options,
|