@neta-art/cohub 12.5.0 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +35 -13
  2. package/dist/board/editor/editor.d.ts +7 -5
  3. package/dist/board/editor/index.js +1 -1
  4. package/dist/board/editor/interaction.js +1 -1
  5. package/dist/board/export/index.d.ts +1 -6
  6. package/dist/board/export/index.js +16 -10
  7. package/dist/board/export/node/index.d.ts +2 -7
  8. package/dist/board/export/node/index.js +2 -5
  9. package/dist/board/export/scene.d.ts +3 -7
  10. package/dist/board/export/scene.js +22 -26
  11. package/dist/board/model/asset-key.d.ts +5 -2
  12. package/dist/board/model/asset-key.js +13 -5
  13. package/dist/board/model/index.d.ts +5 -4
  14. package/dist/board/model/index.js +4 -3
  15. package/dist/board/model/media-playback.d.ts +4 -6
  16. package/dist/board/model/media-playback.js +4 -4
  17. package/dist/board/model/read.d.ts +7 -0
  18. package/dist/board/model/read.js +18 -0
  19. package/dist/board/model/themes.d.ts +50 -0
  20. package/dist/board/model/themes.js +44 -6
  21. package/dist/board/render/backdrop-layer.d.ts +21 -0
  22. package/dist/board/render/backdrop-layer.js +227 -0
  23. package/dist/board/render/backdrop.d.ts +45 -0
  24. package/dist/board/render/backdrop.js +62 -0
  25. package/dist/board/render/index.d.ts +3 -2
  26. package/dist/board/render/index.js +7 -6
  27. package/dist/board/render/renderers/arrow-card-renderer.js +1 -1
  28. package/dist/board/render/renderers/audio-card-renderer.js +2 -2
  29. package/dist/board/render/renderers/file-card-renderer.js +1 -1
  30. package/dist/board/render/renderers/frame-card-renderer.js +1 -1
  31. package/dist/board/render/renderers/model-card-renderer.js +1 -1
  32. package/dist/board/render/renderers/shape-card-renderer.js +1 -1
  33. package/dist/board/render/renderers/task-card-renderer.js +2 -2
  34. package/dist/board/render/renderers/text-card-renderer.js +2 -2
  35. package/dist/board/render/renderers/video-card-renderer.js +1 -1
  36. package/dist/board/render/theme.d.ts +2 -0
  37. package/dist/board/render/theme.js +4 -2
  38. package/dist/board/replica/index.d.ts +3 -2
  39. package/dist/board/replica/index.js +34 -24
  40. package/dist/board/replica/indexeddb.js +14 -85
  41. package/dist/board/stage/assets.d.ts +4 -3
  42. package/dist/board/stage/assets.js +186 -83
  43. package/dist/board/stage/backdrop.d.ts +25 -0
  44. package/dist/board/stage/backdrop.js +104 -0
  45. package/dist/board/stage/index.d.ts +2 -1
  46. package/dist/board/stage/scene.js +12 -5
  47. package/dist/board/stage/stage.d.ts +7 -2
  48. package/dist/board/stage/stage.js +44 -24
  49. package/dist/board/stage/texture-pool.d.ts +1 -1
  50. package/dist/board/stage/texture-pool.js +4 -5
  51. package/dist/chunks/app-realtime.js +1 -1
  52. package/dist/chunks/environment.d.ts +34 -21
  53. package/dist/chunks/environment.js +4 -3
  54. package/dist/chunks/http-error.js +28 -5
  55. package/dist/chunks/http.d.ts +87 -18
  56. package/dist/chunks/http.js +1855 -59
  57. package/dist/chunks/websocket.d.ts +9 -1
  58. package/dist/http.d.ts +2 -2
  59. package/dist/http.js +1 -1
  60. package/dist/index.d.ts +9 -3
  61. package/dist/index.js +6 -1080
  62. package/dist/indexeddb.js +79 -0
  63. package/dist/media.d.ts +18 -32
  64. package/dist/media.js +81 -67
  65. package/dist/protocol/dist/board-model.d.ts +33 -26
  66. package/dist/protocol/dist/board-model.js +21 -18
  67. package/dist/protocol/dist/board.d.ts +21 -1
  68. package/dist/protocol/dist/board.js +5 -1
  69. package/dist/protocol/dist/core/media.d.ts +32 -9
  70. package/dist/protocol/dist/core/media.js +203 -48
  71. package/dist/protocol/dist/index.d.ts +3 -3
  72. package/dist/voice-input.js +1 -1
  73. package/dist/websocket.js +37 -5
  74. package/package.json +1 -1
  75. package/dist/board/render/board-background.d.ts +0 -18
  76. package/dist/board/render/board-background.js +0 -104
@@ -64,6 +64,14 @@ declare const BOARD_THEME_DATA: {
64
64
  };
65
65
  };
66
66
  readonly style: {};
67
+ readonly backdrop: {
68
+ readonly pattern: {
69
+ readonly kind: "dots";
70
+ readonly pitch: 24;
71
+ readonly color: 2566444;
72
+ readonly size: 2;
73
+ };
74
+ };
67
75
  };
68
76
  readonly light: {
69
77
  readonly colorScheme: "light";
@@ -127,6 +135,14 @@ declare const BOARD_THEME_DATA: {
127
135
  };
128
136
  };
129
137
  readonly style: {};
138
+ readonly backdrop: {
139
+ readonly pattern: {
140
+ readonly kind: "dots";
141
+ readonly pitch: 24;
142
+ readonly color: 15001321;
143
+ readonly size: 2;
144
+ };
145
+ };
130
146
  };
131
147
  readonly "solarized-dark": {
132
148
  readonly colorScheme: "dark";
@@ -190,6 +206,14 @@ declare const BOARD_THEME_DATA: {
190
206
  };
191
207
  };
192
208
  readonly style: {};
209
+ readonly backdrop: {
210
+ readonly pattern: {
211
+ readonly kind: "dots";
212
+ readonly pitch: 24;
213
+ readonly color: 1122594;
214
+ readonly size: 2;
215
+ };
216
+ };
193
217
  };
194
218
  readonly "solarized-light": {
195
219
  readonly colorScheme: "light";
@@ -253,6 +277,14 @@ declare const BOARD_THEME_DATA: {
253
277
  };
254
278
  };
255
279
  readonly style: {};
280
+ readonly backdrop: {
281
+ readonly pattern: {
282
+ readonly kind: "dots";
283
+ readonly pitch: 24;
284
+ readonly color: 15130570;
285
+ readonly size: 2;
286
+ };
287
+ };
256
288
  };
257
289
  readonly "neta-studio": {
258
290
  readonly colorScheme: "dark";
@@ -405,6 +437,15 @@ declare const BOARD_THEME_DATA: {
405
437
  readonly font: "\"Figtree Variable\", \"PingFang SC\", \"Noto Sans CJK SC\", \"Microsoft YaHei\", system-ui, sans-serif";
406
438
  readonly frameLabelSize: 16;
407
439
  };
440
+ readonly backdrop: {
441
+ readonly pattern: {
442
+ readonly kind: "dots";
443
+ readonly pitch: 24;
444
+ readonly color: 14935011;
445
+ readonly size: 2;
446
+ readonly shape: "square";
447
+ };
448
+ };
408
449
  };
409
450
  readonly "neta-pixel-dark": {
410
451
  readonly colorScheme: "dark";
@@ -489,6 +530,15 @@ declare const BOARD_THEME_DATA: {
489
530
  readonly font: "\"Figtree Variable\", \"PingFang SC\", \"Noto Sans CJK SC\", \"Microsoft YaHei\", system-ui, sans-serif";
490
531
  readonly frameLabelSize: 16;
491
532
  };
533
+ readonly backdrop: {
534
+ readonly pattern: {
535
+ readonly kind: "dots";
536
+ readonly pitch: 24;
537
+ readonly color: 3816512;
538
+ readonly size: 2;
539
+ readonly shape: "square";
540
+ };
541
+ };
492
542
  };
493
543
  };
494
544
  //#endregion
@@ -70,7 +70,13 @@ const BOARD_THEME_DATA = {
70
70
  label: 15330286
71
71
  }
72
72
  },
73
- style: {}
73
+ style: {},
74
+ backdrop: { pattern: {
75
+ kind: "dots",
76
+ pitch: 24,
77
+ color: 2566444,
78
+ size: 2
79
+ } }
74
80
  },
75
81
  light: {
76
82
  colorScheme: "light",
@@ -133,7 +139,13 @@ const BOARD_THEME_DATA = {
133
139
  label: 66050
134
140
  }
135
141
  },
136
- style: {}
142
+ style: {},
143
+ backdrop: { pattern: {
144
+ kind: "dots",
145
+ pitch: 24,
146
+ color: 15001321,
147
+ size: 2
148
+ } }
137
149
  },
138
150
  "solarized-dark": {
139
151
  colorScheme: "dark",
@@ -196,7 +208,13 @@ const BOARD_THEME_DATA = {
196
208
  label: 12572374
197
209
  }
198
210
  },
199
- style: {}
211
+ style: {},
212
+ backdrop: { pattern: {
213
+ kind: "dots",
214
+ pitch: 24,
215
+ color: 1122594,
216
+ size: 2
217
+ } }
200
218
  },
201
219
  "solarized-light": {
202
220
  colorScheme: "light",
@@ -259,7 +277,13 @@ const BOARD_THEME_DATA = {
259
277
  label: 2110772
260
278
  }
261
279
  },
262
- style: {}
280
+ style: {},
281
+ backdrop: { pattern: {
282
+ kind: "dots",
283
+ pitch: 24,
284
+ color: 15130570,
285
+ size: 2
286
+ } }
263
287
  },
264
288
  "neta-studio": {
265
289
  colorScheme: "dark",
@@ -409,7 +433,14 @@ const BOARD_THEME_DATA = {
409
433
  motion: "stepped",
410
434
  font: "\"Figtree Variable\", \"PingFang SC\", \"Noto Sans CJK SC\", \"Microsoft YaHei\", system-ui, sans-serif",
411
435
  frameLabelSize: 16
412
- }
436
+ },
437
+ backdrop: { pattern: {
438
+ kind: "dots",
439
+ pitch: 24,
440
+ color: 14935011,
441
+ size: 2,
442
+ shape: "square"
443
+ } }
413
444
  },
414
445
  "neta-pixel-dark": {
415
446
  colorScheme: "dark",
@@ -493,7 +524,14 @@ const BOARD_THEME_DATA = {
493
524
  motion: "stepped",
494
525
  font: "\"Figtree Variable\", \"PingFang SC\", \"Noto Sans CJK SC\", \"Microsoft YaHei\", system-ui, sans-serif",
495
526
  frameLabelSize: 16
496
- }
527
+ },
528
+ backdrop: { pattern: {
529
+ kind: "dots",
530
+ pitch: 24,
531
+ color: 3816512,
532
+ size: 2,
533
+ shape: "square"
534
+ } }
497
535
  }
498
536
  };
499
537
  //#endregion
@@ -0,0 +1,21 @@
1
+ import { BoardBackdrop } from "./backdrop.js";
2
+ import { Container, Texture } from "pixi.js";
3
+ //#region src/board/render/backdrop-layer.d.ts
4
+ type BoardBackdropView = {
5
+ x: number;
6
+ y: number;
7
+ zoom: number;
8
+ width: number;
9
+ height: number;
10
+ density: number;
11
+ };
12
+ type BoardBackdropLayer = {
13
+ readonly container: Container;
14
+ sync(backdrop: BoardBackdrop, view: BoardBackdropView, texture: Texture | null, imageAlpha?: number): void;
15
+ destroy(): void;
16
+ };
17
+ declare function createBoardBackdropLayer(options: {
18
+ patterns: boolean;
19
+ }): BoardBackdropLayer;
20
+ //#endregion
21
+ export { BoardBackdropLayer, BoardBackdropView, createBoardBackdropLayer };
@@ -0,0 +1,227 @@
1
+ import { boardPatternLevel } from "./backdrop.js";
2
+ import { Container, Geometry, Mesh, Shader, Sprite, TilingSprite, UniformGroup } from "pixi.js";
3
+ //#region src/board/render/backdrop-layer.ts
4
+ const VERTEX = `
5
+ in vec2 aPosition;
6
+ out vec2 vPosition;
7
+
8
+ uniform mat3 uProjectionMatrix;
9
+ uniform mat3 uWorldTransformMatrix;
10
+ uniform mat3 uTransformMatrix;
11
+
12
+ void main() {
13
+ mat3 mvp = uProjectionMatrix * uWorldTransformMatrix * uTransformMatrix;
14
+ gl_Position = vec4((mvp * vec3(aPosition, 1.0)).xy, 0.0, 1.0);
15
+ vPosition = aPosition;
16
+ }
17
+ `;
18
+ const FRAGMENT = `
19
+ in vec2 vPosition;
20
+ out vec4 finalColor;
21
+
22
+ uniform float uDensity;
23
+ uniform vec2 uOrigin;
24
+ uniform float uPitch;
25
+ uniform float uFade;
26
+ uniform float uSize;
27
+ uniform float uSquare;
28
+ uniform float uLines;
29
+ uniform vec4 uInk;
30
+
31
+ vec2 snap(vec2 center) {
32
+ return mod(uSize, 2.0) == 1.0 ? floor(center) + 0.5 : floor(center + 0.5);
33
+ }
34
+
35
+ float coverage(vec2 p, float pitch) {
36
+ vec2 d = abs(p - snap(uOrigin + floor((p - uOrigin) / pitch + 0.5) * pitch));
37
+ float radius = uSize * 0.5;
38
+ if (uLines > 0.5) return min(d.x, d.y) < radius ? 1.0 : 0.0;
39
+ if (uSquare > 0.5) return max(d.x, d.y) < radius ? 1.0 : 0.0;
40
+ float edge = 0.5 * uDensity;
41
+ return clamp((radius + edge - length(d)) / edge, 0.0, 1.0);
42
+ }
43
+
44
+ void main() {
45
+ vec2 p = vPosition * uDensity;
46
+ float alpha = uInk.a * max(coverage(p, uPitch * 2.0), coverage(p, uPitch) * uFade);
47
+ finalColor = vec4(uInk.rgb * alpha, alpha);
48
+ }
49
+ `;
50
+ function wrap(value, period) {
51
+ return (value % period + period) % period;
52
+ }
53
+ function createPatternMesh() {
54
+ const positions = /* @__PURE__ */ new Float32Array(8);
55
+ const geometry = new Geometry({
56
+ attributes: { aPosition: {
57
+ buffer: positions,
58
+ format: "float32x2"
59
+ } },
60
+ indexBuffer: new Uint32Array([
61
+ 0,
62
+ 1,
63
+ 2,
64
+ 0,
65
+ 2,
66
+ 3
67
+ ])
68
+ });
69
+ const uniforms = new UniformGroup({
70
+ uDensity: {
71
+ value: 1,
72
+ type: "f32"
73
+ },
74
+ uOrigin: {
75
+ value: /* @__PURE__ */ new Float32Array(2),
76
+ type: "vec2<f32>"
77
+ },
78
+ uPitch: {
79
+ value: 1,
80
+ type: "f32"
81
+ },
82
+ uFade: {
83
+ value: 0,
84
+ type: "f32"
85
+ },
86
+ uSize: {
87
+ value: 1,
88
+ type: "f32"
89
+ },
90
+ uSquare: {
91
+ value: 0,
92
+ type: "f32"
93
+ },
94
+ uLines: {
95
+ value: 0,
96
+ type: "f32"
97
+ },
98
+ uInk: {
99
+ value: /* @__PURE__ */ new Float32Array(4),
100
+ type: "vec4<f32>"
101
+ }
102
+ });
103
+ const shader = Shader.from({
104
+ gl: {
105
+ name: "board-backdrop-pattern",
106
+ vertex: VERTEX,
107
+ fragment: FRAGMENT,
108
+ preferredFragmentPrecision: "highp"
109
+ },
110
+ resources: { patternUniforms: uniforms }
111
+ });
112
+ const mesh = new Mesh({
113
+ geometry,
114
+ shader,
115
+ label: "board-backdrop-pattern"
116
+ });
117
+ let width = 0;
118
+ let height = 0;
119
+ return {
120
+ mesh,
121
+ sync(pattern, view) {
122
+ if (view.width !== width || view.height !== height) {
123
+ width = view.width;
124
+ height = view.height;
125
+ positions.set([
126
+ 0,
127
+ 0,
128
+ width,
129
+ 0,
130
+ width,
131
+ height,
132
+ 0,
133
+ height
134
+ ]);
135
+ geometry.getBuffer("aPosition").update();
136
+ }
137
+ const level = boardPatternLevel(pattern, view.zoom);
138
+ const pitch = level.pitch * view.density;
139
+ const values = uniforms.uniforms;
140
+ values.uDensity = view.density;
141
+ values.uOrigin[0] = wrap(view.x * view.density, pitch * 2);
142
+ values.uOrigin[1] = wrap(view.y * view.density, pitch * 2);
143
+ values.uPitch = pitch;
144
+ values.uFade = level.fade;
145
+ values.uSize = Math.max(1, Math.round(pattern.size * view.density));
146
+ values.uSquare = pattern.shape === "square" ? 1 : 0;
147
+ values.uLines = pattern.kind === "grid" ? 1 : 0;
148
+ values.uInk[0] = (pattern.color >> 16 & 255) / 255;
149
+ values.uInk[1] = (pattern.color >> 8 & 255) / 255;
150
+ values.uInk[2] = (pattern.color & 255) / 255;
151
+ values.uInk[3] = pattern.alpha;
152
+ },
153
+ destroy() {
154
+ mesh.destroy();
155
+ geometry.destroy();
156
+ shader.destroy();
157
+ }
158
+ };
159
+ }
160
+ function placeImage(parts, image, texture, view, alpha) {
161
+ if (image.fit === "repeat") {
162
+ if (parts.picture) parts.picture.visible = false;
163
+ parts.tiles ??= parts.container.addChildAt(new TilingSprite({
164
+ texture,
165
+ label: "board-backdrop-tiles"
166
+ }), 0);
167
+ const tiles = parts.tiles;
168
+ const tileWidth = (image.tile?.width ?? texture.width) * view.zoom;
169
+ const tileHeight = (image.tile?.height ?? texture.height) * view.zoom;
170
+ tiles.texture = texture;
171
+ tiles.visible = true;
172
+ tiles.alpha = alpha;
173
+ tiles.width = view.width;
174
+ tiles.height = view.height;
175
+ tiles.tileScale.set(tileWidth / texture.width, tileHeight / texture.height);
176
+ tiles.tilePosition.set(wrap(view.x, tileWidth), wrap(view.y, tileHeight));
177
+ return;
178
+ }
179
+ if (parts.tiles) parts.tiles.visible = false;
180
+ parts.picture ??= parts.container.addChildAt(new Sprite({
181
+ texture,
182
+ label: "board-backdrop-picture"
183
+ }), 0);
184
+ const picture = parts.picture;
185
+ const scale = (image.fit === "cover" ? Math.max : Math.min)(view.width / texture.width, view.height / texture.height);
186
+ picture.texture = texture;
187
+ picture.visible = true;
188
+ picture.alpha = alpha;
189
+ picture.width = texture.width * scale;
190
+ picture.height = texture.height * scale;
191
+ picture.position.set((view.width - picture.width) / 2, (view.height - picture.height) / 2);
192
+ }
193
+ function createBoardBackdropLayer(options) {
194
+ const container = new Container({ label: "board-backdrop" });
195
+ const parts = {
196
+ tiles: null,
197
+ picture: null,
198
+ container
199
+ };
200
+ let pattern = null;
201
+ return {
202
+ container,
203
+ sync(backdrop, view, texture, imageAlpha = 1) {
204
+ if (backdrop.image && texture) placeImage(parts, backdrop.image, texture, view, backdrop.image.opacity * imageAlpha);
205
+ else {
206
+ if (parts.tiles) parts.tiles.visible = false;
207
+ if (parts.picture) parts.picture.visible = false;
208
+ }
209
+ const shown = options.patterns && backdrop.pattern !== null;
210
+ if (shown && backdrop.pattern) {
211
+ if (!pattern) {
212
+ pattern = createPatternMesh();
213
+ container.addChild(pattern.mesh);
214
+ }
215
+ pattern.sync(backdrop.pattern, view);
216
+ }
217
+ if (pattern) pattern.mesh.visible = shown;
218
+ },
219
+ destroy() {
220
+ pattern?.destroy();
221
+ pattern = null;
222
+ container.destroy({ children: true });
223
+ }
224
+ };
225
+ }
226
+ //#endregion
227
+ export { createBoardBackdropLayer };
@@ -0,0 +1,45 @@
1
+ import { BoardBackgroundFit, BoardSettings } from "../../protocol/dist/board-model.js";
2
+ import "../../protocol/dist/index.js";
3
+ import { BoardShapeColors } from "../model/palette.js";
4
+ import { BoardRenderPalette } from "./renderers/board-renderer-registry.js";
5
+ //#region src/board/render/backdrop.d.ts
6
+ type BoardBackdropPattern = {
7
+ kind: "dots" | "grid";
8
+ pitch: number;
9
+ color: number;
10
+ alpha: number;
11
+ size: number;
12
+ shape: "round" | "square";
13
+ subdivide: boolean;
14
+ };
15
+ type BoardBackdropImage = {
16
+ src: string;
17
+ fit: BoardBackgroundFit;
18
+ opacity: number;
19
+ tile?: {
20
+ width: number;
21
+ height: number;
22
+ };
23
+ };
24
+ type BoardBackdrop = {
25
+ color: number;
26
+ image: BoardBackdropImage | null;
27
+ pattern: BoardBackdropPattern | null;
28
+ };
29
+ type BoardThemeBackdrop = {
30
+ image?: BoardBackdropImage;
31
+ pattern?: Pick<BoardBackdropPattern, "kind" | "pitch" | "color"> & Partial<Pick<BoardBackdropPattern, "alpha" | "size" | "shape">>;
32
+ };
33
+ type BoardBackdropTheme = {
34
+ palette: BoardRenderPalette;
35
+ colors: BoardShapeColors;
36
+ colorScheme: "dark" | "light";
37
+ backdrop?: BoardThemeBackdrop;
38
+ };
39
+ declare function resolveBoardBackdrop(settings: BoardSettings, theme: BoardBackdropTheme, purpose?: "stage" | "export"): BoardBackdrop;
40
+ declare function boardPatternLevel(pattern: Pick<BoardBackdropPattern, "pitch" | "subdivide">, zoom: number): {
41
+ pitch: number;
42
+ fade: number;
43
+ };
44
+ //#endregion
45
+ export { BoardBackdrop, BoardBackdropImage, BoardBackdropPattern, BoardBackdropTheme, BoardThemeBackdrop, boardPatternLevel, resolveBoardBackdrop };
@@ -0,0 +1,62 @@
1
+ import "../../protocol/dist/board-model.js";
2
+ import { isBoardColorId, pickBoardColor } from "../model/palette.js";
3
+ import { parseBoardCssColor } from "./css-color.js";
4
+ //#region src/board/render/backdrop.ts
5
+ const PATTERN_DEFAULTS = {
6
+ dots: {
7
+ alpha: .5,
8
+ size: 2
9
+ },
10
+ grid: {
11
+ alpha: 1,
12
+ size: 1
13
+ }
14
+ };
15
+ function resolveBoardBackdrop(settings, theme, purpose = "stage") {
16
+ const { color, image, pattern } = settings.background;
17
+ const themed = !(color !== void 0 || image !== void 0) && purpose === "stage" ? theme.backdrop : void 0;
18
+ return {
19
+ color: backgroundColor(settings.background.color, theme),
20
+ image: image ? {
21
+ src: image.src,
22
+ fit: image.fit,
23
+ opacity: image.opacity ?? 1
24
+ } : themed?.image ?? null,
25
+ pattern: purpose === "export" || pattern === "none" ? null : pattern ? patternStyle(theme, pattern, settings.grid?.size ?? 24, false) : themed?.pattern ? patternStyle(theme, themed.pattern.kind, themed.pattern.pitch, true) : null
26
+ };
27
+ }
28
+ function backgroundColor(color, theme) {
29
+ const value = typeof color === "object" ? color[theme.colorScheme] : color;
30
+ if (!value) return theme.palette.bg;
31
+ const token = value.trim().toLowerCase();
32
+ if (isBoardColorId(token)) return pickBoardColor(theme.colors, token, theme.colorScheme).fill;
33
+ return parseBoardCssColor(value) ?? theme.palette.bg;
34
+ }
35
+ function patternStyle(theme, kind, pitch, subdivide) {
36
+ const own = theme.backdrop?.pattern?.kind === kind ? theme.backdrop.pattern : void 0;
37
+ const defaults = PATTERN_DEFAULTS[kind];
38
+ return {
39
+ kind,
40
+ pitch,
41
+ color: own?.color ?? (kind === "grid" ? theme.palette.border : theme.palette.muted),
42
+ alpha: own ? own.alpha ?? 1 : defaults.alpha,
43
+ size: own?.size ?? defaults.size,
44
+ shape: own?.shape ?? "round",
45
+ subdivide
46
+ };
47
+ }
48
+ const MIN_GAP = 8;
49
+ const FADE = .25;
50
+ function boardPatternLevel(pattern, zoom) {
51
+ const gap = Math.max(pattern.pitch / 1.25, MIN_GAP);
52
+ const unit = pattern.pitch * Math.max(zoom, 1e-6);
53
+ const level = Math.ceil(Math.log2(gap / unit));
54
+ const pitch = unit * 2 ** (pattern.subdivide ? level : Math.max(0, level));
55
+ const t = Math.min(1, Math.max(0, (pitch / gap - 1) / FADE));
56
+ return {
57
+ pitch,
58
+ fade: t * t * (3 - 2 * t)
59
+ };
60
+ }
61
+ //#endregion
62
+ export { boardPatternLevel, resolveBoardBackdrop };
@@ -3,7 +3,8 @@ import { BOARD_LOD_HYSTERESIS, BoardLod, BoardLodKind, COMPACT_BOARD_LOD, DEFAUL
3
3
  import { BoardCardHit, BoardCardRenderer, BoardCardRendererResolver, BoardRenderContext, BoardRenderLabels, BoardRenderPalette, BoardScriptHost, DEFAULT_BOARD_RENDER_LABELS, createBoardCardRendererResolver, getBoardCardRenderer } from "./renderers/board-renderer-registry.js";
4
4
  import { createBoardRenderSampler } from "./sampling.js";
5
5
  import { BoardRenderDiagnostic, inspectBoardItems, inspectBoardScene, measureBoardText } from "./diagnostics.js";
6
- import { BoardBackgroundContext, createBoardBackground, updateBoardBackground } from "./board-background.js";
6
+ import { BoardBackdrop, BoardBackdropImage, BoardBackdropPattern, BoardBackdropTheme, BoardThemeBackdrop, boardPatternLevel, resolveBoardBackdrop } from "./backdrop.js";
7
+ import { BoardBackdropLayer, BoardBackdropView, createBoardBackdropLayer } from "./backdrop-layer.js";
7
8
  import { CARD_TAG_SIZE, CardGlyph, CardTag, createCardTag, drawCardGlyph, formatBoardDuration, syncCardTag, traceCube, zoomCardTag } from "./card-tag.js";
8
9
  import { ClipGroup, clippingAncestor, isClippingFrame, syncClipGroup, traceFrameOutline } from "./clip.js";
9
10
  import { BoardCssPaint, parseBoardCssColor, parseBoardCssPaint } from "./css-color.js";
@@ -21,4 +22,4 @@ import { BoardTextEditInput, BoardTextEditLayout, boardTextEditLayout } from "./
21
22
  import { fitTextToLines, fitTextToWidth } from "./text-fit.js";
22
23
  import { boardTextResolution, getBoardResolution, syncTextResolution, textZoomBucket } from "./text-resolution.js";
23
24
  import { VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, loadVideoThumbnailTexture, videoTextureNaturalSize, videoThumbnailSize } from "./video-thumbnail.js";
24
- export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, BOARD_LOD_HYSTERESIS, BOARD_PLAY_MEDIA, BoardBackgroundContext, BoardCardHit, BoardCardRenderer, BoardCardRendererResolver, BoardCssPaint, BoardLod, BoardLodKind, BoardMediaAction, BoardRenderContext, BoardRenderDiagnostic, BoardRenderLabels, BoardRenderPalette, BoardRenderStyle, BoardRenderStyleInput, BoardRenderTheme, BoardScriptHost, BoardScriptHostOptions, BoardSelectionStyle, BoardShadowStyle, BoardTextEditInput, BoardTextEditLayout, BoardTextLineLayout, BoardTextLineOptions, BoardTextStyle, BoardTextWhiteSpace, BrowserBoardScriptHost, CARD_TAG_SIZE, COMPACT_BOARD_LOD, CardCrop, CardElevation, CardGlyph, CardRect, CardSurface, CardTag, ClipGroup, DEFAULT_BOARD_LOD, DEFAULT_BOARD_RENDER_LABELS, type FarPlateStyle, PIXEL_STEP, VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, boardCardDetailed, boardLodRatio, boardLodSize, boardLongEdge, boardMediaActionAt, boardRenderTheme, boardTextEditLayout, boardTextResolution, boardTextSize, boardTextStyle, canvasFont, canvasFontFamily, cardElevation, cardOutlinePoints, cardShadow, clippingAncestor, containRect, createBoardBackground, createBoardCardRendererResolver, createBoardRenderSampler, createBoardScriptHost, createCardTag, cssBaselineShift, dashPattern, defaultBoardPalette, defaultBoardRenderStyle, drawCardGlyph, drawCardShadow, drawCardSurface, drawFarBars, drawFarPlate, endAngle, ensureBoardTextMeasurement, farPictureTone, fillCardPicture, fitLineWithEllipsis, fitTextToLines, fitTextToWidth, formatBoardDuration, getBoardCardRenderer, getBoardResolution, inspectBoardItems, inspectBoardScene, installBoardTextMeasurement, isBoardCard, isClippingFrame, itemAlpha, itemColor, layoutTextLines, loadVideoThumbnailTexture, measureBoardText, measureTextWidth, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayHit, mediaPlayKeyCenter, onBoardTextFontsChange, parseBoardCssColor, parseBoardCssPaint, prepareBrowserBoardScripts, resolveBoardRenderStyle, roundRectPoints, syncCardTag, syncClipGroup, syncTextResolution, textZoomBucket, traceArrowhead, traceCardOutline, traceCube, traceFrameOutline, tracePixelRect, tracePolyline, trimPolyline, updateBoardBackground, videoTextureNaturalSize, videoThumbnailSize, zoomCardTag };
25
+ export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, BOARD_LOD_HYSTERESIS, BOARD_PLAY_MEDIA, BoardBackdrop, BoardBackdropImage, BoardBackdropLayer, BoardBackdropPattern, BoardBackdropTheme, BoardBackdropView, BoardCardHit, BoardCardRenderer, BoardCardRendererResolver, BoardCssPaint, BoardLod, BoardLodKind, BoardMediaAction, BoardRenderContext, BoardRenderDiagnostic, BoardRenderLabels, BoardRenderPalette, BoardRenderStyle, BoardRenderStyleInput, BoardRenderTheme, BoardScriptHost, BoardScriptHostOptions, BoardSelectionStyle, BoardShadowStyle, BoardTextEditInput, BoardTextEditLayout, BoardTextLineLayout, BoardTextLineOptions, BoardTextStyle, BoardTextWhiteSpace, BoardThemeBackdrop, BrowserBoardScriptHost, CARD_TAG_SIZE, COMPACT_BOARD_LOD, CardCrop, CardElevation, CardGlyph, CardRect, CardSurface, CardTag, ClipGroup, DEFAULT_BOARD_LOD, DEFAULT_BOARD_RENDER_LABELS, type FarPlateStyle, PIXEL_STEP, VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, boardCardDetailed, boardLodRatio, boardLodSize, boardLongEdge, boardMediaActionAt, boardPatternLevel, boardRenderTheme, boardTextEditLayout, boardTextResolution, boardTextSize, boardTextStyle, canvasFont, canvasFontFamily, cardElevation, cardOutlinePoints, cardShadow, clippingAncestor, containRect, createBoardBackdropLayer, createBoardCardRendererResolver, createBoardRenderSampler, createBoardScriptHost, createCardTag, cssBaselineShift, dashPattern, defaultBoardPalette, defaultBoardRenderStyle, drawCardGlyph, drawCardShadow, drawCardSurface, drawFarBars, drawFarPlate, endAngle, ensureBoardTextMeasurement, farPictureTone, fillCardPicture, fitLineWithEllipsis, fitTextToLines, fitTextToWidth, formatBoardDuration, getBoardCardRenderer, getBoardResolution, inspectBoardItems, inspectBoardScene, installBoardTextMeasurement, isBoardCard, isClippingFrame, itemAlpha, itemColor, layoutTextLines, loadVideoThumbnailTexture, measureBoardText, measureTextWidth, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayHit, mediaPlayKeyCenter, onBoardTextFontsChange, parseBoardCssColor, parseBoardCssPaint, prepareBrowserBoardScripts, resolveBoardBackdrop, resolveBoardRenderStyle, roundRectPoints, syncCardTag, syncClipGroup, syncTextResolution, textZoomBucket, traceArrowhead, traceCardOutline, traceCube, traceFrameOutline, tracePixelRect, tracePolyline, trimPolyline, videoTextureNaturalSize, videoThumbnailSize, zoomCardTag };
@@ -1,14 +1,15 @@
1
1
  import { parseBoardCssColor, parseBoardCssPaint } from "./css-color.js";
2
- import { defaultBoardPalette, itemAlpha, itemColor } from "./palette.js";
3
- import { createBoardRenderSampler } from "./sampling.js";
2
+ import { boardPatternLevel, resolveBoardBackdrop } from "./backdrop.js";
3
+ import { createBoardBackdropLayer } from "./backdrop-layer.js";
4
4
  import { BOARD_FONT_STACKS, boardTextStyle, canvasFont, canvasFontFamily, cssBaselineShift, ensureBoardTextMeasurement, fitLineWithEllipsis, installBoardTextMeasurement, layoutTextLines, measureTextWidth, onBoardTextFontsChange } from "./text-measurement.js";
5
- import { inspectBoardItems, inspectBoardScene, measureBoardText } from "./diagnostics.js";
6
- import { BOARD_LOD_HYSTERESIS, COMPACT_BOARD_LOD, DEFAULT_BOARD_LOD, boardCardDetailed, boardLodRatio, boardLodSize, boardLongEdge, boardTextSize } from "./lod.js";
7
- import { createBoardBackground, updateBoardBackground } from "./board-background.js";
8
5
  import { fitTextToLines, fitTextToWidth } from "./text-fit.js";
9
6
  import { boardTextResolution, getBoardResolution, syncTextResolution, textZoomBucket } from "./text-resolution.js";
10
7
  import { CARD_TAG_SIZE, createCardTag, drawCardGlyph, formatBoardDuration, syncCardTag, traceCube, zoomCardTag } from "./card-tag.js";
11
8
  import { clippingAncestor, isClippingFrame, syncClipGroup, traceFrameOutline } from "./clip.js";
9
+ import { inspectBoardItems, inspectBoardScene, measureBoardText } from "./diagnostics.js";
10
+ import { defaultBoardPalette, itemAlpha, itemColor } from "./palette.js";
11
+ import { createBoardRenderSampler } from "./sampling.js";
12
+ import { BOARD_LOD_HYSTERESIS, COMPACT_BOARD_LOD, DEFAULT_BOARD_LOD, boardCardDetailed, boardLodRatio, boardLodSize, boardLongEdge, boardTextSize } from "./lod.js";
12
13
  import { dashPattern, endAngle, roundRectPoints, traceArrowhead, tracePolyline, trimPolyline } from "./stroke.js";
13
14
  import { PIXEL_STEP, cardElevation, cardOutlinePoints, cardShadow, containRect, drawCardShadow, drawCardSurface, fillCardPicture, isBoardCard, traceCardOutline, tracePixelRect } from "./surface.js";
14
15
  import { drawFarBars, drawFarPlate, farPictureTone } from "./renderers/far-plate.js";
@@ -21,4 +22,4 @@ import { defaultBoardRenderStyle, resolveBoardRenderStyle } from "./style.js";
21
22
  import { boardRenderTheme } from "./theme.js";
22
23
  import { boardTextEditLayout } from "./text-edit.js";
23
24
  import { VIDEO_THUMBNAIL_MAX_EDGE, loadVideoThumbnailTexture, videoTextureNaturalSize, videoThumbnailSize } from "./video-thumbnail.js";
24
- export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, BOARD_LOD_HYSTERESIS, BOARD_PLAY_MEDIA, CARD_TAG_SIZE, COMPACT_BOARD_LOD, DEFAULT_BOARD_LOD, DEFAULT_BOARD_RENDER_LABELS, PIXEL_STEP, VIDEO_THUMBNAIL_MAX_EDGE, boardCardDetailed, boardLodRatio, boardLodSize, boardLongEdge, boardMediaActionAt, boardRenderTheme, boardTextEditLayout, boardTextResolution, boardTextSize, boardTextStyle, canvasFont, canvasFontFamily, cardElevation, cardOutlinePoints, cardShadow, clippingAncestor, containRect, createBoardBackground, createBoardCardRendererResolver, createBoardRenderSampler, createBoardScriptHost, createCardTag, cssBaselineShift, dashPattern, defaultBoardPalette, defaultBoardRenderStyle, drawCardGlyph, drawCardShadow, drawCardSurface, drawFarBars, drawFarPlate, endAngle, ensureBoardTextMeasurement, farPictureTone, fillCardPicture, fitLineWithEllipsis, fitTextToLines, fitTextToWidth, formatBoardDuration, getBoardCardRenderer, getBoardResolution, inspectBoardItems, inspectBoardScene, installBoardTextMeasurement, isBoardCard, isClippingFrame, itemAlpha, itemColor, layoutTextLines, loadVideoThumbnailTexture, measureBoardText, measureTextWidth, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayHit, mediaPlayKeyCenter, onBoardTextFontsChange, parseBoardCssColor, parseBoardCssPaint, prepareBrowserBoardScripts, resolveBoardRenderStyle, roundRectPoints, syncCardTag, syncClipGroup, syncTextResolution, textZoomBucket, traceArrowhead, traceCardOutline, traceCube, traceFrameOutline, tracePixelRect, tracePolyline, trimPolyline, updateBoardBackground, videoTextureNaturalSize, videoThumbnailSize, zoomCardTag };
25
+ export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, BOARD_LOD_HYSTERESIS, BOARD_PLAY_MEDIA, CARD_TAG_SIZE, COMPACT_BOARD_LOD, DEFAULT_BOARD_LOD, DEFAULT_BOARD_RENDER_LABELS, PIXEL_STEP, VIDEO_THUMBNAIL_MAX_EDGE, boardCardDetailed, boardLodRatio, boardLodSize, boardLongEdge, boardMediaActionAt, boardPatternLevel, boardRenderTheme, boardTextEditLayout, boardTextResolution, boardTextSize, boardTextStyle, canvasFont, canvasFontFamily, cardElevation, cardOutlinePoints, cardShadow, clippingAncestor, containRect, createBoardBackdropLayer, createBoardCardRendererResolver, createBoardRenderSampler, createBoardScriptHost, createCardTag, cssBaselineShift, dashPattern, defaultBoardPalette, defaultBoardRenderStyle, drawCardGlyph, drawCardShadow, drawCardSurface, drawFarBars, drawFarPlate, endAngle, ensureBoardTextMeasurement, farPictureTone, fillCardPicture, fitLineWithEllipsis, fitTextToLines, fitTextToWidth, formatBoardDuration, getBoardCardRenderer, getBoardResolution, inspectBoardItems, inspectBoardScene, installBoardTextMeasurement, isBoardCard, isClippingFrame, itemAlpha, itemColor, layoutTextLines, loadVideoThumbnailTexture, measureBoardText, measureTextWidth, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayHit, mediaPlayKeyCenter, onBoardTextFontsChange, parseBoardCssColor, parseBoardCssPaint, prepareBrowserBoardScripts, resolveBoardBackdrop, resolveBoardRenderStyle, roundRectPoints, syncCardTag, syncClipGroup, syncTextResolution, textZoomBucket, traceArrowhead, traceCardOutline, traceCube, traceFrameOutline, tracePixelRect, tracePolyline, trimPolyline, videoTextureNaturalSize, videoThumbnailSize, zoomCardTag };
@@ -1,7 +1,7 @@
1
1
  import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
2
2
  import { resolveSceneArrow } from "../../model/arrow-geometry.js";
3
- import { itemAlpha, itemColor } from "../palette.js";
4
3
  import { syncTextResolution } from "../text-resolution.js";
4
+ import { itemAlpha, itemColor } from "../palette.js";
5
5
  import { dashPattern, endAngle, traceArrowhead, tracePolyline, trimPolyline } from "../stroke.js";
6
6
  import { drawCardSurface } from "../surface.js";
7
7
  import { drawFarStroke } from "./far-plate.js";
@@ -1,9 +1,9 @@
1
1
  import { getMediaResourceTitle } from "../../model/media.js";
2
- import { boardCardDetailed } from "../lod.js";
2
+ import { drawAudioWaveform } from "../audio-waveform.js";
3
3
  import { fitTextToWidth } from "../text-fit.js";
4
4
  import { syncTextResolution } from "../text-resolution.js";
5
5
  import { formatBoardDuration } from "../card-tag.js";
6
- import { drawAudioWaveform } from "../audio-waveform.js";
6
+ import { boardCardDetailed } from "../lod.js";
7
7
  import { cardElevation, drawCardSurface } from "../surface.js";
8
8
  import { positionShell } from "./base-card-renderer.js";
9
9
  import { drawFarPlate } from "./far-plate.js";
@@ -2,10 +2,10 @@ import { BOARD_FONT_STACK, BOARD_MONO_FONT_STACK } from "../../../protocol/dist/
2
2
  import { boardItemPreview } from "../../../protocol/dist/board-model.js";
3
3
  import { fileCategory, fileStem } from "../../model/file-snapshot.js";
4
4
  import { fileCategoryAccent, fileMetaLine, filePreviewKind, fileTypeLabel } from "../../model/file-preview.js";
5
- import { boardCardDetailed } from "../lod.js";
6
5
  import { fitTextToLines } from "../text-fit.js";
7
6
  import { syncTextResolution } from "../text-resolution.js";
8
7
  import { createCardTag, syncCardTag, zoomCardTag } from "../card-tag.js";
8
+ import { boardCardDetailed } from "../lod.js";
9
9
  import { cardElevation, containRect, drawCardSurface, traceCardOutline } from "../surface.js";
10
10
  import { positionShell } from "./base-card-renderer.js";
11
11
  import { drawFarPlate, farPictureTone } from "./far-plate.js";
@@ -1,7 +1,7 @@
1
1
  import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
2
2
  import { BOARD_FRAME_LABEL_LINE_HEIGHT, frameLabelOffset } from "../../model/text-metrics.js";
3
- import { itemAlpha, itemColor } from "../palette.js";
4
3
  import { syncTextResolution } from "../text-resolution.js";
4
+ import { itemAlpha, itemColor } from "../palette.js";
5
5
  import { dashPattern, roundRectPoints, tracePolyline, trimPolyline } from "../stroke.js";
6
6
  import { createLabel, positionShell } from "./base-card-renderer.js";
7
7
  import { drawFarPlate } from "./far-plate.js";
@@ -1,8 +1,8 @@
1
1
  import { isBoardModelItem } from "../../model/media.js";
2
2
  import { fileStem } from "../../model/file-snapshot.js";
3
3
  import { fileMetaLine } from "../../model/file-preview.js";
4
- import { boardCardDetailed } from "../lod.js";
5
4
  import { createCardTag, syncCardTag, traceCube, zoomCardTag } from "../card-tag.js";
5
+ import { boardCardDetailed } from "../lod.js";
6
6
  import { cardElevation, containRect, drawCardSurface } from "../surface.js";
7
7
  import { positionShell } from "./base-card-renderer.js";
8
8
  import { drawFarPlate, farPictureTone } from "./far-plate.js";
@@ -1,8 +1,8 @@
1
1
  import { worldPoint } from "../../model/geometry.js";
2
2
  import { layoutShapeLabel } from "../../model/text-metrics.js";
3
- import { itemAlpha, itemColor } from "../palette.js";
4
3
  import { boardTextStyle, cssBaselineShift } from "../text-measurement.js";
5
4
  import { syncTextResolution } from "../text-resolution.js";
5
+ import { itemAlpha, itemColor } from "../palette.js";
6
6
  import { dashPattern, roundRectPoints, tracePolyline, trimPolyline } from "../stroke.js";
7
7
  import { positionShell } from "./base-card-renderer.js";
8
8
  import { drawFarPlate } from "./far-plate.js";