@neta-art/cohub 11.5.1 → 12.1.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/dist/board/editor/animation.js +2 -1
- package/dist/board/editor/creation.js +1 -1
- package/dist/board/editor/document-edits.d.ts +1 -1
- package/dist/board/editor/document-edits.js +1 -19
- package/dist/board/editor/document.js +2 -1
- package/dist/board/editor/index.d.ts +2 -1
- package/dist/board/editor/index.js +2 -1
- package/dist/board/editor/snapshots.js +11 -13
- package/dist/board/export/scene.js +1 -0
- package/dist/board/model/client-geometry.d.ts +22 -0
- package/dist/board/model/client-geometry.js +94 -0
- package/dist/board/model/document-share.d.ts +5 -0
- package/dist/board/model/document-share.js +27 -0
- package/dist/board/model/index.d.ts +5 -4
- package/dist/board/model/index.js +4 -3
- package/dist/board/model/items/create.d.ts +5 -1
- package/dist/board/model/items/create.js +29 -58
- package/dist/board/model/items/index.d.ts +2 -2
- package/dist/board/model/items/index.js +2 -2
- package/dist/board/model/items/registry.js +2 -5
- package/dist/board/model/json.d.ts +4 -0
- package/dist/board/model/json.js +22 -0
- package/dist/board/model/media-playback.d.ts +6 -3
- package/dist/board/player/index.d.ts +6 -2
- package/dist/board/player/index.js +33 -15
- package/dist/board/render/card-tag.d.ts +0 -1
- package/dist/board/render/card-tag.js +15 -17
- package/dist/board/render/index.d.ts +3 -3
- package/dist/board/render/index.js +3 -3
- package/dist/board/render/renderers/arrow-card-renderer.js +8 -6
- package/dist/board/render/renderers/audio-card-renderer.js +10 -6
- package/dist/board/render/renderers/base-card-renderer.d.ts +1 -1
- package/dist/board/render/renderers/base-card-renderer.js +2 -3
- package/dist/board/render/renderers/board-renderer-registry.d.ts +6 -2
- package/dist/board/render/renderers/custom-card-renderer.js +23 -18
- package/dist/board/render/renderers/file-card-renderer.js +14 -9
- package/dist/board/render/renderers/frame-card-renderer.js +7 -4
- package/dist/board/render/renderers/image-card-renderer.js +13 -49
- package/dist/board/render/renderers/model-card-renderer.js +4 -1
- package/dist/board/render/renderers/shape-card-renderer.js +8 -6
- package/dist/board/render/renderers/task-card-renderer.js +13 -10
- package/dist/board/render/renderers/text-card-renderer.js +7 -5
- package/dist/board/render/renderers/unknown-card-renderer.js +8 -6
- package/dist/board/render/renderers/video-card-renderer.js +19 -18
- package/dist/board/render/script-host.d.ts +2 -0
- package/dist/board/render/script-host.js +44 -9
- package/dist/board/render/script-resolution.d.ts +4 -0
- package/dist/board/render/script-resolution.js +18 -0
- package/dist/board/render/surface.d.ts +9 -2
- package/dist/board/render/surface.js +15 -1
- package/dist/board/render/text-resolution.d.ts +4 -7
- package/dist/board/render/text-resolution.js +20 -22
- package/dist/board/replica/index.js +4 -1
- package/dist/board/stage/assets.d.ts +12 -8
- package/dist/board/stage/assets.js +173 -88
- package/dist/board/stage/canvas-size.d.ts +18 -0
- package/dist/board/stage/canvas-size.js +31 -0
- package/dist/board/stage/index.d.ts +3 -3
- package/dist/board/stage/index.js +3 -3
- package/dist/board/stage/lru.d.ts +3 -2
- package/dist/board/stage/lru.js +8 -4
- package/dist/board/stage/pointer.d.ts +1 -1
- package/dist/board/stage/pointer.js +4 -5
- package/dist/board/stage/scene.d.ts +8 -1
- package/dist/board/stage/scene.js +72 -10
- package/dist/board/stage/stage.d.ts +1 -0
- package/dist/board/stage/stage.js +151 -63
- package/dist/board/stage/text-resolution-tracker.d.ts +8 -0
- package/dist/board/stage/text-resolution-tracker.js +33 -0
- package/dist/board/stage/views.d.ts +7 -2
- package/dist/board/stage/views.js +50 -21
- package/dist/chunks/environment.d.ts +16 -2
- package/dist/index.js +65 -22
- package/dist/protocol/dist/board-constants.js +56 -1
- package/dist/protocol/dist/board-layout.d.ts +8 -1
- package/dist/protocol/dist/board-layout.js +16 -4
- package/dist/protocol/dist/board-model.js +13 -19
- package/dist/protocol/dist/board-schema.d.ts +52 -0
- package/dist/protocol/dist/board-schema.js +8 -0
- package/dist/protocol/dist/core/media.js +1 -0
- package/dist/protocol/dist/index.d.ts +2 -2
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BoardItemCapabilities, BoardItemDefinition, BoardItemOf, BoardItemResizeMode, FULL_CAPABILITIES, defineBoardItem } from "./definition.js";
|
|
2
2
|
import { builtinBoardItems } from "./builtin.js";
|
|
3
|
-
import { BoardAppMetadata, BoardItemEntry, BoardMediaItemKind, boardItemOrigin, boardOriginKey, createAppBoardItem, createArrowBoardItem, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createMediaBoardItem, createShapeBoardItem, createTaskBoardItem, createTaskResultItems, createTextBoardItem, mediaFrameSize, titleForBoardItem } from "./create.js";
|
|
3
|
+
import { BoardAppMetadata, BoardItemEntry, BoardMediaItemKind, boardItemOrigin, boardOriginKey, boardTaskCardSize, createAppBoardItem, createArrowBoardItem, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createMediaBoardItem, createShapeBoardItem, createTaskBoardItem, createTaskResultItems, createTextBoardItem, mediaFrameSize, titleForBoardItem } from "./create.js";
|
|
4
4
|
import { createBoardEntityId, createBoardItemId } from "./id.js";
|
|
5
5
|
import { BoardItemInput, BoardRegistry, createBoardRegistry, defaultBoardRegistry } from "./registry.js";
|
|
6
|
-
export { BoardAppMetadata, BoardItemCapabilities, BoardItemDefinition, BoardItemEntry, BoardItemInput, BoardItemOf, BoardItemResizeMode, BoardMediaItemKind, BoardRegistry, FULL_CAPABILITIES, boardItemOrigin, boardOriginKey, builtinBoardItems, createAppBoardItem, createArrowBoardItem, createBoardEntityId, createBoardItemId, createBoardRegistry, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createMediaBoardItem, createShapeBoardItem, createTaskBoardItem, createTaskResultItems, createTextBoardItem, defaultBoardRegistry, defineBoardItem, mediaFrameSize, titleForBoardItem };
|
|
6
|
+
export { BoardAppMetadata, BoardItemCapabilities, BoardItemDefinition, BoardItemEntry, BoardItemInput, BoardItemOf, BoardItemResizeMode, BoardMediaItemKind, BoardRegistry, FULL_CAPABILITIES, boardItemOrigin, boardOriginKey, boardTaskCardSize, builtinBoardItems, createAppBoardItem, createArrowBoardItem, createBoardEntityId, createBoardItemId, createBoardRegistry, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createMediaBoardItem, createShapeBoardItem, createTaskBoardItem, createTaskResultItems, createTextBoardItem, defaultBoardRegistry, defineBoardItem, mediaFrameSize, titleForBoardItem };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FULL_CAPABILITIES, defineBoardItem } from "./definition.js";
|
|
2
2
|
import { builtinBoardItems } from "./builtin.js";
|
|
3
3
|
import { createBoardEntityId, createBoardItemId } from "./id.js";
|
|
4
|
-
import { boardItemOrigin, boardOriginKey, createAppBoardItem, createArrowBoardItem, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createMediaBoardItem, createShapeBoardItem, createTaskBoardItem, createTaskResultItems, createTextBoardItem, mediaFrameSize, titleForBoardItem } from "./create.js";
|
|
4
|
+
import { boardItemOrigin, boardOriginKey, boardTaskCardSize, createAppBoardItem, createArrowBoardItem, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createMediaBoardItem, createShapeBoardItem, createTaskBoardItem, createTaskResultItems, createTextBoardItem, mediaFrameSize, titleForBoardItem } from "./create.js";
|
|
5
5
|
import { createBoardRegistry, defaultBoardRegistry } from "./registry.js";
|
|
6
|
-
export { FULL_CAPABILITIES, boardItemOrigin, boardOriginKey, builtinBoardItems, createAppBoardItem, createArrowBoardItem, createBoardEntityId, createBoardItemId, createBoardRegistry, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createMediaBoardItem, createShapeBoardItem, createTaskBoardItem, createTaskResultItems, createTextBoardItem, defaultBoardRegistry, defineBoardItem, mediaFrameSize, titleForBoardItem };
|
|
6
|
+
export { FULL_CAPABILITIES, boardItemOrigin, boardOriginKey, boardTaskCardSize, builtinBoardItems, createAppBoardItem, createArrowBoardItem, createBoardEntityId, createBoardItemId, createBoardRegistry, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createMediaBoardItem, createShapeBoardItem, createTaskBoardItem, createTaskResultItems, createTextBoardItem, defaultBoardRegistry, defineBoardItem, mediaFrameSize, titleForBoardItem };
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
+
import { boardDefaultSize } from "../../../protocol/dist/board-constants.js";
|
|
1
2
|
import { hasAuthoredSize, parseBoardItem } from "../../../protocol/dist/board-model.js";
|
|
2
3
|
import { frameContainsPoint, itemBounds } from "../geometry.js";
|
|
3
4
|
import { FULL_CAPABILITIES } from "./definition.js";
|
|
4
5
|
import { builtinBoardItems } from "./builtin.js";
|
|
5
6
|
import { createBoardItemId } from "./id.js";
|
|
6
7
|
//#region src/board/model/items/registry.ts
|
|
7
|
-
const DEFAULT_ITEM_SIZE = {
|
|
8
|
-
width: 240,
|
|
9
|
-
height: 160
|
|
10
|
-
};
|
|
11
8
|
function createBoardRegistry(definitions = []) {
|
|
12
9
|
const byType = /* @__PURE__ */ new Map();
|
|
13
10
|
for (const definition of [...builtinBoardItems, ...definitions]) byType.set(definition.type, definition);
|
|
@@ -52,7 +49,7 @@ function createBoardRegistry(definitions = []) {
|
|
|
52
49
|
create(type, { props = {}, at, size, id = createBoardItemId() }) {
|
|
53
50
|
const valid = validateProps(type, props);
|
|
54
51
|
if (!valid.ok) throw new Error(valid.message);
|
|
55
|
-
const box = size ?? byType.get(type)?.size ??
|
|
52
|
+
const box = size ?? byType.get(type)?.size ?? boardDefaultSize(type);
|
|
56
53
|
const placement = hasAuthoredSize(type) ? {
|
|
57
54
|
position: {
|
|
58
55
|
x: at.x - box.width / 2,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/board/model/json.ts
|
|
2
|
+
function sameJson(a, b) {
|
|
3
|
+
if (a === b) return true;
|
|
4
|
+
if (!a || !b || typeof a !== "object" || typeof b !== "object") return false;
|
|
5
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
6
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
|
|
7
|
+
for (let index = 0; index < a.length; index += 1) if (!sameJson(a[index], b[index])) return false;
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
const left = a;
|
|
11
|
+
const right = b;
|
|
12
|
+
let members = 0;
|
|
13
|
+
for (const key of Object.keys(left)) {
|
|
14
|
+
if (left[key] === void 0) continue;
|
|
15
|
+
members += 1;
|
|
16
|
+
if (!sameJson(left[key], right[key])) return false;
|
|
17
|
+
}
|
|
18
|
+
for (const key of Object.keys(right)) if (right[key] !== void 0) members -= 1;
|
|
19
|
+
return members === 0;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { sameJson };
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { BoardSceneItem } from "./scene.js";
|
|
2
2
|
//#region src/board/model/media-playback.d.ts
|
|
3
|
+
type BoardAssetUrlOptions = {
|
|
4
|
+
fresh?: boolean;
|
|
5
|
+
};
|
|
3
6
|
type BoardAssetSource = {
|
|
4
|
-
resolveFileUrl: (path: string) => Promise<string | null>;
|
|
5
|
-
resolvePlaybackUrl?: (path: string) => Promise<string | null>;
|
|
7
|
+
resolveFileUrl: (path: string, options?: BoardAssetUrlOptions) => Promise<string | null>;
|
|
8
|
+
resolvePlaybackUrl?: (path: string, options?: BoardAssetUrlOptions) => Promise<string | null>;
|
|
6
9
|
};
|
|
7
10
|
declare function resolveBoardMediaUrl(src: string, source: BoardAssetSource, purpose?: "preview" | "playback"): Promise<string | null>;
|
|
8
11
|
type BoardPlayableMedia = {
|
|
@@ -17,4 +20,4 @@ declare function playableBoardMediaList(item: BoardSceneItem | null, assetSource
|
|
|
17
20
|
declare function playableBoardMedia(item: BoardSceneItem | null, assetSource: BoardAssetSource, artifactId?: string | null): BoardPlayableMedia | null;
|
|
18
21
|
declare function resetBoardPlaybackUrlCache(): void;
|
|
19
22
|
//#endregion
|
|
20
|
-
export { BoardAssetSource, BoardPlayableMedia, playableBoardMedia, playableBoardMediaList, resetBoardPlaybackUrlCache, resolveBoardMediaUrl };
|
|
23
|
+
export { BoardAssetSource, BoardAssetUrlOptions, BoardPlayableMedia, playableBoardMedia, playableBoardMediaList, resetBoardPlaybackUrlCache, resolveBoardMediaUrl };
|
|
@@ -10,7 +10,11 @@ type BoardPlayerFrame = {
|
|
|
10
10
|
playbackTime: number | null;
|
|
11
11
|
running: boolean;
|
|
12
12
|
};
|
|
13
|
-
|
|
13
|
+
type BoardPlaybackClock = {
|
|
14
|
+
time: number | null;
|
|
15
|
+
advancing: boolean;
|
|
16
|
+
};
|
|
17
|
+
declare function playbackClockAt(playback: BoardPlaybackSnapshot, document: BoardDocument, now: number): BoardPlaybackClock;
|
|
14
18
|
declare function createBoardPlayer(options?: {
|
|
15
19
|
resolveColor?: BoardColorResolver;
|
|
16
20
|
}): {
|
|
@@ -21,4 +25,4 @@ declare function createBoardPlayer(options?: {
|
|
|
21
25
|
type BoardPlayer = ReturnType<typeof createBoardPlayer>;
|
|
22
26
|
declare function nextLocalPlayback(current: BoardPlaybackSnapshot | null, command: BoardPlaybackCommand, document: BoardDocument, now?: number): BoardPlaybackSnapshot | null;
|
|
23
27
|
//#endregion
|
|
24
|
-
export { BoardPlayer, BoardPlayerFrame, createBoardPlayer, nextLocalPlayback,
|
|
28
|
+
export { BoardPlaybackClock, BoardPlayer, BoardPlayerFrame, createBoardPlayer, nextLocalPlayback, playbackClockAt };
|
|
@@ -5,16 +5,35 @@ import { createBoardEntityId } from "../model/items/id.js";
|
|
|
5
5
|
const ENTER_ANIMATION = "\0enter";
|
|
6
6
|
const ENTER_STAGGER_MS = 45;
|
|
7
7
|
const ENTER_MAX_ITEMS = 80;
|
|
8
|
-
|
|
8
|
+
const SETTLED = {
|
|
9
|
+
time: null,
|
|
10
|
+
advancing: false
|
|
11
|
+
};
|
|
12
|
+
function playbackClockAt(playback, document, now) {
|
|
9
13
|
const animation = document.animations[playback.animationId];
|
|
10
|
-
if (!animation || playback.status === "stopped") return
|
|
11
|
-
if (playback.status !== "playing") return
|
|
12
|
-
|
|
14
|
+
if (!animation || playback.status === "stopped") return SETTLED;
|
|
15
|
+
if (playback.status !== "playing") return {
|
|
16
|
+
time: Math.min(playback.position, animation.duration),
|
|
17
|
+
advancing: false
|
|
18
|
+
};
|
|
19
|
+
const position = playback.position + Math.max(0, now - playback.effectiveAt) * playback.timeScale;
|
|
13
20
|
const pause = animation.markers.find((marker) => marker.pause && marker.at > playback.position && marker.at <= position);
|
|
14
|
-
if (pause) return
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
21
|
+
if (pause) return {
|
|
22
|
+
time: pause.at,
|
|
23
|
+
advancing: false
|
|
24
|
+
};
|
|
25
|
+
if (animation.loop || animation.play === "always") return {
|
|
26
|
+
time: position % animation.duration,
|
|
27
|
+
advancing: true
|
|
28
|
+
};
|
|
29
|
+
if (position < animation.duration) return {
|
|
30
|
+
time: position,
|
|
31
|
+
advancing: true
|
|
32
|
+
};
|
|
33
|
+
return {
|
|
34
|
+
time: animation.end === "reset" ? null : animation.duration,
|
|
35
|
+
advancing: false
|
|
36
|
+
};
|
|
18
37
|
}
|
|
19
38
|
function createBoardPlayer(options = {}) {
|
|
20
39
|
let document = null;
|
|
@@ -89,11 +108,10 @@ function createBoardPlayer(options = {}) {
|
|
|
89
108
|
}
|
|
90
109
|
let playbackTime = null;
|
|
91
110
|
if (playback && playback.animationId !== exclude) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
111
|
+
const clock = playbackClockAt(playback, current, wallNow);
|
|
112
|
+
playbackTime = clock.time;
|
|
113
|
+
if (playbackTime !== null) times.set(playback.animationId, playbackTime);
|
|
114
|
+
if (clock.advancing) running = true;
|
|
97
115
|
}
|
|
98
116
|
if (entrance) {
|
|
99
117
|
times.set(ENTER_ANIMATION, now - entrance.startedAt);
|
|
@@ -111,7 +129,7 @@ function createBoardPlayer(options = {}) {
|
|
|
111
129
|
};
|
|
112
130
|
}
|
|
113
131
|
function nextLocalPlayback(current, command, document, now = Date.now()) {
|
|
114
|
-
const position = current ?
|
|
132
|
+
const position = current ? playbackClockAt(current, document, now).time ?? 0 : 0;
|
|
115
133
|
const base = {
|
|
116
134
|
effectiveAt: now,
|
|
117
135
|
commandId: command.commandId,
|
|
@@ -159,4 +177,4 @@ function nextLocalPlayback(current, command, document, now = Date.now()) {
|
|
|
159
177
|
}
|
|
160
178
|
}
|
|
161
179
|
//#endregion
|
|
162
|
-
export { createBoardPlayer, nextLocalPlayback,
|
|
180
|
+
export { createBoardPlayer, nextLocalPlayback, playbackClockAt };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { fitTextToWidth } from "./text-fit.js";
|
|
2
|
-
import { syncTextResolution
|
|
2
|
+
import { syncTextResolution } from "./text-resolution.js";
|
|
3
3
|
import { Container, Graphics, Text } from "pixi.js";
|
|
4
4
|
//#region src/board/render/card-tag.ts
|
|
5
5
|
const CARD_TAG_SIZE = 11;
|
|
@@ -177,13 +177,15 @@ function createCardTag() {
|
|
|
177
177
|
icon,
|
|
178
178
|
text: null,
|
|
179
179
|
sig: "",
|
|
180
|
-
resolution: 0,
|
|
181
180
|
width: 0
|
|
182
181
|
};
|
|
183
182
|
}
|
|
183
|
+
function tagScale(zoom) {
|
|
184
|
+
return Math.min(MAX_GROWTH, Math.max(1, 1 / Math.max(zoom, .01)));
|
|
185
|
+
}
|
|
184
186
|
function zoomCardTag(tag, zoom) {
|
|
185
187
|
if (!tag.text || !tag.sig) return;
|
|
186
|
-
const scale =
|
|
188
|
+
const scale = tagScale(zoom);
|
|
187
189
|
const span = 17 + tag.text.width;
|
|
188
190
|
tag.root.scale.set(scale);
|
|
189
191
|
tag.root.position.set(0, -18 * scale);
|
|
@@ -197,7 +199,6 @@ function syncCardTag(tag, input, context) {
|
|
|
197
199
|
return;
|
|
198
200
|
}
|
|
199
201
|
if (!tag.text) {
|
|
200
|
-
tag.resolution = textResolutionForZoom(context.zoom);
|
|
201
202
|
tag.text = new Text({
|
|
202
203
|
text: "",
|
|
203
204
|
style: {
|
|
@@ -205,30 +206,27 @@ function syncCardTag(tag, input, context) {
|
|
|
205
206
|
fontSize: 11,
|
|
206
207
|
fontWeight: "500"
|
|
207
208
|
},
|
|
208
|
-
resolution: tag.resolution,
|
|
209
209
|
roundPixels: true
|
|
210
210
|
});
|
|
211
211
|
tag.root.addChild(tag.text);
|
|
212
212
|
}
|
|
213
|
-
syncTextResolution(tag.text, tag, context.zoom);
|
|
214
213
|
const sig = [
|
|
215
214
|
input.glyph,
|
|
216
215
|
input.text,
|
|
217
216
|
input.width,
|
|
218
217
|
context.themeKey
|
|
219
218
|
].join("|");
|
|
220
|
-
if (sig
|
|
221
|
-
|
|
222
|
-
|
|
219
|
+
if (sig !== tag.sig) {
|
|
220
|
+
tag.sig = sig;
|
|
221
|
+
const color = context.palette.muted;
|
|
222
|
+
const pixel = context.style.icons === "pixel";
|
|
223
|
+
drawCardGlyph(tag.icon.clear(), input.glyph, color, pixel);
|
|
224
|
+
tag.text.style.fill = color;
|
|
225
|
+
tag.text.style.fontFamily = context.style.font;
|
|
226
|
+
fitTextToWidth(tag.text, input.text, Math.max(1, input.width - ICON - GAP));
|
|
227
|
+
tag.text.position.set(17, (ICON - tag.text.height) / 2);
|
|
223
228
|
}
|
|
224
|
-
tag.
|
|
225
|
-
const color = context.palette.muted;
|
|
226
|
-
const pixel = context.style.icons === "pixel";
|
|
227
|
-
drawCardGlyph(tag.icon.clear(), input.glyph, color, pixel);
|
|
228
|
-
tag.text.style.fill = color;
|
|
229
|
-
tag.text.style.fontFamily = context.style.font;
|
|
230
|
-
fitTextToWidth(tag.text, input.text, Math.max(1, input.width - ICON - GAP));
|
|
231
|
-
tag.text.position.set(17, (ICON - tag.text.height) / 2);
|
|
229
|
+
syncTextResolution(tag.text, context.textResolution * tagScale(context.zoom));
|
|
232
230
|
zoomCardTag(tag, context.zoom);
|
|
233
231
|
}
|
|
234
232
|
//#endregion
|
|
@@ -11,10 +11,10 @@ import { defaultBoardPalette, itemAlpha, itemColor } from "./palette.js";
|
|
|
11
11
|
import { BoardScriptHostOptions, BrowserBoardScriptHost, createBoardScriptHost } from "./script-host.js";
|
|
12
12
|
import { prepareBrowserBoardScripts } from "./script-export.js";
|
|
13
13
|
import { dashPattern, endAngle, roundRectPoints, traceArrowhead, tracePolyline, trimPolyline } from "./stroke.js";
|
|
14
|
-
import { CardElevation, CardRect, CardSurface, PIXEL_STEP, cardElevation, cardOutlinePoints, cardShadow, containRect, drawCardShadow, drawCardSurface, isBoardCard, traceCardOutline, tracePixelRect } from "./surface.js";
|
|
14
|
+
import { CardCrop, CardElevation, CardRect, CardSurface, PIXEL_STEP, cardElevation, cardOutlinePoints, cardShadow, containRect, drawCardShadow, drawCardSurface, fillCardPicture, isBoardCard, traceCardOutline, tracePixelRect } from "./surface.js";
|
|
15
15
|
import { BOARD_EFFECT_MAX_PARTICLES } from "./renderers/effect-card-renderer.js";
|
|
16
16
|
import { ellipsizeWrappedLines, fitLineWithEllipsis, fitTextToLines, fitTextToWidth } from "./text-fit.js";
|
|
17
17
|
import { BOARD_FONT_STACKS, ensureBoardTextMeasurement, installBoardTextMeasurement } from "./text-measurement.js";
|
|
18
|
-
import { boardCardDetailed, getBoardResolution, syncTextResolution, syncTextWrapWidth,
|
|
18
|
+
import { boardCardDetailed, boardTextResolution, getBoardResolution, syncTextResolution, syncTextWrapWidth, textZoomBucket } from "./text-resolution.js";
|
|
19
19
|
import { VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, loadVideoThumbnailTexture, videoTextureNaturalSize, videoThumbnailSize } from "./video-thumbnail.js";
|
|
20
|
-
export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, BoardBackgroundContext, BoardCardRenderer, BoardCardRendererResolver, BoardCssPaint, BoardMediaAction, BoardRenderContext, BoardRenderDiagnostic, BoardRenderLabels, BoardRenderPalette, BoardRenderStyle, BoardScriptHost, BoardScriptHostOptions, BoardSelectionStyle, BoardShadowStyle, BrowserBoardScriptHost, CARD_TAG_SIZE, CardElevation, CardGlyph, CardRect, CardSurface, CardTag, ClipGroup, DEFAULT_BOARD_RENDER_LABELS, PIXEL_STEP, VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, boardCardDetailed, boardMediaActionAt, cardElevation, cardOutlinePoints, cardShadow, clippingAncestor, containRect, createBoardBackground, createBoardCardRendererResolver, createBoardRenderSampler, createBoardScriptHost, createCardTag, dashPattern, defaultBoardPalette, defaultBoardRenderStyle, drawCardGlyph, drawCardShadow, drawCardSurface, ellipsizeWrappedLines, endAngle, ensureBoardTextMeasurement, fitLineWithEllipsis, fitTextToLines, fitTextToWidth, formatBoardDuration, getBoardCardRenderer, getBoardResolution, inspectBoardItems, inspectBoardScene, installBoardTextMeasurement, isBoardCard, isClippingFrame, itemAlpha, itemColor, loadVideoThumbnailTexture, measureBoardText, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayKeyCenter, parseBoardCssColor, parseBoardCssPaint, prepareBrowserBoardScripts, resolveBoardRenderStyle, roundRectPoints, syncCardTag, syncClipGroup, syncTextResolution, syncTextWrapWidth,
|
|
20
|
+
export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, BoardBackgroundContext, BoardCardRenderer, BoardCardRendererResolver, BoardCssPaint, BoardMediaAction, BoardRenderContext, BoardRenderDiagnostic, BoardRenderLabels, BoardRenderPalette, BoardRenderStyle, BoardScriptHost, BoardScriptHostOptions, BoardSelectionStyle, BoardShadowStyle, BrowserBoardScriptHost, CARD_TAG_SIZE, CardCrop, CardElevation, CardGlyph, CardRect, CardSurface, CardTag, ClipGroup, DEFAULT_BOARD_RENDER_LABELS, PIXEL_STEP, VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, boardCardDetailed, boardMediaActionAt, boardTextResolution, cardElevation, cardOutlinePoints, cardShadow, clippingAncestor, containRect, createBoardBackground, createBoardCardRendererResolver, createBoardRenderSampler, createBoardScriptHost, createCardTag, dashPattern, defaultBoardPalette, defaultBoardRenderStyle, drawCardGlyph, drawCardShadow, drawCardSurface, ellipsizeWrappedLines, endAngle, ensureBoardTextMeasurement, fillCardPicture, fitLineWithEllipsis, fitTextToLines, fitTextToWidth, formatBoardDuration, getBoardCardRenderer, getBoardResolution, inspectBoardItems, inspectBoardScene, installBoardTextMeasurement, isBoardCard, isClippingFrame, itemAlpha, itemColor, loadVideoThumbnailTexture, measureBoardText, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayKeyCenter, parseBoardCssColor, parseBoardCssPaint, prepareBrowserBoardScripts, resolveBoardRenderStyle, roundRectPoints, syncCardTag, syncClipGroup, syncTextResolution, syncTextWrapWidth, textZoomBucket, traceArrowhead, traceCardOutline, traceCube, traceFrameOutline, tracePixelRect, tracePolyline, trimPolyline, updateBoardBackground, videoTextureNaturalSize, videoThumbnailSize, zoomCardTag };
|
|
@@ -5,11 +5,11 @@ import { BOARD_FONT_STACKS, ensureBoardTextMeasurement, installBoardTextMeasurem
|
|
|
5
5
|
import { inspectBoardItems, inspectBoardScene, measureBoardText } from "./diagnostics.js";
|
|
6
6
|
import { createBoardBackground, updateBoardBackground } from "./board-background.js";
|
|
7
7
|
import { ellipsizeWrappedLines, fitLineWithEllipsis, fitTextToLines, fitTextToWidth } from "./text-fit.js";
|
|
8
|
-
import { boardCardDetailed, getBoardResolution, syncTextResolution, syncTextWrapWidth,
|
|
8
|
+
import { boardCardDetailed, boardTextResolution, getBoardResolution, syncTextResolution, syncTextWrapWidth, textZoomBucket } from "./text-resolution.js";
|
|
9
9
|
import { CARD_TAG_SIZE, createCardTag, drawCardGlyph, formatBoardDuration, syncCardTag, traceCube, zoomCardTag } from "./card-tag.js";
|
|
10
10
|
import { clippingAncestor, isClippingFrame, syncClipGroup, traceFrameOutline } from "./clip.js";
|
|
11
11
|
import { dashPattern, endAngle, roundRectPoints, traceArrowhead, tracePolyline, trimPolyline } from "./stroke.js";
|
|
12
|
-
import { PIXEL_STEP, cardElevation, cardOutlinePoints, cardShadow, containRect, drawCardShadow, drawCardSurface, isBoardCard, traceCardOutline, tracePixelRect } from "./surface.js";
|
|
12
|
+
import { PIXEL_STEP, cardElevation, cardOutlinePoints, cardShadow, containRect, drawCardShadow, drawCardSurface, fillCardPicture, isBoardCard, traceCardOutline, tracePixelRect } from "./surface.js";
|
|
13
13
|
import { boardMediaActionAt, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayKeyCenter } from "./media-interaction.js";
|
|
14
14
|
import { BOARD_EFFECT_MAX_PARTICLES } from "./renderers/effect-card-renderer.js";
|
|
15
15
|
import { DEFAULT_BOARD_RENDER_LABELS, createBoardCardRendererResolver, getBoardCardRenderer } from "./renderers/board-renderer-registry.js";
|
|
@@ -17,4 +17,4 @@ import { createBoardScriptHost } from "./script-host.js";
|
|
|
17
17
|
import { prepareBrowserBoardScripts } from "./script-export.js";
|
|
18
18
|
import { defaultBoardRenderStyle, resolveBoardRenderStyle } from "./style.js";
|
|
19
19
|
import { VIDEO_THUMBNAIL_MAX_EDGE, loadVideoThumbnailTexture, videoTextureNaturalSize, videoThumbnailSize } from "./video-thumbnail.js";
|
|
20
|
-
export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, CARD_TAG_SIZE, DEFAULT_BOARD_RENDER_LABELS, PIXEL_STEP, VIDEO_THUMBNAIL_MAX_EDGE, boardCardDetailed, boardMediaActionAt, cardElevation, cardOutlinePoints, cardShadow, clippingAncestor, containRect, createBoardBackground, createBoardCardRendererResolver, createBoardRenderSampler, createBoardScriptHost, createCardTag, dashPattern, defaultBoardPalette, defaultBoardRenderStyle, drawCardGlyph, drawCardShadow, drawCardSurface, ellipsizeWrappedLines, endAngle, ensureBoardTextMeasurement, fitLineWithEllipsis, fitTextToLines, fitTextToWidth, formatBoardDuration, getBoardCardRenderer, getBoardResolution, inspectBoardItems, inspectBoardScene, installBoardTextMeasurement, isBoardCard, isClippingFrame, itemAlpha, itemColor, loadVideoThumbnailTexture, measureBoardText, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayKeyCenter, parseBoardCssColor, parseBoardCssPaint, prepareBrowserBoardScripts, resolveBoardRenderStyle, roundRectPoints, syncCardTag, syncClipGroup, syncTextResolution, syncTextWrapWidth,
|
|
20
|
+
export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, CARD_TAG_SIZE, DEFAULT_BOARD_RENDER_LABELS, PIXEL_STEP, VIDEO_THUMBNAIL_MAX_EDGE, boardCardDetailed, boardMediaActionAt, boardTextResolution, cardElevation, cardOutlinePoints, cardShadow, clippingAncestor, containRect, createBoardBackground, createBoardCardRendererResolver, createBoardRenderSampler, createBoardScriptHost, createCardTag, dashPattern, defaultBoardPalette, defaultBoardRenderStyle, drawCardGlyph, drawCardShadow, drawCardSurface, ellipsizeWrappedLines, endAngle, ensureBoardTextMeasurement, fillCardPicture, fitLineWithEllipsis, fitTextToLines, fitTextToWidth, formatBoardDuration, getBoardCardRenderer, getBoardResolution, inspectBoardItems, inspectBoardScene, installBoardTextMeasurement, isBoardCard, isClippingFrame, itemAlpha, itemColor, loadVideoThumbnailTexture, measureBoardText, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayKeyCenter, parseBoardCssColor, parseBoardCssPaint, prepareBrowserBoardScripts, resolveBoardRenderStyle, roundRectPoints, syncCardTag, syncClipGroup, syncTextResolution, syncTextWrapWidth, textZoomBucket, traceArrowhead, traceCardOutline, traceCube, traceFrameOutline, tracePixelRect, tracePolyline, trimPolyline, updateBoardBackground, videoTextureNaturalSize, videoThumbnailSize, zoomCardTag };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
|
|
2
2
|
import { pathPointAt, resolveSceneArrow } from "../../model/arrow-geometry.js";
|
|
3
3
|
import { itemAlpha, itemColor } from "../palette.js";
|
|
4
|
-
import { syncTextResolution
|
|
4
|
+
import { syncTextResolution } from "../text-resolution.js";
|
|
5
5
|
import { dashPattern, endAngle, traceArrowhead, tracePolyline, trimPolyline } from "../stroke.js";
|
|
6
6
|
import { drawCardSurface } from "../surface.js";
|
|
7
7
|
import { drawFarStroke } from "./far-plate.js";
|
|
@@ -18,7 +18,6 @@ function sync(container, item, context) {
|
|
|
18
18
|
parts.line.alpha = itemAlpha(context, style.stroke);
|
|
19
19
|
const color = itemColor(context, style.stroke, "brand");
|
|
20
20
|
const size = style.strokeWidth ?? 2.5;
|
|
21
|
-
syncTextResolution(parts.label, parts, context.zoom);
|
|
22
21
|
const resolved = resolveSceneArrow(item, context.scene);
|
|
23
22
|
const path = trimPolyline(resolved.path, style.trim);
|
|
24
23
|
const lineSig = [
|
|
@@ -85,6 +84,7 @@ function sync(container, item, context) {
|
|
|
85
84
|
border: context.palette.border
|
|
86
85
|
});
|
|
87
86
|
}
|
|
87
|
+
syncTextResolution(parts.label, context.textResolution);
|
|
88
88
|
const visible = props.label.length > 0 && (style.trim === void 0 || style.trim >= .5);
|
|
89
89
|
parts.label.visible = visible;
|
|
90
90
|
parts.backdrop.visible = visible;
|
|
@@ -98,7 +98,6 @@ const arrowCardRenderer = {
|
|
|
98
98
|
create: (item, context) => {
|
|
99
99
|
const root = new Container();
|
|
100
100
|
const line = new Graphics();
|
|
101
|
-
const resolution = textResolutionForZoom(context.zoom);
|
|
102
101
|
const label = new Text({
|
|
103
102
|
text: "",
|
|
104
103
|
style: {
|
|
@@ -107,7 +106,7 @@ const arrowCardRenderer = {
|
|
|
107
106
|
fontSize: 14,
|
|
108
107
|
fontWeight: "500"
|
|
109
108
|
},
|
|
110
|
-
resolution,
|
|
109
|
+
resolution: context.textResolution,
|
|
111
110
|
roundPixels: true
|
|
112
111
|
});
|
|
113
112
|
label.anchor.set(.5);
|
|
@@ -119,8 +118,7 @@ const arrowCardRenderer = {
|
|
|
119
118
|
backdrop,
|
|
120
119
|
label,
|
|
121
120
|
lineSig: "",
|
|
122
|
-
labelSig: ""
|
|
123
|
-
resolution
|
|
121
|
+
labelSig: ""
|
|
124
122
|
});
|
|
125
123
|
if (item.type === "arrow") sync(root, item, context);
|
|
126
124
|
return root;
|
|
@@ -128,6 +126,10 @@ const arrowCardRenderer = {
|
|
|
128
126
|
update: (container, item, context) => {
|
|
129
127
|
if (item.type === "arrow") sync(container, item, context);
|
|
130
128
|
},
|
|
129
|
+
resolution: (container, _item, context) => {
|
|
130
|
+
const parts = partsByContainer.get(container);
|
|
131
|
+
if (parts) syncTextResolution(parts.label, context.textResolution);
|
|
132
|
+
},
|
|
131
133
|
renderFar: (graphics, item, context) => {
|
|
132
134
|
if (item.type !== "arrow") return;
|
|
133
135
|
const arrow = item;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getMediaResourceTitle } from "../../model/media.js";
|
|
2
2
|
import { fitTextToWidth } from "../text-fit.js";
|
|
3
|
-
import { boardCardDetailed, syncTextResolution
|
|
3
|
+
import { boardCardDetailed, syncTextResolution } from "../text-resolution.js";
|
|
4
4
|
import { formatBoardDuration } from "../card-tag.js";
|
|
5
5
|
import { drawAudioWaveform } from "../audio-waveform.js";
|
|
6
6
|
import { cardElevation, drawCardSurface } from "../surface.js";
|
|
@@ -25,12 +25,15 @@ function audioKeyCenter(width, height) {
|
|
|
25
25
|
function sync(container, item, context) {
|
|
26
26
|
const parts = partsByContainer.get(container);
|
|
27
27
|
if (!parts) return;
|
|
28
|
+
syncContent(parts, item, context);
|
|
29
|
+
syncTextResolution(parts.title, context.textResolution);
|
|
30
|
+
}
|
|
31
|
+
function syncContent(parts, item, context) {
|
|
28
32
|
positionShell(parts.root, item);
|
|
29
33
|
const { width, height } = item.frame;
|
|
30
34
|
const title = item.props.snapshot?.title ?? getMediaResourceTitle(item.props.src);
|
|
31
35
|
const durationMs = item.props.snapshot?.durationMs;
|
|
32
36
|
const detailed = boardCardDetailed(context.zoom);
|
|
33
|
-
syncTextResolution(parts.title, parts, context.zoom);
|
|
34
37
|
const elevation = cardElevation(context, item.id);
|
|
35
38
|
const sig = [
|
|
36
39
|
width,
|
|
@@ -83,14 +86,13 @@ const audioCardRenderer = {
|
|
|
83
86
|
const root = new Container();
|
|
84
87
|
const plate = new Graphics();
|
|
85
88
|
const wave = new Graphics();
|
|
86
|
-
const resolution = textResolutionForZoom(context.zoom);
|
|
87
89
|
const title = new Text({
|
|
88
90
|
text: "",
|
|
89
91
|
style: {
|
|
90
92
|
fontSize: 13,
|
|
91
93
|
fontWeight: "600"
|
|
92
94
|
},
|
|
93
|
-
resolution,
|
|
95
|
+
resolution: context.textResolution,
|
|
94
96
|
roundPixels: true
|
|
95
97
|
});
|
|
96
98
|
root.addChild(plate, wave, title);
|
|
@@ -99,8 +101,7 @@ const audioCardRenderer = {
|
|
|
99
101
|
plate,
|
|
100
102
|
wave,
|
|
101
103
|
title,
|
|
102
|
-
sig: ""
|
|
103
|
-
resolution
|
|
104
|
+
sig: ""
|
|
104
105
|
});
|
|
105
106
|
if (item.type === "audio") sync(root, item, context);
|
|
106
107
|
return root;
|
|
@@ -108,6 +109,9 @@ const audioCardRenderer = {
|
|
|
108
109
|
update: (container, item, context) => {
|
|
109
110
|
if (item.type === "audio") sync(container, item, context);
|
|
110
111
|
},
|
|
112
|
+
resolution: (container, item, context) => {
|
|
113
|
+
if (item.type === "audio") sync(container, item, context);
|
|
114
|
+
},
|
|
111
115
|
renderFar: (graphics, item, context) => {
|
|
112
116
|
drawFarPlate(graphics, item.frame, {
|
|
113
117
|
fill: context.palette.surface,
|
|
@@ -2,7 +2,7 @@ import { BoardFrame } from "../../../protocol/dist/board-layout.js";
|
|
|
2
2
|
import "../../../protocol/dist/index.js";
|
|
3
3
|
import { Container, Text } from "pixi.js";
|
|
4
4
|
//#region src/board/render/renderers/base-card-renderer.d.ts
|
|
5
|
-
declare function createLabel(text: string, style: Record<string, unknown
|
|
5
|
+
declare function createLabel(text: string, style: Record<string, unknown>, resolution: number): Text;
|
|
6
6
|
declare function positionShell(root: Container, item: {
|
|
7
7
|
frame: BoardFrame;
|
|
8
8
|
}): void;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
|
|
2
|
-
import { getBoardResolution } from "../text-resolution.js";
|
|
3
2
|
import { Text } from "pixi.js";
|
|
4
3
|
//#region src/board/render/renderers/base-card-renderer.ts
|
|
5
|
-
function createLabel(text, style) {
|
|
4
|
+
function createLabel(text, style, resolution) {
|
|
6
5
|
return new Text({
|
|
7
|
-
resolution
|
|
6
|
+
resolution,
|
|
8
7
|
roundPixels: true,
|
|
9
8
|
text,
|
|
10
9
|
style: {
|
|
@@ -22,7 +22,7 @@ type BoardScriptHost = {
|
|
|
22
22
|
document?: (document: BoardDocument, time: number) => BoardDocument;
|
|
23
23
|
ready?: (id: string) => boolean;
|
|
24
24
|
revision?: (id: string) => number;
|
|
25
|
-
frame: (item: SceneItem<BoardCustomItem>, time: number
|
|
25
|
+
frame: (item: SceneItem<BoardCustomItem>, time: number) => Texture | null;
|
|
26
26
|
error: (id: string) => string | null;
|
|
27
27
|
release: (id: string) => void;
|
|
28
28
|
};
|
|
@@ -48,6 +48,8 @@ type BoardRenderContext = {
|
|
|
48
48
|
themeKey: string;
|
|
49
49
|
rendererType: "gpu" | "canvas";
|
|
50
50
|
zoom: number;
|
|
51
|
+
/** Texture pixels per world unit for text; see `boardTextResolution`. */
|
|
52
|
+
textResolution: number;
|
|
51
53
|
time: number;
|
|
52
54
|
reducedMotion: boolean;
|
|
53
55
|
labels: BoardRenderLabels;
|
|
@@ -61,7 +63,7 @@ type BoardRenderContext = {
|
|
|
61
63
|
getTexture: (key: string) => Texture | null;
|
|
62
64
|
hasError: (key: string) => boolean;
|
|
63
65
|
fileState: (path: string) => "ok" | "missing" | "unavailable";
|
|
64
|
-
acquireTexture: (key: string) => void;
|
|
66
|
+
acquireTexture: (key: string, item: BoardSceneItem) => void;
|
|
65
67
|
releaseTexture: (key: string) => void;
|
|
66
68
|
};
|
|
67
69
|
type BoardCardRenderer = {
|
|
@@ -73,6 +75,8 @@ type BoardCardRenderer = {
|
|
|
73
75
|
tick?: (container: Container, clock: number) => number | null;
|
|
74
76
|
create: (item: BoardSceneItem, context: BoardRenderContext) => Container;
|
|
75
77
|
update: (container: Container, item: BoardSceneItem, context: BoardRenderContext) => void;
|
|
78
|
+
/** Called when the zoom bucket or text resolution changes. */
|
|
79
|
+
resolution?: (container: Container, item: BoardSceneItem, context: BoardRenderContext) => void;
|
|
76
80
|
/** Runs on every zoom step; only update transforms and visibility. */
|
|
77
81
|
zoom?: (container: Container, zoom: number) => void;
|
|
78
82
|
renderFar?: (graphics: Graphics, item: BoardSceneItem, context: BoardRenderContext) => void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BOARD_MONO_FONT_STACK } from "../../../protocol/dist/board-constants.js";
|
|
2
|
-
import {
|
|
2
|
+
import { syncTextResolution } from "../text-resolution.js";
|
|
3
3
|
import { positionShell } from "./base-card-renderer.js";
|
|
4
4
|
import { drawFarPlate } from "./far-plate.js";
|
|
5
5
|
import { Container, Graphics, Sprite, Text, Texture } from "pixi.js";
|
|
@@ -13,10 +13,8 @@ function sync(container, item, context) {
|
|
|
13
13
|
parts.id = item.id;
|
|
14
14
|
}
|
|
15
15
|
positionShell(parts.root, item);
|
|
16
|
-
syncTextResolution(parts.label, parts.label, context.zoom);
|
|
17
16
|
const { width, height } = item.frame;
|
|
18
|
-
const
|
|
19
|
-
const texture = context.scripts?.frame(item, context.time, resolution) ?? null;
|
|
17
|
+
const texture = context.scripts?.frame(item, context.time) ?? null;
|
|
20
18
|
const error = context.scripts?.error(item.id) ?? null;
|
|
21
19
|
parts.sprite.visible = Boolean(texture);
|
|
22
20
|
const display = texture ?? Texture.EMPTY;
|
|
@@ -32,19 +30,21 @@ function sync(container, item, context) {
|
|
|
32
30
|
message,
|
|
33
31
|
context.themeKey
|
|
34
32
|
].join("|");
|
|
35
|
-
if (sig
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
33
|
+
if (sig !== parts.sig) {
|
|
34
|
+
parts.sig = sig;
|
|
35
|
+
parts.placeholder.clear();
|
|
36
|
+
if (!ready || error) parts.placeholder.rect(0, 0, width, height).stroke({
|
|
37
|
+
color: context.palette.border,
|
|
38
|
+
width: 1,
|
|
39
|
+
alpha: .8
|
|
40
|
+
});
|
|
41
|
+
parts.label.visible = !ready || Boolean(error);
|
|
42
|
+
parts.label.text = message;
|
|
43
|
+
parts.label.style.fill = error ? context.colors.rose.stroke : context.palette.muted;
|
|
44
|
+
parts.label.style.wordWrapWidth = Math.max(40, width - 16);
|
|
45
|
+
parts.label.position.set(width / 2, height / 2);
|
|
46
|
+
}
|
|
47
|
+
syncTextResolution(parts.label, context.textResolution);
|
|
48
48
|
}
|
|
49
49
|
const customCardRenderer = {
|
|
50
50
|
id: "custom-card",
|
|
@@ -63,7 +63,8 @@ const customCardRenderer = {
|
|
|
63
63
|
wordWrap: true,
|
|
64
64
|
breakWords: true
|
|
65
65
|
},
|
|
66
|
-
resolution:
|
|
66
|
+
resolution: context.textResolution,
|
|
67
|
+
roundPixels: true
|
|
67
68
|
});
|
|
68
69
|
label.anchor.set(.5);
|
|
69
70
|
root.addChild(sprite, placeholder, label);
|
|
@@ -81,6 +82,10 @@ const customCardRenderer = {
|
|
|
81
82
|
update: (container, item, context) => {
|
|
82
83
|
if (item.type === "custom") sync(container, item, context);
|
|
83
84
|
},
|
|
85
|
+
resolution: (container, _item, context) => {
|
|
86
|
+
const parts = partsByContainer.get(container);
|
|
87
|
+
if (parts) syncTextResolution(parts.label, context.textResolution);
|
|
88
|
+
},
|
|
84
89
|
renderFar: (graphics, item, context) => {
|
|
85
90
|
drawFarPlate(graphics, item.frame, {
|
|
86
91
|
fill: context.palette.muted,
|
|
@@ -47,6 +47,14 @@ function syncClip(parts, rect, style) {
|
|
|
47
47
|
function sync(container, item, context) {
|
|
48
48
|
const parts = partsByContainer.get(container);
|
|
49
49
|
if (!parts) return;
|
|
50
|
+
syncContent(parts, item, context);
|
|
51
|
+
for (const text of [
|
|
52
|
+
parts.title,
|
|
53
|
+
parts.excerpt,
|
|
54
|
+
parts.typeMark
|
|
55
|
+
]) syncTextResolution(text, context.textResolution);
|
|
56
|
+
}
|
|
57
|
+
function syncContent(parts, item, context) {
|
|
50
58
|
positionShell(parts.root, item);
|
|
51
59
|
const { width, height } = item.frame;
|
|
52
60
|
const detail = detailFor(context.zoom);
|
|
@@ -64,16 +72,13 @@ function sync(container, item, context) {
|
|
|
64
72
|
const kind = filePreviewKind(item.props.snapshot);
|
|
65
73
|
const category = fileCategory(item.props.src, item.props.snapshot?.mimeType);
|
|
66
74
|
const accent = fileCategoryAccent(category, context.palette);
|
|
67
|
-
syncTextResolution(parts.title, parts.titleRes, context.zoom);
|
|
68
|
-
syncTextResolution(parts.excerpt, parts.excerptRes, context.zoom);
|
|
69
|
-
syncTextResolution(parts.typeMark, parts.typeMarkRes, context.zoom);
|
|
70
75
|
const visualSig = [
|
|
71
76
|
key ?? "",
|
|
72
77
|
width,
|
|
73
78
|
height,
|
|
74
79
|
detail,
|
|
75
80
|
elevation,
|
|
76
|
-
texture
|
|
81
|
+
texture?.uid ?? "none",
|
|
77
82
|
coverFailed,
|
|
78
83
|
fileState,
|
|
79
84
|
kind,
|
|
@@ -190,7 +195,7 @@ const fileCardRenderer = {
|
|
|
190
195
|
const cover = new Sprite(Texture.EMPTY);
|
|
191
196
|
const coverMask = new Graphics();
|
|
192
197
|
cover.mask = coverMask;
|
|
193
|
-
const resolution =
|
|
198
|
+
const resolution = context.textResolution;
|
|
194
199
|
const title = new Text({
|
|
195
200
|
text: "",
|
|
196
201
|
style: {
|
|
@@ -247,10 +252,7 @@ const fileCardRenderer = {
|
|
|
247
252
|
title,
|
|
248
253
|
excerpt,
|
|
249
254
|
visualSig: "",
|
|
250
|
-
textSig: ""
|
|
251
|
-
titleRes: { resolution },
|
|
252
|
-
excerptRes: { resolution },
|
|
253
|
-
typeMarkRes: { resolution }
|
|
255
|
+
textSig: ""
|
|
254
256
|
});
|
|
255
257
|
if (item.type === "file") sync(root, item, context);
|
|
256
258
|
return root;
|
|
@@ -258,6 +260,9 @@ const fileCardRenderer = {
|
|
|
258
260
|
update: (container, item, context) => {
|
|
259
261
|
if (item.type === "file") sync(container, item, context);
|
|
260
262
|
},
|
|
263
|
+
resolution: (container, item, context) => {
|
|
264
|
+
if (item.type === "file") sync(container, item, context);
|
|
265
|
+
},
|
|
261
266
|
zoom: (container, zoom) => {
|
|
262
267
|
const tag = partsByContainer.get(container)?.tag;
|
|
263
268
|
if (tag) zoomCardTag(tag, zoom);
|