@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/react.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
|
function isAssetRef(value) {
|
|
7
7
|
return typeof value === "string" && ASSET_REF_PATTERN.test(value) && new TextEncoder().encode(value).length <= 512;
|
|
@@ -33,7 +33,7 @@ function clampAssetCacheBytes(value) {
|
|
|
33
33
|
return Math.min(ASSET_CACHE_BYTES_MAX, Math.max(ASSET_CACHE_BYTES_MIN, Math.floor(value)));
|
|
34
34
|
}
|
|
35
35
|
//#endregion
|
|
36
|
-
//#region src/core
|
|
36
|
+
//#region src/core/document/identifiers.ts
|
|
37
37
|
function documentId(value) {
|
|
38
38
|
if (!value) throw new TypeError("DocumentId cannot be empty");
|
|
39
39
|
return value;
|
|
@@ -234,7 +234,7 @@ function validation(message, path) {
|
|
|
234
234
|
return new DocumentRecoveryError("DOCUMENT_VALIDATION_FAILED", message, void 0, path);
|
|
235
235
|
}
|
|
236
236
|
//#endregion
|
|
237
|
-
//#region src/core
|
|
237
|
+
//#region src/core/shapes/affine2d.ts
|
|
238
238
|
var IDENTITY = [
|
|
239
239
|
1,
|
|
240
240
|
0,
|
|
@@ -318,7 +318,7 @@ function avgScale(m) {
|
|
|
318
318
|
return (Math.hypot(m[0], m[1]) + Math.hypot(m[2], m[3])) / 2;
|
|
319
319
|
}
|
|
320
320
|
//#endregion
|
|
321
|
-
//#region src/core
|
|
321
|
+
//#region src/core/document/boardSearch.ts
|
|
322
322
|
function hay(s) {
|
|
323
323
|
return s.toLowerCase();
|
|
324
324
|
}
|
|
@@ -383,7 +383,7 @@ function searchBoard(query, board) {
|
|
|
383
383
|
return hits;
|
|
384
384
|
}
|
|
385
385
|
//#endregion
|
|
386
|
-
//#region src/core
|
|
386
|
+
//#region src/core/shapes/types.ts
|
|
387
387
|
/** Erasure level at which a point counts as fully erased. */
|
|
388
388
|
var ERASE_THRESHOLD = .95;
|
|
389
389
|
function cloneStroke(stroke) {
|
|
@@ -455,7 +455,7 @@ function cloneImage(img) {
|
|
|
455
455
|
return { ...img };
|
|
456
456
|
}
|
|
457
457
|
//#endregion
|
|
458
|
-
//#region src/core
|
|
458
|
+
//#region src/core/document/clusterStore.ts
|
|
459
459
|
/** A stroke joins a cluster last written to within this window at full reach. */
|
|
460
460
|
var RECENT_MS = 8e3;
|
|
461
461
|
/** Older clusters are still joinable, at half the gap threshold. */
|
|
@@ -626,7 +626,7 @@ function clamp$3(v, lo, hi) {
|
|
|
626
626
|
return Math.min(hi, Math.max(lo, v));
|
|
627
627
|
}
|
|
628
628
|
//#endregion
|
|
629
|
-
//#region src/core
|
|
629
|
+
//#region src/core/shapes/extensionTypes.ts
|
|
630
630
|
function cloneCustomObject(object) {
|
|
631
631
|
return {
|
|
632
632
|
...object,
|
|
@@ -636,7 +636,7 @@ function cloneCustomObject(object) {
|
|
|
636
636
|
};
|
|
637
637
|
}
|
|
638
638
|
//#endregion
|
|
639
|
-
//#region src/core
|
|
639
|
+
//#region src/core/shapes/kitchenTimer.ts
|
|
640
640
|
var TIMER_DEFAULT_DURATION_MS = 300 * 1e3;
|
|
641
641
|
var TIMER_PRESETS_MS = [
|
|
642
642
|
6e4,
|
|
@@ -692,7 +692,7 @@ function formatTimer(ms) {
|
|
|
692
692
|
return `${Math.floor(total / 60)}:${(total % 60).toString().padStart(2, "0")}`;
|
|
693
693
|
}
|
|
694
694
|
//#endregion
|
|
695
|
-
//#region src/core
|
|
695
|
+
//#region src/core/shapes/itemLock.ts
|
|
696
696
|
/**
|
|
697
697
|
* Apply or clear a lock in place. Unlock always drops the holder so a stale
|
|
698
698
|
* name cannot linger on an unlocked item.
|
|
@@ -729,7 +729,7 @@ function serializeLock(item) {
|
|
|
729
729
|
};
|
|
730
730
|
}
|
|
731
731
|
//#endregion
|
|
732
|
-
//#region src/core
|
|
732
|
+
//#region src/core/document/document.ts
|
|
733
733
|
/**
|
|
734
734
|
* The one place a live Stroke becomes its wire representation — in
|
|
735
735
|
* particular, points collapse from {x,y,pressure,erase?} objects into
|
|
@@ -1288,7 +1288,7 @@ function computeBBox(stroke) {
|
|
|
1288
1288
|
return world;
|
|
1289
1289
|
}
|
|
1290
1290
|
//#endregion
|
|
1291
|
-
//#region src/core
|
|
1291
|
+
//#region src/core/commands/commands.ts
|
|
1292
1292
|
/** One drawing action — a marker stroke, or a shape's strokes as one unit. */
|
|
1293
1293
|
var AddStrokesCommand = class {
|
|
1294
1294
|
constructor(strokes) {
|
|
@@ -1630,7 +1630,7 @@ var LockItemsCommand = class {
|
|
|
1630
1630
|
}
|
|
1631
1631
|
};
|
|
1632
1632
|
//#endregion
|
|
1633
|
-
//#region src/core
|
|
1633
|
+
//#region src/core/history/history.ts
|
|
1634
1634
|
var LIMIT = 200;
|
|
1635
1635
|
var History = class {
|
|
1636
1636
|
constructor(doc) {
|
|
@@ -1691,7 +1691,7 @@ var History = class {
|
|
|
1691
1691
|
}
|
|
1692
1692
|
};
|
|
1693
1693
|
//#endregion
|
|
1694
|
-
//#region src/core
|
|
1694
|
+
//#region src/core/events/ops.ts
|
|
1695
1695
|
var ADDED = [
|
|
1696
1696
|
["added", "strokes"],
|
|
1697
1697
|
["notesAdded", "notes"],
|
|
@@ -1745,7 +1745,7 @@ function changeToOps(change, restoring = false) {
|
|
|
1745
1745
|
return ops;
|
|
1746
1746
|
}
|
|
1747
1747
|
//#endregion
|
|
1748
|
-
//#region src/core
|
|
1748
|
+
//#region src/core/shapes/ribbonEdges.ts
|
|
1749
1749
|
var MIN_WIDTH_FACTOR = .35;
|
|
1750
1750
|
var END_TAPER = .55;
|
|
1751
1751
|
function ribbonEdges(points, baseWidth) {
|
|
@@ -1777,7 +1777,7 @@ function ribbonEdges(points, baseWidth) {
|
|
|
1777
1777
|
return out;
|
|
1778
1778
|
}
|
|
1779
1779
|
//#endregion
|
|
1780
|
-
//#region src/core
|
|
1780
|
+
//#region src/core/document/spatialIndex.ts
|
|
1781
1781
|
var CELL = 8;
|
|
1782
1782
|
var SpatialIndex = class {
|
|
1783
1783
|
constructor(doc) {
|
|
@@ -1850,7 +1850,7 @@ function cellsOf(box) {
|
|
|
1850
1850
|
return keys;
|
|
1851
1851
|
}
|
|
1852
1852
|
//#endregion
|
|
1853
|
-
//#region src/core
|
|
1853
|
+
//#region src/core/shapes/stamps.ts
|
|
1854
1854
|
var STAMPS = [
|
|
1855
1855
|
{
|
|
1856
1856
|
kind: "star",
|
|
@@ -1895,7 +1895,7 @@ function stampDataUrl(kind) {
|
|
|
1895
1895
|
return `data:image/svg+xml;utf8,${encodeURIComponent(SVG[kind])}`;
|
|
1896
1896
|
}
|
|
1897
1897
|
//#endregion
|
|
1898
|
-
//#region src/
|
|
1898
|
+
//#region src/collaboration/presence/presence.ts
|
|
1899
1899
|
/** Keep beacons clear of typical chrome at the top and bottom of the Board. */
|
|
1900
1900
|
var BEACON_INSET = {
|
|
1901
1901
|
top: 72,
|
|
@@ -1931,7 +1931,7 @@ function clamp$2(value, min, max) {
|
|
|
1931
1931
|
return Math.min(max, Math.max(min, value));
|
|
1932
1932
|
}
|
|
1933
1933
|
//#endregion
|
|
1934
|
-
//#region src/
|
|
1934
|
+
//#region src/persistence/serialization/svg.ts
|
|
1935
1935
|
/** Matches the key light used by the board shader and note shadows. */
|
|
1936
1936
|
var LIGHT = {
|
|
1937
1937
|
x: -.25,
|
|
@@ -2298,7 +2298,7 @@ function fmt(n) {
|
|
|
2298
2298
|
return String(Math.round(n * 100) / 100);
|
|
2299
2299
|
}
|
|
2300
2300
|
//#endregion
|
|
2301
|
-
//#region src/core
|
|
2301
|
+
//#region src/core/shapes/sceneGeometry.ts
|
|
2302
2302
|
var EMPTY_BOUNDS = {
|
|
2303
2303
|
x: 0,
|
|
2304
2304
|
y: 0,
|
|
@@ -2362,7 +2362,7 @@ function textCorners(x, y, text, fontSize, align, m) {
|
|
|
2362
2362
|
return rectCorners(x + (align === "center" ? -width / 2 : align === "end" ? -width : 0), y, width, height, m);
|
|
2363
2363
|
}
|
|
2364
2364
|
//#endregion
|
|
2365
|
-
//#region src/core
|
|
2365
|
+
//#region src/core/shapes/customObjects.ts
|
|
2366
2366
|
var FALLBACK_LABEL_MAX_LENGTH = 80;
|
|
2367
2367
|
function toReadonly(object) {
|
|
2368
2368
|
return object;
|
|
@@ -2491,7 +2491,7 @@ function extensionIdFromType(type) {
|
|
|
2491
2491
|
return slash === -1 ? type : type.slice(0, slash);
|
|
2492
2492
|
}
|
|
2493
2493
|
//#endregion
|
|
2494
|
-
//#region src/core
|
|
2494
|
+
//#region src/core/shapes/extensionRegistry.ts
|
|
2495
2495
|
function buildExtensionRegistry(extensions) {
|
|
2496
2496
|
const list = extensions ?? [];
|
|
2497
2497
|
const diagnostics = [];
|
|
@@ -2588,7 +2588,7 @@ function isWellFormedNamespacedId(id) {
|
|
|
2588
2588
|
return isWellFormedId(id) && id.includes("/") && !id.startsWith("/") && !id.endsWith("/");
|
|
2589
2589
|
}
|
|
2590
2590
|
//#endregion
|
|
2591
|
-
//#region src/
|
|
2591
|
+
//#region src/persistence/adapters/assetValidation.ts
|
|
2592
2592
|
function sniffImageMediaType(bytes) {
|
|
2593
2593
|
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";
|
|
2594
2594
|
if (bytes.length >= 3 && bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) return "image/jpeg";
|
|
@@ -2675,7 +2675,7 @@ function validateDecodedDimensions(width, height) {
|
|
|
2675
2675
|
};
|
|
2676
2676
|
}
|
|
2677
2677
|
//#endregion
|
|
2678
|
-
//#region src/assetController.ts
|
|
2678
|
+
//#region src/persistence/adapters/assetController.ts
|
|
2679
2679
|
var FAILURE_COALESCE_MS = 4e3;
|
|
2680
2680
|
var AssetController = class {
|
|
2681
2681
|
constructor(resolver, options) {
|
|
@@ -2854,7 +2854,7 @@ function toAssetResolutionError(cause, ref) {
|
|
|
2854
2854
|
return new AssetResolutionError("unknown", true, cause instanceof Error ? cause.message : String(cause), ref);
|
|
2855
2855
|
}
|
|
2856
2856
|
//#endregion
|
|
2857
|
-
//#region src/
|
|
2857
|
+
//#region src/persistence/serialization/assetRefCollector.ts
|
|
2858
2858
|
/** Every unique Asset reference in the document, and which object(s) use it. */
|
|
2859
2859
|
function collectDocumentAssetRefs(doc, registry) {
|
|
2860
2860
|
const refs = /* @__PURE__ */ new Map();
|
|
@@ -2881,7 +2881,7 @@ function collectSceneAssetRefs(node, objectId, add) {
|
|
|
2881
2881
|
if (node.kind === "group") for (const child of node.children) collectSceneAssetRefs(child, objectId, add);
|
|
2882
2882
|
}
|
|
2883
2883
|
//#endregion
|
|
2884
|
-
//#region src/assetExport.ts
|
|
2884
|
+
//#region src/persistence/serialization/assetExport.ts
|
|
2885
2885
|
/** Strict mode's rejection — never contains credentials, a fetchable location, or a raw resolver message. */
|
|
2886
2886
|
var SvgAssetExportError = class extends Error {
|
|
2887
2887
|
constructor(missingAssets) {
|
|
@@ -2937,7 +2937,7 @@ function toDataUri(bytes, mediaType) {
|
|
|
2937
2937
|
return `data:${mediaType};base64,${btoa(binary)}`;
|
|
2938
2938
|
}
|
|
2939
2939
|
//#endregion
|
|
2940
|
-
//#region src/assetIngestion.ts
|
|
2940
|
+
//#region src/persistence/adapters/assetIngestion.ts
|
|
2941
2941
|
async function decodeDimensionsWithImageBitmap(bytes, mediaType) {
|
|
2942
2942
|
const blob = new Blob([bytes], { type: mediaType });
|
|
2943
2943
|
let bitmap;
|
|
@@ -35583,7 +35583,7 @@ var WebGLRenderer = class {
|
|
|
35583
35583
|
}
|
|
35584
35584
|
};
|
|
35585
35585
|
//#endregion
|
|
35586
|
-
//#region
|
|
35586
|
+
//#region src/core/events/auditEvents.ts
|
|
35587
35587
|
var BY_LABEL = {
|
|
35588
35588
|
draw: {
|
|
35589
35589
|
action: "create",
|
|
@@ -35703,7 +35703,7 @@ function lowerFirst(s) {
|
|
|
35703
35703
|
return s.charAt(0).toLowerCase() + s.slice(1);
|
|
35704
35704
|
}
|
|
35705
35705
|
//#endregion
|
|
35706
|
-
//#region
|
|
35706
|
+
//#region src/renderer/shapes/AssetTextureCache.ts
|
|
35707
35707
|
var AssetTextureCache = class {
|
|
35708
35708
|
constructor(assetController) {
|
|
35709
35709
|
this.assetController = assetController;
|
|
@@ -35794,7 +35794,7 @@ function toDecodeError(cause, ref) {
|
|
|
35794
35794
|
return new AssetResolutionError("decode-failed", false, cause instanceof Error ? cause.message : String(cause), ref);
|
|
35795
35795
|
}
|
|
35796
35796
|
//#endregion
|
|
35797
|
-
//#region
|
|
35797
|
+
//#region src/renderer/canvas/raycast.ts
|
|
35798
35798
|
var origin$1 = new Vector3();
|
|
35799
35799
|
var target = new Vector3();
|
|
35800
35800
|
function pointerToBoard(clientX, clientY, canvas, camera) {
|
|
@@ -35825,7 +35825,7 @@ function pointerToPlane(clientX, clientY, canvas, camera, z) {
|
|
|
35825
35825
|
};
|
|
35826
35826
|
}
|
|
35827
35827
|
//#endregion
|
|
35828
|
-
//#region
|
|
35828
|
+
//#region src/renderer/canvas/fog.ts
|
|
35829
35829
|
function createFogUniforms(color) {
|
|
35830
35830
|
return {
|
|
35831
35831
|
uFogColor: { value: new Color(color) },
|
|
@@ -35846,18 +35846,24 @@ var FOG_GLSL = `
|
|
|
35846
35846
|
}
|
|
35847
35847
|
`;
|
|
35848
35848
|
//#endregion
|
|
35849
|
-
//#region
|
|
35849
|
+
//#region src/renderer/canvas/boardSurface.ts
|
|
35850
35850
|
var GRID_MODE_CODE = {
|
|
35851
35851
|
none: 0,
|
|
35852
35852
|
line: 1,
|
|
35853
35853
|
dot: 2
|
|
35854
35854
|
};
|
|
35855
|
+
var TEXTURE_CODE = {
|
|
35856
|
+
flat: 0,
|
|
35857
|
+
textured: 1
|
|
35858
|
+
};
|
|
35855
35859
|
/** Used when a caller doesn't supply one (e.g. ScrawlEngine constructed without a Host theme). */
|
|
35856
35860
|
var DEFAULT_BOARD_SURFACE_THEME = {
|
|
35857
35861
|
color: "#f5f5f3",
|
|
35858
35862
|
gridMode: "none",
|
|
35859
35863
|
gridColor: "#deded8",
|
|
35860
|
-
gridSpacing: 5
|
|
35864
|
+
gridSpacing: 5,
|
|
35865
|
+
gridLineWidth: 1,
|
|
35866
|
+
surfaceTexture: "flat"
|
|
35861
35867
|
};
|
|
35862
35868
|
/** Grid alpha fades out below this on-screen spacing (px) — otherwise it aliases into a solid wash when zoomed out. */
|
|
35863
35869
|
var GRID_FADE_MIN_PX = 3;
|
|
@@ -35878,8 +35884,10 @@ var FRAGMENT = `
|
|
|
35878
35884
|
uniform float uGridMode;
|
|
35879
35885
|
uniform vec3 uGridColor;
|
|
35880
35886
|
uniform float uGridSpacing;
|
|
35881
|
-
uniform float
|
|
35887
|
+
uniform float uWorldPerPixel;
|
|
35888
|
+
uniform float uGridLineWidthPx;
|
|
35882
35889
|
uniform float uGridFade;
|
|
35890
|
+
uniform float uSurfaceTexture;
|
|
35883
35891
|
varying vec3 vWorldPos;
|
|
35884
35892
|
|
|
35885
35893
|
float hash(vec2 p) {
|
|
@@ -35899,37 +35907,45 @@ var FRAGMENT = `
|
|
|
35899
35907
|
${FOG_GLSL}
|
|
35900
35908
|
|
|
35901
35909
|
// Distance from p's nearest axis-aligned grid line, in world units.
|
|
35910
|
+
// A crisp, ~uGridLineWidthPx-wide line: full alpha to its half-width, a
|
|
35911
|
+
// ~1px anti-aliased falloff beyond that — not a wide, soft-edged band.
|
|
35902
35912
|
float gridLineAlpha(vec2 p) {
|
|
35903
35913
|
vec2 cell = mod(p, uGridSpacing);
|
|
35904
35914
|
vec2 distToLine = min(cell, uGridSpacing - cell);
|
|
35905
|
-
|
|
35915
|
+
float halfWidth = 0.5 * uGridLineWidthPx * uWorldPerPixel;
|
|
35916
|
+
float aa = uWorldPerPixel;
|
|
35917
|
+
vec2 lineAlpha2 = 1.0 - smoothstep(halfWidth - aa * 0.5, halfWidth + aa * 0.5, distToLine);
|
|
35906
35918
|
return max(lineAlpha2.x, lineAlpha2.y);
|
|
35907
35919
|
}
|
|
35908
35920
|
|
|
35909
|
-
// Distance from p's nearest grid intersection, in world units.
|
|
35921
|
+
// Distance from p's nearest grid intersection, in world units. Dot radius
|
|
35922
|
+
// matches the configured line width in pixels, same anti-aliasing.
|
|
35910
35923
|
float gridDotAlpha(vec2 p) {
|
|
35911
35924
|
vec2 cell = mod(p, uGridSpacing) - uGridSpacing * 0.5;
|
|
35912
35925
|
float dist = length(cell);
|
|
35913
|
-
float radius =
|
|
35914
|
-
|
|
35926
|
+
float radius = uGridLineWidthPx * uWorldPerPixel;
|
|
35927
|
+
float aa = uWorldPerPixel;
|
|
35928
|
+
return 1.0 - smoothstep(radius - aa * 0.5, radius + aa * 0.5, dist);
|
|
35915
35929
|
}
|
|
35916
35930
|
|
|
35917
35931
|
void main() {
|
|
35918
35932
|
vec3 col = uColor;
|
|
35919
35933
|
|
|
35920
|
-
|
|
35921
|
-
|
|
35922
|
-
|
|
35934
|
+
if (uSurfaceTexture > 0.5) {
|
|
35935
|
+
// Melamine micro-texture: two octaves of value noise, +-1.75% brightness.
|
|
35936
|
+
float n = vnoise(vWorldPos.xy * 2.3) * 0.6 + vnoise(vWorldPos.xy * 9.7) * 0.4;
|
|
35937
|
+
col *= 1.0 + (n - 0.5) * 0.035;
|
|
35923
35938
|
|
|
35924
|
-
|
|
35925
|
-
|
|
35926
|
-
|
|
35927
|
-
|
|
35928
|
-
|
|
35929
|
-
|
|
35930
|
-
|
|
35931
|
-
|
|
35932
|
-
|
|
35939
|
+
// Satin sheen: Fresnel rim + a specular band from the key light. Both
|
|
35940
|
+
// are ~zero in the straight-on working view and bloom as the camera tilts.
|
|
35941
|
+
vec3 V = normalize(cameraPosition - vWorldPos);
|
|
35942
|
+
vec3 N = vec3(0.0, 0.0, 1.0);
|
|
35943
|
+
float fres = pow(1.0 - max(dot(N, V), 0.0), 3.0);
|
|
35944
|
+
vec3 L = normalize(vec3(-0.25, 0.4, 0.88));
|
|
35945
|
+
vec3 H = normalize(L + V);
|
|
35946
|
+
float spec = pow(max(dot(N, H), 0.0), 90.0);
|
|
35947
|
+
col += (fres * 0.18 + spec * 0.06) * vec3(1.0);
|
|
35948
|
+
}
|
|
35933
35949
|
|
|
35934
35950
|
if (uGridMode > 0.5 && uGridFade > 0.001) {
|
|
35935
35951
|
float gridAlpha = (uGridMode < 1.5 ? gridLineAlpha(vWorldPos.xy) : gridDotAlpha(vWorldPos.xy)) * uGridFade;
|
|
@@ -35949,8 +35965,10 @@ function createBoardSurface(fog, theme) {
|
|
|
35949
35965
|
uGridMode: { value: GRID_MODE_CODE[theme.gridMode] },
|
|
35950
35966
|
uGridColor: { value: new Color(theme.gridColor) },
|
|
35951
35967
|
uGridSpacing: { value: Math.max(.001, theme.gridSpacing) },
|
|
35952
|
-
|
|
35968
|
+
uGridLineWidthPx: { value: Math.max(.1, theme.gridLineWidth) },
|
|
35969
|
+
uWorldPerPixel: { value: .05 },
|
|
35953
35970
|
uGridFade: { value: 0 },
|
|
35971
|
+
uSurfaceTexture: { value: TEXTURE_CODE[theme.surfaceTexture] },
|
|
35954
35972
|
...fog
|
|
35955
35973
|
}
|
|
35956
35974
|
});
|
|
@@ -35958,13 +35976,15 @@ function createBoardSurface(fog, theme) {
|
|
|
35958
35976
|
mesh.name = "board-surface";
|
|
35959
35977
|
return mesh;
|
|
35960
35978
|
}
|
|
35961
|
-
/** Applies a theme change (initial or live) — everything except the per-frame fade/
|
|
35979
|
+
/** Applies a theme change (initial or live) — everything except the per-frame fade/pixel-ratio. */
|
|
35962
35980
|
function setBoardSurfaceTheme(mesh, theme) {
|
|
35963
35981
|
const uniforms = mesh.material.uniforms;
|
|
35964
35982
|
uniforms.uColor.value.set(theme.color);
|
|
35965
35983
|
uniforms.uGridMode.value = GRID_MODE_CODE[theme.gridMode];
|
|
35966
35984
|
uniforms.uGridColor.value.set(theme.gridColor);
|
|
35967
35985
|
uniforms.uGridSpacing.value = Math.max(.001, theme.gridSpacing);
|
|
35986
|
+
uniforms.uGridLineWidthPx.value = Math.max(.1, theme.gridLineWidth);
|
|
35987
|
+
uniforms.uSurfaceTexture.value = TEXTURE_CODE[theme.surfaceTexture];
|
|
35968
35988
|
}
|
|
35969
35989
|
/** Keep the plane centered under the view, larger than the fog horizon, and the grid's on-screen weight/fade current. */
|
|
35970
35990
|
function updateBoardSurface(mesh, centerX, centerY, fogFar, worldPerPixel) {
|
|
@@ -35972,7 +35992,7 @@ function updateBoardSurface(mesh, centerX, centerY, fogFar, worldPerPixel) {
|
|
|
35972
35992
|
const size = fogFar * 2.5;
|
|
35973
35993
|
mesh.scale.set(size, size, 1);
|
|
35974
35994
|
const uniforms = mesh.material.uniforms;
|
|
35975
|
-
uniforms.
|
|
35995
|
+
uniforms.uWorldPerPixel.value = worldPerPixel;
|
|
35976
35996
|
const t = (uniforms.uGridSpacing.value / Math.max(1e-6, worldPerPixel) - GRID_FADE_MIN_PX) / (GRID_FADE_MAX_PX - GRID_FADE_MIN_PX);
|
|
35977
35997
|
uniforms.uGridFade.value = MathUtils.clamp(t, 0, 1);
|
|
35978
35998
|
}
|
|
@@ -36145,7 +36165,7 @@ var CameraRig = class {
|
|
|
36145
36165
|
}
|
|
36146
36166
|
};
|
|
36147
36167
|
//#endregion
|
|
36148
|
-
//#region
|
|
36168
|
+
//#region src/renderer/canvas/scene.ts
|
|
36149
36169
|
var SceneRig = class {
|
|
36150
36170
|
constructor(canvas, boardTheme) {
|
|
36151
36171
|
this.renderer = new WebGLRenderer({
|
|
@@ -36192,7 +36212,7 @@ var SceneRig = class {
|
|
|
36192
36212
|
}
|
|
36193
36213
|
};
|
|
36194
36214
|
//#endregion
|
|
36195
|
-
//#region
|
|
36215
|
+
//#region src/renderer/shapes/inkMaterial.ts
|
|
36196
36216
|
var VERTEX = `
|
|
36197
36217
|
attribute float aAlpha;
|
|
36198
36218
|
varying vec2 vUv;
|
|
@@ -36323,7 +36343,7 @@ var InkMaterials = class {
|
|
|
36323
36343
|
}
|
|
36324
36344
|
};
|
|
36325
36345
|
//#endregion
|
|
36326
|
-
//#region
|
|
36346
|
+
//#region src/renderer/shapes/ribbonGeometry.ts
|
|
36327
36347
|
/** Ink floats a hair above the board to avoid z-fighting with the surface. */
|
|
36328
36348
|
var INK_Z = .02;
|
|
36329
36349
|
/** Highlighter always renders under opaque ink (build prompt §4.1). */
|
|
@@ -36374,7 +36394,7 @@ function buildRibbonGeometry(points, baseWidth, z = INK_Z) {
|
|
|
36374
36394
|
return geometry;
|
|
36375
36395
|
}
|
|
36376
36396
|
//#endregion
|
|
36377
|
-
//#region
|
|
36397
|
+
//#region src/renderer/shapes/strokeRenderer.ts
|
|
36378
36398
|
var strokeZ = (stroke) => stroke.tool === "highlighter" ? HIGHLIGHT_Z : INK_Z;
|
|
36379
36399
|
/**
|
|
36380
36400
|
* Derives ink meshes from the document by subscription — the document never
|
|
@@ -36507,7 +36527,7 @@ function syncMatrix(mesh, stroke) {
|
|
|
36507
36527
|
mesh.matrixWorldNeedsUpdate = true;
|
|
36508
36528
|
}
|
|
36509
36529
|
//#endregion
|
|
36510
|
-
//#region
|
|
36530
|
+
//#region src/renderer/shapes/markerProp.ts
|
|
36511
36531
|
var BODY_LENGTH = 11;
|
|
36512
36532
|
var BODY_RADIUS = .85;
|
|
36513
36533
|
var TIP_LENGTH = 1.6;
|
|
@@ -36603,7 +36623,7 @@ var MarkerProp = class {
|
|
|
36603
36623
|
}
|
|
36604
36624
|
};
|
|
36605
36625
|
//#endregion
|
|
36606
|
-
//#region
|
|
36626
|
+
//#region src/renderer/shapes/noteGeometry.ts
|
|
36607
36627
|
/**
|
|
36608
36628
|
* Height of the sheet above the board at (u, v) ∈ [0,1]².
|
|
36609
36629
|
* v = 1 is the adhesive edge (always 0); u = 1 is the peel corner side.
|
|
@@ -36647,7 +36667,7 @@ function applyCurl(geometry, curl, peel) {
|
|
|
36647
36667
|
color.needsUpdate = true;
|
|
36648
36668
|
}
|
|
36649
36669
|
//#endregion
|
|
36650
|
-
//#region
|
|
36670
|
+
//#region src/renderer/shapes/stickyNotes.ts
|
|
36651
36671
|
var TEXTURE_SIZE = 512;
|
|
36652
36672
|
var FOCUS_COLOR$4 = 2450411;
|
|
36653
36673
|
var CURL = .3;
|
|
@@ -43223,7 +43243,7 @@ SYNCABLE_PROPS.forEach((prop) => {
|
|
|
43223
43243
|
new Box3();
|
|
43224
43244
|
new Color();
|
|
43225
43245
|
//#endregion
|
|
43226
|
-
//#region
|
|
43246
|
+
//#region src/renderer/shapes/tables.ts
|
|
43227
43247
|
var FONT_URL$2 = "/fonts/inter-medium.woff";
|
|
43228
43248
|
var TABLE_Z = .012;
|
|
43229
43249
|
var HEADER_Z = .014;
|
|
@@ -43572,7 +43592,7 @@ var TablesRenderer = class {
|
|
|
43572
43592
|
}
|
|
43573
43593
|
};
|
|
43574
43594
|
//#endregion
|
|
43575
|
-
//#region
|
|
43595
|
+
//#region src/renderer/text/textBlocks.ts
|
|
43576
43596
|
var FONT_URL$1 = "/fonts/inter-medium.woff";
|
|
43577
43597
|
var TEXT_Z = .02;
|
|
43578
43598
|
var FOCUS_COLOR$2 = 2450411;
|
|
@@ -43676,7 +43696,7 @@ var TextBlocksRenderer = class {
|
|
|
43676
43696
|
}
|
|
43677
43697
|
};
|
|
43678
43698
|
//#endregion
|
|
43679
|
-
//#region
|
|
43699
|
+
//#region src/renderer/shapes/comments.ts
|
|
43680
43700
|
var PIN_Z = .04;
|
|
43681
43701
|
var PIN_WIDTH = 3.6;
|
|
43682
43702
|
var PIN_HEIGHT = 3.6;
|
|
@@ -43844,7 +43864,7 @@ function drawBubblePath(ctx, x, y, w, h, r, tailX, tailY, tailW) {
|
|
|
43844
43864
|
ctx.closePath();
|
|
43845
43865
|
}
|
|
43846
43866
|
//#endregion
|
|
43847
|
-
//#region
|
|
43867
|
+
//#region src/renderer/shapes/images.ts
|
|
43848
43868
|
var IMAGE_Z = .015;
|
|
43849
43869
|
var FRAME_BORDER = .4;
|
|
43850
43870
|
var FOCUS_COLOR$1 = 2450411;
|
|
@@ -44054,7 +44074,7 @@ function applyPlaceholderTexture(visual, label) {
|
|
|
44054
44074
|
visual.imageMesh.material.needsUpdate = true;
|
|
44055
44075
|
}
|
|
44056
44076
|
//#endregion
|
|
44057
|
-
//#region
|
|
44077
|
+
//#region src/renderer/shapes/kitchenTimers.ts
|
|
44058
44078
|
var FACE_SIZE = 256;
|
|
44059
44079
|
var BODY_COLOR = 14753096;
|
|
44060
44080
|
var KNOB_COLOR = 16448250;
|
|
@@ -44252,7 +44272,7 @@ function renderTimerFace(timer, canvas, now = Date.now()) {
|
|
|
44252
44272
|
return c;
|
|
44253
44273
|
}
|
|
44254
44274
|
//#endregion
|
|
44255
|
-
//#region
|
|
44275
|
+
//#region src/renderer/shapes/customObjects.ts
|
|
44256
44276
|
var FONT_URL = "/fonts/inter-medium.woff";
|
|
44257
44277
|
var CUSTOM_Z = .02;
|
|
44258
44278
|
var FOCUS_COLOR = 2450411;
|
|
@@ -44614,7 +44634,7 @@ function disposeObject3D(obj) {
|
|
|
44614
44634
|
});
|
|
44615
44635
|
}
|
|
44616
44636
|
//#endregion
|
|
44617
|
-
//#region
|
|
44637
|
+
//#region src/interaction/pointer/hitTest.ts
|
|
44618
44638
|
/** Topmost (most recently added) stroke under the point, or null. */
|
|
44619
44639
|
function hitStroke(doc, index, p, slop) {
|
|
44620
44640
|
const candidates = index.query(p.x - slop, p.y - slop, p.x + slop, p.y + slop);
|
|
@@ -44655,7 +44675,7 @@ function distToSegmentSq(p, a, b) {
|
|
|
44655
44675
|
return dx * dx + dy * dy;
|
|
44656
44676
|
}
|
|
44657
44677
|
//#endregion
|
|
44658
|
-
//#region
|
|
44678
|
+
//#region src/interaction/tools/eraserTool.ts
|
|
44659
44679
|
var DECAY_PER_PASS = .4;
|
|
44660
44680
|
/** A point can take another decay pass after this long — rubbing works. */
|
|
44661
44681
|
var REARM_MS = 250;
|
|
@@ -44783,7 +44803,7 @@ function partitionByErasure(points) {
|
|
|
44783
44803
|
return runs;
|
|
44784
44804
|
}
|
|
44785
44805
|
//#endregion
|
|
44786
|
-
//#region
|
|
44806
|
+
//#region src/interaction/tools/noteDrag.ts
|
|
44787
44807
|
/**
|
|
44788
44808
|
* Drag the focused note in X/Y. The grab is resolved on the note's own
|
|
44789
44809
|
* z-plane, not the board, so the note doesn't jump under a tilted ray.
|
|
@@ -44850,7 +44870,7 @@ var NoteDragState = class {
|
|
|
44850
44870
|
}
|
|
44851
44871
|
};
|
|
44852
44872
|
//#endregion
|
|
44853
|
-
//#region
|
|
44873
|
+
//#region src/interaction/tools/imageDrag.ts
|
|
44854
44874
|
/** Drag the focused image in X/Y; one command per drag. */
|
|
44855
44875
|
var ImageDragState = class {
|
|
44856
44876
|
constructor(ctx) {
|
|
@@ -44902,7 +44922,7 @@ var ImageDragState = class {
|
|
|
44902
44922
|
}
|
|
44903
44923
|
};
|
|
44904
44924
|
//#endregion
|
|
44905
|
-
//#region
|
|
44925
|
+
//#region src/interaction/tools/timerDrag.ts
|
|
44906
44926
|
/** Drag the focused timer in X/Y; one command per drag. */
|
|
44907
44927
|
var TimerDragState = class {
|
|
44908
44928
|
constructor(ctx) {
|
|
@@ -44954,7 +44974,7 @@ var TimerDragState = class {
|
|
|
44954
44974
|
}
|
|
44955
44975
|
};
|
|
44956
44976
|
//#endregion
|
|
44957
|
-
//#region
|
|
44977
|
+
//#region src/interaction/tools/shapeGeometry.ts
|
|
44958
44978
|
/** Uniform synthetic pressure; the ink shader supplies the hand-drawn feel. */
|
|
44959
44979
|
var PRESSURE = .7;
|
|
44960
44980
|
var MIN_ELLIPSE_SEGMENTS = 24;
|
|
@@ -45143,7 +45163,7 @@ function snappedEnd(a, b) {
|
|
|
45143
45163
|
};
|
|
45144
45164
|
}
|
|
45145
45165
|
//#endregion
|
|
45146
|
-
//#region
|
|
45166
|
+
//#region src/interaction/tools/shapeTool.ts
|
|
45147
45167
|
var MIN_DRAG_PX$1 = 4;
|
|
45148
45168
|
/** Drag out a shape; live preview through the real ink material. */
|
|
45149
45169
|
var ShapeTool = class {
|
|
@@ -45174,7 +45194,7 @@ var ShapeTool = class {
|
|
|
45174
45194
|
const strokes = this.polylines.map((points) => ({
|
|
45175
45195
|
id: crypto.randomUUID(),
|
|
45176
45196
|
color: this.ctx.inkColor(),
|
|
45177
|
-
baseWidth: this.ctx.
|
|
45197
|
+
baseWidth: this.ctx.shapeStrokeWidth(),
|
|
45178
45198
|
points
|
|
45179
45199
|
}));
|
|
45180
45200
|
this.ctx.clusters.assign(strokes[0]);
|
|
@@ -45208,13 +45228,13 @@ var ShapeTool = class {
|
|
|
45208
45228
|
this.previews[i].visible = polyline !== void 0;
|
|
45209
45229
|
if (polyline) {
|
|
45210
45230
|
this.previews[i].geometry.dispose();
|
|
45211
|
-
this.previews[i].geometry = buildRibbonGeometry(polyline, this.ctx.
|
|
45231
|
+
this.previews[i].geometry = buildRibbonGeometry(polyline, this.ctx.shapeStrokeWidth());
|
|
45212
45232
|
}
|
|
45213
45233
|
}
|
|
45214
45234
|
}
|
|
45215
45235
|
};
|
|
45216
45236
|
//#endregion
|
|
45217
|
-
//#region
|
|
45237
|
+
//#region src/interaction/tools/tableDrag.ts
|
|
45218
45238
|
function getHandleCursor(handle) {
|
|
45219
45239
|
switch (handle) {
|
|
45220
45240
|
case "nw":
|
|
@@ -45334,7 +45354,7 @@ var TableDragState = class {
|
|
|
45334
45354
|
}
|
|
45335
45355
|
};
|
|
45336
45356
|
//#endregion
|
|
45337
|
-
//#region
|
|
45357
|
+
//#region src/interaction/tools/tableTool.ts
|
|
45338
45358
|
var MIN_DRAG_PX = 6;
|
|
45339
45359
|
var TableTool = class {
|
|
45340
45360
|
constructor(ctx) {
|
|
@@ -45465,7 +45485,7 @@ var TableTool = class {
|
|
|
45465
45485
|
}
|
|
45466
45486
|
};
|
|
45467
45487
|
//#endregion
|
|
45468
|
-
//#region
|
|
45488
|
+
//#region src/interaction/tools/commentTool.ts
|
|
45469
45489
|
/** Click on the board to drop a new comment pin or open an existing one. */
|
|
45470
45490
|
var CommentTool = class {
|
|
45471
45491
|
constructor(ctx) {
|
|
@@ -45500,7 +45520,7 @@ var CommentTool = class {
|
|
|
45500
45520
|
}
|
|
45501
45521
|
};
|
|
45502
45522
|
//#endregion
|
|
45503
|
-
//#region
|
|
45523
|
+
//#region src/interaction/tools/textDrag.ts
|
|
45504
45524
|
/** Drag the focused text block in X/Y; one command per drag. */
|
|
45505
45525
|
var TextDragState = class {
|
|
45506
45526
|
constructor(ctx) {
|
|
@@ -45552,7 +45572,7 @@ var TextDragState = class {
|
|
|
45552
45572
|
}
|
|
45553
45573
|
};
|
|
45554
45574
|
//#endregion
|
|
45555
|
-
//#region
|
|
45575
|
+
//#region src/interaction/tools/fsm.ts
|
|
45556
45576
|
var ToolStateMachine = class {
|
|
45557
45577
|
constructor() {
|
|
45558
45578
|
this.states = /* @__PURE__ */ new Map();
|
|
@@ -45754,7 +45774,7 @@ var IdleState = class {
|
|
|
45754
45774
|
}
|
|
45755
45775
|
};
|
|
45756
45776
|
//#endregion
|
|
45757
|
-
//#region
|
|
45777
|
+
//#region src/renderer/selection/gizmo.ts
|
|
45758
45778
|
var GIZMO_Z = .05;
|
|
45759
45779
|
var HANDLE_PX = 9;
|
|
45760
45780
|
var HANDLE_HIT_PX = 12;
|
|
@@ -45985,7 +46005,7 @@ function boxesEqual(a, b) {
|
|
|
45985
46005
|
return a.minX === b.minX && a.minY === b.minY && a.maxX === b.maxX && a.maxY === b.maxY;
|
|
45986
46006
|
}
|
|
45987
46007
|
//#endregion
|
|
45988
|
-
//#region
|
|
46008
|
+
//#region src/interaction/tools/pressure.ts
|
|
45989
46009
|
var SIM_MAX = 1;
|
|
45990
46010
|
var SIM_MIN = .3;
|
|
45991
46011
|
var SMOOTHING = .25;
|
|
@@ -46007,7 +46027,7 @@ function clamp(v, lo, hi) {
|
|
|
46007
46027
|
return Math.min(hi, Math.max(lo, v));
|
|
46008
46028
|
}
|
|
46009
46029
|
//#endregion
|
|
46010
|
-
//#region
|
|
46030
|
+
//#region src/interaction/tools/strokeBuilder.ts
|
|
46011
46031
|
var StrokeBuilder = class {
|
|
46012
46032
|
constructor() {
|
|
46013
46033
|
this.points = [];
|
|
@@ -46057,7 +46077,7 @@ function catmullRom(v0, v1, v2, v3, t) {
|
|
|
46057
46077
|
return .5 * (2 * v1 + (-v0 + v2) * t + (2 * v0 - 5 * v1 + 4 * v2 - v3) * t2 + (-v0 + 3 * v1 - 3 * v2 + v3) * t3);
|
|
46058
46078
|
}
|
|
46059
46079
|
//#endregion
|
|
46060
|
-
//#region
|
|
46080
|
+
//#region src/interaction/tools/markerTool.ts
|
|
46061
46081
|
/** Sample spacing while drawing, in screen pixels. */
|
|
46062
46082
|
var MIN_SAMPLE_PX = 1.5;
|
|
46063
46083
|
/** A highlighter is a chisel tip: near-constant width, little pressure play. */
|
|
@@ -46160,7 +46180,7 @@ var MarkerTool = class {
|
|
|
46160
46180
|
}
|
|
46161
46181
|
};
|
|
46162
46182
|
//#endregion
|
|
46163
|
-
//#region
|
|
46183
|
+
//#region src/interaction/tools/orbitTool.ts
|
|
46164
46184
|
/**
|
|
46165
46185
|
* Orbit-preview (build prompt §4.2): alt-drag tilts the camera off-axis to
|
|
46166
46186
|
* read the board's material and depth; releasing eases back to the working
|
|
@@ -46195,7 +46215,7 @@ var OrbitTool = class {
|
|
|
46195
46215
|
}
|
|
46196
46216
|
};
|
|
46197
46217
|
//#endregion
|
|
46198
|
-
//#region
|
|
46218
|
+
//#region src/interaction/tools/panTool.ts
|
|
46199
46219
|
/** Grab-pan: content follows the pointer. */
|
|
46200
46220
|
var PanTool = class {
|
|
46201
46221
|
constructor(ctx) {
|
|
@@ -46225,7 +46245,7 @@ var PanTool = class {
|
|
|
46225
46245
|
}
|
|
46226
46246
|
};
|
|
46227
46247
|
//#endregion
|
|
46228
|
-
//#region
|
|
46248
|
+
//#region src/renderer/selection/selection.ts
|
|
46229
46249
|
/** The set of selected stroke ids. Drops ids the document no longer has. */
|
|
46230
46250
|
var SelectionManager = class {
|
|
46231
46251
|
constructor(doc) {
|
|
@@ -46276,7 +46296,7 @@ var SelectionManager = class {
|
|
|
46276
46296
|
}
|
|
46277
46297
|
};
|
|
46278
46298
|
//#endregion
|
|
46279
|
-
//#region
|
|
46299
|
+
//#region src/interaction/tools/selectTool.ts
|
|
46280
46300
|
var HIT_SLOP_PX = 4;
|
|
46281
46301
|
var CLICK_TOLERANCE_PX = 3;
|
|
46282
46302
|
var MIN_SCALE = .05;
|
|
@@ -46492,7 +46512,7 @@ function safeRatio(numerator, denominator) {
|
|
|
46492
46512
|
return raw;
|
|
46493
46513
|
}
|
|
46494
46514
|
//#endregion
|
|
46495
|
-
//#region
|
|
46515
|
+
//#region src/interaction/tools/customTool.ts
|
|
46496
46516
|
function extensionIdFromToolId(toolId) {
|
|
46497
46517
|
const slash = toolId.indexOf("/");
|
|
46498
46518
|
return slash === -1 ? toolId : toolId.slice(0, slash);
|
|
@@ -46607,12 +46627,19 @@ var ExtensionCommandBatch = class {
|
|
|
46607
46627
|
}
|
|
46608
46628
|
};
|
|
46609
46629
|
//#endregion
|
|
46610
|
-
//#region
|
|
46630
|
+
//#region src/composition/ScrawlEngine.ts
|
|
46611
46631
|
/** Marker stroke width in board units (~1% of the default view height). */
|
|
46612
46632
|
var BASE_WIDTH = .5;
|
|
46613
46633
|
/** Highlighter chisel width — wide enough to cover a line of handwriting. */
|
|
46614
46634
|
var HIGHLIGHT_WIDTH = 2.2;
|
|
46615
46635
|
/**
|
|
46636
|
+
* Shape (rectangle, ellipse, arrow, ...) border width in board units.
|
|
46637
|
+
* Deliberately thinner than BASE_WIDTH: a shape border reads as a crisp,
|
|
46638
|
+
* structural line, not an expressive marker stroke — this is also the
|
|
46639
|
+
* fallback when no Host theme configures ScrawlTheme.shapeStrokeWidth.
|
|
46640
|
+
*/
|
|
46641
|
+
var DEFAULT_SHAPE_STROKE_WIDTH = .15;
|
|
46642
|
+
/**
|
|
46616
46643
|
* Identity of a rendered selection badge: which item, its lock state, and
|
|
46617
46644
|
* where it sits on screen (rounded to the pixel, so sub-pixel camera drift
|
|
46618
46645
|
* does not churn React).
|
|
@@ -46633,10 +46660,11 @@ function emptyExtensionRegistry() {
|
|
|
46633
46660
|
* React never reaches past this class.
|
|
46634
46661
|
*/
|
|
46635
46662
|
var ScrawlEngine = class {
|
|
46636
|
-
constructor(canvas, documentId$1, extensionRegistry = emptyExtensionRegistry(), assetController = new AssetController(void 0), boardTheme = DEFAULT_BOARD_SURFACE_THEME) {
|
|
46663
|
+
constructor(canvas, documentId$1, extensionRegistry = emptyExtensionRegistry(), assetController = new AssetController(void 0), boardTheme = DEFAULT_BOARD_SURFACE_THEME, shapeStrokeWidth = DEFAULT_SHAPE_STROKE_WIDTH) {
|
|
46637
46664
|
this.canvas = canvas;
|
|
46638
46665
|
this.extensionRegistry = extensionRegistry;
|
|
46639
46666
|
this.boardTheme = boardTheme;
|
|
46667
|
+
this.shapeStrokeWidth = shapeStrokeWidth;
|
|
46640
46668
|
this.onToolChange = null;
|
|
46641
46669
|
this.onZoomChange = null;
|
|
46642
46670
|
this.onAuditEvent = null;
|
|
@@ -46731,6 +46759,7 @@ var ScrawlEngine = class {
|
|
|
46731
46759
|
setTool: (t) => this.setTool(t),
|
|
46732
46760
|
inkColor: () => this.tool === "highlighter" ? this.highlightColor : this.color,
|
|
46733
46761
|
baseWidth: () => this.tool === "highlighter" ? HIGHLIGHT_WIDTH : BASE_WIDTH,
|
|
46762
|
+
shapeStrokeWidth: () => this.shapeStrokeWidth,
|
|
46734
46763
|
activeTool: () => this.tool,
|
|
46735
46764
|
isSpaceHeld: () => this.spaceHeld,
|
|
46736
46765
|
pointerToBoard: (e) => pointerToBoard(e.clientX, e.clientY, canvas, this.scene.cameraRig.camera),
|
|
@@ -46995,6 +47024,10 @@ var ScrawlEngine = class {
|
|
|
46995
47024
|
this.boardTheme = theme;
|
|
46996
47025
|
this.scene.applyBoardTheme(theme);
|
|
46997
47026
|
}
|
|
47027
|
+
/** Live update of the shape tool's border width (board units). Already-drawn shapes keep the width they were drawn with. */
|
|
47028
|
+
setShapeStrokeWidth(width) {
|
|
47029
|
+
this.shapeStrokeWidth = width;
|
|
47030
|
+
}
|
|
46998
47031
|
/**
|
|
46999
47032
|
* Snap to a peer's camera. No-op while drawing so pointer-to-board
|
|
47000
47033
|
* mapping does not warp the in-progress stroke.
|
|
@@ -48056,7 +48089,7 @@ var ScrawlEngine = class {
|
|
|
48056
48089
|
}
|
|
48057
48090
|
};
|
|
48058
48091
|
//#endregion
|
|
48059
|
-
//#region src/controller-internal.ts
|
|
48092
|
+
//#region src/composition/controller-internal.ts
|
|
48060
48093
|
function createBoardController(options) {
|
|
48061
48094
|
return createBoardControllerWithEngine(options);
|
|
48062
48095
|
}
|
|
@@ -48074,9 +48107,12 @@ function createBoardControllerWithEngine(options, existingEngine) {
|
|
|
48074
48107
|
color: options.boardTheme?.surface ?? DEFAULT_BOARD_SURFACE_THEME.color,
|
|
48075
48108
|
gridMode: options.boardTheme?.gridMode ?? DEFAULT_BOARD_SURFACE_THEME.gridMode,
|
|
48076
48109
|
gridColor: options.boardTheme?.gridColor ?? DEFAULT_BOARD_SURFACE_THEME.gridColor,
|
|
48077
|
-
gridSpacing: options.boardTheme?.gridSpacing ?? DEFAULT_BOARD_SURFACE_THEME.gridSpacing
|
|
48110
|
+
gridSpacing: options.boardTheme?.gridSpacing ?? DEFAULT_BOARD_SURFACE_THEME.gridSpacing,
|
|
48111
|
+
gridLineWidth: options.boardTheme?.gridLineWidth ?? DEFAULT_BOARD_SURFACE_THEME.gridLineWidth,
|
|
48112
|
+
surfaceTexture: options.boardTheme?.surfaceTexture ?? DEFAULT_BOARD_SURFACE_THEME.surfaceTexture
|
|
48078
48113
|
};
|
|
48079
|
-
|
|
48114
|
+
let currentShapeStrokeWidth = options.boardTheme?.shapeStrokeWidth ?? .15;
|
|
48115
|
+
const engine = existingEngine ?? (options.canvas ? new ScrawlEngine(options.canvas, options.document.id, extensionRegistry, assetController, currentBoardTheme, currentShapeStrokeWidth) : null);
|
|
48080
48116
|
const document = engine?.document ?? new BoardDocument(documentId(options.document.id));
|
|
48081
48117
|
const history = engine?.history ?? new History(document);
|
|
48082
48118
|
const createId = options.createId ?? (() => crypto.randomUUID());
|
|
@@ -48565,9 +48601,15 @@ function createBoardControllerWithEngine(options, existingEngine) {
|
|
|
48565
48601
|
color: theme.surface ?? currentBoardTheme.color,
|
|
48566
48602
|
gridMode: theme.gridMode ?? currentBoardTheme.gridMode,
|
|
48567
48603
|
gridColor: theme.gridColor ?? currentBoardTheme.gridColor,
|
|
48568
|
-
gridSpacing: theme.gridSpacing ?? currentBoardTheme.gridSpacing
|
|
48604
|
+
gridSpacing: theme.gridSpacing ?? currentBoardTheme.gridSpacing,
|
|
48605
|
+
gridLineWidth: theme.gridLineWidth ?? currentBoardTheme.gridLineWidth,
|
|
48606
|
+
surfaceTexture: theme.surfaceTexture ?? currentBoardTheme.surfaceTexture
|
|
48569
48607
|
};
|
|
48570
48608
|
engine?.applyBoardTheme(currentBoardTheme);
|
|
48609
|
+
if (theme.shapeStrokeWidth !== void 0) {
|
|
48610
|
+
currentShapeStrokeWidth = theme.shapeStrokeWidth;
|
|
48611
|
+
engine?.setShapeStrokeWidth(currentShapeStrokeWidth);
|
|
48612
|
+
}
|
|
48571
48613
|
} },
|
|
48572
48614
|
view: {
|
|
48573
48615
|
fit() {
|
|
@@ -49338,7 +49380,7 @@ function createLocalBoard(options) {
|
|
|
49338
49380
|
};
|
|
49339
49381
|
}
|
|
49340
49382
|
//#endregion
|
|
49341
|
-
//#region src/theme.ts
|
|
49383
|
+
//#region src/ui/theme.ts
|
|
49342
49384
|
var scrawlThemePresets = Object.freeze({
|
|
49343
49385
|
light: Object.freeze({
|
|
49344
49386
|
surface: "#ffffff",
|
|
@@ -49365,9 +49407,12 @@ var scrawlThemePresets = Object.freeze({
|
|
|
49365
49407
|
motionEasing: "cubic-bezier(0.2, 0, 0, 1)",
|
|
49366
49408
|
density: "comfortable",
|
|
49367
49409
|
boardSurface: "#f5f5f3",
|
|
49410
|
+
boardSurfaceTexture: "flat",
|
|
49368
49411
|
gridMode: "none",
|
|
49369
49412
|
gridColor: "#deded8",
|
|
49370
|
-
gridSpacing: 5
|
|
49413
|
+
gridSpacing: 5,
|
|
49414
|
+
gridLineWidth: 1,
|
|
49415
|
+
shapeStrokeWidth: .15
|
|
49371
49416
|
}),
|
|
49372
49417
|
dark: Object.freeze({
|
|
49373
49418
|
surface: "#171816",
|
|
@@ -49394,9 +49439,12 @@ var scrawlThemePresets = Object.freeze({
|
|
|
49394
49439
|
motionEasing: "cubic-bezier(0.2, 0, 0, 1)",
|
|
49395
49440
|
density: "comfortable",
|
|
49396
49441
|
boardSurface: "#232420",
|
|
49442
|
+
boardSurfaceTexture: "flat",
|
|
49397
49443
|
gridMode: "none",
|
|
49398
49444
|
gridColor: "#33352f",
|
|
49399
|
-
gridSpacing: 5
|
|
49445
|
+
gridSpacing: 5,
|
|
49446
|
+
gridLineWidth: 1,
|
|
49447
|
+
shapeStrokeWidth: .15
|
|
49400
49448
|
})
|
|
49401
49449
|
});
|
|
49402
49450
|
var variableNames = {
|
|
@@ -49424,9 +49472,12 @@ var variableNames = {
|
|
|
49424
49472
|
motionEasing: "--scrawl-motion-easing",
|
|
49425
49473
|
density: "--scrawl-density",
|
|
49426
49474
|
boardSurface: "--scrawl-board-surface",
|
|
49475
|
+
boardSurfaceTexture: "--scrawl-board-surface-texture",
|
|
49427
49476
|
gridMode: "--scrawl-grid-mode",
|
|
49428
49477
|
gridColor: "--scrawl-grid-color",
|
|
49429
|
-
gridSpacing: "--scrawl-grid-spacing"
|
|
49478
|
+
gridSpacing: "--scrawl-grid-spacing",
|
|
49479
|
+
gridLineWidth: "--scrawl-grid-line-width",
|
|
49480
|
+
shapeStrokeWidth: "--scrawl-shape-stroke-width"
|
|
49430
49481
|
};
|
|
49431
49482
|
var colorTokens = /* @__PURE__ */ new Set([
|
|
49432
49483
|
"surface",
|
|
@@ -49482,10 +49533,22 @@ function validateScrawlTheme(theme) {
|
|
|
49482
49533
|
token,
|
|
49483
49534
|
message: "Expected none, line, or dot"
|
|
49484
49535
|
});
|
|
49536
|
+
else if (token === "boardSurfaceTexture" && value !== "flat" && value !== "textured") diagnostics.push({
|
|
49537
|
+
token,
|
|
49538
|
+
message: "Expected flat or textured"
|
|
49539
|
+
});
|
|
49485
49540
|
else if (token === "gridSpacing" && (!finiteNumber(value) || value < .5 || value > 50)) diagnostics.push({
|
|
49486
49541
|
token,
|
|
49487
49542
|
message: "Expected spacing 0.5-50 board units"
|
|
49488
49543
|
});
|
|
49544
|
+
else if (token === "gridLineWidth" && (!finiteNumber(value) || value < .5 || value > 8)) diagnostics.push({
|
|
49545
|
+
token,
|
|
49546
|
+
message: "Expected line width 0.5-8px"
|
|
49547
|
+
});
|
|
49548
|
+
else if (token === "shapeStrokeWidth" && (!finiteNumber(value) || value < .01 || value > 5)) diagnostics.push({
|
|
49549
|
+
token,
|
|
49550
|
+
message: "Expected stroke width 0.01-5 board units"
|
|
49551
|
+
});
|
|
49489
49552
|
else if ((token.endsWith("Family") || token.startsWith("elevation") || token === "motionEasing") && (typeof value !== "string" || !value.trim() || /[;{}]/.test(value))) diagnostics.push({
|
|
49490
49553
|
token,
|
|
49491
49554
|
message: "Expected a safe CSS value"
|
|
@@ -49556,12 +49619,12 @@ function luminance(color) {
|
|
|
49556
49619
|
return channels[0] * .2126 + channels[1] * .7152 + channels[2] * .0722;
|
|
49557
49620
|
}
|
|
49558
49621
|
function formatValue(token, value) {
|
|
49559
|
-
if (token === "baseFontSize" || token === "controlRadius" || token === "panelRadius") return `${value}px`;
|
|
49622
|
+
if (token === "baseFontSize" || token === "controlRadius" || token === "panelRadius" || token === "gridLineWidth") return `${value}px`;
|
|
49560
49623
|
if (token === "motionDuration") return `${value}ms`;
|
|
49561
49624
|
return String(value);
|
|
49562
49625
|
}
|
|
49563
49626
|
//#endregion
|
|
49564
|
-
//#region src/inline-editing.tsx
|
|
49627
|
+
//#region src/ui/dialogs/inline-editing.tsx
|
|
49565
49628
|
/** Inline note, text, and table-cell editors — driven entirely by public controller events and commands. */
|
|
49566
49629
|
function InlineEditors({ controller, renderPortal }) {
|
|
49567
49630
|
const [editor, setEditor] = useState(null);
|
|
@@ -49792,7 +49855,7 @@ function InlineEditors({ controller, renderPortal }) {
|
|
|
49792
49855
|
}))] });
|
|
49793
49856
|
}
|
|
49794
49857
|
//#endregion
|
|
49795
|
-
//#region src/style-shelf.tsx
|
|
49858
|
+
//#region src/ui/toolbar/style-shelf.tsx
|
|
49796
49859
|
var ERASER_RADII = [
|
|
49797
49860
|
["Fine", 1],
|
|
49798
49861
|
["Medium", 2],
|
|
@@ -49955,7 +50018,7 @@ function StyleShelf({ controller, snapshot }) {
|
|
|
49955
50018
|
});
|
|
49956
50019
|
}
|
|
49957
50020
|
//#endregion
|
|
49958
|
-
//#region src/default-ui.tsx
|
|
50021
|
+
//#region src/ui/default-ui.tsx
|
|
49959
50022
|
var PRIMARY_TOOLS = [
|
|
49960
50023
|
{
|
|
49961
50024
|
tool: "select",
|
|
@@ -50484,7 +50547,7 @@ function download(blob, name) {
|
|
|
50484
50547
|
URL.revokeObjectURL(url);
|
|
50485
50548
|
}
|
|
50486
50549
|
//#endregion
|
|
50487
|
-
//#region src/presence.tsx
|
|
50550
|
+
//#region src/ui/panels/presence.tsx
|
|
50488
50551
|
var labelStyle = {
|
|
50489
50552
|
borderRadius: 999,
|
|
50490
50553
|
color: "#fff",
|
|
@@ -50644,9 +50707,12 @@ function ScrawlProvider({ controller, children, preset = "light", theme, portalC
|
|
|
50644
50707
|
useEffect(() => {
|
|
50645
50708
|
controller.boardTheme.set({
|
|
50646
50709
|
surface: resolved.values.boardSurface,
|
|
50710
|
+
surfaceTexture: resolved.values.boardSurfaceTexture,
|
|
50647
50711
|
gridMode: resolved.values.gridMode,
|
|
50648
50712
|
gridColor: resolved.values.gridColor,
|
|
50649
|
-
gridSpacing: resolved.values.gridSpacing
|
|
50713
|
+
gridSpacing: resolved.values.gridSpacing,
|
|
50714
|
+
gridLineWidth: resolved.values.gridLineWidth,
|
|
50715
|
+
shapeStrokeWidth: resolved.values.shapeStrokeWidth
|
|
50650
50716
|
});
|
|
50651
50717
|
}, [controller, resolved]);
|
|
50652
50718
|
useDeferredDisposal(controller, disposeOnUnmount);
|
|
@@ -50699,9 +50765,12 @@ function Scrawl({ children, preset, theme, portalContainer, className, style, on
|
|
|
50699
50765
|
const resolved = resolveScrawlTheme(preset, theme);
|
|
50700
50766
|
const boardTheme = {
|
|
50701
50767
|
surface: resolved.values.boardSurface,
|
|
50768
|
+
surfaceTexture: resolved.values.boardSurfaceTexture,
|
|
50702
50769
|
gridMode: resolved.values.gridMode,
|
|
50703
50770
|
gridColor: resolved.values.gridColor,
|
|
50704
|
-
gridSpacing: resolved.values.gridSpacing
|
|
50771
|
+
gridSpacing: resolved.values.gridSpacing,
|
|
50772
|
+
gridLineWidth: resolved.values.gridLineWidth,
|
|
50773
|
+
shapeStrokeWidth: resolved.values.shapeStrokeWidth
|
|
50705
50774
|
};
|
|
50706
50775
|
controller = createBoardController({
|
|
50707
50776
|
...options,
|