@neta-art/cohub 8.23.0 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/board/animation.d.ts +57 -181
- package/dist/board/animation.js +374 -220
- package/dist/board/core/arrow-geometry.d.ts +33 -18
- package/dist/board/core/arrow-geometry.js +283 -52
- package/dist/board/core/draw-geometry.d.ts +22 -36
- package/dist/board/core/draw-geometry.js +148 -85
- package/dist/board/core/export-assets.d.ts +3 -6
- package/dist/board/core/export-assets.js +0 -2
- package/dist/board/core/export-plan.d.ts +12 -63
- package/dist/board/core/export-plan.js +55 -94
- package/dist/board/core/palette.d.ts +4 -21
- package/dist/board/core/palette.js +8 -13
- package/dist/board/core/scene.d.ts +33 -0
- package/dist/board/core/scene.js +302 -0
- package/dist/board/core/shape-definition.d.ts +12 -24
- package/dist/board/core/shape-definition.js +0 -19
- package/dist/board/core/shape-types.d.ts +6 -120
- package/dist/board/core/shape-types.js +5 -5
- package/dist/board/core/text-metrics.d.ts +8 -11
- package/dist/board/core/text-metrics.js +5 -34
- package/dist/board/core/tool-styles.d.ts +6 -16
- package/dist/board/core/tool-styles.js +17 -25
- package/dist/board/export/index.d.ts +10 -17
- package/dist/board/export/index.js +22 -21
- package/dist/board/export/scene.d.ts +10 -16
- package/dist/board/export/scene.js +17 -30
- package/dist/board/geometry.d.ts +27 -56
- package/dist/board/geometry.js +7 -67
- package/dist/board/headless/index.d.ts +7 -27
- package/dist/board/headless/index.js +20 -19
- package/dist/board/headless/sketch.d.ts +19 -0
- package/dist/board/headless/sketch.js +146 -0
- package/dist/board/image-key.d.ts +2 -12
- package/dist/board/image-key.js +3 -13
- package/dist/board/index.d.ts +18 -20
- package/dist/board/index.js +17 -17
- package/dist/board/media-playback.d.ts +3 -6
- package/dist/board/media-playback.js +6 -6
- package/dist/board/presets.d.ts +150 -0
- package/dist/board/presets.js +226 -0
- package/dist/board/render/board-background.d.ts +5 -3
- package/dist/board/render/board-background.js +8 -7
- package/dist/board/render/clip.d.ts +14 -0
- package/dist/board/render/clip.js +47 -0
- package/dist/board/render/index.d.ts +8 -5
- package/dist/board/render/index.js +7 -4
- package/dist/board/render/media-interaction.d.ts +4 -5
- package/dist/board/render/media-interaction.js +1 -2
- package/dist/board/render/palette.d.ts +6 -2
- package/dist/board/render/palette.js +7 -1
- package/dist/board/render/renderers/arrow-card-renderer.js +69 -71
- package/dist/board/render/renderers/audio-card-renderer.js +3 -3
- package/dist/board/render/renderers/base-card-renderer.d.ts +6 -17
- package/dist/board/render/renderers/base-card-renderer.js +1 -24
- package/dist/board/render/renderers/board-renderer-registry.d.ts +20 -50
- package/dist/board/render/renderers/board-renderer-registry.js +6 -7
- package/dist/board/render/renderers/draw-card-renderer.js +89 -56
- package/dist/board/render/renderers/effect-card-renderer.d.ts +6 -0
- package/dist/board/render/renderers/effect-card-renderer.js +197 -0
- package/dist/board/render/renderers/far-plate.d.ts +4 -21
- package/dist/board/render/renderers/far-plate.js +15 -34
- package/dist/board/render/renderers/file-card-renderer.d.ts +4 -25
- package/dist/board/render/renderers/file-card-renderer.js +8 -58
- package/dist/board/render/renderers/frame-card-renderer.js +28 -28
- package/dist/board/render/renderers/image-card-renderer.d.ts +4 -3
- package/dist/board/render/renderers/image-card-renderer.js +0 -9
- package/dist/board/render/renderers/shape-card-renderer.d.ts +9 -0
- package/dist/board/render/renderers/shape-card-renderer.js +240 -0
- package/dist/board/render/renderers/sketch-card-renderer.d.ts +5 -0
- package/dist/board/render/renderers/sketch-card-renderer.js +98 -0
- package/dist/board/render/renderers/task-card-renderer.d.ts +0 -1
- package/dist/board/render/renderers/task-card-renderer.js +14 -16
- package/dist/board/render/renderers/text-card-renderer.d.ts +1 -3
- package/dist/board/render/renderers/text-card-renderer.js +56 -46
- package/dist/board/render/renderers/unknown-card-renderer.js +4 -10
- package/dist/board/render/renderers/video-card-renderer.d.ts +4 -2
- package/dist/board/render/renderers/video-card-renderer.js +2 -1
- package/dist/board/render/sketch-host.d.ts +14 -0
- package/dist/board/render/sketch-host.js +216 -0
- package/dist/board/render/stroke.d.ts +12 -0
- package/dist/board/render/stroke.js +90 -0
- package/dist/board/render/text-measurement.d.ts +6 -26
- package/dist/board/render/text-measurement.js +11 -30
- package/dist/board/replay.d.ts +6 -31
- package/dist/board/replay.js +45 -203
- package/dist/board/runtime/board-player.d.ts +24 -0
- package/dist/board/runtime/board-player.js +161 -0
- package/dist/board/task.d.ts +2 -10
- package/dist/board/task.js +1 -10
- package/dist/chunks/environment.d.ts +2296 -3864
- package/dist/chunks/host-bridge.d.ts +253 -0
- package/dist/chunks/http.d.ts +238 -58
- package/dist/chunks/http.js +1061 -1034
- package/dist/chunks/transport.js +113 -59
- package/dist/chunks/websocket.d.ts +1 -1
- package/dist/chunks/websocket.js +1 -1
- package/dist/host-bridge.d.ts +54 -0
- package/dist/host-bridge.js +322 -0
- package/dist/http.d.ts +3 -3
- package/dist/index.d.ts +76 -193
- package/dist/index.js +2037 -1191
- package/dist/protocol/dist/board-constants.d.ts +1 -29
- package/dist/protocol/dist/board-constants.js +2 -115
- package/dist/protocol/dist/board-layout.d.ts +59 -0
- package/dist/protocol/dist/board-layout.js +482 -0
- package/dist/protocol/dist/board-model.d.ts +2052 -0
- package/dist/protocol/dist/board-model.js +592 -0
- package/dist/protocol/dist/board-patch.d.ts +86 -0
- package/dist/protocol/dist/board-patch.js +734 -0
- package/dist/protocol/dist/board-schema.d.ts +33 -0
- package/dist/protocol/dist/board-schema.js +59 -0
- package/dist/protocol/dist/board-upgrade.d.ts +1 -0
- package/dist/protocol/dist/board-url.d.ts +1 -3
- package/dist/protocol/dist/board-url.js +2 -2
- package/dist/protocol/dist/board.d.ts +37 -232
- package/dist/protocol/dist/board.js +62 -160
- package/dist/protocol/dist/display/actions.d.ts +1 -0
- package/dist/protocol/dist/display/index.d.ts +2 -0
- package/dist/protocol/dist/index.d.ts +11 -12
- package/dist/protocol/dist/model/metrics.d.ts +2 -0
- package/dist/protocol/dist/model/session.d.ts +2 -1
- package/dist/protocol/dist/realtime/types.d.ts +2 -2
- package/dist/protocol/dist/runtime/index.d.ts +1 -0
- package/dist/space-picker.d.ts +1 -0
- package/dist/space-picker.js +1 -0
- package/dist/types.d.ts +2 -5
- package/package.json +9 -1
- package/dist/board/core/connections.d.ts +0 -108
- package/dist/board/core/connections.js +0 -455
- package/dist/board/mutation.d.ts +0 -6
- package/dist/board/mutation.js +0 -14
- package/dist/board/render/connection-layer.d.ts +0 -53
- package/dist/board/render/connection-layer.js +0 -375
- package/dist/board/render/renderers/geo-card-renderer.d.ts +0 -5
- package/dist/board/render/renderers/geo-card-renderer.js +0 -127
- package/dist/board/semantic-document.d.ts +0 -37
- package/dist/board/semantic-document.js +0 -288
- package/dist/board/semantic-mutation.d.ts +0 -10
- package/dist/board/semantic-mutation.js +0 -209
- package/dist/protocol/dist/board-animation.js +0 -34
- package/dist/protocol/dist/board-authoring.d.ts +0 -1326
- package/dist/protocol/dist/board-authoring.js +0 -302
- package/dist/protocol/dist/board-capability-registry.d.ts +0 -2
- package/dist/protocol/dist/board-capability-registry.js +0 -123
- package/dist/protocol/dist/board-codec.d.ts +0 -3
- package/dist/protocol/dist/board-codec.js +0 -383
- package/dist/protocol/dist/board-composition.d.ts +0 -383
- package/dist/protocol/dist/board-composition.js +0 -310
- package/dist/protocol/dist/board-connection.d.ts +0 -317
- package/dist/protocol/dist/board-connection.js +0 -219
- package/dist/protocol/dist/board-document.d.ts +0 -1566
- package/dist/protocol/dist/board-document.js +0 -456
- package/dist/protocol/dist/board-effect.d.ts +0 -96
- package/dist/protocol/dist/board-effect.js +0 -54
- package/dist/protocol/dist/board-geometry.d.ts +0 -15
- package/dist/protocol/dist/board-geometry.js +0 -137
- package/dist/protocol/dist/board-node.d.ts +0 -8
- package/dist/protocol/dist/board-node.js +0 -252
- /package/dist/protocol/dist/{board-animation.d.ts → host-bridge.d.ts} +0 -0
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BoardSettings } from "../../protocol/dist/board-model.js";
|
|
2
|
+
import "../../protocol/dist/index.js";
|
|
3
|
+
import { BoardViewport } from "../geometry.js";
|
|
2
4
|
import { BoardRenderPalette } from "./renderers/board-renderer-registry.js";
|
|
3
5
|
import { Application, Container } from "pixi.js";
|
|
4
6
|
//#region src/board/render/board-background.d.ts
|
|
5
7
|
type BoardBackgroundContext = {
|
|
6
8
|
app: Application;
|
|
7
|
-
|
|
9
|
+
settings: BoardSettings;
|
|
8
10
|
viewport: BoardViewport;
|
|
11
|
+
colorScheme: "dark" | "light";
|
|
9
12
|
palette: BoardRenderPalette;
|
|
10
|
-
/** The host renders an image backdrop below the transparent Pixi canvas. */
|
|
11
13
|
hasImageBackground?: boolean;
|
|
12
14
|
};
|
|
13
15
|
declare function createBoardBackground(context: BoardBackgroundContext): Container;
|
|
@@ -28,11 +28,12 @@ function buildGridTexture(context, size, color, opacity, kind) {
|
|
|
28
28
|
return target;
|
|
29
29
|
}
|
|
30
30
|
function sync(parts, context) {
|
|
31
|
-
const { app,
|
|
31
|
+
const { app, settings, viewport, palette } = context;
|
|
32
32
|
const width = app.screen.width;
|
|
33
33
|
const height = app.screen.height;
|
|
34
|
-
const
|
|
35
|
-
const
|
|
34
|
+
const declared = settings.background.color;
|
|
35
|
+
const cssColor = typeof declared === "object" ? declared[context.colorScheme] : declared;
|
|
36
|
+
const bgColor = cssColor ? parseBoardCssColor(cssColor) ?? palette.bg : palette.bg;
|
|
36
37
|
const bgAlpha = context.hasImageBackground ? 0 : 1;
|
|
37
38
|
if (parts.lastWidth !== width || parts.lastHeight !== height || parts.lastBg !== bgColor || parts.lastBgAlpha !== bgAlpha) {
|
|
38
39
|
parts.fill.clear();
|
|
@@ -45,10 +46,10 @@ function sync(parts, context) {
|
|
|
45
46
|
parts.lastBg = bgColor;
|
|
46
47
|
parts.lastBgAlpha = bgAlpha;
|
|
47
48
|
}
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const
|
|
49
|
+
const kind = settings.background.kind === "grid" ? "grid" : "dots";
|
|
50
|
+
const visible = settings.grid?.visible === true;
|
|
51
|
+
const size = Math.max(4, settings.grid?.size ?? 24);
|
|
52
|
+
const opacity = .12;
|
|
52
53
|
const key = `${kind}|${size}|${palette.border}|${opacity}`;
|
|
53
54
|
if (!visible) {
|
|
54
55
|
if (parts.sprite) parts.sprite.visible = false;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BoardScene, BoardSceneItem } from "../core/scene.js";
|
|
2
|
+
import { Container, Graphics } from "pixi.js";
|
|
3
|
+
//#region src/board/render/clip.d.ts
|
|
4
|
+
declare function isClippingFrame(item: BoardSceneItem): boolean;
|
|
5
|
+
declare function clippingAncestor(scene: BoardScene, item: BoardSceneItem): string | undefined;
|
|
6
|
+
declare function traceFrameOutline(graphics: Graphics, item: BoardSceneItem): void;
|
|
7
|
+
type ClipGroup = {
|
|
8
|
+
group: Container;
|
|
9
|
+
mask: Graphics;
|
|
10
|
+
sig: string;
|
|
11
|
+
};
|
|
12
|
+
declare function syncClipGroup(entry: ClipGroup | undefined, item: BoardSceneItem): ClipGroup;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { ClipGroup, clippingAncestor, isClippingFrame, syncClipGroup, traceFrameOutline };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { framePoint } from "../../protocol/dist/board-layout.js";
|
|
2
|
+
import { Container, Graphics } from "pixi.js";
|
|
3
|
+
//#region src/board/render/clip.ts
|
|
4
|
+
function isClippingFrame(item) {
|
|
5
|
+
return item.type === "frame" && item.props.clip !== false;
|
|
6
|
+
}
|
|
7
|
+
function clippingAncestor(scene, item) {
|
|
8
|
+
let cursor = item.parent;
|
|
9
|
+
for (let depth = 0; cursor && depth < 64; depth += 1) {
|
|
10
|
+
const parent = scene.get(cursor);
|
|
11
|
+
if (!parent) return void 0;
|
|
12
|
+
if (isClippingFrame(parent)) return cursor;
|
|
13
|
+
cursor = parent.parent;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function traceFrameOutline(graphics, item) {
|
|
17
|
+
const corners = [
|
|
18
|
+
framePoint(item.frame, 0, 0),
|
|
19
|
+
framePoint(item.frame, 1, 0),
|
|
20
|
+
framePoint(item.frame, 1, 1),
|
|
21
|
+
framePoint(item.frame, 0, 1)
|
|
22
|
+
];
|
|
23
|
+
graphics.poly(corners.flatMap((point) => [point.x, point.y])).fill(16777215);
|
|
24
|
+
}
|
|
25
|
+
function syncClipGroup(entry, item) {
|
|
26
|
+
const next = entry ?? (() => {
|
|
27
|
+
const group = new Container({ label: `board-clip-${item.id}` });
|
|
28
|
+
const mask = new Graphics();
|
|
29
|
+
group.addChild(mask);
|
|
30
|
+
group.mask = mask;
|
|
31
|
+
return {
|
|
32
|
+
group,
|
|
33
|
+
mask,
|
|
34
|
+
sig: ""
|
|
35
|
+
};
|
|
36
|
+
})();
|
|
37
|
+
const { x, y, width, height, rotation } = item.frame;
|
|
38
|
+
const sig = `${x},${y},${width},${height},${rotation}`;
|
|
39
|
+
if (sig !== next.sig) {
|
|
40
|
+
next.sig = sig;
|
|
41
|
+
next.mask.clear();
|
|
42
|
+
traceFrameOutline(next.mask, item);
|
|
43
|
+
}
|
|
44
|
+
return next;
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { clippingAncestor, isClippingFrame, syncClipGroup, traceFrameOutline };
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { BoardCardRenderer, BoardRenderContext, BoardRenderPalette, boardCardRenderersForTest, getBoardCardRenderer, registerBoardCardRenderer } from "./renderers/board-renderer-registry.js";
|
|
1
|
+
import { BoardCardRenderer, BoardRenderContext, BoardRenderPalette, BoardSketchHost, boardCardRenderersForTest, getBoardCardRenderer, registerBoardCardRenderer } from "./renderers/board-renderer-registry.js";
|
|
2
2
|
import { BoardBackgroundContext, createBoardBackground, updateBoardBackground } from "./board-background.js";
|
|
3
|
-
import {
|
|
3
|
+
import { ClipGroup, clippingAncestor, isClippingFrame, syncClipGroup, traceFrameOutline } from "./clip.js";
|
|
4
4
|
import { parseBoardCssColor } from "./css-color.js";
|
|
5
5
|
import { BoardMediaAction, boardMediaActionAt, mediaPlayBadgeHit, mediaPlayBadgeVisible } from "./media-interaction.js";
|
|
6
|
-
import { defaultBoardPalette } from "./palette.js";
|
|
6
|
+
import { defaultBoardPalette, itemColor } from "./palette.js";
|
|
7
|
+
import { BoardSketchHostOptions, BrowserBoardSketchHost, createBoardSketchHost } from "./sketch-host.js";
|
|
8
|
+
import { dashPattern, endAngle, traceArrowhead, tracePolyline, trimPolyline } from "./stroke.js";
|
|
9
|
+
import { BOARD_EFFECT_MAX_PARTICLES } from "./renderers/effect-card-renderer.js";
|
|
7
10
|
import { TASK_CARD_FULL_DETAIL_ZOOM } from "./renderers/task-card-renderer.js";
|
|
8
|
-
import { ensureBoardTextMeasurement, installBoardTextMeasurement } from "./text-measurement.js";
|
|
11
|
+
import { BOARD_FONT_STACKS, ensureBoardTextMeasurement, installBoardTextMeasurement } from "./text-measurement.js";
|
|
9
12
|
import { getBoardResolution, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket } from "./text-resolution.js";
|
|
10
13
|
import { VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, loadVideoThumbnailTexture, videoTextureNaturalSize, videoThumbnailSize } from "./video-thumbnail.js";
|
|
11
|
-
export { BoardBackgroundContext, BoardCardRenderer, BoardMediaAction, BoardRenderContext, BoardRenderPalette,
|
|
14
|
+
export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, BoardBackgroundContext, BoardCardRenderer, BoardMediaAction, BoardRenderContext, BoardRenderPalette, BoardSketchHost, BoardSketchHostOptions, BrowserBoardSketchHost, ClipGroup, TASK_CARD_FULL_DETAIL_ZOOM, VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, boardCardRenderersForTest, boardMediaActionAt, clippingAncestor, createBoardBackground, createBoardSketchHost, dashPattern, defaultBoardPalette, endAngle, ensureBoardTextMeasurement, getBoardCardRenderer, getBoardResolution, installBoardTextMeasurement, isClippingFrame, itemColor, loadVideoThumbnailTexture, mediaPlayBadgeHit, mediaPlayBadgeVisible, parseBoardCssColor, registerBoardCardRenderer, syncClipGroup, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket, traceArrowhead, traceFrameOutline, tracePolyline, trimPolyline, updateBoardBackground, videoTextureNaturalSize, videoThumbnailSize };
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { parseBoardCssColor } from "./css-color.js";
|
|
2
2
|
import { createBoardBackground, updateBoardBackground } from "./board-background.js";
|
|
3
|
+
import { clippingAncestor, isClippingFrame, syncClipGroup, traceFrameOutline } from "./clip.js";
|
|
3
4
|
import { getBoardResolution, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket } from "./text-resolution.js";
|
|
4
|
-
import { createConnectionLayer, framesFromItems } from "./connection-layer.js";
|
|
5
5
|
import { TASK_CARD_FULL_DETAIL_ZOOM } from "./renderers/task-card-renderer.js";
|
|
6
6
|
import { boardMediaActionAt, mediaPlayBadgeHit, mediaPlayBadgeVisible } from "./media-interaction.js";
|
|
7
|
-
import { defaultBoardPalette } from "./palette.js";
|
|
8
|
-
import { ensureBoardTextMeasurement, installBoardTextMeasurement } from "./text-measurement.js";
|
|
7
|
+
import { defaultBoardPalette, itemColor } from "./palette.js";
|
|
8
|
+
import { BOARD_FONT_STACKS, ensureBoardTextMeasurement, installBoardTextMeasurement } from "./text-measurement.js";
|
|
9
|
+
import { dashPattern, endAngle, traceArrowhead, tracePolyline, trimPolyline } from "./stroke.js";
|
|
10
|
+
import { BOARD_EFFECT_MAX_PARTICLES } from "./renderers/effect-card-renderer.js";
|
|
9
11
|
import { boardCardRenderersForTest, getBoardCardRenderer, registerBoardCardRenderer } from "./renderers/board-renderer-registry.js";
|
|
12
|
+
import { createBoardSketchHost } from "./sketch-host.js";
|
|
10
13
|
import { VIDEO_THUMBNAIL_MAX_EDGE, loadVideoThumbnailTexture, videoTextureNaturalSize, videoThumbnailSize } from "./video-thumbnail.js";
|
|
11
|
-
export { TASK_CARD_FULL_DETAIL_ZOOM, VIDEO_THUMBNAIL_MAX_EDGE, boardCardRenderersForTest, boardMediaActionAt, createBoardBackground,
|
|
14
|
+
export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, TASK_CARD_FULL_DETAIL_ZOOM, VIDEO_THUMBNAIL_MAX_EDGE, boardCardRenderersForTest, boardMediaActionAt, clippingAncestor, createBoardBackground, createBoardSketchHost, dashPattern, defaultBoardPalette, endAngle, ensureBoardTextMeasurement, getBoardCardRenderer, getBoardResolution, installBoardTextMeasurement, isClippingFrame, itemColor, loadVideoThumbnailTexture, mediaPlayBadgeHit, mediaPlayBadgeVisible, parseBoardCssColor, registerBoardCardRenderer, syncClipGroup, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket, traceArrowhead, traceFrameOutline, tracePolyline, trimPolyline, updateBoardBackground, videoTextureNaturalSize, videoThumbnailSize };
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import { BoardItem } from "../../protocol/dist/board-document.js";
|
|
2
1
|
import { WorldPoint } from "../geometry.js";
|
|
2
|
+
import { BoardSceneItem } from "../core/scene.js";
|
|
3
3
|
//#region src/board/render/media-interaction.d.ts
|
|
4
4
|
type BoardMediaAction = {
|
|
5
5
|
action: "play-media";
|
|
6
6
|
itemId: string;
|
|
7
7
|
};
|
|
8
|
-
declare function mediaPlayBadgeVisible(item:
|
|
8
|
+
declare function mediaPlayBadgeVisible(item: BoardSceneItem, zoom: number, options: {
|
|
9
9
|
materialized: boolean;
|
|
10
10
|
hasVideoPreview: boolean;
|
|
11
11
|
}): boolean;
|
|
12
|
-
|
|
13
|
-
declare function
|
|
14
|
-
declare function boardMediaActionAt(item: BoardItem, point: WorldPoint, zoom: number, options: {
|
|
12
|
+
declare function mediaPlayBadgeHit(item: BoardSceneItem, point: WorldPoint, zoom: number): boolean;
|
|
13
|
+
declare function boardMediaActionAt(item: BoardSceneItem, point: WorldPoint, zoom: number, options: {
|
|
15
14
|
materialized: boolean;
|
|
16
15
|
hasVideoPreview: boolean;
|
|
17
16
|
}): BoardMediaAction | null;
|
|
@@ -5,11 +5,10 @@ function mediaPlayBadgeVisible(item, zoom, options) {
|
|
|
5
5
|
if (!options.materialized) return false;
|
|
6
6
|
if (item.type === "video" || item.type === "audio") return true;
|
|
7
7
|
if (item.type !== "task" || zoom < .55) return false;
|
|
8
|
-
const artifact = featuredTaskArtifact(item.snapshot.artifacts);
|
|
8
|
+
const artifact = featuredTaskArtifact(item.props.snapshot.artifacts);
|
|
9
9
|
if (artifact?.type === "audio") return true;
|
|
10
10
|
return artifact?.type === "video" && (Boolean(artifact.previewUrl) || options.hasVideoPreview);
|
|
11
11
|
}
|
|
12
|
-
/** The central badge is a fixed screen-space target, independent of Board zoom. */
|
|
13
12
|
function mediaPlayBadgeHit(item, point, zoom) {
|
|
14
13
|
const radius = 28 / Math.max(zoom, .05);
|
|
15
14
|
const centerX = item.frame.x + item.frame.width / 2;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BoardColor } from "../../protocol/dist/board-model.js";
|
|
2
|
+
import "../../protocol/dist/index.js";
|
|
3
|
+
import { BoardColorId } from "../core/palette.js";
|
|
4
|
+
import { BoardRenderContext, BoardRenderPalette } from "./renderers/board-renderer-registry.js";
|
|
2
5
|
//#region src/board/render/palette.d.ts
|
|
3
6
|
declare function defaultBoardPalette(mode: "dark" | "light"): BoardRenderPalette;
|
|
7
|
+
declare function itemColor(context: Pick<BoardRenderContext, "colors" | "colorScheme" | "palette">, color: BoardColor | undefined, fallback: BoardColorId, part?: "stroke" | "fill" | "label"): number;
|
|
4
8
|
//#endregion
|
|
5
|
-
export { defaultBoardPalette };
|
|
9
|
+
export { defaultBoardPalette, itemColor };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { resolveItemColor } from "../core/palette.js";
|
|
2
|
+
import { parseBoardCssColor } from "./css-color.js";
|
|
1
3
|
//#region src/board/render/palette.ts
|
|
2
4
|
const DARK = {
|
|
3
5
|
bg: 1315860,
|
|
@@ -26,5 +28,9 @@ const LIGHT = {
|
|
|
26
28
|
function defaultBoardPalette(mode) {
|
|
27
29
|
return { ...mode === "light" ? LIGHT : DARK };
|
|
28
30
|
}
|
|
31
|
+
function itemColor(context, color, fallback, part = "stroke") {
|
|
32
|
+
if (((typeof color === "object" && color ? color[context.colorScheme] : color) ?? fallback) === "neutral" && part !== "fill") return context.palette.text;
|
|
33
|
+
return resolveItemColor(color, fallback, context.colors, context.colorScheme, parseBoardCssColor, part);
|
|
34
|
+
}
|
|
29
35
|
//#endregion
|
|
30
|
-
export { defaultBoardPalette };
|
|
36
|
+
export { defaultBoardPalette, itemColor };
|
|
@@ -1,95 +1,91 @@
|
|
|
1
1
|
import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
|
|
2
|
-
import {
|
|
3
|
-
import { pickBoardColor } from "../../core/palette.js";
|
|
2
|
+
import { pathPointAt, resolveSceneArrow } from "../../core/arrow-geometry.js";
|
|
4
3
|
import { syncTextResolution, textResolutionForZoom } from "../text-resolution.js";
|
|
5
4
|
import { drawFarStroke } from "./far-plate.js";
|
|
5
|
+
import { itemColor } from "../palette.js";
|
|
6
|
+
import { dashPattern, endAngle, traceArrowhead, tracePolyline, trimPolyline } from "../stroke.js";
|
|
6
7
|
import { Container, Graphics, Text } from "pixi.js";
|
|
7
8
|
//#region src/board/render/renderers/arrow-card-renderer.ts
|
|
8
9
|
const partsByContainer = /* @__PURE__ */ new WeakMap();
|
|
9
|
-
/** Open chevron arrowhead — clearly directional, not a tiny filled nub. */
|
|
10
|
-
function drawArrowhead(graphics, tip, angle, size, color, strokeWidth) {
|
|
11
|
-
const spread = Math.PI / 6;
|
|
12
|
-
const left = {
|
|
13
|
-
x: tip.x - size * Math.cos(angle - spread),
|
|
14
|
-
y: tip.y - size * Math.sin(angle - spread)
|
|
15
|
-
};
|
|
16
|
-
const right = {
|
|
17
|
-
x: tip.x - size * Math.cos(angle + spread),
|
|
18
|
-
y: tip.y - size * Math.sin(angle + spread)
|
|
19
|
-
};
|
|
20
|
-
graphics.moveTo(left.x, left.y).lineTo(tip.x, tip.y).lineTo(right.x, right.y).stroke({
|
|
21
|
-
color,
|
|
22
|
-
width: Math.max(1.5, strokeWidth),
|
|
23
|
-
alpha: 1,
|
|
24
|
-
cap: "round",
|
|
25
|
-
join: "round"
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
10
|
function sync(container, item, context) {
|
|
29
11
|
const parts = partsByContainer.get(container);
|
|
30
12
|
if (!parts) return;
|
|
31
13
|
parts.root.position.set(0, 0);
|
|
32
14
|
parts.root.rotation = 0;
|
|
15
|
+
parts.root.scale.set(1);
|
|
16
|
+
const { props, style } = item;
|
|
33
17
|
const selected = context.selectedIds.has(item.id);
|
|
34
18
|
const hovered = context.hoveredId === item.id;
|
|
35
|
-
const color =
|
|
19
|
+
const color = itemColor(context, style.stroke, "brand");
|
|
20
|
+
const size = style.strokeWidth ?? 2.5;
|
|
36
21
|
syncTextResolution(parts.label, parts, context.zoom);
|
|
37
|
-
const resolved =
|
|
22
|
+
const resolved = resolveSceneArrow(item, context.scene);
|
|
23
|
+
const path = trimPolyline(resolved.path, style.trim);
|
|
38
24
|
const lineSig = [
|
|
39
|
-
|
|
40
|
-
resolved.start.y,
|
|
41
|
-
resolved.end.x,
|
|
42
|
-
resolved.end.y,
|
|
43
|
-
resolved.control.x,
|
|
44
|
-
resolved.control.y,
|
|
25
|
+
path.map((point) => `${point.x},${point.y}`).join(";"),
|
|
45
26
|
selected,
|
|
46
27
|
hovered,
|
|
47
|
-
color
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
28
|
+
color,
|
|
29
|
+
size,
|
|
30
|
+
style.dash,
|
|
31
|
+
props.arrowStart,
|
|
32
|
+
props.arrowEnd
|
|
51
33
|
].join("|");
|
|
52
34
|
if (lineSig !== parts.lineSig) {
|
|
53
35
|
parts.lineSig = lineSig;
|
|
54
36
|
parts.line.clear();
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
37
|
+
const width = selected ? size + 1 : size;
|
|
38
|
+
const stroke = {
|
|
39
|
+
color,
|
|
40
|
+
width,
|
|
41
|
+
alpha: selected || hovered ? 1 : .92,
|
|
42
|
+
cap: "round",
|
|
43
|
+
join: "round"
|
|
44
|
+
};
|
|
45
|
+
tracePolyline(parts.line, path, dashPattern(style.dash, width));
|
|
46
|
+
parts.line.stroke(stroke);
|
|
47
|
+
const first = path[0];
|
|
48
|
+
const last = path[path.length - 1];
|
|
49
|
+
if (first && last) {
|
|
50
|
+
const span = Math.hypot(last.x - first.x, last.y - first.y);
|
|
51
|
+
const headSize = Math.min(Math.max(14, size * 5.5), Math.max(10, span * .28));
|
|
52
|
+
const complete = style.trim === void 0 || style.trim >= 1;
|
|
53
|
+
const endDirection = endAngle(path, false);
|
|
54
|
+
const startDirection = endAngle(path, true);
|
|
55
|
+
if (props.arrowEnd && endDirection !== null && path.length > 1) traceArrowhead(parts.line, last, endDirection, headSize);
|
|
56
|
+
if (props.arrowStart && startDirection !== null && complete) traceArrowhead(parts.line, first, startDirection, headSize);
|
|
66
57
|
parts.line.stroke({
|
|
67
|
-
|
|
68
|
-
width,
|
|
69
|
-
alpha: selected || hovered ? 1 : .92,
|
|
70
|
-
cap: "round",
|
|
71
|
-
join: "round"
|
|
58
|
+
...stroke,
|
|
59
|
+
width: Math.max(1.5, width)
|
|
72
60
|
});
|
|
73
|
-
const span = Math.hypot(tail.x - head.x, tail.y - head.y);
|
|
74
|
-
const headSize = Math.min(Math.max(14, item.size * 5.5), Math.max(10, span * .28));
|
|
75
|
-
if (item.arrowEnd) {
|
|
76
|
-
const prev = samples[samples.length - 2];
|
|
77
|
-
if (prev) drawArrowhead(parts.line, tail, Math.atan2(tail.y - prev.y, tail.x - prev.x), headSize, strokeColor, width);
|
|
78
|
-
}
|
|
79
|
-
if (item.arrowStart) {
|
|
80
|
-
const next = samples[1];
|
|
81
|
-
if (next) drawArrowhead(parts.line, head, Math.atan2(head.y - next.y, head.x - next.x), headSize, strokeColor, width);
|
|
82
|
-
}
|
|
83
61
|
}
|
|
84
62
|
}
|
|
85
|
-
const labelSig = [
|
|
63
|
+
const labelSig = [
|
|
64
|
+
props.label,
|
|
65
|
+
context.palette.text,
|
|
66
|
+
context.palette.bg,
|
|
67
|
+
props.fontSize
|
|
68
|
+
].join("|");
|
|
86
69
|
if (labelSig !== parts.labelSig) {
|
|
87
70
|
parts.labelSig = labelSig;
|
|
88
|
-
parts.label.text =
|
|
89
|
-
parts.label.style.fill =
|
|
71
|
+
parts.label.text = props.label;
|
|
72
|
+
parts.label.style.fill = context.palette.text;
|
|
73
|
+
parts.label.style.fontSize = props.fontSize;
|
|
74
|
+
const padX = props.fontSize * .4;
|
|
75
|
+
const padY = props.fontSize * .15;
|
|
76
|
+
const { width, height } = parts.label;
|
|
77
|
+
parts.backdrop.clear();
|
|
78
|
+
parts.backdrop.roundRect(-width / 2 - padX, -height / 2 - padY, width + padX * 2, height + padY * 2, props.fontSize * .3).fill({
|
|
79
|
+
color: context.palette.bg,
|
|
80
|
+
alpha: .92
|
|
81
|
+
});
|
|
90
82
|
}
|
|
91
|
-
|
|
92
|
-
parts.label.
|
|
83
|
+
const visible = props.label.length > 0 && (style.trim === void 0 || style.trim >= .5);
|
|
84
|
+
parts.label.visible = visible;
|
|
85
|
+
parts.backdrop.visible = visible;
|
|
86
|
+
const mid = style.trim === void 0 ? resolved.mid : pathPointAt(resolved.path, .5);
|
|
87
|
+
parts.label.position.set(mid.x, mid.y);
|
|
88
|
+
parts.backdrop.position.set(mid.x, mid.y);
|
|
93
89
|
}
|
|
94
90
|
const arrowCardRenderer = {
|
|
95
91
|
id: "arrow-card",
|
|
@@ -103,17 +99,19 @@ const arrowCardRenderer = {
|
|
|
103
99
|
style: {
|
|
104
100
|
fill: 16777215,
|
|
105
101
|
fontFamily: BOARD_FONT_STACK,
|
|
106
|
-
fontSize:
|
|
102
|
+
fontSize: 14,
|
|
107
103
|
fontWeight: "500"
|
|
108
104
|
},
|
|
109
105
|
resolution,
|
|
110
106
|
roundPixels: true
|
|
111
107
|
});
|
|
112
108
|
label.anchor.set(.5);
|
|
113
|
-
|
|
109
|
+
const backdrop = new Graphics();
|
|
110
|
+
root.addChild(line, backdrop, label);
|
|
114
111
|
partsByContainer.set(root, {
|
|
115
112
|
root,
|
|
116
113
|
line,
|
|
114
|
+
backdrop,
|
|
117
115
|
label,
|
|
118
116
|
lineSig: "",
|
|
119
117
|
labelSig: "",
|
|
@@ -127,11 +125,11 @@ const arrowCardRenderer = {
|
|
|
127
125
|
},
|
|
128
126
|
renderFar: (graphics, item, context) => {
|
|
129
127
|
if (item.type !== "arrow") return;
|
|
130
|
-
const
|
|
131
|
-
const
|
|
132
|
-
drawFarStroke(graphics,
|
|
133
|
-
color:
|
|
134
|
-
width:
|
|
128
|
+
const arrow = item;
|
|
129
|
+
const resolved = resolveSceneArrow(arrow, context.scene);
|
|
130
|
+
drawFarStroke(graphics, trimPolyline(resolved.path, arrow.style.trim), {
|
|
131
|
+
color: itemColor(context, arrow.style.stroke, "brand"),
|
|
132
|
+
width: arrow.style.strokeWidth ?? 2.5,
|
|
135
133
|
alpha: .85
|
|
136
134
|
});
|
|
137
135
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
|
|
2
|
-
import { syncTextResolution, syncTextWrapWidth, textResolutionForZoom } from "../text-resolution.js";
|
|
3
2
|
import { drawAudioWaveform } from "../audio-waveform.js";
|
|
3
|
+
import { syncTextResolution, syncTextWrapWidth, textResolutionForZoom } from "../text-resolution.js";
|
|
4
4
|
import { positionShell } from "./base-card-renderer.js";
|
|
5
5
|
import { drawFarPlate } from "./far-plate.js";
|
|
6
6
|
import { Container, Graphics, Text } from "pixi.js";
|
|
@@ -15,7 +15,7 @@ function sync(container, item, context) {
|
|
|
15
15
|
const { width, height } = item.frame;
|
|
16
16
|
const selected = context.selectedIds.has(item.id);
|
|
17
17
|
const hovered = context.hoveredId === item.id;
|
|
18
|
-
const title = item.snapshot?.title ?? item.
|
|
18
|
+
const title = item.props.snapshot?.title ?? item.props.src.split("/").pop() ?? "Audio";
|
|
19
19
|
syncTextResolution(parts.label, parts, context.zoom);
|
|
20
20
|
if (parts.label.text !== title) parts.label.text = title;
|
|
21
21
|
syncTextWrapWidth(parts.label, parts, Math.max(1, width - 24), false);
|
|
@@ -46,7 +46,7 @@ function sync(container, item, context) {
|
|
|
46
46
|
const labelBand = Math.min(height * .38, parts.label.height + 16);
|
|
47
47
|
const waveformInset = Math.min(24, width * .08);
|
|
48
48
|
parts.waveform.clear();
|
|
49
|
-
drawAudioWaveform(parts.waveform, `${item.
|
|
49
|
+
drawAudioWaveform(parts.waveform, `${item.props.src}:${item.props.snapshot?.mtimeMs ?? "unknown"}`, {
|
|
50
50
|
x: waveformInset,
|
|
51
51
|
y: 10,
|
|
52
52
|
width: Math.max(1, width - waveformInset * 2),
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BoardFrame } from "../../../protocol/dist/board-layout.js";
|
|
2
|
+
import "../../../protocol/dist/index.js";
|
|
2
3
|
import { BoardRenderPalette } from "./board-renderer-registry.js";
|
|
3
4
|
import { Container, Text } from "pixi.js";
|
|
4
5
|
//#region src/board/render/renderers/base-card-renderer.d.ts
|
|
5
6
|
declare const CARD_RADIUS = 10;
|
|
6
7
|
declare const CARD_PADDING = 12;
|
|
7
8
|
declare const FOOTER_HEIGHT = 34;
|
|
8
|
-
declare function emphasisColor(item: BoardItem, palette: BoardRenderPalette): number;
|
|
9
9
|
declare function createLabel(text: string, style: Record<string, unknown>): Text;
|
|
10
10
|
type CardShellState = {
|
|
11
11
|
width: number;
|
|
@@ -16,11 +16,8 @@ type CardShellState = {
|
|
|
16
16
|
title: string;
|
|
17
17
|
};
|
|
18
18
|
type CardShell = {
|
|
19
|
-
/** Root container positioned by the item frame. */
|
|
20
19
|
root: Container;
|
|
21
|
-
/** Masked container for renderer-specific content. */
|
|
22
20
|
content: Container;
|
|
23
|
-
/** Rectangle (local coords) available for content. */
|
|
24
21
|
contentRect: () => {
|
|
25
22
|
x: number;
|
|
26
23
|
y: number;
|
|
@@ -30,17 +27,9 @@ type CardShell = {
|
|
|
30
27
|
update: (state: CardShellState, palette: BoardRenderPalette, footer: boolean) => void;
|
|
31
28
|
destroy: () => void;
|
|
32
29
|
};
|
|
33
|
-
/**
|
|
34
|
-
* Shared card chrome: rounded background, selection/hover border, optional
|
|
35
|
-
* footer with title, and a masked content region. Tracks the last rendered
|
|
36
|
-
* state so unchanged attributes are not redrawn.
|
|
37
|
-
*/
|
|
38
30
|
declare function createCardShell(): CardShell;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
* `frame.rotation` as a rotation about the frame center).
|
|
43
|
-
*/
|
|
44
|
-
declare function positionShell(root: Container, item: BoardItem): void;
|
|
31
|
+
declare function positionShell(root: Container, item: {
|
|
32
|
+
frame: BoardFrame;
|
|
33
|
+
}): void;
|
|
45
34
|
//#endregion
|
|
46
|
-
export { CARD_PADDING, CARD_RADIUS, CardShell, CardShellState, FOOTER_HEIGHT, createCardShell, createLabel,
|
|
35
|
+
export { CARD_PADDING, CARD_RADIUS, CardShell, CardShellState, FOOTER_HEIGHT, createCardShell, createLabel, positionShell };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
|
|
2
|
-
import { parseBoardCssColor } from "../css-color.js";
|
|
3
2
|
import { getBoardResolution } from "../text-resolution.js";
|
|
4
3
|
import { Container, Graphics, Text } from "pixi.js";
|
|
5
4
|
//#region src/board/render/renderers/base-card-renderer.ts
|
|
@@ -10,18 +9,6 @@ const TEXT_OPTIONS = {
|
|
|
10
9
|
resolution: getBoardResolution(),
|
|
11
10
|
roundPixels: true
|
|
12
11
|
};
|
|
13
|
-
function emphasisColor(item, palette) {
|
|
14
|
-
if (item.style?.accentColor) {
|
|
15
|
-
const normalized = parseBoardCssColor(item.style.accentColor);
|
|
16
|
-
if (normalized != null) return normalized;
|
|
17
|
-
}
|
|
18
|
-
switch (item.style?.emphasis) {
|
|
19
|
-
case "rare": return palette.rare;
|
|
20
|
-
case "epic": return palette.epic;
|
|
21
|
-
case "legendary": return palette.legendary;
|
|
22
|
-
default: return palette.brand;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
12
|
function createLabel(text, style) {
|
|
26
13
|
return new Text({
|
|
27
14
|
...TEXT_OPTIONS,
|
|
@@ -29,11 +16,6 @@ function createLabel(text, style) {
|
|
|
29
16
|
style
|
|
30
17
|
});
|
|
31
18
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Shared card chrome: rounded background, selection/hover border, optional
|
|
34
|
-
* footer with title, and a masked content region. Tracks the last rendered
|
|
35
|
-
* state so unchanged attributes are not redrawn.
|
|
36
|
-
*/
|
|
37
19
|
function createCardShell() {
|
|
38
20
|
const root = new Container();
|
|
39
21
|
const background = new Graphics();
|
|
@@ -120,11 +102,6 @@ function createCardShell() {
|
|
|
120
102
|
destroy
|
|
121
103
|
};
|
|
122
104
|
}
|
|
123
|
-
/**
|
|
124
|
-
* Position a shell root at an item frame. The container pivots around its
|
|
125
|
-
* center so that Pixi's rotation matches the geometry model (which treats
|
|
126
|
-
* `frame.rotation` as a rotation about the frame center).
|
|
127
|
-
*/
|
|
128
105
|
function positionShell(root, item) {
|
|
129
106
|
const { x, y, width, height, rotation } = item.frame;
|
|
130
107
|
root.pivot.set(width / 2, height / 2);
|
|
@@ -133,4 +110,4 @@ function positionShell(root, item) {
|
|
|
133
110
|
root.rotation = (rotation || 0) * Math.PI / 180;
|
|
134
111
|
}
|
|
135
112
|
//#endregion
|
|
136
|
-
export { CARD_PADDING, CARD_RADIUS, FOOTER_HEIGHT, createCardShell, createLabel,
|
|
113
|
+
export { CARD_PADDING, CARD_RADIUS, FOOTER_HEIGHT, createCardShell, createLabel, positionShell };
|