@neta-art/cohub 9.0.1 → 11.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.
- package/README.md +108 -102
- package/dist/board/editor/align.d.ts +11 -0
- package/dist/board/editor/align.js +72 -0
- package/dist/board/editor/animation.d.ts +17 -0
- package/dist/board/editor/animation.js +187 -0
- package/dist/board/editor/camera.d.ts +32 -0
- package/dist/board/editor/camera.js +137 -0
- package/dist/board/editor/clipboard.d.ts +41 -0
- package/dist/board/editor/clipboard.js +129 -0
- package/dist/board/editor/connection-ports.d.ts +19 -0
- package/dist/board/editor/connection-ports.js +85 -0
- package/dist/board/editor/context.d.ts +111 -0
- package/dist/board/editor/context.js +30 -0
- package/dist/board/editor/copy.d.ts +17 -0
- package/dist/board/editor/copy.js +121 -0
- package/dist/board/editor/creation.d.ts +51 -0
- package/dist/board/editor/creation.js +225 -0
- package/dist/board/editor/deletion.d.ts +9 -0
- package/dist/board/editor/deletion.js +90 -0
- package/dist/board/editor/document-edits.d.ts +22 -0
- package/dist/board/editor/document-edits.js +193 -0
- package/dist/board/editor/document.d.ts +41 -0
- package/dist/board/editor/document.js +302 -0
- package/dist/board/editor/editor.d.ts +225 -0
- package/dist/board/editor/editor.js +439 -0
- package/dist/board/editor/index.d.ts +18 -0
- package/dist/board/editor/index.js +12 -0
- package/dist/board/editor/interaction.d.ts +115 -0
- package/dist/board/editor/interaction.js +584 -0
- package/dist/board/editor/query.d.ts +27 -0
- package/dist/board/editor/query.js +203 -0
- package/dist/board/editor/remote.d.ts +11 -0
- package/dist/board/editor/remote.js +55 -0
- package/dist/board/editor/selection-transform.d.ts +24 -0
- package/dist/board/editor/selection-transform.js +81 -0
- package/dist/board/editor/selection.d.ts +33 -0
- package/dist/board/editor/selection.js +197 -0
- package/dist/board/editor/snapping.d.ts +33 -0
- package/dist/board/editor/snapping.js +75 -0
- package/dist/board/editor/snapshots.d.ts +27 -0
- package/dist/board/editor/snapshots.js +132 -0
- package/dist/board/editor/spatial.d.ts +41 -0
- package/dist/board/editor/spatial.js +191 -0
- package/dist/board/editor/state.d.ts +12 -0
- package/dist/board/editor/state.js +49 -0
- package/dist/board/editor/tool.d.ts +10 -0
- package/dist/board/editor/tool.js +19 -0
- package/dist/board/editor/wheel.d.ts +5 -0
- package/dist/board/editor/wheel.js +17 -0
- package/dist/board/export/index.d.ts +28 -6
- package/dist/board/export/index.js +47 -13
- package/dist/board/export/node/index.d.ts +56 -0
- package/dist/board/{headless → export/node}/index.js +26 -21
- package/dist/board/export/node/scripts.d.ts +16 -0
- package/dist/board/export/node/scripts.js +258 -0
- package/dist/board/export/scene.d.ts +8 -5
- package/dist/board/export/scene.js +24 -9
- package/dist/board/{animation.d.ts → model/animation.d.ts} +8 -5
- package/dist/board/{animation.js → model/animation.js} +37 -10
- package/dist/board/{core → model}/arrow-geometry.d.ts +2 -2
- package/dist/board/{core → model}/arrow-geometry.js +2 -2
- package/dist/board/model/authoring.d.ts +20 -0
- package/dist/board/model/authoring.js +185 -0
- package/dist/board/{core → model}/draw-geometry.d.ts +2 -2
- package/dist/board/{core → model}/draw-geometry.js +1 -1
- package/dist/board/model/draw-input.d.ts +14 -0
- package/dist/board/model/draw-input.js +28 -0
- package/dist/board/{core → model}/export-assets.d.ts +1 -1
- package/dist/board/{core → model}/export-assets.js +1 -1
- package/dist/board/{core → model}/export-plan.d.ts +2 -2
- package/dist/board/{core → model}/export-plan.js +3 -2
- package/dist/board/{core → model}/file-preview.d.ts +1 -1
- package/dist/board/{core → model}/file-preview.js +2 -2
- package/dist/board/{core → model}/file-snapshot.d.ts +1 -1
- package/dist/board/{core → model}/file-snapshot.js +4 -3
- package/dist/board/{geometry.d.ts → model/geometry.d.ts} +3 -3
- package/dist/board/{geometry.js → model/geometry.js} +1 -1
- package/dist/board/{image-key.d.ts → model/image-key.d.ts} +2 -2
- package/dist/board/{image-key.js → model/image-key.js} +7 -3
- package/dist/board/model/index.d.ts +42 -0
- package/dist/board/model/index.js +39 -0
- package/dist/board/model/items/builtin.d.ts +5 -0
- package/dist/board/model/items/builtin.js +119 -0
- package/dist/board/model/items/create.d.ts +61 -0
- package/dist/board/model/items/create.js +272 -0
- package/dist/board/model/items/definition.d.ts +35 -0
- package/dist/board/model/items/definition.js +18 -0
- package/dist/board/model/items/id.d.ts +5 -0
- package/dist/board/model/items/id.js +11 -0
- package/dist/board/model/items/index.d.ts +6 -0
- package/dist/board/model/items/index.js +6 -0
- package/dist/board/model/items/registry.d.ts +35 -0
- package/dist/board/model/items/registry.js +84 -0
- package/dist/board/{media-playback.d.ts → model/media-playback.d.ts} +4 -3
- package/dist/board/{media-playback.js → model/media-playback.js} +15 -5
- package/dist/board/{media.d.ts → model/media.d.ts} +1 -1
- package/dist/board/{media.js → model/media.js} +8 -2
- package/dist/board/{core → model}/palette.d.ts +1 -1
- package/dist/board/{core → model}/palette.js +1 -1
- package/dist/board/{presets.d.ts → model/presets.d.ts} +3 -3
- package/dist/board/{presets.js → model/presets.js} +1 -1
- package/dist/board/{replay.d.ts → model/replay.d.ts} +5 -5
- package/dist/board/{replay.js → model/replay.js} +2 -2
- package/dist/board/model/sampling.d.ts +19 -0
- package/dist/board/model/sampling.js +96 -0
- package/dist/board/{core → model}/scene.d.ts +1 -1
- package/dist/board/{core → model}/scene.js +1 -1
- package/dist/board/model/script-example.d.ts +4 -0
- package/dist/board/model/script-example.js +21 -0
- package/dist/board/model/script-hit.d.ts +10 -0
- package/dist/board/model/script-hit.js +52 -0
- package/dist/board/model/script-index.d.ts +7 -0
- package/dist/board/model/script-index.js +15 -0
- package/dist/board/model/script-scene.d.ts +24 -0
- package/dist/board/model/script-scene.js +267 -0
- package/dist/board/model/script.d.ts +105 -0
- package/dist/board/model/script.js +1 -0
- package/dist/board/model/shape-types.d.ts +8 -0
- package/dist/board/model/shape-types.js +8 -0
- package/dist/board/{task.d.ts → model/task.d.ts} +4 -4
- package/dist/board/{task.js → model/task.js} +3 -3
- package/dist/board/{core → model}/text-metrics.d.ts +1 -1
- package/dist/board/{core → model}/text-metrics.js +1 -1
- package/dist/board/{core → model}/tool-styles.d.ts +1 -1
- package/dist/board/{core → model}/tool-styles.js +1 -1
- package/dist/board/{runtime/board-player.d.ts → player/index.d.ts} +2 -2
- package/dist/board/{runtime/board-player.js → player/index.js} +5 -4
- package/dist/board/render/board-background.d.ts +1 -1
- package/dist/board/render/clip.d.ts +1 -1
- package/dist/board/render/css-color.d.ts +6 -1
- package/dist/board/render/css-color.js +34 -20
- package/dist/board/render/diagnostics.d.ts +20 -0
- package/dist/board/render/diagnostics.js +117 -0
- package/dist/board/render/index.d.ts +9 -6
- package/dist/board/render/index.js +10 -7
- package/dist/board/render/media-interaction.d.ts +2 -2
- package/dist/board/render/media-interaction.js +1 -1
- package/dist/board/render/palette.d.ts +3 -2
- package/dist/board/render/palette.js +7 -3
- package/dist/board/render/renderers/arrow-card-renderer.js +4 -3
- package/dist/board/render/renderers/audio-card-renderer.js +2 -1
- package/dist/board/render/renderers/board-renderer-registry.d.ts +20 -10
- package/dist/board/render/renderers/board-renderer-registry.js +17 -17
- package/dist/board/render/renderers/custom-card-renderer.d.ts +5 -0
- package/dist/board/render/renderers/{sketch-card-renderer.js → custom-card-renderer.js} +16 -15
- package/dist/board/render/renderers/draw-card-renderer.js +4 -3
- package/dist/board/render/renderers/effect-card-renderer.js +22 -5
- package/dist/board/render/renderers/far-plate.js +1 -1
- package/dist/board/render/renderers/file-card-renderer.d.ts +1 -1
- package/dist/board/render/renderers/file-card-renderer.js +2 -2
- package/dist/board/render/renderers/frame-card-renderer.js +30 -14
- package/dist/board/render/renderers/image-card-renderer.d.ts +1 -1
- package/dist/board/render/renderers/image-card-renderer.js +43 -4
- package/dist/board/render/renderers/shape-card-renderer.js +11 -28
- package/dist/board/render/renderers/task-card-renderer.js +1 -1
- package/dist/board/render/renderers/text-card-renderer.js +6 -4
- package/dist/board/render/renderers/unknown-card-renderer.js +1 -0
- package/dist/board/render/renderers/video-card-renderer.d.ts +1 -1
- package/dist/board/render/renderers/video-card-renderer.js +2 -1
- package/dist/board/render/sampling.d.ts +22 -0
- package/dist/board/render/sampling.js +21 -0
- package/dist/board/render/script-export.d.ts +11 -0
- package/dist/board/render/script-export.js +86 -0
- package/dist/board/render/script-host.d.ts +31 -0
- package/dist/board/render/script-host.js +421 -0
- package/dist/board/render/script-modules.d.ts +2 -0
- package/dist/board/render/script-modules.js +2 -0
- package/dist/board/render/script-runtime.d.ts +29 -0
- package/dist/board/render/script-runtime.js +213 -0
- package/dist/board/render/script-sandbox.d.ts +4 -0
- package/dist/board/render/script-sandbox.js +173 -0
- package/dist/board/render/stroke.d.ts +3 -2
- package/dist/board/render/stroke.js +23 -2
- package/dist/board/render/text-measurement.js +2 -2
- package/dist/board/replica/index.d.ts +70 -0
- package/dist/board/replica/index.js +276 -0
- package/dist/board/stage/assets.d.ts +41 -0
- package/dist/board/stage/assets.js +355 -0
- package/dist/board/stage/index.d.ts +8 -0
- package/dist/board/stage/index.js +8 -0
- package/dist/board/stage/lru.d.ts +32 -0
- package/dist/board/stage/lru.js +29 -0
- package/dist/board/stage/maintenance.d.ts +5 -0
- package/dist/board/stage/maintenance.js +11 -0
- package/dist/board/stage/pointer.d.ts +8 -0
- package/dist/board/stage/pointer.js +33 -0
- package/dist/board/stage/scene.d.ts +85 -0
- package/dist/board/stage/scene.js +515 -0
- package/dist/board/stage/script-pointer.d.ts +19 -0
- package/dist/board/stage/script-pointer.js +35 -0
- package/dist/board/stage/stage.d.ts +76 -0
- package/dist/board/stage/stage.js +774 -0
- package/dist/board/stage/texture-pool.d.ts +24 -0
- package/dist/board/stage/texture-pool.js +153 -0
- package/dist/board/stage/views.d.ts +38 -0
- package/dist/board/stage/views.js +93 -0
- package/dist/chunks/environment.d.ts +289 -23
- package/dist/chunks/host-bridge.d.ts +2 -2
- package/dist/chunks/http.d.ts +185 -71
- package/dist/chunks/http.js +368 -269
- package/dist/chunks/transport.js +3 -1
- package/dist/chunks/websocket.d.ts +9 -1
- package/dist/chunks/websocket.js +16 -2
- package/dist/host-bridge.js +2 -1
- package/dist/http.d.ts +2 -2
- package/dist/index.d.ts +182 -4
- package/dist/index.js +1393 -129
- package/dist/media.d.ts +1 -10
- package/dist/media.js +16 -27
- package/dist/protocol/dist/board-assets.d.ts +1 -0
- package/dist/protocol/dist/board-constants.js +2 -2
- package/dist/protocol/dist/board-model.d.ts +201 -11
- package/dist/protocol/dist/board-model.js +33 -14
- package/dist/protocol/dist/board-patch.js +3 -2
- package/dist/protocol/dist/board-schema.d.ts +4 -2
- package/dist/protocol/dist/board-schema.js +18 -4
- package/dist/protocol/dist/board-script-modules.d.ts +25 -0
- package/dist/protocol/dist/board-script-modules.js +127 -0
- package/dist/protocol/dist/board.d.ts +28 -2
- package/dist/protocol/dist/board.js +3 -1
- package/dist/protocol/dist/core/media.d.ts +5 -0
- package/dist/protocol/dist/core/media.js +39 -0
- package/dist/protocol/dist/display/index.d.ts +1 -0
- package/dist/protocol/dist/index.d.ts +7 -5
- package/dist/protocol/dist/realtime/types.d.ts +1 -0
- package/dist/protocol/dist/rtc/index.d.ts +1 -0
- package/dist/types.d.ts +1 -1
- package/package.json +21 -8
- package/dist/board/core/shape-definition.d.ts +0 -23
- package/dist/board/core/shape-definition.js +0 -45
- package/dist/board/core/shape-types.d.ts +0 -38
- package/dist/board/core/shape-types.js +0 -22
- package/dist/board/headless/index.d.ts +0 -55
- package/dist/board/headless/sketch.d.ts +0 -19
- package/dist/board/headless/sketch.js +0 -146
- package/dist/board/index.d.ts +0 -30
- package/dist/board/index.js +0 -29
- package/dist/board/render/renderers/sketch-card-renderer.d.ts +0 -5
- package/dist/board/render/sketch-host.d.ts +0 -14
- package/dist/board/render/sketch-host.js +0 -216
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Texture } from "pixi.js";
|
|
2
|
+
//#region src/board/stage/texture-pool.d.ts
|
|
3
|
+
type BoardImageTexturePool = {
|
|
4
|
+
acquire: (url: string) => Promise<Texture | null>;
|
|
5
|
+
release: (url: string) => Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
/** A CDN variant that fails to process falls back to the media it came from. */
|
|
8
|
+
declare function loadBoardImageTexture(url: string): Promise<Texture>;
|
|
9
|
+
declare function unloadBoardImageTexture(url: string, texture: Texture | null): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Share image textures by resolved URL without sharing Board ownership.
|
|
12
|
+
*
|
|
13
|
+
* Pixi's Assets cache is global, but its unload operation is not reference
|
|
14
|
+
* counted. The pool adds that missing application-level ownership layer:
|
|
15
|
+
* multiple Board managers share one load and texture, while the last release
|
|
16
|
+
* is the only one allowed to unload it.
|
|
17
|
+
*/
|
|
18
|
+
declare function createBoardImageTexturePool(options?: {
|
|
19
|
+
loadTexture?: (url: string) => Promise<Texture | null>;
|
|
20
|
+
unloadTexture?: (url: string, texture: Texture | null) => Promise<void>;
|
|
21
|
+
}): BoardImageTexturePool;
|
|
22
|
+
declare const boardImageTexturePool: BoardImageTexturePool;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { BoardImageTexturePool, boardImageTexturePool, createBoardImageTexturePool, loadBoardImageTexture, unloadBoardImageTexture };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { variantSource } from "../../media.js";
|
|
2
|
+
import { loadVideoThumbnailTexture } from "../render/video-thumbnail.js";
|
|
3
|
+
import { Assets, Texture } from "pixi.js";
|
|
4
|
+
//#region src/board/stage/texture-pool.ts
|
|
5
|
+
/** Load an image in the page's CORS context when Pixi's worker path fails. */
|
|
6
|
+
function loadImageElementTexture(url) {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
const image = new Image();
|
|
9
|
+
image.crossOrigin = "anonymous";
|
|
10
|
+
image.onload = () => {
|
|
11
|
+
try {
|
|
12
|
+
resolve(Texture.from(image));
|
|
13
|
+
} catch (error) {
|
|
14
|
+
reject(error);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
image.onerror = () => reject(/* @__PURE__ */ new Error(`Failed to load board image: ${url}`));
|
|
18
|
+
image.src = url;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Bypass the HTTP cache: an `<img>` that fetched this URL without CORS leaves
|
|
23
|
+
* an entry lacking CORS headers, and every CORS load of it then fails.
|
|
24
|
+
*/
|
|
25
|
+
async function loadUncachedTexture(url) {
|
|
26
|
+
const response = await fetch(url, { cache: "no-store" });
|
|
27
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
28
|
+
return Texture.from(await createImageBitmap(await response.blob()));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Keep Pixi's worker/ImageBitmap fast path, but recover through an anonymous
|
|
32
|
+
* image element when that browser context rejects a cross-origin cover, then
|
|
33
|
+
* through an uncached fetch when the cached copy is not CORS-readable.
|
|
34
|
+
*/
|
|
35
|
+
async function loadImageTexture(url) {
|
|
36
|
+
try {
|
|
37
|
+
return await Assets.load({
|
|
38
|
+
src: url,
|
|
39
|
+
parser: "texture"
|
|
40
|
+
});
|
|
41
|
+
} catch (workerError) {
|
|
42
|
+
const errors = [workerError];
|
|
43
|
+
for (const load of [loadImageElementTexture, loadUncachedTexture]) try {
|
|
44
|
+
return await load(url);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
errors.push(error);
|
|
47
|
+
}
|
|
48
|
+
throw new AggregateError(errors, `Failed to load board image: ${url}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** A CDN variant that fails to process falls back to the media it came from. */
|
|
52
|
+
async function loadBoardImageTexture(url) {
|
|
53
|
+
try {
|
|
54
|
+
return await loadImageTexture(url);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
const source = variantSource(url);
|
|
57
|
+
if (!source) throw error;
|
|
58
|
+
return source.type === "video" ? loadVideoThumbnailTexture(source.url) : loadImageTexture(source.url);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function unloadBoardImageTexture(url, texture) {
|
|
62
|
+
await Assets.unload(url).catch(() => {});
|
|
63
|
+
if (!texture?.destroyed) texture?.destroy(true);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Share image textures by resolved URL without sharing Board ownership.
|
|
67
|
+
*
|
|
68
|
+
* Pixi's Assets cache is global, but its unload operation is not reference
|
|
69
|
+
* counted. The pool adds that missing application-level ownership layer:
|
|
70
|
+
* multiple Board managers share one load and texture, while the last release
|
|
71
|
+
* is the only one allowed to unload it.
|
|
72
|
+
*/
|
|
73
|
+
function createBoardImageTexturePool(options) {
|
|
74
|
+
const load = options?.loadTexture ?? loadBoardImageTexture;
|
|
75
|
+
const unload = options?.unloadTexture ?? unloadBoardImageTexture;
|
|
76
|
+
const entries = /* @__PURE__ */ new Map();
|
|
77
|
+
function removeIfIdle(url, entry) {
|
|
78
|
+
if (entry.refs === 0 && entry.loading === null && entry.unloading === null && entry.texture === null && entries.get(url) === entry) entries.delete(url);
|
|
79
|
+
}
|
|
80
|
+
function releaseFailedAcquire(url, entry) {
|
|
81
|
+
entry.refs = Math.max(0, entry.refs - 1);
|
|
82
|
+
removeIfIdle(url, entry);
|
|
83
|
+
}
|
|
84
|
+
function unloadIfIdle(url, entry) {
|
|
85
|
+
if (entry.refs > 0 || entry.loading || entry.unloading || !entry.texture) return entry.unloading ?? Promise.resolve();
|
|
86
|
+
const texture = entry.texture;
|
|
87
|
+
entry.texture = null;
|
|
88
|
+
const unloading = Promise.resolve().then(() => unload(url, texture)).catch(() => {});
|
|
89
|
+
entry.unloading = unloading;
|
|
90
|
+
unloading.finally(() => {
|
|
91
|
+
if (entry.unloading === unloading) entry.unloading = null;
|
|
92
|
+
removeIfIdle(url, entry);
|
|
93
|
+
});
|
|
94
|
+
return unloading;
|
|
95
|
+
}
|
|
96
|
+
async function acquire(url) {
|
|
97
|
+
let entry = entries.get(url);
|
|
98
|
+
if (!entry) {
|
|
99
|
+
entry = {
|
|
100
|
+
refs: 0,
|
|
101
|
+
texture: null,
|
|
102
|
+
loading: null,
|
|
103
|
+
unloading: null
|
|
104
|
+
};
|
|
105
|
+
entries.set(url, entry);
|
|
106
|
+
}
|
|
107
|
+
entry.refs += 1;
|
|
108
|
+
if (entry.unloading) await entry.unloading;
|
|
109
|
+
if (entry.texture) return entry.texture;
|
|
110
|
+
if (!entry.loading) {
|
|
111
|
+
const current = entry;
|
|
112
|
+
entry.loading = Promise.resolve().then(() => load(url)).then((texture) => {
|
|
113
|
+
current.loading = null;
|
|
114
|
+
current.texture = texture;
|
|
115
|
+
if (!texture) removeIfIdle(url, current);
|
|
116
|
+
else unloadIfIdle(url, current);
|
|
117
|
+
return texture;
|
|
118
|
+
}, (error) => {
|
|
119
|
+
current.loading = null;
|
|
120
|
+
removeIfIdle(url, current);
|
|
121
|
+
throw error;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
const texture = await entry.loading;
|
|
126
|
+
if (!texture) releaseFailedAcquire(url, entry);
|
|
127
|
+
return texture;
|
|
128
|
+
} catch (error) {
|
|
129
|
+
releaseFailedAcquire(url, entry);
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async function release(url) {
|
|
134
|
+
const entry = entries.get(url);
|
|
135
|
+
if (!entry || entry.refs <= 0) return;
|
|
136
|
+
entry.refs -= 1;
|
|
137
|
+
if (entry.refs > 0) return;
|
|
138
|
+
if (entry.loading) try {
|
|
139
|
+
await entry.loading;
|
|
140
|
+
} catch {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (entry.refs === 0) await unloadIfIdle(url, entry);
|
|
144
|
+
else removeIfIdle(url, entry);
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
acquire,
|
|
148
|
+
release
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
const boardImageTexturePool = createBoardImageTexturePool();
|
|
152
|
+
//#endregion
|
|
153
|
+
export { boardImageTexturePool, createBoardImageTexturePool, loadBoardImageTexture, unloadBoardImageTexture };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { BoardViewport } from "../model/geometry.js";
|
|
2
|
+
import { BoardScene, BoardSceneItem } from "../model/scene.js";
|
|
3
|
+
import "../model/index.js";
|
|
4
|
+
import { BoardPointerEvent } from "../editor/interaction.js";
|
|
5
|
+
import { BoardEditor } from "../editor/editor.js";
|
|
6
|
+
import "../editor/index.js";
|
|
7
|
+
//#region src/board/stage/views.d.ts
|
|
8
|
+
type BoardItemViewContext = {
|
|
9
|
+
editor: BoardEditor;
|
|
10
|
+
zoom: number;
|
|
11
|
+
selected: boolean;
|
|
12
|
+
toPointerEvent(event: PointerEvent): BoardPointerEvent;
|
|
13
|
+
};
|
|
14
|
+
type BoardItemViewInstance = {
|
|
15
|
+
update?(item: BoardSceneItem, context: BoardItemViewContext): void;
|
|
16
|
+
destroy?(): void;
|
|
17
|
+
};
|
|
18
|
+
type BoardItemView = {
|
|
19
|
+
type: string | ((item: BoardSceneItem) => boolean);
|
|
20
|
+
mount(element: HTMLElement, item: BoardSceneItem, context: BoardItemViewContext): BoardItemViewInstance;
|
|
21
|
+
};
|
|
22
|
+
type BoardItemViewLayer = {
|
|
23
|
+
readonly element: HTMLElement;
|
|
24
|
+
sync(input: {
|
|
25
|
+
ids: ReadonlySet<string> | null;
|
|
26
|
+
scene: BoardScene;
|
|
27
|
+
camera: BoardViewport;
|
|
28
|
+
surface: {
|
|
29
|
+
width: number;
|
|
30
|
+
height: number;
|
|
31
|
+
};
|
|
32
|
+
selection: ReadonlySet<string>;
|
|
33
|
+
}): void;
|
|
34
|
+
destroy(): void;
|
|
35
|
+
};
|
|
36
|
+
declare function createBoardItemViewLayer(host: HTMLElement, editor: BoardEditor, views: readonly BoardItemView[], camera: () => BoardViewport): BoardItemViewLayer;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { BoardItemView, BoardItemViewContext, BoardItemViewInstance, BoardItemViewLayer, createBoardItemViewLayer };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { toBoardPointerEvent } from "./pointer.js";
|
|
2
|
+
//#region src/board/stage/views.ts
|
|
3
|
+
const VISIBLE_MARGIN = 240;
|
|
4
|
+
function screenStyle(frame, camera, order) {
|
|
5
|
+
const { zoom } = camera;
|
|
6
|
+
return [
|
|
7
|
+
`z-index:${order}`,
|
|
8
|
+
`left:${frame.x * zoom + camera.x}px`,
|
|
9
|
+
`top:${frame.y * zoom + camera.y}px`,
|
|
10
|
+
`width:${frame.width * zoom}px`,
|
|
11
|
+
`height:${frame.height * zoom}px`,
|
|
12
|
+
`--board-zoom:${zoom}`,
|
|
13
|
+
`transform:rotate(${frame.rotation}deg)`
|
|
14
|
+
].join(";");
|
|
15
|
+
}
|
|
16
|
+
function onScreen(frame, camera, surface) {
|
|
17
|
+
const left = frame.x * camera.zoom + camera.x;
|
|
18
|
+
const top = frame.y * camera.zoom + camera.y;
|
|
19
|
+
return left + frame.width * camera.zoom >= -240 && top + frame.height * camera.zoom >= -240 && left <= surface.width + VISIBLE_MARGIN && top <= surface.height + VISIBLE_MARGIN;
|
|
20
|
+
}
|
|
21
|
+
function createBoardItemViewLayer(host, editor, views, camera) {
|
|
22
|
+
const element = host.ownerDocument.createElement("div");
|
|
23
|
+
element.dataset.boardViews = "";
|
|
24
|
+
element.style.cssText = "position:absolute;inset:0;z-index:2;overflow:hidden;pointer-events:none";
|
|
25
|
+
host.appendChild(element);
|
|
26
|
+
const mounted = /* @__PURE__ */ new Map();
|
|
27
|
+
const toPointerEvent = (event) => toBoardPointerEvent(event, host.getBoundingClientRect(), camera());
|
|
28
|
+
const viewFor = (item) => views.find((view) => typeof view.type === "string" ? view.type === item.type : view.type(item));
|
|
29
|
+
function unmount(id, entry) {
|
|
30
|
+
entry.instance.destroy?.();
|
|
31
|
+
entry.element.remove();
|
|
32
|
+
mounted.delete(id);
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
element,
|
|
36
|
+
sync({ ids, scene, camera: view, surface, selection }) {
|
|
37
|
+
if (views.length === 0) return;
|
|
38
|
+
const live = /* @__PURE__ */ new Set();
|
|
39
|
+
for (const id of ids ?? scene.items.map((item) => item.id)) {
|
|
40
|
+
const item = scene.get(id);
|
|
41
|
+
if (!item) continue;
|
|
42
|
+
const itemView = viewFor(item);
|
|
43
|
+
if (!itemView || !onScreen(item.frame, view, surface)) continue;
|
|
44
|
+
live.add(item.id);
|
|
45
|
+
const context = {
|
|
46
|
+
editor,
|
|
47
|
+
zoom: view.zoom,
|
|
48
|
+
selected: selection.has(item.id),
|
|
49
|
+
toPointerEvent
|
|
50
|
+
};
|
|
51
|
+
const style = screenStyle(item.frame, view, scene.indexOf(item.id));
|
|
52
|
+
let entry = mounted.get(item.id);
|
|
53
|
+
if (entry && entry.view !== itemView) {
|
|
54
|
+
unmount(item.id, entry);
|
|
55
|
+
entry = void 0;
|
|
56
|
+
}
|
|
57
|
+
if (!entry) {
|
|
58
|
+
const node = host.ownerDocument.createElement("div");
|
|
59
|
+
node.dataset.boardItem = item.id;
|
|
60
|
+
node.style.cssText = `position:absolute;pointer-events:none;transform-origin:center;${style}`;
|
|
61
|
+
element.appendChild(node);
|
|
62
|
+
mounted.set(item.id, {
|
|
63
|
+
view: itemView,
|
|
64
|
+
element: node,
|
|
65
|
+
instance: itemView.mount(node, item, context),
|
|
66
|
+
item,
|
|
67
|
+
zoom: context.zoom,
|
|
68
|
+
selected: context.selected,
|
|
69
|
+
style
|
|
70
|
+
});
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (entry.style !== style) {
|
|
74
|
+
entry.element.style.cssText = `position:absolute;pointer-events:none;transform-origin:center;${style}`;
|
|
75
|
+
entry.style = style;
|
|
76
|
+
}
|
|
77
|
+
if (entry.item !== item || entry.zoom !== context.zoom || entry.selected !== context.selected) {
|
|
78
|
+
entry.item = item;
|
|
79
|
+
entry.zoom = context.zoom;
|
|
80
|
+
entry.selected = context.selected;
|
|
81
|
+
entry.instance.update?.(item, context);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
for (const [id, entry] of mounted) if (!live.has(id)) unmount(id, entry);
|
|
85
|
+
},
|
|
86
|
+
destroy() {
|
|
87
|
+
for (const [id, entry] of mounted) unmount(id, entry);
|
|
88
|
+
element.remove();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { createBoardItemViewLayer };
|