@scrawl-board/board 0.1.0-beta.0 → 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.d.ts +38 -7
- package/dist/browser.js +128 -19
- package/dist/core.d.ts +96 -25
- package/dist/core.js +44 -4
- package/dist/index.d.ts +69 -30
- package/dist/index.js +178 -23
- package/dist/react.d.ts +46 -7
- package/dist/react.js +170 -23
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -23,6 +23,11 @@ var AssetResolutionError = class extends Error {
|
|
|
23
23
|
var ASSET_CACHE_BYTES_DEFAULT = 256 * 1024 * 1024;
|
|
24
24
|
var ASSET_CACHE_BYTES_MIN = 64 * 1024 * 1024;
|
|
25
25
|
var ASSET_CACHE_BYTES_MAX = 512 * 1024 * 1024;
|
|
26
|
+
var SUPPORTED_ASSET_MEDIA_TYPES = [
|
|
27
|
+
"image/png",
|
|
28
|
+
"image/jpeg",
|
|
29
|
+
"image/webp"
|
|
30
|
+
];
|
|
26
31
|
function clampAssetCacheBytes(value) {
|
|
27
32
|
if (value === void 0 || !Number.isFinite(value)) return ASSET_CACHE_BYTES_DEFAULT;
|
|
28
33
|
return Math.min(ASSET_CACHE_BYTES_MAX, Math.max(ASSET_CACHE_BYTES_MIN, Math.floor(value)));
|
|
@@ -445,7 +450,6 @@ function measureTable(table) {
|
|
|
445
450
|
height: table.rowHeights.reduce((sum, h) => sum + h, 0)
|
|
446
451
|
};
|
|
447
452
|
}
|
|
448
|
-
var BOARD_COLOR = "#FFFFFF";
|
|
449
453
|
var FOG_COLOR = "#FFFFFF";
|
|
450
454
|
function cloneImage(img) {
|
|
451
455
|
return { ...img };
|
|
@@ -1937,12 +1941,19 @@ var LIGHT = {
|
|
|
1937
1941
|
var MARGIN = 4;
|
|
1938
1942
|
var NOTE_FONT_RATIO = 44 / 512;
|
|
1939
1943
|
var NOTE_PAD_RATIO = 40 / 512;
|
|
1944
|
+
/** Matches the theme system's light-preset `boardSurface` default (theme.ts) — kept in sync manually, since core-internal stays decoupled from the theme layer. */
|
|
1945
|
+
var DEFAULT_BACKGROUND_COLOR = "#f5f5f3";
|
|
1940
1946
|
/**
|
|
1941
1947
|
* `registry` is optional and only enables rendering Custom objects through
|
|
1942
1948
|
* their own `describe()` — without it (or for an object whose extension
|
|
1943
1949
|
* isn't in it), Custom objects still export via the standard fallback
|
|
1944
1950
|
* placeholder (`fallback.bounds`/`label`), never silently dropped.
|
|
1945
1951
|
*
|
|
1952
|
+
* `backgroundColor` should be the Host's actual resolved `boardTheme.surface`
|
|
1953
|
+
* so an export matches what was on screen; defaults to the theme system's
|
|
1954
|
+
* own light-preset default when the caller doesn't have one on hand. The
|
|
1955
|
+
* board's reference grid, if any, is a screen-only aid and never exported.
|
|
1956
|
+
*
|
|
1946
1957
|
* `resolvedAssets` (ticket #23) maps an Asset reference to an already-
|
|
1947
1958
|
* resolved `data:` URI — see `assetExport.ts`'s `exportDocumentSVGWithAssets`,
|
|
1948
1959
|
* which is the only intended caller that ever passes one. Without it, every
|
|
@@ -1950,7 +1961,7 @@ var NOTE_PAD_RATIO = 40 / 512;
|
|
|
1950
1961
|
* placeholder instead of guessing at a URL; a legacy `src`-backed image is
|
|
1951
1962
|
* unaffected either way.
|
|
1952
1963
|
*/
|
|
1953
|
-
function documentToSVG(doc, now = 0, registry, resolvedAssets) {
|
|
1964
|
+
function documentToSVG(doc, now = 0, registry, backgroundColor = DEFAULT_BACKGROUND_COLOR, resolvedAssets) {
|
|
1954
1965
|
const notes = doc.notes ?? [];
|
|
1955
1966
|
const texts = doc.textBlocks ?? [];
|
|
1956
1967
|
const tables = doc.tables ?? [];
|
|
@@ -1963,7 +1974,7 @@ function documentToSVG(doc, now = 0, registry, resolvedAssets) {
|
|
|
1963
1974
|
const highlights = doc.strokes.filter((s) => s.tool === "highlighter");
|
|
1964
1975
|
const ink = doc.strokes.filter((s) => s.tool !== "highlighter");
|
|
1965
1976
|
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${view}">\n<defs>\n${defs}\n</defs>\n${[
|
|
1966
|
-
`<rect x="${fmt(bounds.minX)}" y="${fmt(bounds.minY)}" width="${fmt(bounds.width)}" height="${fmt(bounds.height)}" fill="${
|
|
1977
|
+
`<rect x="${fmt(bounds.minX)}" y="${fmt(bounds.minY)}" width="${fmt(bounds.width)}" height="${fmt(bounds.height)}" fill="${backgroundColor}"/>`,
|
|
1967
1978
|
...images.map((image) => imageToElement(image, resolvedAssets)),
|
|
1968
1979
|
...tables.map(tableToGroup),
|
|
1969
1980
|
...highlights.flatMap(strokeToPaths),
|
|
@@ -2879,7 +2890,7 @@ var SvgAssetExportError = class extends Error {
|
|
|
2879
2890
|
this.name = "SvgAssetExportError";
|
|
2880
2891
|
}
|
|
2881
2892
|
};
|
|
2882
|
-
async function exportDocumentSVGWithAssets(doc, now, registry, assetController, options) {
|
|
2893
|
+
async function exportDocumentSVGWithAssets(doc, now, registry, assetController, backgroundColor, options) {
|
|
2883
2894
|
const refs = collectDocumentAssetRefs(doc, registry);
|
|
2884
2895
|
const resolvedAssets = /* @__PURE__ */ new Map();
|
|
2885
2896
|
const missingAssets = [];
|
|
@@ -2915,7 +2926,7 @@ async function exportDocumentSVGWithAssets(doc, now, registry, assetController,
|
|
|
2915
2926
|
}
|
|
2916
2927
|
if (missingAssets.length > 0 && options?.missingAssets !== "placeholder") throw new SvgAssetExportError(missingAssets);
|
|
2917
2928
|
return {
|
|
2918
|
-
svg: documentToSVG(doc, now, registry, resolvedAssets),
|
|
2929
|
+
svg: documentToSVG(doc, now, registry, backgroundColor, resolvedAssets),
|
|
2919
2930
|
missingAssets
|
|
2920
2931
|
};
|
|
2921
2932
|
}
|
|
@@ -35836,6 +35847,21 @@ var FOG_GLSL = `
|
|
|
35836
35847
|
`;
|
|
35837
35848
|
//#endregion
|
|
35838
35849
|
//#region ../../src/scrawl/engine/boardSurface.ts
|
|
35850
|
+
var GRID_MODE_CODE = {
|
|
35851
|
+
none: 0,
|
|
35852
|
+
line: 1,
|
|
35853
|
+
dot: 2
|
|
35854
|
+
};
|
|
35855
|
+
/** Used when a caller doesn't supply one (e.g. ScrawlEngine constructed without a Host theme). */
|
|
35856
|
+
var DEFAULT_BOARD_SURFACE_THEME = {
|
|
35857
|
+
color: "#f5f5f3",
|
|
35858
|
+
gridMode: "none",
|
|
35859
|
+
gridColor: "#deded8",
|
|
35860
|
+
gridSpacing: 5
|
|
35861
|
+
};
|
|
35862
|
+
/** Grid alpha fades out below this on-screen spacing (px) — otherwise it aliases into a solid wash when zoomed out. */
|
|
35863
|
+
var GRID_FADE_MIN_PX = 3;
|
|
35864
|
+
var GRID_FADE_MAX_PX = 8;
|
|
35839
35865
|
var VERTEX$1 = `
|
|
35840
35866
|
varying vec3 vWorldPos;
|
|
35841
35867
|
void main() {
|
|
@@ -35849,6 +35875,11 @@ var FRAGMENT = `
|
|
|
35849
35875
|
uniform vec3 uFogColor;
|
|
35850
35876
|
uniform float uFogNear;
|
|
35851
35877
|
uniform float uFogFar;
|
|
35878
|
+
uniform float uGridMode;
|
|
35879
|
+
uniform vec3 uGridColor;
|
|
35880
|
+
uniform float uGridSpacing;
|
|
35881
|
+
uniform float uGridLineWorld;
|
|
35882
|
+
uniform float uGridFade;
|
|
35852
35883
|
varying vec3 vWorldPos;
|
|
35853
35884
|
|
|
35854
35885
|
float hash(vec2 p) {
|
|
@@ -35867,6 +35898,22 @@ var FRAGMENT = `
|
|
|
35867
35898
|
|
|
35868
35899
|
${FOG_GLSL}
|
|
35869
35900
|
|
|
35901
|
+
// Distance from p's nearest axis-aligned grid line, in world units.
|
|
35902
|
+
float gridLineAlpha(vec2 p) {
|
|
35903
|
+
vec2 cell = mod(p, uGridSpacing);
|
|
35904
|
+
vec2 distToLine = min(cell, uGridSpacing - cell);
|
|
35905
|
+
vec2 lineAlpha2 = 1.0 - smoothstep(uGridLineWorld, uGridLineWorld * 2.0, distToLine);
|
|
35906
|
+
return max(lineAlpha2.x, lineAlpha2.y);
|
|
35907
|
+
}
|
|
35908
|
+
|
|
35909
|
+
// Distance from p's nearest grid intersection, in world units.
|
|
35910
|
+
float gridDotAlpha(vec2 p) {
|
|
35911
|
+
vec2 cell = mod(p, uGridSpacing) - uGridSpacing * 0.5;
|
|
35912
|
+
float dist = length(cell);
|
|
35913
|
+
float radius = uGridLineWorld * 1.5;
|
|
35914
|
+
return 1.0 - smoothstep(radius, radius * 2.0, dist);
|
|
35915
|
+
}
|
|
35916
|
+
|
|
35870
35917
|
void main() {
|
|
35871
35918
|
vec3 col = uColor;
|
|
35872
35919
|
|
|
@@ -35884,16 +35931,26 @@ var FRAGMENT = `
|
|
|
35884
35931
|
float spec = pow(max(dot(N, H), 0.0), 90.0);
|
|
35885
35932
|
col += (fres * 0.18 + spec * 0.06) * vec3(1.0);
|
|
35886
35933
|
|
|
35934
|
+
if (uGridMode > 0.5 && uGridFade > 0.001) {
|
|
35935
|
+
float gridAlpha = (uGridMode < 1.5 ? gridLineAlpha(vWorldPos.xy) : gridDotAlpha(vWorldPos.xy)) * uGridFade;
|
|
35936
|
+
col = mix(col, uGridColor, gridAlpha);
|
|
35937
|
+
}
|
|
35938
|
+
|
|
35887
35939
|
col = applyBoardFog(col, vWorldPos);
|
|
35888
35940
|
gl_FragColor = vec4(col, 1.0);
|
|
35889
35941
|
}
|
|
35890
35942
|
`;
|
|
35891
|
-
function createBoardSurface(fog) {
|
|
35943
|
+
function createBoardSurface(fog, theme) {
|
|
35892
35944
|
const material = new ShaderMaterial({
|
|
35893
35945
|
vertexShader: VERTEX$1,
|
|
35894
35946
|
fragmentShader: FRAGMENT,
|
|
35895
35947
|
uniforms: {
|
|
35896
|
-
uColor: { value: new Color(
|
|
35948
|
+
uColor: { value: new Color(theme.color) },
|
|
35949
|
+
uGridMode: { value: GRID_MODE_CODE[theme.gridMode] },
|
|
35950
|
+
uGridColor: { value: new Color(theme.gridColor) },
|
|
35951
|
+
uGridSpacing: { value: Math.max(.001, theme.gridSpacing) },
|
|
35952
|
+
uGridLineWorld: { value: .05 },
|
|
35953
|
+
uGridFade: { value: 0 },
|
|
35897
35954
|
...fog
|
|
35898
35955
|
}
|
|
35899
35956
|
});
|
|
@@ -35901,11 +35958,32 @@ function createBoardSurface(fog) {
|
|
|
35901
35958
|
mesh.name = "board-surface";
|
|
35902
35959
|
return mesh;
|
|
35903
35960
|
}
|
|
35904
|
-
/**
|
|
35905
|
-
function
|
|
35961
|
+
/** Applies a theme change (initial or live) — everything except the per-frame fade/line-width. */
|
|
35962
|
+
function setBoardSurfaceTheme(mesh, theme) {
|
|
35963
|
+
const uniforms = mesh.material.uniforms;
|
|
35964
|
+
uniforms.uColor.value.set(theme.color);
|
|
35965
|
+
uniforms.uGridMode.value = GRID_MODE_CODE[theme.gridMode];
|
|
35966
|
+
uniforms.uGridColor.value.set(theme.gridColor);
|
|
35967
|
+
uniforms.uGridSpacing.value = Math.max(.001, theme.gridSpacing);
|
|
35968
|
+
}
|
|
35969
|
+
/** Keep the plane centered under the view, larger than the fog horizon, and the grid's on-screen weight/fade current. */
|
|
35970
|
+
function updateBoardSurface(mesh, centerX, centerY, fogFar, worldPerPixel) {
|
|
35906
35971
|
mesh.position.set(centerX, centerY, 0);
|
|
35907
35972
|
const size = fogFar * 2.5;
|
|
35908
35973
|
mesh.scale.set(size, size, 1);
|
|
35974
|
+
const uniforms = mesh.material.uniforms;
|
|
35975
|
+
uniforms.uGridLineWorld.value = worldPerPixel;
|
|
35976
|
+
const t = (uniforms.uGridSpacing.value / Math.max(1e-6, worldPerPixel) - GRID_FADE_MIN_PX) / (GRID_FADE_MAX_PX - GRID_FADE_MIN_PX);
|
|
35977
|
+
uniforms.uGridFade.value = MathUtils.clamp(t, 0, 1);
|
|
35978
|
+
}
|
|
35979
|
+
/** Temporarily zeroes the grid's contribution (for export snapshots) and returns a restore function. */
|
|
35980
|
+
function suppressBoardSurfaceGrid(mesh) {
|
|
35981
|
+
const uniforms = mesh.material.uniforms;
|
|
35982
|
+
const previous = uniforms.uGridFade.value;
|
|
35983
|
+
uniforms.uGridFade.value = 0;
|
|
35984
|
+
return () => {
|
|
35985
|
+
uniforms.uGridFade.value = previous;
|
|
35986
|
+
};
|
|
35909
35987
|
}
|
|
35910
35988
|
var MIN_HEIGHT = 40;
|
|
35911
35989
|
var MAX_HEIGHT = 1500;
|
|
@@ -36069,7 +36147,7 @@ var CameraRig = class {
|
|
|
36069
36147
|
//#endregion
|
|
36070
36148
|
//#region ../../src/scrawl/engine/scene.ts
|
|
36071
36149
|
var SceneRig = class {
|
|
36072
|
-
constructor(canvas) {
|
|
36150
|
+
constructor(canvas, boardTheme) {
|
|
36073
36151
|
this.renderer = new WebGLRenderer({
|
|
36074
36152
|
canvas,
|
|
36075
36153
|
antialias: true
|
|
@@ -36079,7 +36157,7 @@ var SceneRig = class {
|
|
|
36079
36157
|
this.scene = new Scene();
|
|
36080
36158
|
this.cameraRig = new CameraRig(canvas.clientWidth / Math.max(1, canvas.clientHeight));
|
|
36081
36159
|
this.fog = createFogUniforms(FOG_COLOR);
|
|
36082
|
-
this.board = createBoardSurface(this.fog);
|
|
36160
|
+
this.board = createBoardSurface(this.fog, boardTheme);
|
|
36083
36161
|
this.scene.add(this.board);
|
|
36084
36162
|
this.inkGroup = new Group();
|
|
36085
36163
|
this.inkGroup.name = "ink";
|
|
@@ -36096,9 +36174,17 @@ var SceneRig = class {
|
|
|
36096
36174
|
renderFrame(dtMs) {
|
|
36097
36175
|
this.cameraRig.update(dtMs);
|
|
36098
36176
|
updateFogForCamera(this.fog, this.cameraRig.height);
|
|
36099
|
-
updateBoardSurface(this.board, this.cameraRig.center.x, this.cameraRig.center.y, this.fog.uFogFar.value);
|
|
36177
|
+
updateBoardSurface(this.board, this.cameraRig.center.x, this.cameraRig.center.y, this.fog.uFogFar.value, this.cameraRig.worldPerPixel());
|
|
36100
36178
|
this.renderer.render(this.scene, this.cameraRig.camera);
|
|
36101
36179
|
}
|
|
36180
|
+
/** Live theme update — the board controller's identity stays fixed across theme changes; this is how a new one reaches the render engine. */
|
|
36181
|
+
applyBoardTheme(theme) {
|
|
36182
|
+
setBoardSurfaceTheme(this.board, theme);
|
|
36183
|
+
}
|
|
36184
|
+
/** Zeroes the grid for one render pass (PNG export never bakes it in) and returns a restore function. */
|
|
36185
|
+
suppressGrid() {
|
|
36186
|
+
return suppressBoardSurfaceGrid(this.board);
|
|
36187
|
+
}
|
|
36102
36188
|
dispose() {
|
|
36103
36189
|
this.board.geometry.dispose();
|
|
36104
36190
|
this.board.material.dispose();
|
|
@@ -46547,9 +46633,10 @@ function emptyExtensionRegistry() {
|
|
|
46547
46633
|
* React never reaches past this class.
|
|
46548
46634
|
*/
|
|
46549
46635
|
var ScrawlEngine = class {
|
|
46550
|
-
constructor(canvas, documentId$1, extensionRegistry = emptyExtensionRegistry(), assetController = new AssetController(void 0)) {
|
|
46636
|
+
constructor(canvas, documentId$1, extensionRegistry = emptyExtensionRegistry(), assetController = new AssetController(void 0), boardTheme = DEFAULT_BOARD_SURFACE_THEME) {
|
|
46551
46637
|
this.canvas = canvas;
|
|
46552
46638
|
this.extensionRegistry = extensionRegistry;
|
|
46639
|
+
this.boardTheme = boardTheme;
|
|
46553
46640
|
this.onToolChange = null;
|
|
46554
46641
|
this.onZoomChange = null;
|
|
46555
46642
|
this.onAuditEvent = null;
|
|
@@ -46596,7 +46683,7 @@ var ScrawlEngine = class {
|
|
|
46596
46683
|
this.stampKind = "star";
|
|
46597
46684
|
this.timerDurationMs = TIMER_DEFAULT_DURATION_MS;
|
|
46598
46685
|
this.readOnly = false;
|
|
46599
|
-
this.scene = new SceneRig(canvas);
|
|
46686
|
+
this.scene = new SceneRig(canvas, boardTheme);
|
|
46600
46687
|
this.document = new BoardDocument(documentId(documentId$1));
|
|
46601
46688
|
this.history = new History(this.document);
|
|
46602
46689
|
this.history.onCommand = (command, kind) => {
|
|
@@ -46903,6 +46990,11 @@ var ScrawlEngine = class {
|
|
|
46903
46990
|
height: rig.height
|
|
46904
46991
|
};
|
|
46905
46992
|
}
|
|
46993
|
+
/** Live update of the board surface color/grid — the engine's identity stays fixed across theme changes. */
|
|
46994
|
+
applyBoardTheme(theme) {
|
|
46995
|
+
this.boardTheme = theme;
|
|
46996
|
+
this.scene.applyBoardTheme(theme);
|
|
46997
|
+
}
|
|
46906
46998
|
/**
|
|
46907
46999
|
* Snap to a peer's camera. No-op while drawing so pointer-to-board
|
|
46908
47000
|
* mapping does not warp the in-progress stroke.
|
|
@@ -46921,7 +47013,7 @@ var ScrawlEngine = class {
|
|
|
46921
47013
|
}
|
|
46922
47014
|
/** The saved document as standalone SVG — a pure walk of the wire format. */
|
|
46923
47015
|
exportSVG() {
|
|
46924
|
-
return documentToSVG(this.document.toJSON(), Date.now(), this.extensionRegistry);
|
|
47016
|
+
return documentToSVG(this.document.toJSON(), Date.now(), this.extensionRegistry, this.boardTheme.color);
|
|
46925
47017
|
}
|
|
46926
47018
|
/**
|
|
46927
47019
|
* Content-framed PNG snapshot. Renders once offscreen-style with UI props
|
|
@@ -46957,6 +47049,7 @@ var ScrawlEngine = class {
|
|
|
46957
47049
|
this.notesRenderer.setFocus(null);
|
|
46958
47050
|
this.textsRenderer.setFocus(null);
|
|
46959
47051
|
this.renderer.setGhostsVisible(false);
|
|
47052
|
+
const restoreGrid = this.scene.suppressGrid();
|
|
46960
47053
|
try {
|
|
46961
47054
|
rig.yaw = 0;
|
|
46962
47055
|
rig.pitch = 0;
|
|
@@ -46967,6 +47060,7 @@ var ScrawlEngine = class {
|
|
|
46967
47060
|
const dataUrl = this.scene.renderer.domElement.toDataURL("image/png");
|
|
46968
47061
|
return await (await fetch(dataUrl)).blob();
|
|
46969
47062
|
} finally {
|
|
47063
|
+
restoreGrid();
|
|
46970
47064
|
rig.center.x = saved.x;
|
|
46971
47065
|
rig.center.y = saved.y;
|
|
46972
47066
|
rig.height = saved.height;
|
|
@@ -47976,7 +48070,13 @@ function createBoardControllerWithEngine(options, existingEngine) {
|
|
|
47976
48070
|
}
|
|
47977
48071
|
const extensionRegistry = registryResult.registry;
|
|
47978
48072
|
const assetController = new AssetController(options.assetResolver, { cacheBytes: options.assetCacheBytes });
|
|
47979
|
-
|
|
48073
|
+
let currentBoardTheme = {
|
|
48074
|
+
color: options.boardTheme?.surface ?? DEFAULT_BOARD_SURFACE_THEME.color,
|
|
48075
|
+
gridMode: options.boardTheme?.gridMode ?? DEFAULT_BOARD_SURFACE_THEME.gridMode,
|
|
48076
|
+
gridColor: options.boardTheme?.gridColor ?? DEFAULT_BOARD_SURFACE_THEME.gridColor,
|
|
48077
|
+
gridSpacing: options.boardTheme?.gridSpacing ?? DEFAULT_BOARD_SURFACE_THEME.gridSpacing
|
|
48078
|
+
};
|
|
48079
|
+
const engine = existingEngine ?? (options.canvas ? new ScrawlEngine(options.canvas, options.document.id, extensionRegistry, assetController, currentBoardTheme) : null);
|
|
47980
48080
|
const document = engine?.document ?? new BoardDocument(documentId(options.document.id));
|
|
47981
48081
|
const history = engine?.history ?? new History(document);
|
|
47982
48082
|
const createId = options.createId ?? (() => crypto.randomUUID());
|
|
@@ -48460,6 +48560,15 @@ function createBoardControllerWithEngine(options, existingEngine) {
|
|
|
48460
48560
|
changed();
|
|
48461
48561
|
}
|
|
48462
48562
|
},
|
|
48563
|
+
boardTheme: { set(theme) {
|
|
48564
|
+
currentBoardTheme = {
|
|
48565
|
+
color: theme.surface ?? currentBoardTheme.color,
|
|
48566
|
+
gridMode: theme.gridMode ?? currentBoardTheme.gridMode,
|
|
48567
|
+
gridColor: theme.gridColor ?? currentBoardTheme.gridColor,
|
|
48568
|
+
gridSpacing: theme.gridSpacing ?? currentBoardTheme.gridSpacing
|
|
48569
|
+
};
|
|
48570
|
+
engine?.applyBoardTheme(currentBoardTheme);
|
|
48571
|
+
} },
|
|
48463
48572
|
view: {
|
|
48464
48573
|
fit() {
|
|
48465
48574
|
assertActive();
|
|
@@ -48764,10 +48873,10 @@ function createBoardControllerWithEngine(options, existingEngine) {
|
|
|
48764
48873
|
gather: (nextView) => engine?.applyGatherView(nextView) ?? false
|
|
48765
48874
|
},
|
|
48766
48875
|
export: {
|
|
48767
|
-
svg: () => engine ? engine.exportSVG() : documentToSVG(document.toJSON(), Date.now(), extensionRegistry),
|
|
48876
|
+
svg: () => engine ? engine.exportSVG() : documentToSVG(document.toJSON(), Date.now(), extensionRegistry, currentBoardTheme.color),
|
|
48768
48877
|
png: (options) => engine ? engine.exportPNG(options?.maxSide, { awaitAssets: options?.awaitAssets }) : Promise.resolve(null),
|
|
48769
48878
|
json: () => document.toJSON(),
|
|
48770
|
-
svgAsync: (svgOptions) => exportDocumentSVGWithAssets(document.toJSON(), Date.now(), extensionRegistry, assetController, svgOptions)
|
|
48879
|
+
svgAsync: (svgOptions) => exportDocumentSVGWithAssets(document.toJSON(), Date.now(), extensionRegistry, assetController, currentBoardTheme.color, svgOptions)
|
|
48771
48880
|
},
|
|
48772
48881
|
assets: { async ingest(bytes, mediaType, name, signal) {
|
|
48773
48882
|
assertActive();
|
|
@@ -49254,7 +49363,11 @@ var scrawlThemePresets = Object.freeze({
|
|
|
49254
49363
|
elevationHigh: "0 8px 20px rgba(28, 28, 26, 0.18)",
|
|
49255
49364
|
motionDuration: 140,
|
|
49256
49365
|
motionEasing: "cubic-bezier(0.2, 0, 0, 1)",
|
|
49257
|
-
density: "comfortable"
|
|
49366
|
+
density: "comfortable",
|
|
49367
|
+
boardSurface: "#f5f5f3",
|
|
49368
|
+
gridMode: "none",
|
|
49369
|
+
gridColor: "#deded8",
|
|
49370
|
+
gridSpacing: 5
|
|
49258
49371
|
}),
|
|
49259
49372
|
dark: Object.freeze({
|
|
49260
49373
|
surface: "#171816",
|
|
@@ -49279,7 +49392,11 @@ var scrawlThemePresets = Object.freeze({
|
|
|
49279
49392
|
elevationHigh: "0 8px 20px rgba(0, 0, 0, 0.38)",
|
|
49280
49393
|
motionDuration: 140,
|
|
49281
49394
|
motionEasing: "cubic-bezier(0.2, 0, 0, 1)",
|
|
49282
|
-
density: "comfortable"
|
|
49395
|
+
density: "comfortable",
|
|
49396
|
+
boardSurface: "#232420",
|
|
49397
|
+
gridMode: "none",
|
|
49398
|
+
gridColor: "#33352f",
|
|
49399
|
+
gridSpacing: 5
|
|
49283
49400
|
})
|
|
49284
49401
|
});
|
|
49285
49402
|
var variableNames = {
|
|
@@ -49305,7 +49422,11 @@ var variableNames = {
|
|
|
49305
49422
|
elevationHigh: "--scrawl-elevation-high",
|
|
49306
49423
|
motionDuration: "--scrawl-motion-duration",
|
|
49307
49424
|
motionEasing: "--scrawl-motion-easing",
|
|
49308
|
-
density: "--scrawl-density"
|
|
49425
|
+
density: "--scrawl-density",
|
|
49426
|
+
boardSurface: "--scrawl-board-surface",
|
|
49427
|
+
gridMode: "--scrawl-grid-mode",
|
|
49428
|
+
gridColor: "--scrawl-grid-color",
|
|
49429
|
+
gridSpacing: "--scrawl-grid-spacing"
|
|
49309
49430
|
};
|
|
49310
49431
|
var colorTokens = /* @__PURE__ */ new Set([
|
|
49311
49432
|
"surface",
|
|
@@ -49318,7 +49439,9 @@ var colorTokens = /* @__PURE__ */ new Set([
|
|
|
49318
49439
|
"selection",
|
|
49319
49440
|
"danger",
|
|
49320
49441
|
"warning",
|
|
49321
|
-
"success"
|
|
49442
|
+
"success",
|
|
49443
|
+
"boardSurface",
|
|
49444
|
+
"gridColor"
|
|
49322
49445
|
]);
|
|
49323
49446
|
var knownTokens = new Set(Object.keys(scrawlThemePresets.light));
|
|
49324
49447
|
function validateScrawlTheme(theme) {
|
|
@@ -49355,6 +49478,14 @@ function validateScrawlTheme(theme) {
|
|
|
49355
49478
|
token,
|
|
49356
49479
|
message: "Expected comfortable or compact"
|
|
49357
49480
|
});
|
|
49481
|
+
else if (token === "gridMode" && value !== "none" && value !== "line" && value !== "dot") diagnostics.push({
|
|
49482
|
+
token,
|
|
49483
|
+
message: "Expected none, line, or dot"
|
|
49484
|
+
});
|
|
49485
|
+
else if (token === "gridSpacing" && (!finiteNumber(value) || value < .5 || value > 50)) diagnostics.push({
|
|
49486
|
+
token,
|
|
49487
|
+
message: "Expected spacing 0.5-50 board units"
|
|
49488
|
+
});
|
|
49358
49489
|
else if ((token.endsWith("Family") || token.startsWith("elevation") || token === "motionEasing") && (typeof value !== "string" || !value.trim() || /[;{}]/.test(value))) diagnostics.push({
|
|
49359
49490
|
token,
|
|
49360
49491
|
message: "Expected a safe CSS value"
|
|
@@ -50510,6 +50641,14 @@ function ScrawlProvider({ controller, children, preset = "light", theme, portalC
|
|
|
50510
50641
|
style
|
|
50511
50642
|
]);
|
|
50512
50643
|
useEffect(() => reportThemeDiagnostics(resolved.diagnostics, onThemeDiagnostic), [resolved, onThemeDiagnostic]);
|
|
50644
|
+
useEffect(() => {
|
|
50645
|
+
controller.boardTheme.set({
|
|
50646
|
+
surface: resolved.values.boardSurface,
|
|
50647
|
+
gridMode: resolved.values.gridMode,
|
|
50648
|
+
gridColor: resolved.values.gridColor,
|
|
50649
|
+
gridSpacing: resolved.values.gridSpacing
|
|
50650
|
+
});
|
|
50651
|
+
}, [controller, resolved]);
|
|
50513
50652
|
useDeferredDisposal(controller, disposeOnUnmount);
|
|
50514
50653
|
const value = useMemo(() => ({
|
|
50515
50654
|
controller,
|
|
@@ -50557,8 +50696,16 @@ function Scrawl({ children, preset, theme, portalContainer, className, style, on
|
|
|
50557
50696
|
try {
|
|
50558
50697
|
if (!runtimeRef.current) {
|
|
50559
50698
|
const canvas = suppliedCanvas === void 0 ? ownedCanvasRef.current : suppliedCanvas;
|
|
50699
|
+
const resolved = resolveScrawlTheme(preset, theme);
|
|
50700
|
+
const boardTheme = {
|
|
50701
|
+
surface: resolved.values.boardSurface,
|
|
50702
|
+
gridMode: resolved.values.gridMode,
|
|
50703
|
+
gridColor: resolved.values.gridColor,
|
|
50704
|
+
gridSpacing: resolved.values.gridSpacing
|
|
50705
|
+
};
|
|
50560
50706
|
controller = createBoardController({
|
|
50561
50707
|
...options,
|
|
50708
|
+
boardTheme,
|
|
50562
50709
|
...canvas ? { canvas } : {}
|
|
50563
50710
|
});
|
|
50564
50711
|
runtimeRef.current = {
|
|
@@ -50794,4 +50941,4 @@ function ScrawlBoard({ documentId, initialDocument, onReady, className, style })
|
|
|
50794
50941
|
});
|
|
50795
50942
|
}
|
|
50796
50943
|
//#endregion
|
|
50797
|
-
export { DefaultBoardChrome, InlineEditors, MultiplayerCursors, Scrawl, ScrawlBoard, ScrawlCanvas, ScrawlDefaultUI, ScrawlPortal, ScrawlProvider, StyleShelf, resolveScrawlTheme, scrawlThemePresets, useScrawlController, useScrawlSnapshot, useScrawlTheme, validateScrawlTheme };
|
|
50944
|
+
export { AssetResolutionError, DefaultBoardChrome, InlineEditors, MultiplayerCursors, SUPPORTED_ASSET_MEDIA_TYPES, Scrawl, ScrawlBoard, ScrawlCanvas, ScrawlDefaultUI, ScrawlPortal, ScrawlProvider, StyleShelf, assetRef, clampAssetCacheBytes, cloneCustomObject, isAssetRef, resolveScrawlTheme, scrawlThemePresets, useScrawlController, useScrawlSnapshot, useScrawlTheme, validateScrawlTheme };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrawl-board/board",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
4
|
"description": "The Scrawl Board SDK: an embeddable, collaborative infinite-canvas whiteboard for React and vanilla JS/TS apps.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|