@neta-art/cohub 12.1.1 → 12.3.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 +85 -8
- package/dist/board/editor/clipboard.js +1 -1
- package/dist/board/editor/creation.js +1 -1
- package/dist/board/editor/document.d.ts +3 -1
- package/dist/board/editor/document.js +8 -6
- package/dist/board/editor/editor.d.ts +8 -3
- package/dist/board/editor/editor.js +8 -2
- package/dist/board/editor/index.d.ts +3 -3
- package/dist/board/editor/index.js +2 -2
- package/dist/board/editor/interaction.d.ts +23 -2
- package/dist/board/editor/interaction.js +93 -4
- package/dist/board/editor/query.d.ts +1 -1
- package/dist/board/editor/query.js +3 -7
- package/dist/board/editor/selection.js +1 -1
- package/dist/board/editor/snapshots.js +5 -57
- package/dist/board/editor/tool.d.ts +4 -1
- package/dist/board/editor/tool.js +6 -1
- package/dist/board/export/index.d.ts +2 -2
- package/dist/board/export/index.js +1 -1
- package/dist/board/export/node/fonts.js +4 -0
- package/dist/board/export/node/index.d.ts +2 -0
- package/dist/board/export/node/index.js +8 -1
- package/dist/board/export/node/scripts.js +1 -1
- package/dist/board/export/scene.d.ts +2 -2
- package/dist/board/export/scene.js +2 -2
- package/dist/board/model/asset-key.d.ts +24 -0
- package/dist/board/model/asset-key.js +104 -0
- package/dist/board/model/export-assets.d.ts +7 -3
- package/dist/board/model/export-assets.js +34 -13
- package/dist/board/model/index.d.ts +9 -7
- package/dist/board/model/index.js +22 -20
- package/dist/board/model/items/create.js +3 -3
- package/dist/board/model/items/definition.d.ts +9 -1
- package/dist/board/model/items/index.d.ts +2 -2
- package/dist/board/model/items/registry.d.ts +2 -1
- package/dist/board/model/items/registry.js +1 -0
- package/dist/board/model/media-sizes.d.ts +28 -0
- package/dist/board/model/media-sizes.js +64 -0
- package/dist/board/model/palette.d.ts +1 -0
- package/dist/board/model/palette.js +20 -130
- package/dist/board/model/sampling.js +1 -1
- package/dist/board/model/text-metrics.d.ts +28 -3
- package/dist/board/model/text-metrics.js +36 -2
- package/dist/board/model/themes.d.ts +495 -0
- package/dist/board/model/themes.js +500 -0
- package/dist/board/render/card-tag.js +2 -2
- package/dist/board/render/index.d.ts +11 -7
- package/dist/board/render/index.js +9 -5
- package/dist/board/render/labels.d.ts +15 -0
- package/dist/board/render/labels.js +14 -0
- package/dist/board/render/lod.d.ts +30 -0
- package/dist/board/render/lod.js +33 -0
- package/dist/board/render/media-interaction.d.ts +5 -2
- package/dist/board/render/media-interaction.js +15 -3
- package/dist/board/render/palette.js +2 -25
- package/dist/board/render/renderers/arrow-card-renderer.js +7 -5
- package/dist/board/render/renderers/audio-card-renderer.js +3 -2
- package/dist/board/render/renderers/board-renderer-registry.d.ts +22 -1
- package/dist/board/render/renderers/board-renderer-registry.js +9 -4
- package/dist/board/render/renderers/custom-card-renderer.js +5 -5
- package/dist/board/render/renderers/draw-card-renderer.js +1 -1
- package/dist/board/render/renderers/far-plate.d.ts +14 -1
- package/dist/board/render/renderers/far-plate.js +31 -8
- package/dist/board/render/renderers/file-card-renderer.js +49 -31
- package/dist/board/render/renderers/frame-card-renderer.js +9 -3
- package/dist/board/render/renderers/image-card-renderer.js +34 -8
- package/dist/board/render/renderers/model-card-renderer.js +6 -6
- package/dist/board/render/renderers/shape-card-renderer.js +25 -24
- package/dist/board/render/renderers/task-card-renderer.js +9 -10
- package/dist/board/render/renderers/text-card-renderer.js +86 -41
- package/dist/board/render/renderers/video-card-renderer.js +5 -4
- package/dist/board/render/script-export.js +1 -1
- package/dist/board/render/script-host.js +3 -3
- package/dist/board/render/style.d.ts +8 -2
- package/dist/board/render/style.js +8 -2
- package/dist/board/render/surface.d.ts +5 -0
- package/dist/board/render/surface.js +13 -3
- package/dist/board/render/text-edit.d.ts +32 -0
- package/dist/board/render/text-edit.js +134 -0
- package/dist/board/render/text-fit.d.ts +1 -3
- package/dist/board/render/text-fit.js +6 -49
- package/dist/board/render/text-measurement.d.ts +25 -1
- package/dist/board/render/text-measurement.js +157 -19
- package/dist/board/render/text-resolution.d.ts +1 -6
- package/dist/board/render/text-resolution.js +1 -10
- package/dist/board/render/theme.d.ts +15 -0
- package/dist/board/render/theme.js +15 -0
- package/dist/board/replica/index.d.ts +4 -2
- package/dist/board/replica/index.js +28 -17
- package/dist/board/replica/indexeddb.d.ts +16 -0
- package/dist/board/replica/indexeddb.js +155 -0
- package/dist/board/stage/assets.d.ts +28 -5
- package/dist/board/stage/assets.js +293 -102
- package/dist/board/stage/bench.d.ts +35 -0
- package/dist/board/stage/bench.js +153 -0
- package/dist/board/stage/device.d.ts +41 -0
- package/dist/board/stage/device.js +62 -0
- package/dist/board/stage/frame-budget.d.ts +19 -0
- package/dist/board/stage/frame-budget.js +69 -0
- package/dist/board/stage/idle.d.ts +4 -0
- package/dist/board/stage/idle.js +26 -0
- package/dist/board/stage/index.d.ts +11 -7
- package/dist/board/stage/index.js +7 -4
- package/dist/board/stage/lru.d.ts +13 -9
- package/dist/board/stage/lru.js +38 -20
- package/dist/board/stage/presses.d.ts +21 -0
- package/dist/board/stage/presses.js +66 -0
- package/dist/board/stage/scene.d.ts +15 -1
- package/dist/board/stage/scene.js +248 -141
- package/dist/board/stage/stage.d.ts +28 -2
- package/dist/board/stage/stage.js +404 -112
- package/dist/board/stage/texture-pool.d.ts +10 -1
- package/dist/board/stage/texture-pool.js +72 -2
- package/dist/chunks/environment.d.ts +6 -0
- package/dist/chunks/http.d.ts +9 -1
- package/dist/chunks/http.js +791 -4
- package/dist/index.d.ts +52 -1
- package/dist/index.js +202 -862
- package/dist/media.d.ts +3 -27
- package/dist/media.js +3 -82
- package/dist/protocol/dist/board-constants.js +3 -3
- package/dist/protocol/dist/board-layout.d.ts +17 -3
- package/dist/protocol/dist/board-layout.js +68 -11
- package/dist/protocol/dist/board-model.d.ts +15 -1
- package/dist/protocol/dist/board-model.js +12 -2
- package/dist/protocol/dist/board-patch.js +1 -1
- package/dist/protocol/dist/board-schema.d.ts +2 -1
- package/dist/protocol/dist/board-schema.js +4 -1
- package/dist/protocol/dist/core/media.d.ts +35 -1
- package/dist/protocol/dist/core/media.js +127 -1
- package/dist/protocol/dist/index.d.ts +3 -3
- package/package.json +4 -2
- package/dist/board/model/image-key.d.ts +0 -9
- package/dist/board/model/image-key.js +0 -33
|
@@ -1,30 +1,37 @@
|
|
|
1
|
-
import { applyMatrix, invertMatrix } from "../../protocol/dist/board-layout.js";
|
|
2
1
|
import { featuredTaskArtifact } from "../../protocol/dist/board-task.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { boardScriptTarget } from "../model/script-hit.js";
|
|
2
|
+
import { applyMatrix, invertMatrix } from "../../protocol/dist/board-layout.js";
|
|
3
|
+
import { itemBounds, pointToWorld, rectsIntersect, screenPoint, stableCullRect, visibleWorldRect, worldPoint } from "../model/geometry.js";
|
|
6
4
|
import { createBoardAnimationSampler, resolveBoardAnimationCamera } from "../model/sampling.js";
|
|
7
|
-
import {
|
|
8
|
-
import { buildFallbackShapeColors, pickBoardColor, resolveItemColor } from "../model/palette.js";
|
|
9
|
-
import { elementClientToLocal } from "../model/client-geometry.js";
|
|
10
|
-
import { isCreationBoardTool } from "../editor/tool.js";
|
|
11
|
-
import { resizeCursorForHandle } from "../editor/selection-transform.js";
|
|
5
|
+
import { pickBoardColor, resolveItemColor } from "../model/palette.js";
|
|
12
6
|
import { parseBoardCssColor } from "../render/css-color.js";
|
|
13
|
-
import {
|
|
7
|
+
import { itemAlpha } from "../render/palette.js";
|
|
8
|
+
import { resolveSceneArrow } from "../model/arrow-geometry.js";
|
|
9
|
+
import { onBoardTextFontsChange } from "../render/text-measurement.js";
|
|
10
|
+
import { boardLodRatio, boardLodSize } from "../render/lod.js";
|
|
14
11
|
import { createBoardBackground, updateBoardBackground } from "../render/board-background.js";
|
|
15
12
|
import { getBoardResolution } from "../render/text-resolution.js";
|
|
16
13
|
import { DEFAULT_BOARD_RENDER_LABELS, getBoardCardRenderer } from "../render/renderers/board-renderer-registry.js";
|
|
14
|
+
import { boardScriptScope, composeBoardScriptItems, prepareBoardScriptOutput, validateBoardScriptCommit } from "../model/script-scene.js";
|
|
15
|
+
import { boardScriptTarget } from "../model/script-hit.js";
|
|
17
16
|
import { createBoardScriptHost } from "../render/script-host.js";
|
|
18
17
|
import { defaultBoardRenderStyle } from "../render/style.js";
|
|
18
|
+
import { boardRenderTheme } from "../render/theme.js";
|
|
19
|
+
import { boardTextureEdge } from "../model/asset-key.js";
|
|
20
|
+
import { elementClientToLocal } from "../model/client-geometry.js";
|
|
21
|
+
import { isCreationBoardTool } from "../editor/tool.js";
|
|
22
|
+
import { resizeCursorForHandle } from "../editor/selection-transform.js";
|
|
19
23
|
import { createBoardPlayer } from "../player/index.js";
|
|
20
24
|
import { createBoardScriptObservers } from "../model/script-observers.js";
|
|
21
|
-
import {
|
|
25
|
+
import { defaultBoardDeviceBudget } from "./device.js";
|
|
26
|
+
import { scheduleBoardIdle } from "./idle.js";
|
|
22
27
|
import { boardCanvasSize, measureBoardCanvasBox } from "./canvas-size.js";
|
|
23
28
|
import { observeDisplayDensity } from "./display-density.js";
|
|
29
|
+
import { createBoardFrameClock } from "./frame-budget.js";
|
|
24
30
|
import { toBoardPointerEvent } from "./pointer.js";
|
|
25
31
|
import { createBoardPointerGestures } from "./pointer-gestures.js";
|
|
26
32
|
import { createBoardScene } from "./scene.js";
|
|
27
33
|
import { scheduleBoardMaintenance } from "./maintenance.js";
|
|
34
|
+
import { boardStagePress, createBoardLongPress, createGhostClickGuard } from "./presses.js";
|
|
28
35
|
import { createBoardScriptPointerRouter } from "./script-pointer.js";
|
|
29
36
|
import { drawBoardOverlay } from "./overlay.js";
|
|
30
37
|
import { createTextResolutionTracker } from "./text-resolution-tracker.js";
|
|
@@ -42,18 +49,26 @@ const LIVE_CHANNELS = [
|
|
|
42
49
|
"editing",
|
|
43
50
|
"playback"
|
|
44
51
|
];
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
colors: buildFallbackShapeColors("dark"),
|
|
50
|
-
colorScheme: "dark"
|
|
51
|
-
};
|
|
52
|
-
}
|
|
52
|
+
const DEFAULT_THEME = {
|
|
53
|
+
key: "dark",
|
|
54
|
+
...boardRenderTheme("dark")
|
|
55
|
+
};
|
|
53
56
|
const NO_IDS = /* @__PURE__ */ new Set();
|
|
54
57
|
const MARCH_STEP_MS = 160;
|
|
55
58
|
const MARCH_SMOOTH_MS = 40;
|
|
56
59
|
const TEXTURE_SETTLE_MS = 150;
|
|
60
|
+
const ADOPT_PIXELS_PER_FRAME = 4194304;
|
|
61
|
+
const LOAD_LEAD_MS = 300;
|
|
62
|
+
const CULL_PADDING = 96;
|
|
63
|
+
const PREFETCH_REST_MS = 200;
|
|
64
|
+
const PREFETCH_LIMIT = 96;
|
|
65
|
+
const FRAME_SAMPLES = 120;
|
|
66
|
+
const ANTIALIAS_MAX_DENSITY = 3;
|
|
67
|
+
const FRAME_SYNC = 1;
|
|
68
|
+
const FRAME_RENDER = 2;
|
|
69
|
+
const FRAME_CARDS = 4;
|
|
70
|
+
const FRAME_SCRIPTS = 8;
|
|
71
|
+
const FRAME_RESIZE = 16;
|
|
57
72
|
const ROTATE_CURSOR = `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M21 12a9 9 0 1 1-2.64-6.36L21 8M21 3v5h-5' fill='none' stroke='%23fff' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M21 12a9 9 0 1 1-2.64-6.36L21 8M21 3v5h-5' fill='none' stroke='%231d1d1f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") 12 12, crosshair`;
|
|
58
73
|
const defaultStyles = /* @__PURE__ */ new Map();
|
|
59
74
|
function styleOf(theme) {
|
|
@@ -66,7 +81,7 @@ function styleOf(theme) {
|
|
|
66
81
|
}
|
|
67
82
|
function mountBoardStage(host, options) {
|
|
68
83
|
const { editor, assets } = options;
|
|
69
|
-
const theme = options.theme ??
|
|
84
|
+
const theme = options.theme ?? (() => DEFAULT_THEME);
|
|
70
85
|
const resolveRenderer = options.renderers ?? getBoardCardRenderer;
|
|
71
86
|
let app = null;
|
|
72
87
|
let world = null;
|
|
@@ -105,22 +120,40 @@ function mountBoardStage(host, options) {
|
|
|
105
120
|
let stopDensity = null;
|
|
106
121
|
let active = true;
|
|
107
122
|
let disposed = false;
|
|
108
|
-
let
|
|
109
|
-
let
|
|
110
|
-
let
|
|
111
|
-
let
|
|
123
|
+
let frameHandle = 0;
|
|
124
|
+
let frameWork = 0;
|
|
125
|
+
let inFrame = false;
|
|
126
|
+
let chained = false;
|
|
127
|
+
const clock = createBoardFrameClock();
|
|
128
|
+
const device = defaultBoardDeviceBudget();
|
|
129
|
+
const currentLod = () => options.lod?.() ?? device.lod;
|
|
130
|
+
const frameTimes = new Float32Array(FRAME_SAMPLES);
|
|
131
|
+
let frameCount = 0;
|
|
132
|
+
let frameCamera = null;
|
|
112
133
|
let cardTickTimer = null;
|
|
113
134
|
let cardTickDue = 0;
|
|
135
|
+
let prefetchKey = "";
|
|
136
|
+
let prefetchMovedAt = 0;
|
|
137
|
+
let prefetchContext = null;
|
|
138
|
+
let cancelPrefetch = null;
|
|
114
139
|
const staleIds = /* @__PURE__ */ new Set();
|
|
115
|
-
let resizeFrame = 0;
|
|
116
140
|
let canvasBox = null;
|
|
117
141
|
let cardEpoch = 0;
|
|
142
|
+
let fontEpoch = 0;
|
|
143
|
+
let shownEditingId = null;
|
|
118
144
|
let surface = {
|
|
119
145
|
width: 0,
|
|
120
146
|
height: 0
|
|
121
147
|
};
|
|
122
148
|
let playbackCamera = null;
|
|
123
149
|
let cursor = "";
|
|
150
|
+
let lastContext = null;
|
|
151
|
+
let hoveredHit = null;
|
|
152
|
+
const ghostClicks = createGhostClickGuard(host.ownerDocument.defaultView);
|
|
153
|
+
const longPress = createBoardLongPress((press) => {
|
|
154
|
+
const item = editor.itemAt(pointToWorld(localPoint(press.clientX, press.clientY), renderCamera()));
|
|
155
|
+
if (item) options.onLongPress?.(item, press);
|
|
156
|
+
});
|
|
124
157
|
const renderCamera = () => playbackCamera ?? editor.camera;
|
|
125
158
|
const views = createBoardItemViewLayer(host, editor, options.views ?? [], renderCamera, scheduleTick);
|
|
126
159
|
const player = createBoardPlayer({ resolveColor: (color) => {
|
|
@@ -192,6 +225,50 @@ function mountBoardStage(host, options) {
|
|
|
192
225
|
}
|
|
193
226
|
}, TEXTURE_SETTLE_MS);
|
|
194
227
|
}
|
|
228
|
+
function cullView(camera) {
|
|
229
|
+
const view = visibleWorldRect(camera, surface.width, surface.height);
|
|
230
|
+
const pad = CULL_PADDING / camera.zoom;
|
|
231
|
+
return {
|
|
232
|
+
x: view.x - pad,
|
|
233
|
+
y: view.y - pad,
|
|
234
|
+
width: view.width + pad * 2,
|
|
235
|
+
height: view.height + pad * 2
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
const arrivals = /* @__PURE__ */ new Set();
|
|
239
|
+
const toned = /* @__PURE__ */ new Set();
|
|
240
|
+
function adoptArrivals() {
|
|
241
|
+
let pixels = 0;
|
|
242
|
+
for (const key of arrivals) {
|
|
243
|
+
const texture = assets.getTexture(key);
|
|
244
|
+
const size = texture ? texture.width * texture.height : 0;
|
|
245
|
+
if (pixels > 0 && pixels + size > ADOPT_PIXELS_PER_FRAME) {
|
|
246
|
+
scheduleTick();
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
pixels += size;
|
|
250
|
+
arrivals.delete(key);
|
|
251
|
+
for (const id of scene?.holders(key) ?? []) {
|
|
252
|
+
staleIds.add(id);
|
|
253
|
+
naturalIds.add(id);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
let lastCenter = null;
|
|
258
|
+
function loadFocus(center, camera) {
|
|
259
|
+
const time = performance.now();
|
|
260
|
+
const previous = lastCenter;
|
|
261
|
+
lastCenter = {
|
|
262
|
+
...center,
|
|
263
|
+
time
|
|
264
|
+
};
|
|
265
|
+
const elapsed = previous ? time - previous.time : 0;
|
|
266
|
+
if (!previous || elapsed <= 0 || elapsed > 100) return center;
|
|
267
|
+
const lead = LOAD_LEAD_MS / elapsed;
|
|
268
|
+
const reach = Math.max(surface.width, surface.height) / 2 / camera.zoom;
|
|
269
|
+
const ahead = (from, to) => to + Math.max(-reach, Math.min(reach, (to - from) * lead));
|
|
270
|
+
return worldPoint(ahead(previous.x, center.x), ahead(previous.y, center.y));
|
|
271
|
+
}
|
|
195
272
|
const naturalIds = /* @__PURE__ */ new Set();
|
|
196
273
|
let liveVersion = -1;
|
|
197
274
|
function adoptNaturalSizes() {
|
|
@@ -237,11 +314,12 @@ function mountBoardStage(host, options) {
|
|
|
237
314
|
hoveredId: editor.hoverId,
|
|
238
315
|
resizingIds: interaction.type === "resizing" ? new Set(interaction.origin.keys()) : /* @__PURE__ */ new Set(),
|
|
239
316
|
liftedIds: liftedIds(),
|
|
317
|
+
editingId: editor.editingId,
|
|
240
318
|
palette: current.palette,
|
|
241
319
|
colors: current.colors,
|
|
242
320
|
colorScheme: current.colorScheme,
|
|
243
321
|
style: styleOf(current),
|
|
244
|
-
themeKey: current.key
|
|
322
|
+
themeKey: `${current.key}:${fontEpoch}`,
|
|
245
323
|
rendererType: app?.renderer.type === RendererType.CANVAS ? "canvas" : "gpu",
|
|
246
324
|
zoom: renderCamera().zoom,
|
|
247
325
|
textResolution: textResolution.value,
|
|
@@ -251,13 +329,15 @@ function mountBoardStage(host, options) {
|
|
|
251
329
|
assetKey: assets.assetKey,
|
|
252
330
|
getTexture: (key) => assets.getTexture(key),
|
|
253
331
|
hasError: (key) => assets.hasError(key),
|
|
332
|
+
assetTone: (key) => assets.getTone(key),
|
|
254
333
|
fileState: (path) => options.fileState?.(path) ?? "ok",
|
|
255
334
|
acquireTexture: (key, item) => {
|
|
256
335
|
assets.acquire(key);
|
|
257
336
|
assets.requestItem(item, boardTextureEdge(item, textureScale()));
|
|
258
337
|
if (assets.getTexture(key)) naturalIds.add(item.id);
|
|
259
338
|
},
|
|
260
|
-
releaseTexture: (key) => assets.release(key)
|
|
339
|
+
releaseTexture: (key) => assets.release(key),
|
|
340
|
+
hoveredHit
|
|
261
341
|
};
|
|
262
342
|
}
|
|
263
343
|
function syncBackground(current) {
|
|
@@ -427,6 +507,36 @@ function mountBoardStage(host, options) {
|
|
|
427
507
|
if (style.selection.dash > 0 && selected.length > 0 && !(options.reducedMotion?.() ?? false)) scheduleMarch(style);
|
|
428
508
|
else stopMarch();
|
|
429
509
|
}
|
|
510
|
+
function opensOnTap(item) {
|
|
511
|
+
return !editor.selection.includes(item.id) && editor.registry.activation(item) === "tap";
|
|
512
|
+
}
|
|
513
|
+
function hitAt(item, point) {
|
|
514
|
+
if (!lastContext || !scene?.getNode(item.id)) return null;
|
|
515
|
+
return resolveRenderer(item, lastContext).hitAt?.(item, point, lastContext) ?? null;
|
|
516
|
+
}
|
|
517
|
+
function hoverHit(input) {
|
|
518
|
+
if (!options.onHit) return;
|
|
519
|
+
const item = input && editor.interaction.type === "idle" && editor.hoverId ? editor.itemById(editor.hoverId) : null;
|
|
520
|
+
const hit = item && input ? hitAt(item, input.world) : null;
|
|
521
|
+
const next = item && hit ? {
|
|
522
|
+
itemId: item.id,
|
|
523
|
+
action: hit.action,
|
|
524
|
+
cursor: hit.cursor ?? "pointer"
|
|
525
|
+
} : null;
|
|
526
|
+
if (next?.itemId === hoveredHit?.itemId && next?.action === hoveredHit?.action) return;
|
|
527
|
+
for (const id of [hoveredHit?.itemId, next?.itemId]) if (id) staleIds.add(id);
|
|
528
|
+
hoveredHit = next;
|
|
529
|
+
scheduleTick();
|
|
530
|
+
}
|
|
531
|
+
function pressHit(event, input) {
|
|
532
|
+
if (!options.onHit || event.button !== 0) return false;
|
|
533
|
+
const item = editor.itemAt(input.world);
|
|
534
|
+
const hit = item ? hitAt(item, input.world) : null;
|
|
535
|
+
if (!item || !hit || options.onHit(item, hit.action, boardStagePress(event)) === false) return false;
|
|
536
|
+
event.preventDefault();
|
|
537
|
+
if (event.pointerType !== "mouse") ghostClicks.arm();
|
|
538
|
+
return true;
|
|
539
|
+
}
|
|
430
540
|
function cursorFor() {
|
|
431
541
|
if (scriptMode === "interact" && scriptHover) {
|
|
432
542
|
const output = scriptOutputs.get(scriptHover.owner);
|
|
@@ -441,49 +551,191 @@ function mountBoardStage(host, options) {
|
|
|
441
551
|
case "draggingArrowHandle":
|
|
442
552
|
case "brushing": return "crosshair";
|
|
443
553
|
}
|
|
444
|
-
if (
|
|
554
|
+
if (interaction.type === "pressing") return "pointer";
|
|
555
|
+
if (editor.spaceHeld) return "grab";
|
|
556
|
+
if (hoveredHit) return hoveredHit.cursor;
|
|
445
557
|
const control = editor.hoveredTransformControl;
|
|
446
558
|
if (control?.kind === "resize") return resizeCursorForHandle(control.handle, editor.selectionTransform?.frame.rotation ?? 0);
|
|
447
559
|
if (control?.kind === "rotate") return ROTATE_CURSOR;
|
|
448
|
-
if (isCreationBoardTool(editor.tool)) return "crosshair";
|
|
449
560
|
const hovered = editor.hoverId ? editor.itemById(editor.hoverId) : null;
|
|
561
|
+
if (hovered && (editor.tool === "select" || editor.tool === "hand") && opensOnTap(hovered)) return "pointer";
|
|
562
|
+
if (editor.tool === "hand") return "grab";
|
|
563
|
+
if (isCreationBoardTool(editor.tool)) return "crosshair";
|
|
450
564
|
return hovered && !hovered.locked && editor.registry.capabilities(hovered).canMove ? "move" : "default";
|
|
451
565
|
}
|
|
566
|
+
function requestFrame(work) {
|
|
567
|
+
if (!active || disposed) return;
|
|
568
|
+
frameWork |= work;
|
|
569
|
+
if (!frameHandle && !inFrame) {
|
|
570
|
+
chained = false;
|
|
571
|
+
frameHandle = requestAnimationFrame(runFrame);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
function cancelFrames() {
|
|
575
|
+
cancelAnimationFrame(frameHandle);
|
|
576
|
+
frameHandle = 0;
|
|
577
|
+
frameWork = 0;
|
|
578
|
+
if (cardTickTimer !== null) clearTimeout(cardTickTimer);
|
|
579
|
+
cardTickTimer = null;
|
|
580
|
+
}
|
|
581
|
+
function runFrame(now) {
|
|
582
|
+
frameHandle = 0;
|
|
583
|
+
if (!app) return;
|
|
584
|
+
const start = performance.now();
|
|
585
|
+
let work = frameWork;
|
|
586
|
+
frameWork = 0;
|
|
587
|
+
inFrame = true;
|
|
588
|
+
try {
|
|
589
|
+
const camera = renderCamera();
|
|
590
|
+
const moving = editor.gestureActive || !frameCamera || camera.x !== frameCamera.x || camera.y !== frameCamera.y || camera.zoom !== frameCamera.zoom;
|
|
591
|
+
frameCamera = camera;
|
|
592
|
+
clock.begin(now, {
|
|
593
|
+
moving,
|
|
594
|
+
chained
|
|
595
|
+
});
|
|
596
|
+
if (work & FRAME_RESIZE && !applyResize()) work &= -17;
|
|
597
|
+
const synced = Boolean(work & 17);
|
|
598
|
+
if (synced) sync();
|
|
599
|
+
else if (work & FRAME_SCRIPTS) {
|
|
600
|
+
syncScripts();
|
|
601
|
+
if (scriptMode !== "paused" && scripts?.animated) frameWork |= FRAME_SCRIPTS;
|
|
602
|
+
}
|
|
603
|
+
if (work & FRAME_CARDS && !synced && scene) {
|
|
604
|
+
const next = scene.tick(performance.now());
|
|
605
|
+
work |= FRAME_RENDER;
|
|
606
|
+
if (next !== null) scheduleCardTick(next);
|
|
607
|
+
}
|
|
608
|
+
if ((work | frameWork) & FRAME_RENDER) {
|
|
609
|
+
frameWork &= -3;
|
|
610
|
+
app.render();
|
|
611
|
+
}
|
|
612
|
+
} finally {
|
|
613
|
+
inFrame = false;
|
|
614
|
+
frameTimes[frameCount++ % FRAME_SAMPLES] = performance.now() - start;
|
|
615
|
+
if (frameWork && active && !disposed) {
|
|
616
|
+
chained = true;
|
|
617
|
+
frameHandle = requestAnimationFrame(runFrame);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
function waitingCards() {
|
|
622
|
+
if (!scene || surface.width === 0) return 0;
|
|
623
|
+
const view = visibleWorldRect(renderCamera(), surface.width, surface.height);
|
|
624
|
+
let waiting = 0;
|
|
625
|
+
for (const id of scene.liveIds()) {
|
|
626
|
+
const item = editor.scene.get(id);
|
|
627
|
+
const key = item && assets.assetKey(item);
|
|
628
|
+
if (key && !assets.hasError(key) && !assets.getTexture(key) && rectsIntersect(itemBounds(item.frame), view)) waiting += 1;
|
|
629
|
+
}
|
|
630
|
+
return waiting;
|
|
631
|
+
}
|
|
632
|
+
function frameStats() {
|
|
633
|
+
const samples = Array.from(frameTimes.subarray(0, Math.min(frameCount, FRAME_SAMPLES))).sort((a, b) => a - b);
|
|
634
|
+
const at = (ratio) => samples[Math.min(samples.length - 1, Math.floor(samples.length * ratio))] ?? 0;
|
|
635
|
+
return {
|
|
636
|
+
p50: at(.5),
|
|
637
|
+
p95: at(.95),
|
|
638
|
+
max: samples.at(-1) ?? 0
|
|
639
|
+
};
|
|
640
|
+
}
|
|
452
641
|
function scheduleRender() {
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
642
|
+
requestFrame(FRAME_RENDER);
|
|
643
|
+
}
|
|
644
|
+
function scheduleTick() {
|
|
645
|
+
requestFrame(FRAME_SYNC);
|
|
646
|
+
}
|
|
647
|
+
function scheduleScriptTick() {
|
|
648
|
+
requestFrame(FRAME_SCRIPTS);
|
|
649
|
+
}
|
|
650
|
+
function resize() {
|
|
651
|
+
requestFrame(FRAME_RESIZE);
|
|
652
|
+
}
|
|
653
|
+
function flushResize() {
|
|
654
|
+
if (!active || disposed) return;
|
|
655
|
+
cancelAnimationFrame(frameHandle);
|
|
656
|
+
frameWork |= FRAME_RESIZE;
|
|
657
|
+
chained = false;
|
|
658
|
+
runFrame(performance.now());
|
|
659
|
+
chained = false;
|
|
458
660
|
}
|
|
459
661
|
function scheduleCardTick(wait) {
|
|
460
662
|
if (!active || disposed) return;
|
|
461
663
|
const due = performance.now() + wait;
|
|
462
|
-
if (
|
|
664
|
+
if (frameWork & FRAME_CARDS || cardTickTimer !== null && cardTickDue <= due) return;
|
|
463
665
|
if (cardTickTimer !== null) clearTimeout(cardTickTimer);
|
|
464
666
|
cardTickTimer = null;
|
|
465
667
|
if (wait > 0) {
|
|
466
668
|
cardTickDue = due;
|
|
467
669
|
cardTickTimer = setTimeout(() => {
|
|
468
670
|
cardTickTimer = null;
|
|
469
|
-
|
|
671
|
+
requestFrame(FRAME_CARDS);
|
|
470
672
|
}, wait);
|
|
471
673
|
return;
|
|
472
674
|
}
|
|
473
|
-
|
|
474
|
-
cardTickFrame = 0;
|
|
475
|
-
if (!scene) return;
|
|
476
|
-
const next = scene.tick(performance.now());
|
|
477
|
-
scheduleRender();
|
|
478
|
-
if (next !== null) scheduleCardTick(next);
|
|
479
|
-
});
|
|
675
|
+
requestFrame(FRAME_CARDS);
|
|
480
676
|
}
|
|
481
|
-
function
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
677
|
+
function schedulePrefetch(camera, context) {
|
|
678
|
+
const margin = assets.prefetch ? options.prefetch ?? device.prefetch : 0;
|
|
679
|
+
if (margin <= 0 || surface.width === 0 || surface.height === 0) return;
|
|
680
|
+
const key = `${camera.x}|${camera.y}|${camera.zoom}|${surface.width}|${surface.height}|${editor.structureVersion}`;
|
|
681
|
+
if (key === prefetchKey) return;
|
|
682
|
+
prefetchKey = key;
|
|
683
|
+
prefetchContext = context;
|
|
684
|
+
prefetchMovedAt = performance.now();
|
|
685
|
+
if (!cancelPrefetch) awaitRest(margin, PREFETCH_REST_MS);
|
|
686
|
+
}
|
|
687
|
+
function awaitRest(margin, delay) {
|
|
688
|
+
cancelPrefetch = scheduleBoardIdle(() => {
|
|
689
|
+
cancelPrefetch = null;
|
|
690
|
+
const remaining = PREFETCH_REST_MS - (performance.now() - prefetchMovedAt);
|
|
691
|
+
if (remaining > 0) awaitRest(margin, remaining);
|
|
692
|
+
else if (prefetchContext) prefetch(margin, prefetchContext);
|
|
693
|
+
}, delay);
|
|
694
|
+
}
|
|
695
|
+
function stopPrefetch() {
|
|
696
|
+
cancelPrefetch?.();
|
|
697
|
+
cancelPrefetch = null;
|
|
698
|
+
prefetchKey = "";
|
|
699
|
+
prefetchContext = null;
|
|
700
|
+
assets.prefetch?.([]);
|
|
701
|
+
}
|
|
702
|
+
function prefetch(margin, context) {
|
|
703
|
+
if (!scene || !active || disposed) return;
|
|
704
|
+
if (editor.gestureActive) {
|
|
705
|
+
prefetchKey = "";
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
const camera = renderCamera();
|
|
709
|
+
const view = visibleWorldRect(camera, surface.width, surface.height);
|
|
710
|
+
const culled = stableCullRect(view);
|
|
711
|
+
const padX = view.width * margin;
|
|
712
|
+
const padY = view.height * margin;
|
|
713
|
+
const ring = {
|
|
714
|
+
x: culled.x - padX,
|
|
715
|
+
y: culled.y - padY,
|
|
716
|
+
width: culled.width + padX * 2,
|
|
717
|
+
height: culled.height + padY * 2
|
|
718
|
+
};
|
|
719
|
+
const centerX = view.x + view.width / 2;
|
|
720
|
+
const centerY = view.y + view.height / 2;
|
|
721
|
+
const lod = currentLod();
|
|
722
|
+
const scale = textureScale();
|
|
723
|
+
const wanted = [];
|
|
724
|
+
for (const id of editor.idsInRect(ring)) {
|
|
725
|
+
const item = editor.scene.get(id);
|
|
726
|
+
if (!item || rectsIntersect(itemBounds(item.frame), culled)) continue;
|
|
727
|
+
const renderer = resolveRenderer(item, context);
|
|
728
|
+
if (renderer.renderFar && boardLodRatio(renderer, boardLodSize(renderer, item), camera.zoom, lod) < 1) continue;
|
|
729
|
+
const { frame } = item;
|
|
730
|
+
const distance = (frame.x + frame.width / 2 - centerX) ** 2 + (frame.y + frame.height / 2 - centerY) ** 2;
|
|
731
|
+
wanted.push({
|
|
732
|
+
item,
|
|
733
|
+
edge: boardTextureEdge(item, scale),
|
|
734
|
+
distance
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
wanted.sort((a, b) => a.distance - b.distance);
|
|
738
|
+
assets.prefetch?.(wanted.slice(0, PREFETCH_LIMIT));
|
|
487
739
|
}
|
|
488
740
|
function cancelScriptPointers(owner, retained) {
|
|
489
741
|
scriptPointers.cancelScripts((pointerId, target) => {
|
|
@@ -512,15 +764,6 @@ function mountBoardStage(host, options) {
|
|
|
512
764
|
}));
|
|
513
765
|
scripts.sync(editor.document, editor.scene, camera, scriptTime, scriptMode === "interact", visibleIds());
|
|
514
766
|
}
|
|
515
|
-
function scheduleScriptTick() {
|
|
516
|
-
if (scriptTickFrame || !active || disposed) return;
|
|
517
|
-
scriptTickFrame = requestAnimationFrame(() => {
|
|
518
|
-
scriptTickFrame = 0;
|
|
519
|
-
if (tickFrame) return;
|
|
520
|
-
syncScripts();
|
|
521
|
-
if (scriptMode !== "paused" && scripts?.animated) scheduleScriptTick();
|
|
522
|
-
});
|
|
523
|
-
}
|
|
524
767
|
function createScripts() {
|
|
525
768
|
return createBoardScriptHost({
|
|
526
769
|
host,
|
|
@@ -636,8 +879,16 @@ function mountBoardStage(host, options) {
|
|
|
636
879
|
world.position.set(camera.x, camera.y);
|
|
637
880
|
world.scale.set(camera.zoom);
|
|
638
881
|
const ids = visibleIds();
|
|
882
|
+
const center = pointToWorld(screenPoint(surface.width / 2, surface.height / 2), camera);
|
|
883
|
+
assets.focus(loadFocus(center, camera));
|
|
884
|
+
adoptArrivals();
|
|
885
|
+
if (toned.size > 0) {
|
|
886
|
+
scene?.repaintFar(toned, assets.assetKey);
|
|
887
|
+
toned.clear();
|
|
888
|
+
}
|
|
639
889
|
textResolution.update(textureScale());
|
|
640
890
|
const context = renderContext(current, renderScene, frame.time);
|
|
891
|
+
lastContext = context;
|
|
641
892
|
if (animationId && effectSampler) {
|
|
642
893
|
context.time = editor.playhead?.time ?? frame.time;
|
|
643
894
|
context.frameAt = effectSampler.frameAt;
|
|
@@ -646,6 +897,10 @@ function mountBoardStage(host, options) {
|
|
|
646
897
|
for (const item of renderScene.items) if (item.type === "effect" && item.props.kind === "trail" && renderScene.opacity(item.id) > 0) pinnedIds.add(item.id);
|
|
647
898
|
for (const id of previews.keys()) pinnedIds.add(id);
|
|
648
899
|
if (editor.editingId) pinnedIds.add(editor.editingId);
|
|
900
|
+
if (editor.editingId !== shownEditingId) {
|
|
901
|
+
for (const id of [shownEditingId, editor.editingId]) if (id) staleIds.add(id);
|
|
902
|
+
shownEditingId = editor.editingId;
|
|
903
|
+
}
|
|
649
904
|
for (const id of frame.items.keys()) {
|
|
650
905
|
pinnedIds.add(id);
|
|
651
906
|
for (const child of renderScene.descendants(id)) pinnedIds.add(child);
|
|
@@ -659,14 +914,21 @@ function mountBoardStage(host, options) {
|
|
|
659
914
|
getItem: (id) => renderScene.get(id) ?? null,
|
|
660
915
|
visibleIds: ids,
|
|
661
916
|
pinnedIds,
|
|
662
|
-
globalSig: [
|
|
917
|
+
globalSig: [
|
|
918
|
+
cardEpoch,
|
|
919
|
+
current.key,
|
|
920
|
+
fontEpoch
|
|
921
|
+
].join("|"),
|
|
663
922
|
staleIds,
|
|
664
923
|
structureVersion: editor.structureVersion,
|
|
665
|
-
geometryVersion: editor.geometryVersion,
|
|
666
924
|
gestureActive: editor.gestureActive && editor.interaction.type !== "panning",
|
|
667
|
-
focus:
|
|
925
|
+
focus: center,
|
|
926
|
+
view: ids ? cullView(camera) : void 0,
|
|
927
|
+
lod: currentLod(),
|
|
928
|
+
budget: clock
|
|
668
929
|
});
|
|
669
930
|
staleIds.clear();
|
|
931
|
+
schedulePrefetch(camera, context);
|
|
670
932
|
if (scene.liveVersion !== liveVersion) {
|
|
671
933
|
liveVersion = scene.liveVersion;
|
|
672
934
|
options.onLiveChange?.(scene.liveIds());
|
|
@@ -690,29 +952,26 @@ function mountBoardStage(host, options) {
|
|
|
690
952
|
const cardWait = scene.tick(performance.now());
|
|
691
953
|
if (cardWait !== null) scheduleCardTick(cardWait);
|
|
692
954
|
}
|
|
693
|
-
function
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
}
|
|
714
|
-
sync();
|
|
715
|
-
});
|
|
955
|
+
function applyResize() {
|
|
956
|
+
if (!app) return false;
|
|
957
|
+
const size = {
|
|
958
|
+
width: host.clientWidth,
|
|
959
|
+
height: host.clientHeight
|
|
960
|
+
};
|
|
961
|
+
if (size.width <= 0 || size.height <= 0) return false;
|
|
962
|
+
const density = host.ownerDocument.defaultView?.devicePixelRatio ?? 1;
|
|
963
|
+
const canvas = boardCanvasSize(canvasBox ?? {
|
|
964
|
+
...size,
|
|
965
|
+
density,
|
|
966
|
+
device: null
|
|
967
|
+
}, density);
|
|
968
|
+
if (canvas.width !== app.screen.width || canvas.height !== app.screen.height || canvas.resolution !== app.renderer.resolution) app.renderer.resize(canvas.width, canvas.height, canvas.resolution);
|
|
969
|
+
if (size.width !== surface.width || size.height !== surface.height) {
|
|
970
|
+
surface = size;
|
|
971
|
+
editor.surfaceSize = surface;
|
|
972
|
+
options.onSurfaceChange?.(surface);
|
|
973
|
+
}
|
|
974
|
+
return true;
|
|
716
975
|
}
|
|
717
976
|
const localPoint = (x, y) => elementClientToLocal(host)(x, y);
|
|
718
977
|
const inViews = (event) => event.target instanceof Node && views.element.contains(event.target);
|
|
@@ -794,8 +1053,11 @@ function mountBoardStage(host, options) {
|
|
|
794
1053
|
return;
|
|
795
1054
|
}
|
|
796
1055
|
if (options.onPointer?.("down", event, input) === false) return;
|
|
1056
|
+
if (pressHit(event, input)) return;
|
|
797
1057
|
pointers.start(event);
|
|
798
1058
|
editor.pointerDown(input);
|
|
1059
|
+
if (options.onLongPress && editor.itemAt(input.world)) longPress.start(event);
|
|
1060
|
+
else longPress.cancel();
|
|
799
1061
|
}
|
|
800
1062
|
function handlePointerMove(event) {
|
|
801
1063
|
if (!active || pointers.has(event.pointerId) || inViews(event)) return;
|
|
@@ -804,21 +1066,28 @@ function mountBoardStage(host, options) {
|
|
|
804
1066
|
function routePointerMove(event) {
|
|
805
1067
|
const input = toInput(event);
|
|
806
1068
|
if (scriptPointer("move", event, input)) return;
|
|
1069
|
+
longPress.move(event);
|
|
807
1070
|
if (options.onPointer?.("move", event, input) === false) return;
|
|
808
1071
|
editor.pointerMove(input);
|
|
1072
|
+
hoverHit(input);
|
|
809
1073
|
}
|
|
810
1074
|
function handlePointerUp(event) {
|
|
811
1075
|
const input = toInput(event);
|
|
812
1076
|
if (scriptPointer("up", event, input)) return;
|
|
1077
|
+
longPress.end(event);
|
|
813
1078
|
if (options.onPointer?.("up", event, input) === false) return;
|
|
814
1079
|
editor.pointerUp(input);
|
|
815
|
-
if (event.type === "pointercancel" || event.pointerType !== "mouse")
|
|
1080
|
+
if (event.type === "pointercancel" || event.pointerType !== "mouse") {
|
|
1081
|
+
editor.pointerLeave();
|
|
1082
|
+
hoverHit(null);
|
|
1083
|
+
}
|
|
816
1084
|
}
|
|
817
1085
|
function handlePointerLeave(event) {
|
|
818
1086
|
if (event.buttons !== 0) return;
|
|
819
1087
|
scriptPointer("leave", event, toInput(event));
|
|
820
1088
|
if (options.onPointer?.("leave", event, toInput(event)) === false) return;
|
|
821
1089
|
editor.pointerLeave();
|
|
1090
|
+
hoverHit(null);
|
|
822
1091
|
}
|
|
823
1092
|
function handleWheel(event) {
|
|
824
1093
|
if (inViews(event)) return;
|
|
@@ -837,7 +1106,7 @@ function mountBoardStage(host, options) {
|
|
|
837
1106
|
return;
|
|
838
1107
|
}
|
|
839
1108
|
if (item && item.type !== "frame" && item.type !== "arrow") return;
|
|
840
|
-
const label = editor.labelItemAt(point);
|
|
1109
|
+
const label = editor.labelItemAt(point, styleOf(theme()).frameLabelSize);
|
|
841
1110
|
if (label) editor.editingId = label.id;
|
|
842
1111
|
else if (!item) editor.beginTextDraft(point);
|
|
843
1112
|
}
|
|
@@ -855,26 +1124,40 @@ function mountBoardStage(host, options) {
|
|
|
855
1124
|
["dblclick", handleDoubleClick]
|
|
856
1125
|
];
|
|
857
1126
|
const stopEditor = editor.subscribe(LIVE_CHANNELS, scheduleTick);
|
|
858
|
-
const
|
|
859
|
-
const
|
|
860
|
-
if (!
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
1127
|
+
const stopActivations = editor.subscribeActivations(({ itemId, pointerType, selected }) => {
|
|
1128
|
+
const item = editor.itemById(itemId);
|
|
1129
|
+
if (!item || !options.onActivate) return;
|
|
1130
|
+
if (pointerType !== "mouse") ghostClicks.arm();
|
|
1131
|
+
options.onActivate(item, {
|
|
1132
|
+
itemId,
|
|
1133
|
+
pointerType,
|
|
1134
|
+
selected
|
|
1135
|
+
});
|
|
1136
|
+
});
|
|
1137
|
+
const stopFonts = onBoardTextFontsChange(() => {
|
|
1138
|
+
editor.relayoutText();
|
|
1139
|
+
fontEpoch += 1;
|
|
1140
|
+
scene?.redrawText();
|
|
1141
|
+
scheduleTick();
|
|
1142
|
+
});
|
|
1143
|
+
const stopAssets = assets.subscribe((key, change) => {
|
|
1144
|
+
if (change === "texture") arrivals.add(key);
|
|
1145
|
+
else if (scene?.counts().far) toned.add(key);
|
|
1146
|
+
else return;
|
|
865
1147
|
scheduleTick();
|
|
866
1148
|
});
|
|
867
1149
|
const resizeObserver = new ResizeObserver((entries) => {
|
|
868
1150
|
const entry = entries[entries.length - 1];
|
|
869
1151
|
if (entry) canvasBox = measureBoardCanvasBox(entry, host.ownerDocument.defaultView?.devicePixelRatio ?? 1);
|
|
870
|
-
|
|
1152
|
+
flushResize();
|
|
871
1153
|
});
|
|
872
1154
|
return {
|
|
873
1155
|
ready: (async () => {
|
|
874
1156
|
const instance = new Application();
|
|
1157
|
+
const density = host.ownerDocument.defaultView?.devicePixelRatio ?? 1;
|
|
875
1158
|
try {
|
|
876
1159
|
await instance.init({
|
|
877
|
-
antialias:
|
|
1160
|
+
antialias: density < ANTIALIAS_MAX_DENSITY,
|
|
878
1161
|
backgroundAlpha: 0,
|
|
879
1162
|
width: host.clientWidth,
|
|
880
1163
|
height: host.clientHeight,
|
|
@@ -982,16 +1265,8 @@ function mountBoardStage(host, options) {
|
|
|
982
1265
|
stopMarch();
|
|
983
1266
|
stopRefine();
|
|
984
1267
|
cancelScriptPointers();
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
cancelAnimationFrame(renderFrame);
|
|
988
|
-
cancelAnimationFrame(tickFrame);
|
|
989
|
-
cancelAnimationFrame(cardTickFrame);
|
|
990
|
-
if (cardTickTimer !== null) clearTimeout(cardTickTimer);
|
|
991
|
-
renderFrame = 0;
|
|
992
|
-
tickFrame = 0;
|
|
993
|
-
cardTickFrame = 0;
|
|
994
|
-
cardTickTimer = null;
|
|
1268
|
+
cancelFrames();
|
|
1269
|
+
stopPrefetch();
|
|
995
1270
|
return;
|
|
996
1271
|
}
|
|
997
1272
|
player.reset();
|
|
@@ -1004,6 +1279,24 @@ function mountBoardStage(host, options) {
|
|
|
1004
1279
|
scheduleTick();
|
|
1005
1280
|
},
|
|
1006
1281
|
isMaterialized: (id) => Boolean(scene?.getNode(id)),
|
|
1282
|
+
stats() {
|
|
1283
|
+
const { textures, cooling, bytes, loading, prefetching } = assets.stats();
|
|
1284
|
+
return {
|
|
1285
|
+
...scene?.counts() ?? {
|
|
1286
|
+
live: 0,
|
|
1287
|
+
far: 0
|
|
1288
|
+
},
|
|
1289
|
+
textures,
|
|
1290
|
+
cooling,
|
|
1291
|
+
textureBytes: bytes,
|
|
1292
|
+
loading: loading ?? 0,
|
|
1293
|
+
prefetching: prefetching ?? 0,
|
|
1294
|
+
waiting: waitingCards(),
|
|
1295
|
+
settling: scene?.settling ?? false,
|
|
1296
|
+
frame: frameStats(),
|
|
1297
|
+
interval: clock.interval
|
|
1298
|
+
};
|
|
1299
|
+
},
|
|
1007
1300
|
toWorld: (clientX, clientY) => pointToWorld(localPoint(clientX, clientY), renderCamera()),
|
|
1008
1301
|
destroy() {
|
|
1009
1302
|
disposed = true;
|
|
@@ -1018,15 +1311,14 @@ function mountBoardStage(host, options) {
|
|
|
1018
1311
|
stopMaintenance?.();
|
|
1019
1312
|
stopDensity?.();
|
|
1020
1313
|
stopEditor();
|
|
1314
|
+
stopActivations();
|
|
1315
|
+
longPress.cancel();
|
|
1316
|
+
ghostClicks.dispose();
|
|
1317
|
+
stopFonts();
|
|
1021
1318
|
stopAssets();
|
|
1022
1319
|
resizeObserver.disconnect();
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
cancelAnimationFrame(renderFrame);
|
|
1026
|
-
cancelAnimationFrame(tickFrame);
|
|
1027
|
-
cancelAnimationFrame(cardTickFrame);
|
|
1028
|
-
if (cardTickTimer !== null) clearTimeout(cardTickTimer);
|
|
1029
|
-
cardTickTimer = null;
|
|
1320
|
+
cancelFrames();
|
|
1321
|
+
stopPrefetch();
|
|
1030
1322
|
for (const [type, listener] of listeners) host.removeEventListener(type, listener);
|
|
1031
1323
|
editor.setPlayedItems(/* @__PURE__ */ new Map());
|
|
1032
1324
|
editor.setScriptItems(/* @__PURE__ */ new Map());
|