@graview/render 0.0.0-stage → 0.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/LICENSE +96 -0
- package/README.md +43 -2
- package/dist/gpu.d.ts +6 -0
- package/dist/gpu.d.ts.map +1 -0
- package/dist/gpu.js +23 -0
- package/dist/gpu.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/interaction/pointer-router.d.ts +94 -0
- package/dist/interaction/pointer-router.d.ts.map +1 -0
- package/dist/interaction/pointer-router.js +148 -0
- package/dist/interaction/pointer-router.js.map +1 -0
- package/dist/platform/html-in-canvas.d.ts +100 -0
- package/dist/platform/html-in-canvas.d.ts.map +1 -0
- package/dist/platform/html-in-canvas.js +172 -0
- package/dist/platform/html-in-canvas.js.map +1 -0
- package/dist/platform/matrix.d.ts +53 -0
- package/dist/platform/matrix.d.ts.map +1 -0
- package/dist/platform/matrix.js +61 -0
- package/dist/platform/matrix.js.map +1 -0
- package/dist/scene/compositor.d.ts +112 -0
- package/dist/scene/compositor.d.ts.map +1 -0
- package/dist/scene/compositor.js +340 -0
- package/dist/scene/compositor.js.map +1 -0
- package/dist/scene/compositor.wgsl.d.ts +15 -0
- package/dist/scene/compositor.wgsl.d.ts.map +1 -0
- package/dist/scene/compositor.wgsl.js +106 -0
- package/dist/scene/compositor.wgsl.js.map +1 -0
- package/dist/scene/connectors.d.ts +60 -0
- package/dist/scene/connectors.d.ts.map +1 -0
- package/dist/scene/connectors.js +95 -0
- package/dist/scene/connectors.js.map +1 -0
- package/dist/scene/frame-plan.d.ts +83 -0
- package/dist/scene/frame-plan.d.ts.map +1 -0
- package/dist/scene/frame-plan.js +119 -0
- package/dist/scene/frame-plan.js.map +1 -0
- package/dist/scene/from-layout.d.ts +14 -0
- package/dist/scene/from-layout.d.ts.map +1 -0
- package/dist/scene/from-layout.js +35 -0
- package/dist/scene/from-layout.js.map +1 -0
- package/dist/scene/plane.d.ts +68 -0
- package/dist/scene/plane.d.ts.map +1 -0
- package/dist/scene/plane.js +94 -0
- package/dist/scene/plane.js.map +1 -0
- package/package.json +64 -3
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Placement } from "../interaction/pointer-router.js";
|
|
2
|
+
import type { Matrix4 } from "../platform/matrix.js";
|
|
3
|
+
import { type ConnectorStyle } from "./connectors.js";
|
|
4
|
+
import { type PlaneStyle } from "./plane.js";
|
|
5
|
+
/** One view drawn into the scene: a DOM subtree, and where it belongs. */
|
|
6
|
+
export interface PlannedView {
|
|
7
|
+
readonly id: string;
|
|
8
|
+
/** 0 focus, 1 relations, 2 context. May be fractional mid-transition. */
|
|
9
|
+
readonly plane: number;
|
|
10
|
+
/** Layout position in canvas pixels, before the plane transform. */
|
|
11
|
+
readonly x: number;
|
|
12
|
+
readonly y: number;
|
|
13
|
+
readonly width: number;
|
|
14
|
+
readonly height: number;
|
|
15
|
+
/** Set when the view's DOM changed and its texture is stale. */
|
|
16
|
+
readonly dirty?: boolean;
|
|
17
|
+
readonly opacity?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface PlannedConnector {
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly kind: string;
|
|
22
|
+
readonly from: string;
|
|
23
|
+
readonly to: string;
|
|
24
|
+
readonly opacity?: number;
|
|
25
|
+
}
|
|
26
|
+
export interface CaptureCommand {
|
|
27
|
+
readonly viewId: string;
|
|
28
|
+
/** Why this frame needed the pixels again — useful when a budget blows. */
|
|
29
|
+
readonly reason: "first" | "live" | "changed";
|
|
30
|
+
}
|
|
31
|
+
export interface ViewDraw {
|
|
32
|
+
readonly viewId: string;
|
|
33
|
+
readonly transform: Matrix4;
|
|
34
|
+
readonly style: PlaneStyle;
|
|
35
|
+
/** Drawn width and height, after the plane's scale. */
|
|
36
|
+
readonly width: number;
|
|
37
|
+
readonly height: number;
|
|
38
|
+
readonly opacity: number;
|
|
39
|
+
}
|
|
40
|
+
export interface ConnectorDraw {
|
|
41
|
+
readonly id: string;
|
|
42
|
+
readonly kind: string;
|
|
43
|
+
readonly style: ConnectorStyle;
|
|
44
|
+
readonly x1: number;
|
|
45
|
+
readonly y1: number;
|
|
46
|
+
readonly x2: number;
|
|
47
|
+
readonly y2: number;
|
|
48
|
+
readonly opacity: number;
|
|
49
|
+
}
|
|
50
|
+
export interface GeometryReport {
|
|
51
|
+
readonly viewId: string;
|
|
52
|
+
readonly transform: Matrix4;
|
|
53
|
+
}
|
|
54
|
+
export interface FramePlan {
|
|
55
|
+
/** Views whose textures need refreshing, in draw order. */
|
|
56
|
+
readonly captures: readonly CaptureCommand[];
|
|
57
|
+
/** Back to front, so the focus plane lands on top. */
|
|
58
|
+
readonly draws: readonly ViewDraw[];
|
|
59
|
+
readonly connectors: readonly ConnectorDraw[];
|
|
60
|
+
/** What to tell the browser about where each view ended up. */
|
|
61
|
+
readonly geometry: readonly GeometryReport[];
|
|
62
|
+
/** What the pointer router needs to route a click. */
|
|
63
|
+
readonly placements: readonly Omit<Placement, "element">[];
|
|
64
|
+
/** Captures this frame. The number the budget is spent on. */
|
|
65
|
+
readonly captureCount: number;
|
|
66
|
+
}
|
|
67
|
+
export interface PlanOptions {
|
|
68
|
+
readonly canvasWidth: number;
|
|
69
|
+
readonly canvasHeight: number;
|
|
70
|
+
/** Frame index of the last capture per view; absent means never captured. */
|
|
71
|
+
readonly capturedAt?: Readonly<Record<string, number>>;
|
|
72
|
+
readonly connectorOverrides?: Readonly<Record<string, Partial<ConnectorStyle>>>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* What a frame consists of, as data — no GPU, no DOM, no browser.
|
|
76
|
+
*
|
|
77
|
+
* Separating the plan from its submission is what lets the fidelity policy,
|
|
78
|
+
* plane ordering and geometry reporting be tested in CI with no GPU present,
|
|
79
|
+
* while the executor that turns a plan into draw calls stays thin enough to
|
|
80
|
+
* verify in a real browser once.
|
|
81
|
+
*/
|
|
82
|
+
export declare function planFrame(views: readonly PlannedView[], connectors: readonly PlannedConnector[], options: PlanOptions): FramePlan;
|
|
83
|
+
//# sourceMappingURL=frame-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-plan.d.ts","sourceRoot":"","sources":["../../src/scene/frame-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { connectorStyle } from "./connectors.js";
|
|
2
|
+
import { mixStyles, styleFor, transformFor } from "./plane.js";
|
|
3
|
+
/**
|
|
4
|
+
* What a frame consists of, as data — no GPU, no DOM, no browser.
|
|
5
|
+
*
|
|
6
|
+
* Separating the plan from its submission is what lets the fidelity policy,
|
|
7
|
+
* plane ordering and geometry reporting be tested in CI with no GPU present,
|
|
8
|
+
* while the executor that turns a plan into draw calls stays thin enough to
|
|
9
|
+
* verify in a real browser once.
|
|
10
|
+
*/
|
|
11
|
+
export function planFrame(views, connectors, options) {
|
|
12
|
+
const capturedAt = options.capturedAt ?? {};
|
|
13
|
+
const captures = [];
|
|
14
|
+
const draws = [];
|
|
15
|
+
const geometry = [];
|
|
16
|
+
const placements = [];
|
|
17
|
+
const centres = new Map();
|
|
18
|
+
// Back to front: the deepest plane is drawn first so the focus plane lands
|
|
19
|
+
// on top of it. Sorting explicitly means callers may hand views over in any
|
|
20
|
+
// order without changing what the scene looks like.
|
|
21
|
+
const ordered = [...views].sort((a, b) => b.plane - a.plane);
|
|
22
|
+
for (const view of ordered) {
|
|
23
|
+
const style = styleAt(view.plane);
|
|
24
|
+
const reason = captureReason(view, style, capturedAt[view.id]);
|
|
25
|
+
if (reason)
|
|
26
|
+
captures.push({ viewId: view.id, reason });
|
|
27
|
+
const transform = transformFor(style, view.x, view.y, options.canvasWidth, options.canvasHeight);
|
|
28
|
+
const width = view.width * style.scale;
|
|
29
|
+
const height = view.height * style.scale;
|
|
30
|
+
draws.push({
|
|
31
|
+
viewId: view.id,
|
|
32
|
+
transform,
|
|
33
|
+
style,
|
|
34
|
+
width,
|
|
35
|
+
height,
|
|
36
|
+
opacity: view.opacity ?? 1,
|
|
37
|
+
});
|
|
38
|
+
geometry.push({ viewId: view.id, transform });
|
|
39
|
+
placements.push({
|
|
40
|
+
transform,
|
|
41
|
+
width: view.width,
|
|
42
|
+
height: view.height,
|
|
43
|
+
depth: view.plane,
|
|
44
|
+
});
|
|
45
|
+
centres.set(view.id, {
|
|
46
|
+
x: transform[12] + width / 2,
|
|
47
|
+
y: transform[13] + height / 2,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const connectorDraws = [];
|
|
51
|
+
for (const connector of connectors) {
|
|
52
|
+
const from = centres.get(connector.from);
|
|
53
|
+
const to = centres.get(connector.to);
|
|
54
|
+
// A connector to something off-scene is a line into nowhere.
|
|
55
|
+
if (!from || !to)
|
|
56
|
+
continue;
|
|
57
|
+
connectorDraws.push({
|
|
58
|
+
id: connector.id,
|
|
59
|
+
kind: connector.kind,
|
|
60
|
+
style: connectorStyle(connector.kind, options.connectorOverrides ?? {}),
|
|
61
|
+
x1: from.x,
|
|
62
|
+
y1: from.y,
|
|
63
|
+
x2: to.x,
|
|
64
|
+
y2: to.y,
|
|
65
|
+
opacity: connector.opacity ?? 1,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
captures,
|
|
70
|
+
draws,
|
|
71
|
+
connectors: connectorDraws,
|
|
72
|
+
geometry,
|
|
73
|
+
placements,
|
|
74
|
+
captureCount: captures.length,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The treatment for a possibly-fractional plane. Mid-transition a view is
|
|
79
|
+
* between two planes, and mixing their treatments is what makes the move read
|
|
80
|
+
* as travel rather than a cut.
|
|
81
|
+
*/
|
|
82
|
+
function styleAt(plane) {
|
|
83
|
+
const lower = Math.floor(plane);
|
|
84
|
+
const upper = Math.ceil(plane);
|
|
85
|
+
if (lower === upper)
|
|
86
|
+
return styleFor(plane);
|
|
87
|
+
return mixStyles(styleFor(lower), styleFor(upper), plane - lower);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Whether a view needs recapturing, and why. Fidelity decides, not plane
|
|
91
|
+
* index — and the split is load-bearing rather than an optimisation:
|
|
92
|
+
* capture costs ~0.016 ms per node up to about 128 live captures a frame and
|
|
93
|
+
* then falls off a cliff (see docs/platform-findings.md).
|
|
94
|
+
*
|
|
95
|
+
* - `full` live: captured every frame, because it is being edited
|
|
96
|
+
* - `summary` cached: captured only when its DOM actually changed
|
|
97
|
+
* - `glyph` captured once, then only when its content actually changed —
|
|
98
|
+
* at glyph scale a cached texture is indistinguishable from a
|
|
99
|
+
* live one, but a stale one shows last week's number for ever
|
|
100
|
+
*/
|
|
101
|
+
function captureReason(view, style, lastCapture) {
|
|
102
|
+
if (lastCapture === undefined)
|
|
103
|
+
return "first";
|
|
104
|
+
// Mid-transition a view's own DOM is still fading, so whatever was captured
|
|
105
|
+
// is not what it looks like. Caching that leaves an entering node stuck as
|
|
106
|
+
// the transparent frame it was first seen in — which is precisely what
|
|
107
|
+
// happened to every person raised onto plane 1.
|
|
108
|
+
if (view.opacity !== undefined && view.opacity < 1)
|
|
109
|
+
return "changed";
|
|
110
|
+
switch (style.fidelity) {
|
|
111
|
+
case "full":
|
|
112
|
+
return "live";
|
|
113
|
+
case "summary":
|
|
114
|
+
return view.dirty ? "changed" : null;
|
|
115
|
+
case "glyph":
|
|
116
|
+
return view.dirty ? "changed" : null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=frame-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-plan.js","sourceRoot":"","sources":["../../src/scene/frame-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { InterpolatedLayout, Layout } from "@graview/layout";
|
|
2
|
+
import type { PlannedConnector, PlannedView } from "./frame-plan.js";
|
|
3
|
+
/**
|
|
4
|
+
* Turns what layout emitted into what the renderer draws.
|
|
5
|
+
*
|
|
6
|
+
* Deliberately trivial: layout decides positions and planes, the renderer
|
|
7
|
+
* decides pixels, and this is the whole conversation between them. If this
|
|
8
|
+
* function ever starts making decisions, the two have begun to overlap.
|
|
9
|
+
*/
|
|
10
|
+
export declare function fromLayout(result: Layout | InterpolatedLayout, dirty?: ReadonlySet<string>): {
|
|
11
|
+
views: PlannedView[];
|
|
12
|
+
connectors: PlannedConnector[];
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=from-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-layout.d.ts","sourceRoot":"","sources":["../../src/scene/from-layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAErE;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,GAAG,kBAAkB,EACnC,KAAK,GAAE,WAAW,CAAC,MAAM,CAAa,GACrC;IAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IAAC,UAAU,EAAE,gBAAgB,EAAE,CAAA;CAAE,CA4B1D"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turns what layout emitted into what the renderer draws.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately trivial: layout decides positions and planes, the renderer
|
|
5
|
+
* decides pixels, and this is the whole conversation between them. If this
|
|
6
|
+
* function ever starts making decisions, the two have begun to overlap.
|
|
7
|
+
*/
|
|
8
|
+
export function fromLayout(result, dirty = new Set()) {
|
|
9
|
+
// Planes may be fractional mid-transition; the frame plan mixes the two
|
|
10
|
+
// plane styles rather than snapping, so this passes them straight through.
|
|
11
|
+
const views = result.nodes.map((node) => ({
|
|
12
|
+
id: node.id,
|
|
13
|
+
plane: node.plane,
|
|
14
|
+
x: node.x,
|
|
15
|
+
y: node.y,
|
|
16
|
+
// Whole-pixel boxes. A fractional size reallocates the texture on every
|
|
17
|
+
// frame of a transition and desynchronises it from the element the
|
|
18
|
+
// browser actually rasterises.
|
|
19
|
+
width: Math.round(node.width),
|
|
20
|
+
height: Math.round(node.height),
|
|
21
|
+
// Mid-fade counts as dirty: the pixels on screen are not the pixels this
|
|
22
|
+
// view will settle at.
|
|
23
|
+
dirty: dirty.has(node.id) || ("opacity" in node && node.opacity < 1),
|
|
24
|
+
opacity: "opacity" in node ? node.opacity : 1,
|
|
25
|
+
}));
|
|
26
|
+
const connectors = result.connectors.map((connector) => ({
|
|
27
|
+
id: connector.id,
|
|
28
|
+
kind: connector.kind,
|
|
29
|
+
from: connector.from,
|
|
30
|
+
to: connector.to,
|
|
31
|
+
opacity: "opacity" in connector ? connector.opacity : 1,
|
|
32
|
+
}));
|
|
33
|
+
return { views, connectors };
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=from-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-layout.js","sourceRoot":"","sources":["../../src/scene/from-layout.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,MAAmC,EACnC,QAA6B,IAAI,GAAG,EAAE;IAEtC,wEAAwE;IACxE,2EAA2E;IAC3E,MAAM,KAAK,GAAkB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvD,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,wEAAwE;QACxE,mEAAmE;QACnE,+BAA+B;QAC/B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QAC7B,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;QAC/B,yEAAyE;QACzE,uBAAuB;QACvB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACpE,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;KAC9C,CAAC,CAAC,CAAC;IAEJ,MAAM,UAAU,GAAuB,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAC3E,EAAE,EAAE,SAAS,CAAC,EAAE;QAChB,IAAI,EAAE,SAAS,CAAC,IAAI;QACpB,IAAI,EAAE,SAAS,CAAC,IAAI;QACpB,EAAE,EAAE,SAAS,CAAC,EAAE;QAChB,OAAO,EAAE,SAAS,IAAI,SAAS,CAAC,CAAC,CAAE,SAAiC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;KACjF,CAAC,CAAC,CAAC;IAEJ,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type Matrix4 } from "../platform/matrix.js";
|
|
2
|
+
/**
|
|
3
|
+
* Discrete z-planes with the camera locked to one axis. No free orbit: every
|
|
4
|
+
* view is nameable and returnable, which is what makes each stop a URL.
|
|
5
|
+
*/
|
|
6
|
+
export declare const PLANES: {
|
|
7
|
+
/** Live, editable DOM. Captured every frame it moves. */
|
|
8
|
+
readonly focus: 0;
|
|
9
|
+
/** The entity type you asked to see, with connectors. */
|
|
10
|
+
readonly relations: 1;
|
|
11
|
+
/** Everything else, as aggregate blocks. */
|
|
12
|
+
readonly context: 2;
|
|
13
|
+
};
|
|
14
|
+
export type PlaneIndex = 0 | 1 | 2;
|
|
15
|
+
/**
|
|
16
|
+
* Atmospheric depth, expressed as numbers a shader can use.
|
|
17
|
+
*
|
|
18
|
+
* Every value here is affine or per-plane uniform — nothing per-element and
|
|
19
|
+
* nothing perspective — so the visual language survives whichever way the
|
|
20
|
+
* platform settles the perspective question. Blur and contrast falloff are
|
|
21
|
+
* near-free in a shader and expensive in CSS, which is what justifies the GPU
|
|
22
|
+
* pipeline at all.
|
|
23
|
+
*/
|
|
24
|
+
export interface PlaneStyle {
|
|
25
|
+
/** Uniform scale. Recession, without foreshortening. */
|
|
26
|
+
readonly scale: number;
|
|
27
|
+
/** Gaussian radius in texels. */
|
|
28
|
+
readonly blur: number;
|
|
29
|
+
/** 0 = full contrast, 1 = fully dissolved into the ground colour. */
|
|
30
|
+
readonly falloff: number;
|
|
31
|
+
/** Drop-shadow opacity separating this plane from the one behind it. */
|
|
32
|
+
readonly shadow: number;
|
|
33
|
+
/** Fidelity the plane asks its views for. */
|
|
34
|
+
readonly fidelity: "full" | "summary" | "glyph";
|
|
35
|
+
}
|
|
36
|
+
export type Scheme = "light" | "dark";
|
|
37
|
+
/**
|
|
38
|
+
* Daylight recession.
|
|
39
|
+
*
|
|
40
|
+
* Not the dark numbers inverted. In daylight a distant thing loses CONTRAST
|
|
41
|
+
* and gains haze; it does not lose light, and it does not blur much — the eye
|
|
42
|
+
* reads distance from washed-out colour and a softer cast shadow. Reusing the
|
|
43
|
+
* dark blur here made receded planes look out of focus rather than far away.
|
|
44
|
+
*/
|
|
45
|
+
export declare const LIGHT_PLANE_STYLES: Readonly<Record<PlaneIndex, PlaneStyle>>;
|
|
46
|
+
export declare const PLANE_STYLES: Readonly<Record<PlaneIndex, PlaneStyle>>;
|
|
47
|
+
export declare function styleFor(plane: number, scheme?: Scheme): PlaneStyle;
|
|
48
|
+
/**
|
|
49
|
+
* Interpolates between two plane styles. Every transition is animatable
|
|
50
|
+
* because both endpoints are the same small bag of numbers — the same reason
|
|
51
|
+
* any two layout states interpolate.
|
|
52
|
+
*/
|
|
53
|
+
export declare function mixStyles(a: PlaneStyle, b: PlaneStyle, t: number): PlaneStyle;
|
|
54
|
+
/**
|
|
55
|
+
* The transform a view at `plane` gets, given where layout put it.
|
|
56
|
+
*
|
|
57
|
+
* Position is layout's, untouched. The plane contributes only treatment —
|
|
58
|
+
* scale, and through the shader blur, falloff and shadow.
|
|
59
|
+
*
|
|
60
|
+
* An earlier version scaled positions about the canvas centre as well, so a
|
|
61
|
+
* receded plane pulled inward. It looked plausible and was wrong: layout no
|
|
62
|
+
* longer knew where anything would end up, so connectors drawn from layout
|
|
63
|
+
* coordinates missed the views they connected. One owner per concern —
|
|
64
|
+
* layout owns position, the plane owns treatment — is what keeps the two
|
|
65
|
+
* halves of the picture agreeing.
|
|
66
|
+
*/
|
|
67
|
+
export declare function transformFor(style: PlaneStyle, x: number, y: number, _canvasWidth?: number, _canvasHeight?: number): Matrix4;
|
|
68
|
+
//# sourceMappingURL=plane.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plane.d.ts","sourceRoot":"","sources":["../../src/scene/plane.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErE;;;GAGG;AACH,eAAO,MAAM,MAAM;IACjB,yDAAyD;;IAEzD,yDAAyD;;IAEzD,4CAA4C;;CAEpC,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEnC;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iCAAiC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,wEAAwE;IACxE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;CACjD;AAED,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEtC;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,CAmBvE,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,CAejE,CAAC;AAEF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,MAAe,GAAG,UAAU,CAG3E;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,CAU7E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,UAAU,EACjB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,YAAY,CAAC,EAAE,MAAM,EACrB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAET"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { planeTransform } from "../platform/matrix.js";
|
|
2
|
+
/**
|
|
3
|
+
* Discrete z-planes with the camera locked to one axis. No free orbit: every
|
|
4
|
+
* view is nameable and returnable, which is what makes each stop a URL.
|
|
5
|
+
*/
|
|
6
|
+
export const PLANES = {
|
|
7
|
+
/** Live, editable DOM. Captured every frame it moves. */
|
|
8
|
+
focus: 0,
|
|
9
|
+
/** The entity type you asked to see, with connectors. */
|
|
10
|
+
relations: 1,
|
|
11
|
+
/** Everything else, as aggregate blocks. */
|
|
12
|
+
context: 2,
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Daylight recession.
|
|
16
|
+
*
|
|
17
|
+
* Not the dark numbers inverted. In daylight a distant thing loses CONTRAST
|
|
18
|
+
* and gains haze; it does not lose light, and it does not blur much — the eye
|
|
19
|
+
* reads distance from washed-out colour and a softer cast shadow. Reusing the
|
|
20
|
+
* dark blur here made receded planes look out of focus rather than far away.
|
|
21
|
+
*/
|
|
22
|
+
export const LIGHT_PLANE_STYLES = {
|
|
23
|
+
0: { scale: 1, blur: 0, falloff: 0, shadow: 0.16, fidelity: "full" },
|
|
24
|
+
1: { scale: 0.95, blur: 0.3, falloff: 0.26, shadow: 0.12, fidelity: "summary" },
|
|
25
|
+
/*
|
|
26
|
+
* Depth comes from BLUR AND FALLOFF, not from shrinking.
|
|
27
|
+
*
|
|
28
|
+
* Pushing the scale to 0.6 did separate the planes and made the strip
|
|
29
|
+
* illegible — ten cards reading "P…", "REA…", "S…". A map you cannot read
|
|
30
|
+
* is not a map. The recession is carried by the atmosphere instead.
|
|
31
|
+
*
|
|
32
|
+
* 0.78 was still shrinking, and still too much: the layout allots each
|
|
33
|
+
* district a slot and the renderer drew it at 78% of it, so a name set at
|
|
34
|
+
* thirteen pixels reached the screen at ten and its kind at under eight.
|
|
35
|
+
* That is under every floor this project holds a control to, and it is a
|
|
36
|
+
* floor the reader's own text size could not lift either — the shrink
|
|
37
|
+
* came after it. The planes keep a shrink small enough to read as depth
|
|
38
|
+
* and no longer small enough to cost a word its legibility.
|
|
39
|
+
*/
|
|
40
|
+
2: { scale: 0.9, blur: 0.3, falloff: 0.34, shadow: 0.07, fidelity: "glyph" },
|
|
41
|
+
};
|
|
42
|
+
export const PLANE_STYLES = {
|
|
43
|
+
// The focus plane is unfiltered on purpose: everything else is judged
|
|
44
|
+
// against it, so it has to be the one true reading of the data.
|
|
45
|
+
0: { scale: 1, blur: 0, falloff: 0, shadow: 0.34, fidelity: "full" },
|
|
46
|
+
// Plane 1 recedes but stays READABLE — its job is to be looked at next,
|
|
47
|
+
// not to be atmosphere. Enough separation to read as further away, little
|
|
48
|
+
// enough that a summary view can still be read.
|
|
49
|
+
1: { scale: 0.95, blur: 0.45, falloff: 0.18, shadow: 0.24, fidelity: "summary" },
|
|
50
|
+
// Plane 2 is context, not content. It should register as presence and
|
|
51
|
+
// count, and reward a glance rather than a read.
|
|
52
|
+
//
|
|
53
|
+
// Blurrier than plane 1, necessarily: recession has to be monotonic or the
|
|
54
|
+
// depth cue inverts and the furthest plane reads as the nearest. This was
|
|
55
|
+
// briefly 0.6 against plane 1's 0.7, which `frame-plan.test.ts` caught.
|
|
56
|
+
2: { scale: 0.9, blur: 0.45, falloff: 0.26, shadow: 0.14, fidelity: "glyph" },
|
|
57
|
+
};
|
|
58
|
+
export function styleFor(plane, scheme = "dark") {
|
|
59
|
+
const clamped = Math.max(0, Math.min(2, Math.round(plane)));
|
|
60
|
+
return (scheme === "light" ? LIGHT_PLANE_STYLES : PLANE_STYLES)[clamped];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Interpolates between two plane styles. Every transition is animatable
|
|
64
|
+
* because both endpoints are the same small bag of numbers — the same reason
|
|
65
|
+
* any two layout states interpolate.
|
|
66
|
+
*/
|
|
67
|
+
export function mixStyles(a, b, t) {
|
|
68
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
69
|
+
const lerp = (x, y) => x + (y - x) * clamped;
|
|
70
|
+
return {
|
|
71
|
+
scale: lerp(a.scale, b.scale),
|
|
72
|
+
blur: lerp(a.blur, b.blur),
|
|
73
|
+
falloff: lerp(a.falloff, b.falloff),
|
|
74
|
+
shadow: lerp(a.shadow, b.shadow),
|
|
75
|
+
fidelity: clamped < 0.5 ? a.fidelity : b.fidelity,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The transform a view at `plane` gets, given where layout put it.
|
|
80
|
+
*
|
|
81
|
+
* Position is layout's, untouched. The plane contributes only treatment —
|
|
82
|
+
* scale, and through the shader blur, falloff and shadow.
|
|
83
|
+
*
|
|
84
|
+
* An earlier version scaled positions about the canvas centre as well, so a
|
|
85
|
+
* receded plane pulled inward. It looked plausible and was wrong: layout no
|
|
86
|
+
* longer knew where anything would end up, so connectors drawn from layout
|
|
87
|
+
* coordinates missed the views they connected. One owner per concern —
|
|
88
|
+
* layout owns position, the plane owns treatment — is what keeps the two
|
|
89
|
+
* halves of the picture agreeing.
|
|
90
|
+
*/
|
|
91
|
+
export function transformFor(style, x, y, _canvasWidth, _canvasHeight) {
|
|
92
|
+
return planeTransform(style.scale, x, y);
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=plane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plane.js","sourceRoot":"","sources":["../../src/scene/plane.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,67 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graview/render",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"./gpu": {
|
|
13
|
+
"types": "./dist/gpu.d.ts",
|
|
14
|
+
"default": "./dist/gpu.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@graview/core": "0.1.0",
|
|
19
|
+
"@graview/layout": "0.1.0"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"@webgpu/types": "^0.1.60"
|
|
23
|
+
},
|
|
24
|
+
"peerDependenciesMeta": {
|
|
25
|
+
"@webgpu/types": {
|
|
26
|
+
"optional": true
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"zod": "^4.4.3"
|
|
31
|
+
},
|
|
32
|
+
"description": "The spatial renderer. The DOM path is what ships; the GPU capture path is EXPERIMENTAL — see README.",
|
|
33
|
+
"keywords": [
|
|
34
|
+
"graview",
|
|
35
|
+
"context-graph",
|
|
36
|
+
"typed-graph",
|
|
37
|
+
"interface",
|
|
38
|
+
"declarative",
|
|
39
|
+
"renderer",
|
|
40
|
+
"canvas",
|
|
41
|
+
"webgpu"
|
|
42
|
+
],
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"README.md"
|
|
46
|
+
],
|
|
47
|
+
"sideEffects": false,
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/en-dash-consulting/graview.git",
|
|
51
|
+
"directory": "packages/render"
|
|
52
|
+
},
|
|
53
|
+
"publishConfig": {
|
|
54
|
+
"access": "public"
|
|
55
|
+
},
|
|
56
|
+
"license": "Elastic-2.0",
|
|
57
|
+
"homepage": "https://graview.dev/docs/packages/render.html",
|
|
58
|
+
"bugs": {
|
|
59
|
+
"url": "https://github.com/en-dash-consulting/graview/issues"
|
|
60
|
+
},
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=22"
|
|
63
|
+
},
|
|
64
|
+
"scripts": {
|
|
65
|
+
"build": "tsc -b"
|
|
66
|
+
}
|
|
6
67
|
}
|