@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,515 @@
|
|
|
1
|
+
import { parseBoardItem } from "../../protocol/dist/board-model.js";
|
|
2
|
+
import { drawPointsBounds } from "../../protocol/dist/board-layout.js";
|
|
3
|
+
import { CORNER_RESIZE_HANDLES, frameCorners, frameHandlePosition, frameRayIntersection, rotationHandleAnchor, rotationHandlePosition } from "../model/geometry.js";
|
|
4
|
+
import { clippingAncestor, isClippingFrame, syncClipGroup } from "../render/clip.js";
|
|
5
|
+
import { Graphics } from "pixi.js";
|
|
6
|
+
//#region src/board/stage/scene.ts
|
|
7
|
+
const FAR_LAYER_ENTER = 450;
|
|
8
|
+
const FAR_LAYER_EXIT = 350;
|
|
9
|
+
const FAR_PASS_BATCH = 240;
|
|
10
|
+
const FAR_LIVE_LIMIT = 64;
|
|
11
|
+
const Z_FAR_LAYER = -1;
|
|
12
|
+
const Z_LIVE_STROKE = Number.MAX_SAFE_INTEGER - 1;
|
|
13
|
+
const Z_OVERLAY = Number.MAX_SAFE_INTEGER;
|
|
14
|
+
const POOL_LIMIT_PER_RENDERER = 48;
|
|
15
|
+
function idSetSignature(ids) {
|
|
16
|
+
let hash = ids.size;
|
|
17
|
+
for (const id of ids) {
|
|
18
|
+
let local = 0;
|
|
19
|
+
for (let i = 0; i < id.length; i += 1) local = local * 31 + id.charCodeAt(i) | 0;
|
|
20
|
+
hash ^= local;
|
|
21
|
+
}
|
|
22
|
+
return hash;
|
|
23
|
+
}
|
|
24
|
+
function traceFrame(graphics, frame) {
|
|
25
|
+
const corners = frameCorners(frame);
|
|
26
|
+
const first = corners[0];
|
|
27
|
+
if (!first) return graphics;
|
|
28
|
+
graphics.moveTo(first.x, first.y);
|
|
29
|
+
for (let index = 1; index < corners.length; index += 1) {
|
|
30
|
+
const point = corners[index];
|
|
31
|
+
if (point) graphics.lineTo(point.x, point.y);
|
|
32
|
+
}
|
|
33
|
+
return graphics.closePath();
|
|
34
|
+
}
|
|
35
|
+
function frameEdgePoints(frame, handle) {
|
|
36
|
+
switch (handle) {
|
|
37
|
+
case "n": return [frameHandlePosition(frame, "nw"), frameHandlePosition(frame, "ne")];
|
|
38
|
+
case "e": return [frameHandlePosition(frame, "ne"), frameHandlePosition(frame, "se")];
|
|
39
|
+
case "s": return [frameHandlePosition(frame, "sw"), frameHandlePosition(frame, "se")];
|
|
40
|
+
case "w": return [frameHandlePosition(frame, "nw"), frameHandlePosition(frame, "sw")];
|
|
41
|
+
default: return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function createBoardScene(options) {
|
|
45
|
+
const { world, overlay, getRenderer } = options;
|
|
46
|
+
world.sortableChildren = true;
|
|
47
|
+
overlay.zIndex = Z_OVERLAY;
|
|
48
|
+
const cards = /* @__PURE__ */ new Map();
|
|
49
|
+
const clips = /* @__PURE__ */ new Map();
|
|
50
|
+
const animatedIds = /* @__PURE__ */ new Set();
|
|
51
|
+
const pools = /* @__PURE__ */ new Map();
|
|
52
|
+
const heldKeys = /* @__PURE__ */ new Map();
|
|
53
|
+
let orderById = /* @__PURE__ */ new Map();
|
|
54
|
+
let farSig = null;
|
|
55
|
+
let farActive = false;
|
|
56
|
+
let lastStructureVersion = -1;
|
|
57
|
+
const liveStrokes = /* @__PURE__ */ new Map();
|
|
58
|
+
function setHeldKey(context, cardId, desiredKey) {
|
|
59
|
+
const heldKey = heldKeys.get(cardId) ?? null;
|
|
60
|
+
if (desiredKey === heldKey) return;
|
|
61
|
+
if (heldKey) context.releaseTexture(heldKey);
|
|
62
|
+
if (desiredKey) context.acquireTexture(desiredKey);
|
|
63
|
+
if (desiredKey) heldKeys.set(cardId, desiredKey);
|
|
64
|
+
else heldKeys.delete(cardId);
|
|
65
|
+
}
|
|
66
|
+
function takeFromPool(rendererId) {
|
|
67
|
+
const pool = pools.get(rendererId);
|
|
68
|
+
if (!pool || pool.length === 0) return null;
|
|
69
|
+
return pool.pop() ?? null;
|
|
70
|
+
}
|
|
71
|
+
function recycle(id, entry, context, destroyed) {
|
|
72
|
+
setHeldKey(context, id, null);
|
|
73
|
+
cards.delete(id);
|
|
74
|
+
animatedIds.delete(id);
|
|
75
|
+
if (destroyed) return;
|
|
76
|
+
entry.container.parent?.removeChild(entry.container);
|
|
77
|
+
entry.container.visible = false;
|
|
78
|
+
const pool = pools.get(entry.renderer.id) ?? [];
|
|
79
|
+
if (pool.length >= POOL_LIMIT_PER_RENDERER) {
|
|
80
|
+
entry.renderer.destroy?.(entry.container, context);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
pool.push(entry.container);
|
|
84
|
+
pools.set(entry.renderer.id, pool);
|
|
85
|
+
}
|
|
86
|
+
function hostFor(item, scene) {
|
|
87
|
+
const clipId = clippingAncestor(scene, item);
|
|
88
|
+
const frame = clipId ? scene.get(clipId) : void 0;
|
|
89
|
+
if (!clipId || !frame) return world;
|
|
90
|
+
let entry = clips.get(clipId);
|
|
91
|
+
if (!entry) {
|
|
92
|
+
entry = syncClipGroup(void 0, frame);
|
|
93
|
+
entry.group.sortableChildren = true;
|
|
94
|
+
clips.set(clipId, entry);
|
|
95
|
+
}
|
|
96
|
+
const parent = hostFor(frame, scene);
|
|
97
|
+
if (entry.group.parent !== parent) parent.addChild(entry.group);
|
|
98
|
+
entry.group.zIndex = (orderById.get(clipId) ?? 0) + .5;
|
|
99
|
+
return entry.group;
|
|
100
|
+
}
|
|
101
|
+
function syncClips(scene) {
|
|
102
|
+
for (const entry of cards.values()) {
|
|
103
|
+
const host = hostFor(entry.item, scene);
|
|
104
|
+
if (entry.container.parent !== host) host.addChild(entry.container);
|
|
105
|
+
}
|
|
106
|
+
for (const [id, entry] of clips) {
|
|
107
|
+
const frame = scene.get(id);
|
|
108
|
+
if (!frame || !isClippingFrame(frame) || entry.group.children.length <= 1) {
|
|
109
|
+
for (const child of [...entry.group.children]) if (child !== entry.mask) world.addChild(child);
|
|
110
|
+
entry.group.destroy({ children: true });
|
|
111
|
+
clips.delete(id);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
syncClipGroup(entry, frame);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function materialize(item, context, globalSig, scene) {
|
|
118
|
+
const renderer = getRenderer(item, context);
|
|
119
|
+
const pooled = takeFromPool(renderer.id);
|
|
120
|
+
const container = pooled ?? renderer.create(item, context);
|
|
121
|
+
container.visible = true;
|
|
122
|
+
if (pooled) renderer.update(container, item, context);
|
|
123
|
+
container.alpha = scene.opacity(item.id);
|
|
124
|
+
hostFor(item, scene).addChild(container);
|
|
125
|
+
if (renderer.animated) animatedIds.add(item.id);
|
|
126
|
+
const entry = {
|
|
127
|
+
item,
|
|
128
|
+
container,
|
|
129
|
+
renderer,
|
|
130
|
+
selected: context.selectedIds.has(item.id),
|
|
131
|
+
hovered: context.hoveredId === item.id,
|
|
132
|
+
resizing: context.resizingIds.has(item.id),
|
|
133
|
+
globalSig,
|
|
134
|
+
scriptRevision: context.scripts?.revision?.(item.id) ?? 0
|
|
135
|
+
};
|
|
136
|
+
cards.set(item.id, entry);
|
|
137
|
+
setHeldKey(context, item.id, context.assetKey(item));
|
|
138
|
+
return entry;
|
|
139
|
+
}
|
|
140
|
+
let farFront = createFarLayer();
|
|
141
|
+
let farBack = createFarLayer();
|
|
142
|
+
let farPainted = false;
|
|
143
|
+
let farCovered = /* @__PURE__ */ new Set();
|
|
144
|
+
let farInput = null;
|
|
145
|
+
let farRunning = false;
|
|
146
|
+
let farQueued = false;
|
|
147
|
+
let farFrame = 0;
|
|
148
|
+
function createFarLayer() {
|
|
149
|
+
const layer = new Graphics({ label: "board-far-layer" });
|
|
150
|
+
layer.zIndex = Z_FAR_LAYER;
|
|
151
|
+
layer.visible = false;
|
|
152
|
+
world.addChild(layer);
|
|
153
|
+
return layer;
|
|
154
|
+
}
|
|
155
|
+
function requestFarPass(signature) {
|
|
156
|
+
farSig = signature;
|
|
157
|
+
if (farRunning) farQueued = true;
|
|
158
|
+
else runFarPass();
|
|
159
|
+
}
|
|
160
|
+
function runFarPass() {
|
|
161
|
+
if (!farInput) return;
|
|
162
|
+
farRunning = true;
|
|
163
|
+
farQueued = false;
|
|
164
|
+
const { context, getItem, pinnedIds } = farInput;
|
|
165
|
+
const ids = visibleFacts(farInput).orderedIds;
|
|
166
|
+
const target = farPainted ? farBack : farFront;
|
|
167
|
+
const painted = /* @__PURE__ */ new Set();
|
|
168
|
+
target.clear();
|
|
169
|
+
if (target === farFront) farCovered = painted;
|
|
170
|
+
let index = 0;
|
|
171
|
+
const step = () => {
|
|
172
|
+
farFrame = 0;
|
|
173
|
+
const end = Math.min(ids.length, index + FAR_PASS_BATCH);
|
|
174
|
+
for (; index < end; index += 1) {
|
|
175
|
+
const id = ids[index];
|
|
176
|
+
if (pinnedIds.has(id)) continue;
|
|
177
|
+
const item = getItem(id);
|
|
178
|
+
if (!item) continue;
|
|
179
|
+
getRenderer(item, context).renderFar?.(target, item, context);
|
|
180
|
+
painted.add(id);
|
|
181
|
+
}
|
|
182
|
+
if (index < ids.length) {
|
|
183
|
+
farFrame = requestAnimationFrame(step);
|
|
184
|
+
if (target === farFront) options.onFarLayerFrame?.();
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (target === farBack) {
|
|
188
|
+
farBack = farFront;
|
|
189
|
+
farFront = target;
|
|
190
|
+
farBack.visible = false;
|
|
191
|
+
farBack.clear();
|
|
192
|
+
farCovered = painted;
|
|
193
|
+
}
|
|
194
|
+
farFront.visible = farActive;
|
|
195
|
+
farPainted = true;
|
|
196
|
+
farRunning = false;
|
|
197
|
+
options.onFarLayerFrame?.();
|
|
198
|
+
if (farQueued) runFarPass();
|
|
199
|
+
};
|
|
200
|
+
step();
|
|
201
|
+
}
|
|
202
|
+
function resetFarLayer() {
|
|
203
|
+
cancelAnimationFrame(farFrame);
|
|
204
|
+
farFrame = 0;
|
|
205
|
+
farRunning = false;
|
|
206
|
+
farQueued = false;
|
|
207
|
+
farInput = null;
|
|
208
|
+
farPainted = false;
|
|
209
|
+
farCovered = /* @__PURE__ */ new Set();
|
|
210
|
+
farSig = null;
|
|
211
|
+
farFront.clear();
|
|
212
|
+
farBack.clear();
|
|
213
|
+
}
|
|
214
|
+
function syncLiveStrokes(input) {
|
|
215
|
+
const { strokes, context, getItem } = input;
|
|
216
|
+
const live = /* @__PURE__ */ new Set();
|
|
217
|
+
for (const stroke of strokes) {
|
|
218
|
+
if (stroke.points.length === 0 || getItem(stroke.id)) continue;
|
|
219
|
+
let entry = liveStrokes.get(stroke.id);
|
|
220
|
+
if (entry && (entry.template.style.stroke !== stroke.color || entry.template.style.strokeWidth !== stroke.size)) {
|
|
221
|
+
removeLiveStroke(stroke.id, context);
|
|
222
|
+
entry = void 0;
|
|
223
|
+
}
|
|
224
|
+
const item = entry ? liveStrokeItem(stroke, entry.template) : createLiveStroke(stroke, input);
|
|
225
|
+
if (!item) continue;
|
|
226
|
+
live.add(stroke.id);
|
|
227
|
+
entry = liveStrokes.get(stroke.id);
|
|
228
|
+
entry?.renderer.update(entry.container, item, context);
|
|
229
|
+
}
|
|
230
|
+
for (const id of liveStrokes.keys()) if (!live.has(id)) removeLiveStroke(id, context);
|
|
231
|
+
}
|
|
232
|
+
function liveStrokeItem(stroke, template) {
|
|
233
|
+
return {
|
|
234
|
+
...template,
|
|
235
|
+
id: stroke.id,
|
|
236
|
+
props: { points: stroke.points },
|
|
237
|
+
frame: {
|
|
238
|
+
...drawPointsBounds(stroke.points, stroke.size),
|
|
239
|
+
rotation: 0
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
function createLiveStroke(stroke, input) {
|
|
244
|
+
const parsed = parseBoardItem({
|
|
245
|
+
type: "draw",
|
|
246
|
+
style: {
|
|
247
|
+
stroke: stroke.color,
|
|
248
|
+
strokeWidth: stroke.size
|
|
249
|
+
},
|
|
250
|
+
props: { points: stroke.points.slice(0, 1) }
|
|
251
|
+
});
|
|
252
|
+
if (!parsed.ok || parsed.item.type !== "draw") return null;
|
|
253
|
+
const template = parsed.item;
|
|
254
|
+
const item = liveStrokeItem(stroke, template);
|
|
255
|
+
const renderer = getRenderer(item, input.context);
|
|
256
|
+
const container = renderer.create(item, input.context);
|
|
257
|
+
container.zIndex = Z_LIVE_STROKE;
|
|
258
|
+
world.addChild(container);
|
|
259
|
+
liveStrokes.set(stroke.id, {
|
|
260
|
+
container,
|
|
261
|
+
renderer,
|
|
262
|
+
template
|
|
263
|
+
});
|
|
264
|
+
return item;
|
|
265
|
+
}
|
|
266
|
+
function removeLiveStroke(id, context) {
|
|
267
|
+
const entry = liveStrokes.get(id);
|
|
268
|
+
if (!entry) return;
|
|
269
|
+
liveStrokes.delete(id);
|
|
270
|
+
world.removeChild(entry.container);
|
|
271
|
+
entry.renderer.destroy?.(entry.container, context);
|
|
272
|
+
}
|
|
273
|
+
let visibleMemo = null;
|
|
274
|
+
function visibleFacts(input) {
|
|
275
|
+
const { items, visibleIds, structureVersion, context, getItem } = input;
|
|
276
|
+
if (visibleMemo?.ids === visibleIds && visibleMemo.structureVersion === structureVersion) return visibleMemo;
|
|
277
|
+
const orderedIds = visibleIds === null ? items.map((item) => item.id) : [...visibleIds].sort((a, b) => (orderById.get(a) ?? 0) - (orderById.get(b) ?? 0));
|
|
278
|
+
const unbatched = /* @__PURE__ */ new Set();
|
|
279
|
+
for (const id of orderedIds) {
|
|
280
|
+
const item = getItem(id);
|
|
281
|
+
if (item && !getRenderer(item, context).renderFar) unbatched.add(id);
|
|
282
|
+
}
|
|
283
|
+
visibleMemo = {
|
|
284
|
+
ids: visibleIds,
|
|
285
|
+
structureVersion,
|
|
286
|
+
signature: visibleIds === null ? 0 : idSetSignature(visibleIds),
|
|
287
|
+
orderedIds,
|
|
288
|
+
unbatched
|
|
289
|
+
};
|
|
290
|
+
return visibleMemo;
|
|
291
|
+
}
|
|
292
|
+
function sync(input) {
|
|
293
|
+
const { items, scene, context, getItem, visibleIds, pinnedIds, globalSig, structureVersion, geometryVersion, gestureActive } = input;
|
|
294
|
+
const structureChanged = structureVersion !== lastStructureVersion;
|
|
295
|
+
if (structureChanged) {
|
|
296
|
+
lastStructureVersion = structureVersion;
|
|
297
|
+
const liveIds = new Set(items.map((item) => item.id));
|
|
298
|
+
for (const [id, entry] of [...cards]) if (!liveIds.has(id)) recycle(id, entry, context, false);
|
|
299
|
+
orderById = new Map(items.map((item, index) => [item.id, index]));
|
|
300
|
+
}
|
|
301
|
+
const visibleCount = visibleIds === null ? items.length : visibleIds.size;
|
|
302
|
+
const nextFarActive = farActive ? visibleCount > FAR_LAYER_EXIT : visibleCount > FAR_LAYER_ENTER;
|
|
303
|
+
const farModeChanged = nextFarActive !== farActive;
|
|
304
|
+
farActive = nextFarActive;
|
|
305
|
+
farFront.visible = farActive;
|
|
306
|
+
if (farActive) {
|
|
307
|
+
farInput = input;
|
|
308
|
+
const nextFarSig = [
|
|
309
|
+
structureVersion,
|
|
310
|
+
geometryVersion,
|
|
311
|
+
globalSig,
|
|
312
|
+
idSetSignature(pinnedIds),
|
|
313
|
+
visibleIds === null ? "all" : visibleFacts(input).signature
|
|
314
|
+
].join("|");
|
|
315
|
+
if (farSig === null || nextFarSig !== farSig && !gestureActive) requestFarPass(nextFarSig);
|
|
316
|
+
} else if (farModeChanged) resetFarLayer();
|
|
317
|
+
const wanted = new Set(pinnedIds);
|
|
318
|
+
if (farActive) {
|
|
319
|
+
const { orderedIds, unbatched } = visibleFacts(input);
|
|
320
|
+
for (const id of unbatched) wanted.add(id);
|
|
321
|
+
let budget = FAR_LIVE_LIMIT;
|
|
322
|
+
for (const id of orderedIds) {
|
|
323
|
+
if (budget === 0) break;
|
|
324
|
+
if (farCovered.has(id) || wanted.has(id)) continue;
|
|
325
|
+
wanted.add(id);
|
|
326
|
+
budget -= 1;
|
|
327
|
+
}
|
|
328
|
+
} else if (visibleIds === null) for (const item of items) wanted.add(item.id);
|
|
329
|
+
else for (const id of visibleIds) wanted.add(id);
|
|
330
|
+
let liveSetChanged = false;
|
|
331
|
+
for (const [id, entry] of [...cards]) if (!wanted.has(id)) {
|
|
332
|
+
recycle(id, entry, context, false);
|
|
333
|
+
liveSetChanged = true;
|
|
334
|
+
}
|
|
335
|
+
for (const id of wanted) {
|
|
336
|
+
const item = getItem(id);
|
|
337
|
+
if (!item) continue;
|
|
338
|
+
let entry = cards.get(id);
|
|
339
|
+
const renderer = getRenderer(item, context);
|
|
340
|
+
if (entry && entry.renderer.id !== renderer.id) {
|
|
341
|
+
world.removeChild(entry.container);
|
|
342
|
+
entry.renderer.destroy?.(entry.container, context);
|
|
343
|
+
recycle(id, entry, context, true);
|
|
344
|
+
entry = void 0;
|
|
345
|
+
}
|
|
346
|
+
if (!entry) {
|
|
347
|
+
materialize(item, context, globalSig, scene);
|
|
348
|
+
liveSetChanged = true;
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
const selected = context.selectedIds.has(id);
|
|
352
|
+
const hovered = context.hoveredId === id;
|
|
353
|
+
const resizing = context.resizingIds.has(id);
|
|
354
|
+
const scriptRevision = context.scripts?.revision?.(id) ?? 0;
|
|
355
|
+
const changed = scriptRevision !== entry.scriptRevision || item !== entry.item || entry.renderer.animated || selected !== entry.selected || hovered !== entry.hovered || resizing !== entry.resizing || globalSig !== entry.globalSig;
|
|
356
|
+
entry.scriptRevision = scriptRevision;
|
|
357
|
+
entry.item = item;
|
|
358
|
+
entry.selected = selected;
|
|
359
|
+
entry.hovered = hovered;
|
|
360
|
+
entry.resizing = resizing;
|
|
361
|
+
entry.globalSig = globalSig;
|
|
362
|
+
setHeldKey(context, id, context.assetKey(item));
|
|
363
|
+
if (changed) {
|
|
364
|
+
entry.renderer.update(entry.container, item, context);
|
|
365
|
+
entry.container.alpha = scene.opacity(id);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (structureChanged || liveSetChanged) syncClips(scene);
|
|
369
|
+
if (structureChanged || farModeChanged || liveSetChanged) applyChildOrder();
|
|
370
|
+
syncLiveStrokes(input);
|
|
371
|
+
}
|
|
372
|
+
function applyChildOrder() {
|
|
373
|
+
for (const [id, entry] of cards) entry.container.zIndex = orderById.get(id) ?? 0;
|
|
374
|
+
world.sortableChildren = true;
|
|
375
|
+
world.sortChildren();
|
|
376
|
+
}
|
|
377
|
+
function drawOverlay(input, palette) {
|
|
378
|
+
overlay.clear();
|
|
379
|
+
const { zoom, pointerType, marquee, selection, transform, controls, hoveredControl, rotationPointer, arrowEndpoints, ports, hoveredPort, arrowDraft, bindTarget } = input;
|
|
380
|
+
const inv = 1 / zoom;
|
|
381
|
+
const brand = palette.brand;
|
|
382
|
+
if (marquee) {
|
|
383
|
+
overlay.rect(marquee.x, marquee.y, marquee.width, marquee.height).fill({
|
|
384
|
+
color: brand,
|
|
385
|
+
alpha: .08
|
|
386
|
+
});
|
|
387
|
+
overlay.rect(marquee.x, marquee.y, marquee.width, marquee.height).stroke({
|
|
388
|
+
color: brand,
|
|
389
|
+
width: inv,
|
|
390
|
+
alpha: .7
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
if (bindTarget) traceFrame(overlay, bindTarget).stroke({
|
|
394
|
+
color: brand,
|
|
395
|
+
width: 2 * inv,
|
|
396
|
+
alpha: .9
|
|
397
|
+
});
|
|
398
|
+
if (arrowDraft) {
|
|
399
|
+
const { from, to, size, targetFrame } = arrowDraft;
|
|
400
|
+
if (targetFrame) traceFrame(overlay, targetFrame).stroke({
|
|
401
|
+
color: brand,
|
|
402
|
+
width: 2 * inv,
|
|
403
|
+
alpha: .9
|
|
404
|
+
});
|
|
405
|
+
overlay.moveTo(from.x, from.y).lineTo(to.x, to.y).stroke({
|
|
406
|
+
color: brand,
|
|
407
|
+
width: Math.max(size, 1.5) * inv,
|
|
408
|
+
alpha: .85,
|
|
409
|
+
cap: "round"
|
|
410
|
+
});
|
|
411
|
+
overlay.circle(to.x, to.y, 3.5 * inv).fill({
|
|
412
|
+
color: brand,
|
|
413
|
+
alpha: .95
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
if (ports && ports.length > 0) for (const port of ports) {
|
|
417
|
+
const hovered = hoveredPort && Math.abs(hoveredPort.x - port.x) < .001 && Math.abs(hoveredPort.y - port.y) < .001;
|
|
418
|
+
const r = (hovered ? port.radius * 1.5 : port.radius) * inv;
|
|
419
|
+
overlay.circle(port.x, port.y, r).fill({
|
|
420
|
+
color: palette.surface,
|
|
421
|
+
alpha: 1
|
|
422
|
+
}).stroke({
|
|
423
|
+
color: brand,
|
|
424
|
+
width: 1.5 * inv,
|
|
425
|
+
alpha: hovered ? 1 : .8
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
if (!transform || selection.length === 0) return;
|
|
429
|
+
const source = transform.frame;
|
|
430
|
+
traceFrame(overlay, source).stroke({
|
|
431
|
+
color: brand,
|
|
432
|
+
width: 1.5 * inv,
|
|
433
|
+
alpha: .95
|
|
434
|
+
});
|
|
435
|
+
if (!controls) return;
|
|
436
|
+
if (arrowEndpoints && arrowEndpoints.length > 0) {
|
|
437
|
+
const r = 5 * inv;
|
|
438
|
+
for (const point of arrowEndpoints) overlay.circle(point.x, point.y, r).fill({
|
|
439
|
+
color: palette.surface,
|
|
440
|
+
alpha: 1
|
|
441
|
+
}).stroke({
|
|
442
|
+
color: brand,
|
|
443
|
+
width: 1.5 * inv
|
|
444
|
+
});
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
if (hoveredControl?.kind === "resize" && transform.resizeMode === "free") {
|
|
448
|
+
const edge = frameEdgePoints(source, hoveredControl.handle);
|
|
449
|
+
if (edge) overlay.moveTo(edge[0].x, edge[0].y).lineTo(edge[1].x, edge[1].y).stroke({
|
|
450
|
+
color: brand,
|
|
451
|
+
width: 2.5 * inv,
|
|
452
|
+
alpha: 1
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
if (transform.resizeMode !== "none") for (const handle of CORNER_RESIZE_HANDLES) {
|
|
456
|
+
const position = frameHandlePosition(source, handle);
|
|
457
|
+
const hovered = hoveredControl?.kind === "resize" && hoveredControl.handle === handle;
|
|
458
|
+
overlay.circle(position.x, position.y, (hovered ? 5 : 4) * inv).fill({
|
|
459
|
+
color: hovered ? brand : palette.surface,
|
|
460
|
+
alpha: 1
|
|
461
|
+
}).stroke({
|
|
462
|
+
color: brand,
|
|
463
|
+
width: 1.5 * inv
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
if (transform.canRotate && (pointerType === "touch" || transform.resizeMode === "none")) {
|
|
467
|
+
const rotation = rotationPointer ?? rotationHandlePosition(source, zoom);
|
|
468
|
+
const anchor = rotationPointer ? frameRayIntersection(source, rotationPointer) : rotationHandleAnchor(source);
|
|
469
|
+
const hovered = rotationPointer !== null || hoveredControl?.kind === "rotate";
|
|
470
|
+
overlay.moveTo(anchor.x, anchor.y).lineTo(rotation.x, rotation.y).stroke({
|
|
471
|
+
color: brand,
|
|
472
|
+
width: inv,
|
|
473
|
+
alpha: .8
|
|
474
|
+
});
|
|
475
|
+
overlay.circle(rotation.x, rotation.y, (hovered ? 6 : 5) * inv).fill({ color: hovered ? brand : palette.surface }).stroke({
|
|
476
|
+
color: brand,
|
|
477
|
+
width: 1.5 * inv
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
function destroy(context) {
|
|
482
|
+
for (const entry of cards.values()) entry.renderer.destroy?.(entry.container, context);
|
|
483
|
+
cards.clear();
|
|
484
|
+
for (const pool of pools.values()) for (const container of pool) container.destroy({ children: true });
|
|
485
|
+
pools.clear();
|
|
486
|
+
for (const key of heldKeys.values()) context.releaseTexture(key);
|
|
487
|
+
heldKeys.clear();
|
|
488
|
+
orderById = /* @__PURE__ */ new Map();
|
|
489
|
+
for (const entry of clips.values()) entry.group.destroy({ children: true });
|
|
490
|
+
clips.clear();
|
|
491
|
+
animatedIds.clear();
|
|
492
|
+
for (const id of [...liveStrokes.keys()]) removeLiveStroke(id, context);
|
|
493
|
+
resetFarLayer();
|
|
494
|
+
farActive = false;
|
|
495
|
+
visibleMemo = null;
|
|
496
|
+
lastStructureVersion = -1;
|
|
497
|
+
}
|
|
498
|
+
return {
|
|
499
|
+
sync,
|
|
500
|
+
getNode: (itemId) => {
|
|
501
|
+
const entry = cards.get(itemId);
|
|
502
|
+
return entry ? {
|
|
503
|
+
item: entry.item,
|
|
504
|
+
container: entry.container
|
|
505
|
+
} : null;
|
|
506
|
+
},
|
|
507
|
+
get animated() {
|
|
508
|
+
return animatedIds.size > 0;
|
|
509
|
+
},
|
|
510
|
+
drawOverlay,
|
|
511
|
+
destroy
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
//#endregion
|
|
515
|
+
export { createBoardScene };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/board/stage/script-pointer.d.ts
|
|
2
|
+
type BoardScriptPointerTarget = {
|
|
3
|
+
owner: string;
|
|
4
|
+
target: string;
|
|
5
|
+
};
|
|
6
|
+
declare function createBoardScriptPointerRouter(): {
|
|
7
|
+
needsRouting(pointerId: number, scriptsEnabled: boolean): boolean;
|
|
8
|
+
owner(pointerId: number): "editor" | "script" | null;
|
|
9
|
+
route(phase: "down" | "move" | "up" | "leave", pointerId: number, target: BoardScriptPointerTarget | null, point: {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
}, cancelled?: boolean): {
|
|
13
|
+
recipient: BoardScriptPointerTarget | null;
|
|
14
|
+
click: BoardScriptPointerTarget | null;
|
|
15
|
+
};
|
|
16
|
+
clear(): void;
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { BoardScriptPointerTarget, createBoardScriptPointerRouter };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/board/stage/script-pointer.ts
|
|
2
|
+
function createBoardScriptPointerRouter() {
|
|
3
|
+
const gestures = /* @__PURE__ */ new Map();
|
|
4
|
+
return {
|
|
5
|
+
needsRouting(pointerId, scriptsEnabled) {
|
|
6
|
+
return scriptsEnabled || gestures.has(pointerId);
|
|
7
|
+
},
|
|
8
|
+
owner(pointerId) {
|
|
9
|
+
const gesture = gestures.get(pointerId);
|
|
10
|
+
return gesture ? gesture.target ? "script" : "editor" : null;
|
|
11
|
+
},
|
|
12
|
+
route(phase, pointerId, target, point, cancelled = false) {
|
|
13
|
+
if (phase === "down") gestures.set(pointerId, {
|
|
14
|
+
target,
|
|
15
|
+
...point
|
|
16
|
+
});
|
|
17
|
+
const gesture = gestures.get(pointerId);
|
|
18
|
+
const recipient = gesture ? gesture.target : phase === "move" ? target : null;
|
|
19
|
+
let click = null;
|
|
20
|
+
if (phase === "up") {
|
|
21
|
+
gestures.delete(pointerId);
|
|
22
|
+
if (!cancelled && gesture?.target && target?.owner === gesture.target.owner && target.target === gesture.target.target && Math.hypot(point.x - gesture.x, point.y - gesture.y) < 5) click = gesture.target;
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
recipient,
|
|
26
|
+
click
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
clear() {
|
|
30
|
+
gestures.clear();
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { createBoardScriptPointerRouter };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { BoardItem } from "../../protocol/dist/board-model.js";
|
|
2
|
+
import { BoardPlaybackSnapshot } from "../../protocol/dist/board.js";
|
|
3
|
+
import "../../protocol/dist/index.js";
|
|
4
|
+
import { BoardScriptOutput, BoardScriptSnapshot } from "../model/script.js";
|
|
5
|
+
import { BoardViewport, WorldPoint } from "../model/geometry.js";
|
|
6
|
+
import { BoardScene, BoardSceneItem } from "../model/scene.js";
|
|
7
|
+
import { BoardShapeColors } from "../model/palette.js";
|
|
8
|
+
import { BoardAssetSource } from "../model/media-playback.js";
|
|
9
|
+
import "../model/index.js";
|
|
10
|
+
import { BoardPointerEvent } from "../editor/interaction.js";
|
|
11
|
+
import { BoardEditor } from "../editor/editor.js";
|
|
12
|
+
import "../editor/index.js";
|
|
13
|
+
import { BoardCardRendererResolver, BoardRenderPalette } from "../render/renderers/board-renderer-registry.js";
|
|
14
|
+
import "../render/index.js";
|
|
15
|
+
import { BoardAssetManager } from "./assets.js";
|
|
16
|
+
import { BoardLiveStroke } from "./scene.js";
|
|
17
|
+
import { BoardItemView } from "./views.js";
|
|
18
|
+
import { Graphics, Renderer } from "pixi.js";
|
|
19
|
+
//#region src/board/stage/stage.d.ts
|
|
20
|
+
type BoardStageTheme = {
|
|
21
|
+
key: string;
|
|
22
|
+
palette: BoardRenderPalette;
|
|
23
|
+
colors: BoardShapeColors;
|
|
24
|
+
colorScheme: "dark" | "light";
|
|
25
|
+
imageBackground?: boolean;
|
|
26
|
+
};
|
|
27
|
+
type BoardStagePointerPhase = "down" | "move" | "up" | "leave";
|
|
28
|
+
type BoardStageOptions = {
|
|
29
|
+
editor: BoardEditor;
|
|
30
|
+
assets: BoardAssetManager;
|
|
31
|
+
source: BoardAssetSource;
|
|
32
|
+
renderers?: BoardCardRendererResolver;
|
|
33
|
+
views?: readonly BoardItemView[];
|
|
34
|
+
theme?: () => BoardStageTheme;
|
|
35
|
+
playback?: () => BoardPlaybackSnapshot | null;
|
|
36
|
+
fileState?: (path: string) => "ok" | "missing" | "unavailable";
|
|
37
|
+
previews?: () => ReadonlyMap<string, BoardItem>;
|
|
38
|
+
strokes?: () => readonly BoardLiveStroke[];
|
|
39
|
+
drawOverlay?: (overlay: Graphics, frame: {
|
|
40
|
+
zoom: number;
|
|
41
|
+
theme: BoardStageTheme;
|
|
42
|
+
scene: BoardScene;
|
|
43
|
+
}) => void;
|
|
44
|
+
onPointer?: (phase: BoardStagePointerPhase, event: PointerEvent, input: BoardPointerEvent) => boolean | undefined;
|
|
45
|
+
onDoubleClick?: (item: BoardSceneItem | null, point: WorldPoint) => boolean | undefined;
|
|
46
|
+
onSurfaceChange?: (size: {
|
|
47
|
+
width: number;
|
|
48
|
+
height: number;
|
|
49
|
+
}) => void;
|
|
50
|
+
onVisibleChange?: (ids: ReadonlySet<string> | null) => void;
|
|
51
|
+
scriptCapabilities?: Record<string, (id: string, input: unknown) => Promise<unknown>>;
|
|
52
|
+
};
|
|
53
|
+
type BoardStage = {
|
|
54
|
+
readonly ready: Promise<boolean>;
|
|
55
|
+
readonly renderer: Renderer | null;
|
|
56
|
+
readonly camera: BoardViewport;
|
|
57
|
+
readonly theme: BoardStageTheme;
|
|
58
|
+
setActive(active: boolean): void;
|
|
59
|
+
setScriptMode(mode: "edit" | "interact" | "paused"): void;
|
|
60
|
+
resetScripts(): void;
|
|
61
|
+
invalidateScript(path: string): void;
|
|
62
|
+
scriptError(id: string): string | null;
|
|
63
|
+
scriptOutput(id: string): BoardScriptOutput | null;
|
|
64
|
+
snapshotScripts(): Promise<Record<string, BoardScriptSnapshot>>;
|
|
65
|
+
restoreScript(id: string, snapshot: BoardScriptSnapshot): void;
|
|
66
|
+
subscribeScripts(listener: () => void): () => void;
|
|
67
|
+
invalidate(options?: {
|
|
68
|
+
cards?: boolean;
|
|
69
|
+
}): void;
|
|
70
|
+
isMaterialized(id: string): boolean;
|
|
71
|
+
toWorld(clientX: number, clientY: number): WorldPoint;
|
|
72
|
+
destroy(): void;
|
|
73
|
+
};
|
|
74
|
+
declare function mountBoardStage(host: HTMLElement, options: BoardStageOptions): BoardStage;
|
|
75
|
+
//#endregion
|
|
76
|
+
export { BoardStage, BoardStageOptions, BoardStagePointerPhase, BoardStageTheme, mountBoardStage };
|