@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,8 +1,10 @@
|
|
|
1
1
|
import { WorldPoint } from "../model/geometry.js";
|
|
2
2
|
import { BoardSceneItem } from "../model/scene.js";
|
|
3
|
+
import { BoardCardHit, BoardRenderContext } from "./renderers/board-renderer-registry.js";
|
|
3
4
|
//#region src/board/render/media-interaction.d.ts
|
|
5
|
+
declare const BOARD_PLAY_MEDIA = "play-media";
|
|
4
6
|
type BoardMediaAction = {
|
|
5
|
-
action:
|
|
7
|
+
action: typeof BOARD_PLAY_MEDIA;
|
|
6
8
|
itemId: string;
|
|
7
9
|
};
|
|
8
10
|
declare function mediaPlayBadgeVisible(item: BoardSceneItem, zoom: number, options: {
|
|
@@ -15,5 +17,6 @@ declare function boardMediaActionAt(item: BoardSceneItem, point: WorldPoint, zoo
|
|
|
15
17
|
materialized: boolean;
|
|
16
18
|
hasVideoPreview: boolean;
|
|
17
19
|
}): BoardMediaAction | null;
|
|
20
|
+
declare function mediaPlayHit(item: BoardSceneItem, point: WorldPoint, context: BoardRenderContext): BoardCardHit | null;
|
|
18
21
|
//#endregion
|
|
19
|
-
export { BoardMediaAction, boardMediaActionAt, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayKeyCenter };
|
|
22
|
+
export { BOARD_PLAY_MEDIA, BoardMediaAction, boardMediaActionAt, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayHit, mediaPlayKeyCenter };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { featuredTaskArtifact } from "../../protocol/dist/board-task.js";
|
|
2
2
|
import { degToRad, rotatePointAround, worldPoint } from "../model/geometry.js";
|
|
3
|
+
import { boardCardDetailed } from "./lod.js";
|
|
3
4
|
import { isBoardModelItem } from "../model/media.js";
|
|
4
|
-
import { boardCardDetailed } from "./text-resolution.js";
|
|
5
5
|
import { audioKeyCenter } from "./renderers/audio-card-renderer.js";
|
|
6
6
|
import { modelKeyCenter } from "./renderers/model-card-renderer.js";
|
|
7
7
|
//#region src/board/render/media-interaction.ts
|
|
8
|
+
const BOARD_PLAY_MEDIA = "play-media";
|
|
8
9
|
function mediaPlayBadgeVisible(item, zoom, options) {
|
|
9
10
|
if (!options.materialized) return false;
|
|
10
11
|
if (item.type === "video" || item.type === "audio") return true;
|
|
@@ -34,9 +35,20 @@ function mediaPlayBadgeHit(item, point, zoom) {
|
|
|
34
35
|
}
|
|
35
36
|
function boardMediaActionAt(item, point, zoom, options) {
|
|
36
37
|
return mediaPlayBadgeVisible(item, zoom, options) && mediaPlayBadgeHit(item, point, zoom) ? {
|
|
37
|
-
action:
|
|
38
|
+
action: BOARD_PLAY_MEDIA,
|
|
38
39
|
itemId: item.id
|
|
39
40
|
} : null;
|
|
40
41
|
}
|
|
42
|
+
const PLAY_HIT = {
|
|
43
|
+
action: BOARD_PLAY_MEDIA,
|
|
44
|
+
cursor: "pointer"
|
|
45
|
+
};
|
|
46
|
+
function mediaPlayHit(item, point, context) {
|
|
47
|
+
const key = context.assetKey(item);
|
|
48
|
+
return boardMediaActionAt(item, point, context.zoom, {
|
|
49
|
+
materialized: true,
|
|
50
|
+
hasVideoPreview: Boolean(key && context.getTexture(key))
|
|
51
|
+
}) ? PLAY_HIT : null;
|
|
52
|
+
}
|
|
41
53
|
//#endregion
|
|
42
|
-
export { boardMediaActionAt, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayKeyCenter };
|
|
54
|
+
export { BOARD_PLAY_MEDIA, boardMediaActionAt, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayHit, mediaPlayKeyCenter };
|
|
@@ -1,32 +1,9 @@
|
|
|
1
|
+
import { BOARD_THEME_DATA } from "../model/themes.js";
|
|
1
2
|
import { resolveItemColor } from "../model/palette.js";
|
|
2
3
|
import { parseBoardCssColor, parseBoardCssPaint } from "./css-color.js";
|
|
3
4
|
//#region src/board/render/palette.ts
|
|
4
|
-
const DARK = {
|
|
5
|
-
bg: 1315860,
|
|
6
|
-
surface: 2105376,
|
|
7
|
-
hover: 2763306,
|
|
8
|
-
border: 3815994,
|
|
9
|
-
brand: 16734751,
|
|
10
|
-
text: 16053492,
|
|
11
|
-
muted: 9211020,
|
|
12
|
-
rare: 3718648,
|
|
13
|
-
epic: 10980346,
|
|
14
|
-
legendary: 16096779
|
|
15
|
-
};
|
|
16
|
-
const LIGHT = {
|
|
17
|
-
bg: 16251129,
|
|
18
|
-
surface: 16777215,
|
|
19
|
-
hover: 15329772,
|
|
20
|
-
border: 14079706,
|
|
21
|
-
brand: 15222030,
|
|
22
|
-
text: 1579035,
|
|
23
|
-
muted: 7041664,
|
|
24
|
-
rare: 2450411,
|
|
25
|
-
epic: 8141549,
|
|
26
|
-
legendary: 11817737
|
|
27
|
-
};
|
|
28
5
|
function defaultBoardPalette(mode) {
|
|
29
|
-
return { ...mode
|
|
6
|
+
return { ...BOARD_THEME_DATA[mode].palette };
|
|
30
7
|
}
|
|
31
8
|
function itemAlpha(context, color) {
|
|
32
9
|
const value = typeof color === "object" && color ? color[context.colorScheme] : color;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
|
|
2
|
-
import { pathPointAt, resolveSceneArrow } from "../../model/arrow-geometry.js";
|
|
3
2
|
import { itemAlpha, itemColor } from "../palette.js";
|
|
3
|
+
import { resolveSceneArrow } from "../../model/arrow-geometry.js";
|
|
4
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";
|
|
8
|
+
import { ARROW_LABEL, arrowLabelAnchor } from "../labels.js";
|
|
8
9
|
import { Container, Graphics, Text } from "pixi.js";
|
|
9
10
|
//#region src/board/render/renderers/arrow-card-renderer.ts
|
|
10
11
|
const partsByContainer = /* @__PURE__ */ new WeakMap();
|
|
@@ -67,8 +68,9 @@ function sync(container, item, context) {
|
|
|
67
68
|
parts.label.text = props.label;
|
|
68
69
|
parts.label.style.fill = context.palette.text;
|
|
69
70
|
parts.label.style.fontSize = props.fontSize;
|
|
70
|
-
|
|
71
|
-
const
|
|
71
|
+
parts.label.style.lineHeight = props.fontSize * ARROW_LABEL.lineHeight;
|
|
72
|
+
const padX = props.fontSize * ARROW_LABEL.padX;
|
|
73
|
+
const padY = props.fontSize * ARROW_LABEL.padY;
|
|
72
74
|
const { width, height } = parts.label;
|
|
73
75
|
const plate = {
|
|
74
76
|
x: -width / 2 - padX,
|
|
@@ -88,7 +90,7 @@ function sync(container, item, context) {
|
|
|
88
90
|
const visible = props.label.length > 0 && (style.trim === void 0 || style.trim >= .5);
|
|
89
91
|
parts.label.visible = visible;
|
|
90
92
|
parts.backdrop.visible = visible;
|
|
91
|
-
const mid =
|
|
93
|
+
const mid = arrowLabelAnchor(resolved, style);
|
|
92
94
|
parts.label.position.set(mid.x, mid.y);
|
|
93
95
|
parts.backdrop.position.set(mid.x, mid.y);
|
|
94
96
|
}
|
|
@@ -104,7 +106,7 @@ const arrowCardRenderer = {
|
|
|
104
106
|
fill: 16777215,
|
|
105
107
|
fontFamily: BOARD_FONT_STACK,
|
|
106
108
|
fontSize: 14,
|
|
107
|
-
fontWeight:
|
|
109
|
+
fontWeight: ARROW_LABEL.fontWeight
|
|
108
110
|
},
|
|
109
111
|
resolution: context.textResolution,
|
|
110
112
|
roundPixels: true
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { boardCardDetailed } from "../lod.js";
|
|
2
2
|
import { fitTextToWidth } from "../text-fit.js";
|
|
3
|
-
import {
|
|
3
|
+
import { syncTextResolution } from "../text-resolution.js";
|
|
4
4
|
import { formatBoardDuration } from "../card-tag.js";
|
|
5
|
+
import { getMediaResourceTitle } from "../../model/media.js";
|
|
5
6
|
import { drawAudioWaveform } from "../audio-waveform.js";
|
|
6
7
|
import { cardElevation, drawCardSurface } from "../surface.js";
|
|
7
8
|
import { positionShell } from "./base-card-renderer.js";
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { BoardCustomItem, BoardDocument, BoardSettings, BoardTaskItem } from "../../../protocol/dist/board-model.js";
|
|
2
2
|
import { BoardFrame } from "../../../protocol/dist/board-layout.js";
|
|
3
3
|
import "../../../protocol/dist/index.js";
|
|
4
|
+
import { WorldPoint } from "../../model/geometry.js";
|
|
4
5
|
import { BoardScene, BoardSceneItem, SceneItem } from "../../model/scene.js";
|
|
5
6
|
import { BoardShapeColors } from "../../model/palette.js";
|
|
6
7
|
import { BoardRenderStyle } from "../style.js";
|
|
8
|
+
import { BoardLodKind } from "../lod.js";
|
|
7
9
|
import { Container, Graphics, Texture } from "pixi.js";
|
|
8
10
|
//#region src/board/render/renderers/board-renderer-registry.d.ts
|
|
9
11
|
type BoardRenderPalette = {
|
|
@@ -41,6 +43,7 @@ type BoardRenderContext = {
|
|
|
41
43
|
hoveredId: string | null;
|
|
42
44
|
resizingIds: Set<string>;
|
|
43
45
|
liftedIds: ReadonlySet<string>;
|
|
46
|
+
editingId?: string | null;
|
|
44
47
|
palette: BoardRenderPalette;
|
|
45
48
|
colors: BoardShapeColors;
|
|
46
49
|
colorScheme: "dark" | "light";
|
|
@@ -62,9 +65,18 @@ type BoardRenderContext = {
|
|
|
62
65
|
assetKey: (item: BoardSceneItem) => string | null;
|
|
63
66
|
getTexture: (key: string) => Texture | null;
|
|
64
67
|
hasError: (key: string) => boolean;
|
|
68
|
+
assetTone?: (key: string) => number | null;
|
|
65
69
|
fileState: (path: string) => "ok" | "missing" | "unavailable";
|
|
66
70
|
acquireTexture: (key: string, item: BoardSceneItem) => void;
|
|
67
71
|
releaseTexture: (key: string) => void;
|
|
72
|
+
hoveredHit?: {
|
|
73
|
+
itemId: string;
|
|
74
|
+
action: string;
|
|
75
|
+
} | null;
|
|
76
|
+
};
|
|
77
|
+
type BoardCardHit = {
|
|
78
|
+
action: string;
|
|
79
|
+
cursor?: string;
|
|
68
80
|
};
|
|
69
81
|
type BoardCardRenderer = {
|
|
70
82
|
id: string;
|
|
@@ -79,6 +91,15 @@ type BoardCardRenderer = {
|
|
|
79
91
|
resolution?: (container: Container, item: BoardSceneItem, context: BoardRenderContext) => void;
|
|
80
92
|
/** Runs on every zoom step; only update transforms and visibility. */
|
|
81
93
|
zoom?: (container: Container, zoom: number) => void;
|
|
94
|
+
/**
|
|
95
|
+
* Level of detail for `renderFar`: `size` is the world-unit measure kept
|
|
96
|
+
* legible (default: the long edge), held against the `BoardLod[kind]` threshold.
|
|
97
|
+
*/
|
|
98
|
+
lod?: {
|
|
99
|
+
kind: BoardLodKind;
|
|
100
|
+
size?: (item: BoardSceneItem) => number;
|
|
101
|
+
};
|
|
102
|
+
hitAt?: (item: BoardSceneItem, point: WorldPoint, context: BoardRenderContext) => BoardCardHit | null;
|
|
82
103
|
renderFar?: (graphics: Graphics, item: BoardSceneItem, context: BoardRenderContext) => void;
|
|
83
104
|
destroy?: (container: Container, context: BoardRenderContext) => void;
|
|
84
105
|
};
|
|
@@ -91,4 +112,4 @@ declare function createBoardCardRendererResolver(renderers?: Iterable<BoardCardR
|
|
|
91
112
|
/** The built-in renderers alone. */
|
|
92
113
|
declare const getBoardCardRenderer: BoardCardRendererResolver;
|
|
93
114
|
//#endregion
|
|
94
|
-
export { BoardCardRenderer, BoardCardRendererResolver, BoardRenderContext, BoardRenderLabels, BoardRenderPalette, BoardScriptHost, DEFAULT_BOARD_RENDER_LABELS, createBoardCardRendererResolver, getBoardCardRenderer };
|
|
115
|
+
export { BoardCardHit, BoardCardRenderer, BoardCardRendererResolver, BoardRenderContext, BoardRenderLabels, BoardRenderPalette, BoardScriptHost, DEFAULT_BOARD_RENDER_LABELS, createBoardCardRendererResolver, getBoardCardRenderer };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ensureBoardTextMeasurement } from "../text-measurement.js";
|
|
2
2
|
import { audioCardRenderer } from "./audio-card-renderer.js";
|
|
3
3
|
import { modelCardRenderer } from "./model-card-renderer.js";
|
|
4
|
+
import { mediaPlayHit } from "../media-interaction.js";
|
|
4
5
|
import { arrowCardRenderer } from "./arrow-card-renderer.js";
|
|
5
6
|
import { drawCardRenderer } from "./draw-card-renderer.js";
|
|
6
7
|
import { effectCardRenderer } from "./effect-card-renderer.js";
|
|
@@ -21,14 +22,18 @@ const DEFAULT_BOARD_RENDER_LABELS = {
|
|
|
21
22
|
previewUnavailable: "Preview unavailable",
|
|
22
23
|
noPreview: "No preview"
|
|
23
24
|
};
|
|
25
|
+
const playable = (renderer) => ({
|
|
26
|
+
...renderer,
|
|
27
|
+
hitAt: mediaPlayHit
|
|
28
|
+
});
|
|
24
29
|
const builtinCardRenderers = [
|
|
25
30
|
textCardRenderer,
|
|
26
31
|
imageCardRenderer,
|
|
27
|
-
videoCardRenderer,
|
|
28
|
-
audioCardRenderer,
|
|
29
|
-
modelCardRenderer,
|
|
32
|
+
playable(videoCardRenderer),
|
|
33
|
+
playable(audioCardRenderer),
|
|
34
|
+
playable(modelCardRenderer),
|
|
30
35
|
fileCardRenderer,
|
|
31
|
-
taskCardRenderer,
|
|
36
|
+
playable(taskCardRenderer),
|
|
32
37
|
shapeCardRenderer,
|
|
33
38
|
drawCardRenderer,
|
|
34
39
|
arrowCardRenderer,
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { BOARD_MONO_FONT_STACK } from "../../../protocol/dist/board-constants.js";
|
|
2
|
+
import { fitTextToLines } from "../text-fit.js";
|
|
2
3
|
import { syncTextResolution } from "../text-resolution.js";
|
|
3
4
|
import { positionShell } from "./base-card-renderer.js";
|
|
4
5
|
import { drawFarPlate } from "./far-plate.js";
|
|
5
6
|
import { Container, Graphics, Sprite, Text, Texture } from "pixi.js";
|
|
6
7
|
//#region src/board/render/renderers/custom-card-renderer.ts
|
|
7
8
|
const partsByContainer = /* @__PURE__ */ new WeakMap();
|
|
9
|
+
const LABEL_LINE = 16;
|
|
8
10
|
function sync(container, item, context) {
|
|
9
11
|
const parts = partsByContainer.get(container);
|
|
10
12
|
if (!parts) return;
|
|
@@ -39,9 +41,8 @@ function sync(container, item, context) {
|
|
|
39
41
|
alpha: .8
|
|
40
42
|
});
|
|
41
43
|
parts.label.visible = !ready || Boolean(error);
|
|
42
|
-
parts.label.text = message;
|
|
43
44
|
parts.label.style.fill = error ? context.colors.rose.stroke : context.palette.muted;
|
|
44
|
-
parts.label.
|
|
45
|
+
fitTextToLines(parts.label, message, Math.max(1, Math.floor((height - 16) / LABEL_LINE)), Math.max(40, width - 16));
|
|
45
46
|
parts.label.position.set(width / 2, height / 2);
|
|
46
47
|
}
|
|
47
48
|
syncTextResolution(parts.label, context.textResolution);
|
|
@@ -59,9 +60,8 @@ const customCardRenderer = {
|
|
|
59
60
|
style: {
|
|
60
61
|
fontFamily: BOARD_MONO_FONT_STACK,
|
|
61
62
|
fontSize: 12,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
breakWords: true
|
|
63
|
+
lineHeight: LABEL_LINE,
|
|
64
|
+
align: "center"
|
|
65
65
|
},
|
|
66
66
|
resolution: context.textResolution,
|
|
67
67
|
roundPixels: true
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { applyMatrix } from "../../../protocol/dist/board-layout.js";
|
|
2
|
-
import { computeDrawBounds, createStrokeRibbonBuilder, trimDrawPoints } from "../../model/draw-geometry.js";
|
|
3
2
|
import { itemAlpha, itemColor } from "../palette.js";
|
|
4
3
|
import { positionShell } from "./base-card-renderer.js";
|
|
5
4
|
import { drawFarStroke, farStrokeSamples } from "./far-plate.js";
|
|
5
|
+
import { computeDrawBounds, createStrokeRibbonBuilder, trimDrawPoints } from "../../model/draw-geometry.js";
|
|
6
6
|
import { Container, Graphics, Mesh, MeshGeometry, Texture } from "pixi.js";
|
|
7
7
|
//#region src/board/render/renderers/draw-card-renderer.ts
|
|
8
8
|
const partsByContainer = /* @__PURE__ */ new WeakMap();
|
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
import { BoardFrame } from "../../../protocol/dist/board-layout.js";
|
|
2
2
|
import "../../../protocol/dist/index.js";
|
|
3
|
+
import { BoardSceneItem } from "../../model/scene.js";
|
|
4
|
+
import { BoardRenderContext } from "./board-renderer-registry.js";
|
|
3
5
|
import { Graphics } from "pixi.js";
|
|
4
6
|
//#region src/board/render/renderers/far-plate.d.ts
|
|
7
|
+
type LocalRect = {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
};
|
|
5
13
|
type FarPlateStyle = {
|
|
6
14
|
fill: number;
|
|
7
15
|
fillAlpha?: number;
|
|
8
16
|
accent?: number;
|
|
9
17
|
accentAlpha?: number;
|
|
10
18
|
};
|
|
19
|
+
declare function farPictureTone(item: BoardSceneItem, context: BoardRenderContext): number | undefined;
|
|
11
20
|
declare function drawFarPlate(graphics: Graphics, frame: BoardFrame, style: FarPlateStyle): void;
|
|
21
|
+
declare function drawFarBars(graphics: Graphics, frame: BoardFrame, bars: readonly LocalRect[], style: {
|
|
22
|
+
color: number;
|
|
23
|
+
alpha: number;
|
|
24
|
+
}): void;
|
|
12
25
|
declare function farStrokeSamples<T>(points: readonly T[]): readonly T[];
|
|
13
26
|
declare function drawFarStroke(graphics: Graphics, points: ReadonlyArray<{
|
|
14
27
|
x: number;
|
|
@@ -19,4 +32,4 @@ declare function drawFarStroke(graphics: Graphics, points: ReadonlyArray<{
|
|
|
19
32
|
alpha?: number;
|
|
20
33
|
}): void;
|
|
21
34
|
//#endregion
|
|
22
|
-
export { FarPlateStyle, drawFarPlate, drawFarStroke, farStrokeSamples };
|
|
35
|
+
export { FarPlateStyle, drawFarBars, drawFarPlate, drawFarStroke, farPictureTone, farStrokeSamples };
|
|
@@ -4,11 +4,11 @@ const FAR_STROKE_MAX_POINTS = 24;
|
|
|
4
4
|
const ACCENT_RATIO = .14;
|
|
5
5
|
const ACCENT_MIN = 2;
|
|
6
6
|
const ACCENT_MAX = 10;
|
|
7
|
-
function
|
|
8
|
-
const x = frame.x +
|
|
9
|
-
const y = frame.y +
|
|
10
|
-
const width = Math.max(0,
|
|
11
|
-
const height = Math.max(0,
|
|
7
|
+
function traceLocal(graphics, frame, rect) {
|
|
8
|
+
const x = frame.x + rect.x;
|
|
9
|
+
const y = frame.y + rect.y;
|
|
10
|
+
const width = Math.max(0, rect.width);
|
|
11
|
+
const height = Math.max(0, rect.height);
|
|
12
12
|
if (!frame.rotation) {
|
|
13
13
|
graphics.rect(x, y, width, height);
|
|
14
14
|
return;
|
|
@@ -32,20 +32,43 @@ function traceFrame(graphics, frame, inset = 0, heightOverride) {
|
|
|
32
32
|
const d = corner(x, y + height);
|
|
33
33
|
graphics.moveTo(a.x, a.y).lineTo(b.x, b.y).lineTo(c.x, c.y).lineTo(d.x, d.y).closePath();
|
|
34
34
|
}
|
|
35
|
+
function farPictureTone(item, context) {
|
|
36
|
+
const key = context.assetKey(item);
|
|
37
|
+
return (key ? context.assetTone?.(key) : null) ?? void 0;
|
|
38
|
+
}
|
|
35
39
|
function drawFarPlate(graphics, frame, style) {
|
|
36
40
|
if (frame.width <= 0 || frame.height <= 0) return;
|
|
37
|
-
|
|
41
|
+
traceLocal(graphics, frame, {
|
|
42
|
+
x: 0,
|
|
43
|
+
y: 0,
|
|
44
|
+
width: frame.width,
|
|
45
|
+
height: frame.height
|
|
46
|
+
});
|
|
38
47
|
graphics.fill({
|
|
39
48
|
color: style.fill,
|
|
40
49
|
alpha: style.fillAlpha ?? 1
|
|
41
50
|
});
|
|
42
51
|
if (style.accent === void 0) return;
|
|
43
|
-
|
|
52
|
+
const band = Math.min(ACCENT_MAX, Math.max(ACCENT_MIN, frame.height * ACCENT_RATIO));
|
|
53
|
+
traceLocal(graphics, frame, {
|
|
54
|
+
x: 0,
|
|
55
|
+
y: 0,
|
|
56
|
+
width: frame.width,
|
|
57
|
+
height: band
|
|
58
|
+
});
|
|
44
59
|
graphics.fill({
|
|
45
60
|
color: style.accent,
|
|
46
61
|
alpha: style.accentAlpha ?? .9
|
|
47
62
|
});
|
|
48
63
|
}
|
|
64
|
+
function drawFarBars(graphics, frame, bars, style) {
|
|
65
|
+
if (bars.length === 0) return;
|
|
66
|
+
for (const bar of bars) traceLocal(graphics, frame, bar);
|
|
67
|
+
graphics.fill({
|
|
68
|
+
color: style.color,
|
|
69
|
+
alpha: style.alpha
|
|
70
|
+
});
|
|
71
|
+
}
|
|
49
72
|
function farStrokeSamples(points) {
|
|
50
73
|
if (points.length <= FAR_STROKE_MAX_POINTS) return points;
|
|
51
74
|
const step = Math.ceil(points.length / FAR_STROKE_MAX_POINTS);
|
|
@@ -70,4 +93,4 @@ function drawFarStroke(graphics, points, style) {
|
|
|
70
93
|
});
|
|
71
94
|
}
|
|
72
95
|
//#endregion
|
|
73
|
-
export { drawFarPlate, drawFarStroke, farStrokeSamples };
|
|
96
|
+
export { drawFarBars, drawFarPlate, drawFarStroke, farPictureTone, farStrokeSamples };
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { BOARD_FONT_STACK, BOARD_MONO_FONT_STACK } from "../../../protocol/dist/board-constants.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { boardItemPreview } from "../../../protocol/dist/board-model.js";
|
|
3
|
+
import { boardCardDetailed } from "../lod.js";
|
|
4
4
|
import { fitTextToLines } from "../text-fit.js";
|
|
5
|
-
import {
|
|
5
|
+
import { syncTextResolution } from "../text-resolution.js";
|
|
6
6
|
import { createCardTag, syncCardTag, zoomCardTag } from "../card-tag.js";
|
|
7
7
|
import { cardElevation, containRect, drawCardSurface, traceCardOutline } from "../surface.js";
|
|
8
8
|
import { positionShell } from "./base-card-renderer.js";
|
|
9
|
-
import { drawFarPlate } from "./far-plate.js";
|
|
9
|
+
import { drawFarPlate, farPictureTone } from "./far-plate.js";
|
|
10
|
+
import { fileCategory, fileStem } from "../../model/file-snapshot.js";
|
|
11
|
+
import { fileCategoryAccent, fileMetaLine, filePreviewKind, fileTypeLabel } from "../../model/file-preview.js";
|
|
10
12
|
import { Container, Graphics, Sprite, Text, Texture } from "pixi.js";
|
|
11
13
|
//#region src/board/render/renderers/file-card-renderer.ts
|
|
12
14
|
const PADDING = 10;
|
|
@@ -26,8 +28,34 @@ const partsByContainer = /* @__PURE__ */ new WeakMap();
|
|
|
26
28
|
function detailFor(zoom) {
|
|
27
29
|
return boardCardDetailed(zoom) ? "full" : "title";
|
|
28
30
|
}
|
|
29
|
-
function
|
|
30
|
-
if (
|
|
31
|
+
function viewOf(item) {
|
|
32
|
+
if (item.type === "file") {
|
|
33
|
+
const { src, snapshot } = item.props;
|
|
34
|
+
return {
|
|
35
|
+
src,
|
|
36
|
+
title: snapshot?.title || fileStem(src),
|
|
37
|
+
excerpt: snapshot?.excerpt ?? "",
|
|
38
|
+
kind: filePreviewKind(snapshot),
|
|
39
|
+
meta: fileMetaLine(src, snapshot?.size),
|
|
40
|
+
mark: fileTypeLabel(src),
|
|
41
|
+
category: fileCategory(src, snapshot?.mimeType)
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const preview = boardItemPreview(item);
|
|
45
|
+
if (!preview) return null;
|
|
46
|
+
const label = (item.type.split(".").pop() ?? item.type).toUpperCase();
|
|
47
|
+
return {
|
|
48
|
+
src: preview.src ?? null,
|
|
49
|
+
title: preview.title || item.type,
|
|
50
|
+
excerpt: preview.excerpt ?? "",
|
|
51
|
+
kind: preview.cover ? "cover" : preview.excerpt ? "text" : "blank",
|
|
52
|
+
meta: label,
|
|
53
|
+
mark: label,
|
|
54
|
+
category: preview.src ? fileCategory(preview.src) : "other"
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function coverHeight(view, height) {
|
|
58
|
+
if (view.kind !== "cover") return 0;
|
|
31
59
|
const ideal = Math.round(height * COVER_RATIO);
|
|
32
60
|
return Math.max(0, Math.min(ideal, height - MIN_BODY_FOR_COVER));
|
|
33
61
|
}
|
|
@@ -46,31 +74,31 @@ function syncClip(parts, rect, style) {
|
|
|
46
74
|
}
|
|
47
75
|
function sync(container, item, context) {
|
|
48
76
|
const parts = partsByContainer.get(container);
|
|
49
|
-
|
|
50
|
-
|
|
77
|
+
const view = viewOf(item);
|
|
78
|
+
if (!parts || !view) return;
|
|
79
|
+
syncContent(parts, item, view, context);
|
|
51
80
|
for (const text of [
|
|
52
81
|
parts.title,
|
|
53
82
|
parts.excerpt,
|
|
54
83
|
parts.typeMark
|
|
55
84
|
]) syncTextResolution(text, context.textResolution);
|
|
56
85
|
}
|
|
57
|
-
function syncContent(parts, item, context) {
|
|
86
|
+
function syncContent(parts, item, view, context) {
|
|
58
87
|
positionShell(parts.root, item);
|
|
59
88
|
const { width, height } = item.frame;
|
|
60
89
|
const detail = detailFor(context.zoom);
|
|
61
90
|
const elevation = cardElevation(context, item.id);
|
|
62
91
|
syncCardTag(parts.tag, {
|
|
63
92
|
glyph: "file",
|
|
64
|
-
text:
|
|
93
|
+
text: view.meta,
|
|
65
94
|
width
|
|
66
95
|
}, context);
|
|
67
96
|
const key = context.assetKey(item);
|
|
68
97
|
const texture = key ? context.getTexture(key) : null;
|
|
69
98
|
const coverFailed = Boolean(key && !texture && context.hasError(key));
|
|
70
|
-
const fileState = context.fileState(
|
|
71
|
-
const band = coverHeight(
|
|
72
|
-
const kind =
|
|
73
|
-
const category = fileCategory(item.props.src, item.props.snapshot?.mimeType);
|
|
99
|
+
const fileState = view.src ? context.fileState(view.src) : "ok";
|
|
100
|
+
const band = coverHeight(view, height);
|
|
101
|
+
const { kind, category, title, excerpt, mark } = view;
|
|
74
102
|
const accent = fileCategoryAccent(category, context.palette);
|
|
75
103
|
const visualSig = [
|
|
76
104
|
key ?? "",
|
|
@@ -129,9 +157,6 @@ function syncContent(parts, item, context) {
|
|
|
129
157
|
parts.excerpt.visible = detail === "full";
|
|
130
158
|
parts.typeMark.visible = kind === "blank";
|
|
131
159
|
}
|
|
132
|
-
const title = item.props.snapshot?.title || fileStem(item.props.src);
|
|
133
|
-
const excerpt = item.props.snapshot?.excerpt ?? "";
|
|
134
|
-
const mark = fileTypeLabel(item.props.src);
|
|
135
160
|
const innerWidth = Math.max(1, width - 20);
|
|
136
161
|
const showTypeMark = kind === "blank";
|
|
137
162
|
const textSig = [
|
|
@@ -146,6 +171,7 @@ function syncContent(parts, item, context) {
|
|
|
146
171
|
context.palette.text,
|
|
147
172
|
context.palette.muted,
|
|
148
173
|
context.style.font,
|
|
174
|
+
context.themeKey,
|
|
149
175
|
accent
|
|
150
176
|
].join("|");
|
|
151
177
|
if (textSig === parts.textSig) return;
|
|
@@ -186,7 +212,7 @@ function syncContent(parts, item, context) {
|
|
|
186
212
|
}
|
|
187
213
|
const fileCardRenderer = {
|
|
188
214
|
id: "file-card",
|
|
189
|
-
canRender: (item) => item.type === "file",
|
|
215
|
+
canRender: (item) => item.type === "file" || boardItemPreview(item) !== null,
|
|
190
216
|
create: (item, context) => {
|
|
191
217
|
const root = new Container();
|
|
192
218
|
const plate = new Graphics();
|
|
@@ -203,8 +229,6 @@ const fileCardRenderer = {
|
|
|
203
229
|
fontFamily: BOARD_FONT_STACK,
|
|
204
230
|
fontSize: TITLE_SIZE,
|
|
205
231
|
fontWeight: "600",
|
|
206
|
-
wordWrap: true,
|
|
207
|
-
breakWords: true,
|
|
208
232
|
lineHeight: TITLE_LINE
|
|
209
233
|
},
|
|
210
234
|
resolution,
|
|
@@ -217,8 +241,6 @@ const fileCardRenderer = {
|
|
|
217
241
|
fontFamily: BOARD_FONT_STACK,
|
|
218
242
|
fontSize: EXCERPT_SIZE,
|
|
219
243
|
fontWeight: "400",
|
|
220
|
-
wordWrap: true,
|
|
221
|
-
breakWords: true,
|
|
222
244
|
lineHeight: EXCERPT_LINE
|
|
223
245
|
},
|
|
224
246
|
resolution,
|
|
@@ -254,23 +276,19 @@ const fileCardRenderer = {
|
|
|
254
276
|
visualSig: "",
|
|
255
277
|
textSig: ""
|
|
256
278
|
});
|
|
257
|
-
|
|
279
|
+
sync(root, item, context);
|
|
258
280
|
return root;
|
|
259
281
|
},
|
|
260
|
-
update:
|
|
261
|
-
|
|
262
|
-
},
|
|
263
|
-
resolution: (container, item, context) => {
|
|
264
|
-
if (item.type === "file") sync(container, item, context);
|
|
265
|
-
},
|
|
282
|
+
update: sync,
|
|
283
|
+
resolution: sync,
|
|
266
284
|
zoom: (container, zoom) => {
|
|
267
285
|
const tag = partsByContainer.get(container)?.tag;
|
|
268
286
|
if (tag) zoomCardTag(tag, zoom);
|
|
269
287
|
},
|
|
270
288
|
renderFar: (graphics, item, context) => {
|
|
271
|
-
const category =
|
|
289
|
+
const category = viewOf(item)?.category ?? "other";
|
|
272
290
|
drawFarPlate(graphics, item.frame, {
|
|
273
|
-
fill: context.palette.surface,
|
|
291
|
+
fill: farPictureTone(item, context) ?? context.palette.surface,
|
|
274
292
|
fillAlpha: .96,
|
|
275
293
|
accent: fileCategoryAccent(category, context.palette),
|
|
276
294
|
accentAlpha: .45
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
|
|
2
2
|
import { itemAlpha, itemColor } from "../palette.js";
|
|
3
|
+
import { BOARD_FRAME_LABEL_LINE_HEIGHT, frameLabelOffset } from "../../model/text-metrics.js";
|
|
3
4
|
import { syncTextResolution } from "../text-resolution.js";
|
|
4
5
|
import { dashPattern, roundRectPoints, tracePolyline, trimPolyline } from "../stroke.js";
|
|
5
6
|
import { createLabel, positionShell } from "./base-card-renderer.js";
|
|
6
7
|
import { drawFarPlate } from "./far-plate.js";
|
|
8
|
+
import "../labels.js";
|
|
7
9
|
import { Container, Graphics } from "pixi.js";
|
|
8
10
|
//#region src/board/render/renderers/frame-card-renderer.ts
|
|
9
11
|
const partsByContainer = /* @__PURE__ */ new WeakMap();
|
|
@@ -57,19 +59,24 @@ function sync(container, item, context) {
|
|
|
57
59
|
parts.label.visible = decorated;
|
|
58
60
|
const title = locked ? `🔒 ${props.label}`.trim() : props.label;
|
|
59
61
|
const labelColor = style.stroke ? baseStroke : context.palette.muted;
|
|
62
|
+
const size = context.style.frameLabelSize;
|
|
60
63
|
const textSig = [
|
|
61
64
|
title,
|
|
62
65
|
labelColor,
|
|
63
|
-
context.style.font
|
|
66
|
+
context.style.font,
|
|
67
|
+
size
|
|
64
68
|
].join("|");
|
|
65
69
|
if (textSig !== parts.textSig) {
|
|
66
70
|
parts.textSig = textSig;
|
|
67
71
|
parts.label.text = title;
|
|
68
72
|
parts.label.style.fill = labelColor;
|
|
69
73
|
parts.label.style.fontFamily = context.style.font;
|
|
74
|
+
parts.label.style.fontSize = size;
|
|
75
|
+
parts.label.style.lineHeight = size * BOARD_FRAME_LABEL_LINE_HEIGHT;
|
|
76
|
+
const offset = frameLabelOffset(size);
|
|
77
|
+
parts.label.position.set(offset.x, offset.y);
|
|
70
78
|
}
|
|
71
79
|
syncTextResolution(parts.label, context.textResolution);
|
|
72
|
-
parts.label.position.set(4, -18);
|
|
73
80
|
}
|
|
74
81
|
const frameCardRenderer = {
|
|
75
82
|
id: "frame-card",
|
|
@@ -80,7 +87,6 @@ const frameCardRenderer = {
|
|
|
80
87
|
const label = createLabel("", {
|
|
81
88
|
fill: context.palette.muted,
|
|
82
89
|
fontFamily: BOARD_FONT_STACK,
|
|
83
|
-
fontSize: 12,
|
|
84
90
|
fontWeight: "600"
|
|
85
91
|
}, context.textResolution);
|
|
86
92
|
root.addChild(box, label);
|