@edv4h/usketch-css3d-renderer 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 +21 -0
- package/README.md +131 -2
- package/dist/css3d-css.d.ts +94 -0
- package/dist/css3d-css.d.ts.map +1 -0
- package/dist/css3d-css.js +136 -0
- package/dist/css3d-css.js.map +1 -0
- package/dist/css3d-renderer.d.ts +85 -0
- package/dist/css3d-renderer.d.ts.map +1 -0
- package/dist/css3d-renderer.js +461 -0
- package/dist/css3d-renderer.js.map +1 -0
- package/dist/css3d-shapes.d.ts +23 -0
- package/dist/css3d-shapes.d.ts.map +1 -0
- package/dist/css3d-shapes.js +110 -0
- package/dist/css3d-shapes.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/shapes-layer.d.ts +53 -0
- package/dist/shapes-layer.d.ts.map +1 -0
- package/dist/shapes-layer.js +198 -0
- package/dist/shapes-layer.js.map +1 -0
- package/dist/shapes-layout.d.ts +163 -0
- package/dist/shapes-layout.d.ts.map +1 -0
- package/dist/shapes-layout.js +277 -0
- package/dist/shapes-layout.js.map +1 -0
- package/package.json +50 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,kBAAkB,EAGlB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,EAEtB,cAAc,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,iBAAiB,EAIjB,cAAc,EACd,yBAAyB,EACzB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,kBAAkB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGN,uBAAuB,EACvB,wBAAwB,EACxB,gBAAgB,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAGN,gBAAgB,EAEhB,oBAAoB,EAEpB,iBAAiB,EACjB,UAAU,GACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAGN,eAAe,EACf,QAAQ,EAGR,0BAA0B,EAC1B,kBAAkB,EAClB,SAAS,EACT,OAAO,EACP,UAAU,EACV,aAAa,EACb,aAAa,EACb,cAAc,EAGd,YAAY,EACZ,cAAc,EACd,WAAW,EACX,WAAW,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,GACT,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type LayerRenderContext, type ShapeData, type ShapeRegistry, type ShapeView3d, type View3dCamera, type View3dOcclusionApi, type View3dTracker } from "@edv4h/usketch-shared";
|
|
2
|
+
import { type Css3dShapeLimits, type Css3dShapeTypes } from "./shapes-layout.js";
|
|
3
|
+
/** The layer's id (the shape-3d plugin's, so a 3D view's layer lists keep naming it). */
|
|
4
|
+
export declare const SHAPE_3D_LAYER_ID = "shape-3d";
|
|
5
|
+
export interface Css3dShapesLayerProps {
|
|
6
|
+
rc: LayerRenderContext;
|
|
7
|
+
shapes: ShapeRegistry;
|
|
8
|
+
tracker: View3dTracker;
|
|
9
|
+
types: Css3dShapeTypes;
|
|
10
|
+
limits: Css3dShapeLimits;
|
|
11
|
+
/** Screen px the 3D view shows past the board box. */
|
|
12
|
+
overscanPx: number;
|
|
13
|
+
/** Ground height at a world point (world units). */
|
|
14
|
+
heightAt: (x: number, y: number) => number;
|
|
15
|
+
/** Told which shapes this layer draws after each render (the DOM layer hides them). */
|
|
16
|
+
onDrawn: (ids: ReadonlySet<string>) => void;
|
|
17
|
+
/** The 3D view's camera, for a type's own `render3d`. */
|
|
18
|
+
camera?: Css3dCameraSource;
|
|
19
|
+
/** What the ground hides: a shape whose top is hidden fades (or isn't drawn). */
|
|
20
|
+
occlusion?: View3dOcclusionApi | null;
|
|
21
|
+
/** Changes to what the ground hides (a counter), to re-render on. */
|
|
22
|
+
occlusionChanges?: Css3dChangeSource;
|
|
23
|
+
}
|
|
24
|
+
/** A counter that moves on every change of something, and its notifications. */
|
|
25
|
+
export interface Css3dChangeSource {
|
|
26
|
+
get(): number;
|
|
27
|
+
subscribe(listener: () => void): () => void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Answers for "is this shape behind the ground", spread over frames: a follow camera
|
|
31
|
+
* re-renders the layer every frame, and asking for every shape each time costs too much
|
|
32
|
+
* (each answer walks the ground along the line of sight). An answer is reused for
|
|
33
|
+
* `maxAgeMs`, and at most `budget` are asked per frame (the stalest first come due as
|
|
34
|
+
* they age); a shape not asked yet counts as in view.
|
|
35
|
+
*/
|
|
36
|
+
export interface OcclusionCache {
|
|
37
|
+
/** Start a frame at `now` (ms): the budget refills. */
|
|
38
|
+
frame(now: number): void;
|
|
39
|
+
/** The answer for `id` at this place, asking `ask` when due and within the budget. */
|
|
40
|
+
get(id: string, key: string, ask: () => boolean): boolean;
|
|
41
|
+
/** Forget everything (the setting or the provider changed). */
|
|
42
|
+
clear(): void;
|
|
43
|
+
}
|
|
44
|
+
export declare function createOcclusionCache(maxAgeMs?: number, budget?: number): OcclusionCache;
|
|
45
|
+
/** How high a shape's top is above its ground (world units) in its 3D mode. Pure. */
|
|
46
|
+
export declare function shapeTop3d(shape: ShapeData, params: ShapeView3d): number;
|
|
47
|
+
/** The drawn camera and its change notifications (see `ShapeView3dRenderContext`). */
|
|
48
|
+
export interface Css3dCameraSource {
|
|
49
|
+
get(): View3dCamera | null;
|
|
50
|
+
subscribe(listener: () => void): () => void;
|
|
51
|
+
}
|
|
52
|
+
export declare function Css3dShapesLayer({ rc, shapes, tracker, types, limits, overscanPx, heightAt, onDrawn, camera, occlusion, occlusionChanges, }: Css3dShapesLayerProps): import("react").JSX.Element | null;
|
|
53
|
+
//# sourceMappingURL=shapes-layer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shapes-layer.d.ts","sourceRoot":"","sources":["../src/shapes-layer.tsx"],"names":[],"mappings":"AAKA,OAAO,EACN,KAAK,kBAAkB,EAEvB,KAAK,SAAS,EAEd,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAElB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAGN,KAAK,gBAAgB,EACrB,KAAK,eAAe,EAYpB,MAAM,oBAAoB,CAAC;AAE5B,yFAAyF;AACzF,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAiC5C,MAAM,WAAW,qBAAqB;IACrC,EAAE,EAAE,kBAAkB,CAAC;IACvB,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,eAAe,CAAC;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3C,uFAAuF;IACvF,OAAO,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IAC5C,yDAAyD;IACzD,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,iFAAiF;IACjF,SAAS,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACtC,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;CACrC;AAED,gFAAgF;AAChF,MAAM,WAAW,iBAAiB;IACjC,GAAG,IAAI,MAAM,CAAC;IACd,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CAC5C;AAID;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC9B,uDAAuD;IACvD,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,sFAAsF;IACtF,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC;IAC1D,+DAA+D;IAC/D,KAAK,IAAI,IAAI,CAAC;CACd;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,SAAM,EAAE,MAAM,SAAK,GAAG,cAAc,CAsBhF;AAED,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAExE;AAED,sFAAsF;AACtF,MAAM,WAAW,iBAAiB;IACjC,GAAG,IAAI,YAAY,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CAC5C;AAID,wBAAgB,gBAAgB,CAAC,EAChC,EAAE,EACF,MAAM,EACN,OAAO,EACP,KAAK,EACL,MAAM,EACN,UAAU,EACV,QAAQ,EACR,OAAO,EACP,MAAkB,EAClB,SAAgB,EAChB,gBAA6B,GAC7B,EAAE,qBAAqB,sCAwKvB"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// The 3D shape layer: draws the shapes that rise out of the ground while the board is
|
|
3
|
+
// shown in 3D. It is a depth layer, so the `translateZ` / `rotateX` below rise out of the
|
|
4
|
+
// tilted ground instead of being flattened onto it. The DOM shape layer skips the same
|
|
5
|
+
// shapes meanwhile (they are claimed through the board's shape claims).
|
|
6
|
+
import { ShapeContent } from "@edv4h/usketch-dom-renderer";
|
|
7
|
+
import { occludedStyle, } from "@edv4h/usketch-shared";
|
|
8
|
+
import { memo, useEffect, useRef, useSyncExternalStore } from "react";
|
|
9
|
+
import { boxTopTransform, boxWalls, poseBox, poseOrigin, poseTransform, render3dFrame, selectShapes3d, shadowStyle, shapeAnchor, shapePose, wallColor, wallShade, } from "./shapes-layout.js";
|
|
10
|
+
/** The layer's id (the shape-3d plugin's, so a 3D view's layer lists keep naming it). */
|
|
11
|
+
export const SHAPE_3D_LAYER_ID = "shape-3d";
|
|
12
|
+
/**
|
|
13
|
+
* The shape's own drawing at its world size, scaled to the node's px box (re-rendered
|
|
14
|
+
* only when the shape or the zoom changes, not as the camera moves). No opacity here:
|
|
15
|
+
* the renderers apply `style.opacity` themselves, as on the flat DOM layer.
|
|
16
|
+
*/
|
|
17
|
+
const StandContent = memo(function StandContent({ shape, def, zoom, }) {
|
|
18
|
+
return (_jsx("div", { style: {
|
|
19
|
+
position: "absolute",
|
|
20
|
+
left: 0,
|
|
21
|
+
top: 0,
|
|
22
|
+
width: shape.width,
|
|
23
|
+
height: shape.height,
|
|
24
|
+
transform: `scale(${zoom})`,
|
|
25
|
+
transformOrigin: "0 0",
|
|
26
|
+
}, children: _jsx(ShapeContent, { shape: shape, def: def }) }));
|
|
27
|
+
});
|
|
28
|
+
const NO_CHANGES = { get: () => 0, subscribe: () => () => { } };
|
|
29
|
+
export function createOcclusionCache(maxAgeMs = 100, budget = 40) {
|
|
30
|
+
const answers = new Map();
|
|
31
|
+
let now = 0;
|
|
32
|
+
let left = budget;
|
|
33
|
+
return {
|
|
34
|
+
frame(t) {
|
|
35
|
+
now = t;
|
|
36
|
+
left = budget;
|
|
37
|
+
},
|
|
38
|
+
get(id, key, ask) {
|
|
39
|
+
const old = answers.get(id);
|
|
40
|
+
const fresh = old && old.key === key && now - old.at < maxAgeMs;
|
|
41
|
+
if (fresh || left <= 0)
|
|
42
|
+
return old?.hidden ?? false;
|
|
43
|
+
left--;
|
|
44
|
+
const hidden = ask();
|
|
45
|
+
answers.set(id, { key, hidden, at: now });
|
|
46
|
+
return hidden;
|
|
47
|
+
},
|
|
48
|
+
clear() {
|
|
49
|
+
answers.clear();
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** How high a shape's top is above its ground (world units) in its 3D mode. Pure. */
|
|
54
|
+
export function shapeTop3d(shape, params) {
|
|
55
|
+
return params.mode === "stand" ? shape.height : params.height;
|
|
56
|
+
}
|
|
57
|
+
const NO_CAMERA = { get: () => null, subscribe: () => () => { } };
|
|
58
|
+
export function Css3dShapesLayer({ rc, shapes, tracker, types, limits, overscanPx, heightAt, onDrawn, camera = NO_CAMERA, occlusion = null, occlusionChanges = NO_CHANGES, }) {
|
|
59
|
+
const view = useSyncExternalStore(tracker.subscribe, tracker.get, tracker.get);
|
|
60
|
+
// Re-render when what the ground hides may change without the viewport moving.
|
|
61
|
+
useSyncExternalStore(occlusionChanges.subscribe, occlusionChanges.get, occlusionChanges.get);
|
|
62
|
+
const cacheRef = useRef(null);
|
|
63
|
+
const look = occlusion?.look() ?? "fade";
|
|
64
|
+
if (!cacheRef.current || cacheRef.current.look !== look || cacheRef.current.api !== occlusion) {
|
|
65
|
+
cacheRef.current = { cache: createOcclusionCache(), look, api: occlusion };
|
|
66
|
+
}
|
|
67
|
+
const occlusionCache = cacheRef.current.cache;
|
|
68
|
+
occlusionCache.frame(typeof performance !== "undefined" ? performance.now() : Date.now());
|
|
69
|
+
const entries = selectShapes3d({
|
|
70
|
+
shapes: rc.shapesSorted,
|
|
71
|
+
types,
|
|
72
|
+
viewport: rc.viewport,
|
|
73
|
+
viewportBounds: rc.viewportBounds,
|
|
74
|
+
overscanPx,
|
|
75
|
+
renderMode: rc.renderMode,
|
|
76
|
+
amount: view.amount,
|
|
77
|
+
limits,
|
|
78
|
+
heightAt,
|
|
79
|
+
});
|
|
80
|
+
const drawn = [];
|
|
81
|
+
for (const entry of entries) {
|
|
82
|
+
const def = shapes.get(entry.shape.type);
|
|
83
|
+
if (def)
|
|
84
|
+
drawn.push({ entry, def });
|
|
85
|
+
}
|
|
86
|
+
const ids = drawn.map((d) => d.entry.shape.id).join("\n");
|
|
87
|
+
// After the paint: the DOM layer hides exactly what is drawn here (only re-sent when
|
|
88
|
+
// the set changes; the receiver also ignores an unchanged set).
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
onDrawn(new Set(ids ? ids.split("\n") : []));
|
|
91
|
+
}, [ids, onDrawn]);
|
|
92
|
+
// Unmounted (the layer replaced or removed): nothing is drawn here any more.
|
|
93
|
+
useEffect(() => () => onDrawn(new Set()), [onDrawn]);
|
|
94
|
+
if (drawn.length === 0)
|
|
95
|
+
return null;
|
|
96
|
+
return (_jsx("div", { "data-shape-3d-layer": "", style: {
|
|
97
|
+
position: "absolute",
|
|
98
|
+
inset: 0,
|
|
99
|
+
pointerEvents: "none",
|
|
100
|
+
transformStyle: "preserve-3d",
|
|
101
|
+
}, children: drawn.map(({ entry, def }) => {
|
|
102
|
+
const { shape, params } = entry;
|
|
103
|
+
const anchor = shapeAnchor(shape, params.mode);
|
|
104
|
+
const where = {
|
|
105
|
+
viewport: rc.viewport,
|
|
106
|
+
amount: view.amount,
|
|
107
|
+
yaw: view.yaw,
|
|
108
|
+
groundHeight: params.ground ? heightAt(anchor.x, anchor.y) : 0,
|
|
109
|
+
};
|
|
110
|
+
const custom = renderCustom(shape, def, params, types, where, camera);
|
|
111
|
+
const top = where.groundHeight + shapeTop3d(shape, params);
|
|
112
|
+
const hidden = occlusion
|
|
113
|
+
? occlusionCache.get(shape.id, `${anchor.x},${anchor.y},${top}`, () => occlusion.hidden(anchor.x, anchor.y, top))
|
|
114
|
+
: false;
|
|
115
|
+
const pose = custom?.pose ?? shapePose(shape, params, where);
|
|
116
|
+
const box = poseBox(pose);
|
|
117
|
+
const isBox = pose.mode === "box";
|
|
118
|
+
// Opacity would flatten a 3D node's children (a box's walls, a type's own
|
|
119
|
+
// planes), so a box fades its faces instead and a type's own drawing hides.
|
|
120
|
+
const shown = custom ? "hide" : look;
|
|
121
|
+
const hiddenStyle = occludedStyle(hidden, shown);
|
|
122
|
+
const nodeStyle = !custom && isBox && shown === "fade" ? undefined : hiddenStyle;
|
|
123
|
+
const faceStyle = nodeStyle ? undefined : hiddenStyle;
|
|
124
|
+
const shadow = params.shadow ? shadowStyle(pose) : null;
|
|
125
|
+
return [
|
|
126
|
+
shadow ? (_jsx("div", { "data-shape-3d-shadow": shape.id, style: {
|
|
127
|
+
position: "absolute",
|
|
128
|
+
left: pose.x,
|
|
129
|
+
top: pose.y,
|
|
130
|
+
width: shadow.width,
|
|
131
|
+
height: shadow.height,
|
|
132
|
+
borderRadius: "50%",
|
|
133
|
+
background: "radial-gradient(closest-side, rgba(0,0,0,0.3), rgba(0,0,0,0))",
|
|
134
|
+
opacity: shadow.opacity,
|
|
135
|
+
transform: shadow.transform,
|
|
136
|
+
transformOrigin: "0 0",
|
|
137
|
+
...(hidden ? { visibility: "hidden" } : null),
|
|
138
|
+
} }, `shadow-${shape.id}`)) : null,
|
|
139
|
+
custom ? (_jsx("div", { "data-shape-3d-id": shape.id, "data-shape-3d-mode": "custom", "data-shape-3d-hidden": hidden ? "" : undefined, style: {
|
|
140
|
+
position: "absolute",
|
|
141
|
+
...box,
|
|
142
|
+
transform: custom.transform,
|
|
143
|
+
transformOrigin: poseOrigin(pose),
|
|
144
|
+
transformStyle: "preserve-3d",
|
|
145
|
+
...nodeStyle,
|
|
146
|
+
}, children: custom.element }, shape.id)) : (_jsx("div", { "data-shape-3d-id": shape.id, "data-shape-3d-mode": pose.mode, "data-shape-3d-hidden": hidden ? "" : undefined, style: {
|
|
147
|
+
position: "absolute",
|
|
148
|
+
...box,
|
|
149
|
+
transform: poseTransform(pose),
|
|
150
|
+
transformOrigin: poseOrigin(pose),
|
|
151
|
+
transformStyle: isBox ? "preserve-3d" : undefined,
|
|
152
|
+
...nodeStyle,
|
|
153
|
+
}, children: isBox ? (_jsxs(_Fragment, { children: [boxWalls(pose).map((w) => (_jsx("div", { "data-shape-3d-wall": w.side, style: {
|
|
154
|
+
position: "absolute",
|
|
155
|
+
left: w.left,
|
|
156
|
+
top: w.top,
|
|
157
|
+
width: w.width,
|
|
158
|
+
height: w.height,
|
|
159
|
+
transformOrigin: w.transformOrigin,
|
|
160
|
+
transform: w.transform,
|
|
161
|
+
background: wallColor(shape),
|
|
162
|
+
boxShadow: wallShade(w.side),
|
|
163
|
+
backfaceVisibility: "hidden",
|
|
164
|
+
...faceStyle,
|
|
165
|
+
} }, w.side))), _jsx("div", { "data-shape-3d-top": "", style: {
|
|
166
|
+
position: "absolute",
|
|
167
|
+
inset: 0,
|
|
168
|
+
transform: boxTopTransform(pose),
|
|
169
|
+
...faceStyle,
|
|
170
|
+
}, children: _jsx(StandContent, { shape: shape, def: def, zoom: pose.zoom }) })] })) : (_jsx(StandContent, { shape: shape, def: def, zoom: pose.zoom })) }, shape.id)),
|
|
171
|
+
];
|
|
172
|
+
}) }));
|
|
173
|
+
}
|
|
174
|
+
/** A type's own `render3d` for this shape, placed by {@link render3dFrame}; `null` = use
|
|
175
|
+
* the generic drawing (no `render3d`, or it returned `null`). */
|
|
176
|
+
function renderCustom(shape, def, params, types, view, camera) {
|
|
177
|
+
const render3d = types[shape.type]?.render3d;
|
|
178
|
+
if (!render3d)
|
|
179
|
+
return null;
|
|
180
|
+
const frame = render3dFrame(shape, params, view);
|
|
181
|
+
const { pose } = frame;
|
|
182
|
+
const element = render3d(shape, {
|
|
183
|
+
params,
|
|
184
|
+
amount: pose.raise,
|
|
185
|
+
zoom: pose.zoom,
|
|
186
|
+
width: round3(pose.width * pose.zoom),
|
|
187
|
+
height: round3(pose.height * pose.zoom),
|
|
188
|
+
faceCamera: frame.faceCamera,
|
|
189
|
+
content: _jsx(StandContent, { shape: shape, def: def, zoom: pose.zoom }),
|
|
190
|
+
camera: () => camera.get(),
|
|
191
|
+
subscribe: (listener) => camera.subscribe(listener),
|
|
192
|
+
});
|
|
193
|
+
return element ? { pose, transform: frame.transform, element } : null;
|
|
194
|
+
}
|
|
195
|
+
function round3(n) {
|
|
196
|
+
return Math.round(n * 1000) / 1000;
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=shapes-layer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shapes-layer.js","sourceRoot":"","sources":["../src/shapes-layer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { type BoundingBox, type RenderMode, type ShapeData, type ShapeTypeView3d, type ShapeView3d, type ShapeView3dMode, shapeView3dAnchor, shapeView3dFoot, type Viewport } from "@edv4h/usketch-shared";
|
|
2
|
+
type Shape3dMode = ShapeView3dMode;
|
|
3
|
+
type Shape3dParams = ShapeView3d;
|
|
4
|
+
/** Each shape type's 3D (`ShapeTypeView3d`), by type. */
|
|
5
|
+
export type Css3dShapeTypes = Readonly<Record<string, ShapeTypeView3d>>;
|
|
6
|
+
/** Screen px a shadow floats above its ground (no z-fighting with a raised terrain top). */
|
|
7
|
+
export declare const SHADOW_LIFT_PX = 0.5;
|
|
8
|
+
/** The foot of a stood-up shape: the middle of its (rotated) bottom edge, world units. */
|
|
9
|
+
export declare const standFoot: typeof shapeView3dFoot;
|
|
10
|
+
/** The point a shape is placed by: the foot for `stand`, the centre otherwise. World units. */
|
|
11
|
+
export declare const shapeAnchor: typeof shapeView3dAnchor;
|
|
12
|
+
/** `a` turned toward `b` by `t` (0…1) the short way round, degrees. Pure. */
|
|
13
|
+
export declare function lerpAngle(a: number, b: number, t: number): number;
|
|
14
|
+
export interface ShapePose {
|
|
15
|
+
mode: Shape3dMode;
|
|
16
|
+
/** The anchor on screen (layer px): the foot (`stand`) or the centre. */
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
/** Heading on the board (deg). `stand`: 0 = facing the near edge. */
|
|
20
|
+
face: number;
|
|
21
|
+
/** How far into 3D it is, 0 (flat on the board) … 1 (fully up). */
|
|
22
|
+
raise: number;
|
|
23
|
+
/** Height of the ground under the anchor, screen px (world height × zoom). */
|
|
24
|
+
lift: number;
|
|
25
|
+
/** `box` / `float`: how far above the ground the face is now, screen px
|
|
26
|
+
* (height × raise × zoom). 0 for `stand`. */
|
|
27
|
+
rise: number;
|
|
28
|
+
zoom: number;
|
|
29
|
+
width: number;
|
|
30
|
+
height: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The pose of a 3D shape. At `amount` 0 it lies exactly where the flat board draws it
|
|
34
|
+
* (heading = its rotation on screen). As the view rises, a `stand` shape stands up and —
|
|
35
|
+
* when facing the camera — turns to face it, against the full camera `yaw` (the ground is
|
|
36
|
+
* spun by the yaw, so the plane turns back by it); a `box` / `float` face rises to its
|
|
37
|
+
* height.
|
|
38
|
+
*/
|
|
39
|
+
export declare function shapePose(shape: ShapeData, params: Shape3dParams, view: {
|
|
40
|
+
viewport: Viewport;
|
|
41
|
+
amount: number;
|
|
42
|
+
yaw: number;
|
|
43
|
+
groundHeight: number;
|
|
44
|
+
}): ShapePose;
|
|
45
|
+
/**
|
|
46
|
+
* The node of a 3D shape: a box of the shape's size on screen, placed so the anchor is
|
|
47
|
+
* its bottom-centre (`stand`, the pivot it folds up about) or its centre. The box must
|
|
48
|
+
* have its real size: Chrome drops a 3D-rotated element with an empty box even when its
|
|
49
|
+
* overflowing content isn't empty.
|
|
50
|
+
*/
|
|
51
|
+
export declare function poseBox(p: Pick<ShapePose, "x" | "y" | "width" | "height" | "zoom"> & {
|
|
52
|
+
mode?: Shape3dMode;
|
|
53
|
+
}): {
|
|
54
|
+
left: number;
|
|
55
|
+
top: number;
|
|
56
|
+
width: number;
|
|
57
|
+
height: number;
|
|
58
|
+
};
|
|
59
|
+
/** `transform-origin` of a stood-up shape's node: the foot. */
|
|
60
|
+
export declare const STAND_ORIGIN = "50% 100%";
|
|
61
|
+
/** `transform-origin` of a 3D shape's node (see {@link poseBox}). */
|
|
62
|
+
export declare function poseOrigin(p: Pick<ShapePose, "mode">): string;
|
|
63
|
+
/**
|
|
64
|
+
* CSS for a 3D shape's node: lift to the ground, turn to the heading, then fold up
|
|
65
|
+
* (`stand`) or rise (`float`). A `box` node is only lifted and turned: its top and walls
|
|
66
|
+
* are children ({@link boxTopTransform}, {@link boxWalls}). `undefined` when flat.
|
|
67
|
+
*/
|
|
68
|
+
export declare function poseTransform(p: ShapePose): string | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* Where a type's own `render3d` draws: the shape's node (as {@link poseBox} /
|
|
71
|
+
* {@link poseOrigin}) lifted to the ground and turned to the shape's own heading, plus
|
|
72
|
+
* how far to turn back to face the camera (scaled by the transition). The generic
|
|
73
|
+
* camera-facing turn isn't applied: `render3d` decides. Pure.
|
|
74
|
+
*/
|
|
75
|
+
export declare function render3dFrame(shape: ShapeData, params: Shape3dParams, view: {
|
|
76
|
+
viewport: Viewport;
|
|
77
|
+
amount: number;
|
|
78
|
+
yaw: number;
|
|
79
|
+
groundHeight: number;
|
|
80
|
+
}): {
|
|
81
|
+
pose: ShapePose;
|
|
82
|
+
transform: string | undefined;
|
|
83
|
+
faceCamera: number;
|
|
84
|
+
};
|
|
85
|
+
/** CSS for a `box` shape's top (the shape's own drawing), relative to its node. */
|
|
86
|
+
export declare function boxTopTransform(p: Pick<ShapePose, "rise">): string | undefined;
|
|
87
|
+
export type BoxSide = "n" | "e" | "s" | "w";
|
|
88
|
+
export interface BoxWall {
|
|
89
|
+
side: BoxSide;
|
|
90
|
+
left: number;
|
|
91
|
+
top: number;
|
|
92
|
+
width: number;
|
|
93
|
+
height: number;
|
|
94
|
+
transformOrigin: string;
|
|
95
|
+
transform: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The four walls of a `box` shape, in its node's px frame: each a flat strip along one
|
|
99
|
+
* edge of the box, folded up about that edge (like the map's cliff walls) so it reaches
|
|
100
|
+
* from the ground to the top, its face outward. None while the box has no height. Pure.
|
|
101
|
+
*/
|
|
102
|
+
export declare function boxWalls(p: Pick<ShapePose, "rise" | "width" | "height" | "zoom">): BoxWall[];
|
|
103
|
+
/**
|
|
104
|
+
* A `box` shape's wall colour: its fill (`style.fill`, else `color`) — the walls darken
|
|
105
|
+
* it with an overlay ({@link wallShade}) — or a neutral grey when it has none usable.
|
|
106
|
+
*/
|
|
107
|
+
export declare function wallColor(shape: ShapeData): string;
|
|
108
|
+
/** The darkening overlay of a wall: east/west a touch darker, as the map's cliffs. */
|
|
109
|
+
export declare function wallShade(side: BoxSide): string;
|
|
110
|
+
/**
|
|
111
|
+
* CSS for a 3D shape's shadow, at its anchor on the ground: a soft ellipse along the
|
|
112
|
+
* heading — at the foot of a `stand` shape, under a `float` one. It grows in with the
|
|
113
|
+
* view (`raise`): the flat board has no shadows. `null` for a `box` (it sits on the
|
|
114
|
+
* ground).
|
|
115
|
+
*/
|
|
116
|
+
export declare function shadowStyle(p: ShapePose): {
|
|
117
|
+
transform: string;
|
|
118
|
+
width: number;
|
|
119
|
+
height: number;
|
|
120
|
+
opacity: number;
|
|
121
|
+
} | null;
|
|
122
|
+
/** How many 3D shapes are drawn, and how. */
|
|
123
|
+
export interface Css3dShapeLimits {
|
|
124
|
+
/** Shapes smaller than this on screen (px, longer side) stay flat. */
|
|
125
|
+
minPx: number;
|
|
126
|
+
/** At most this many shapes are drawn in 3D — the nearest (lowest on screen) win. */
|
|
127
|
+
maxCount: number;
|
|
128
|
+
/** Shapes holding no 3D parameters still lie on the terrain's height where it is
|
|
129
|
+
* raised (drawn here as a flat `float` of height 0), instead of on the board at 0.
|
|
130
|
+
* Default `true`. */
|
|
131
|
+
groundFlat: boolean;
|
|
132
|
+
}
|
|
133
|
+
export declare const DEFAULT_CSS3D_SHAPE_LIMITS: Css3dShapeLimits;
|
|
134
|
+
/** What a shape holding no 3D parameters is drawn as on raised ground: flat, at its height. */
|
|
135
|
+
export declare const GROUND_FLAT_PARAMS: Shape3dParams;
|
|
136
|
+
export interface Shape3dEntry {
|
|
137
|
+
shape: ShapeData;
|
|
138
|
+
params: Shape3dParams;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The shapes to draw in 3D now (in z-order). Only while the view is (partly) 3D, never
|
|
142
|
+
* in the global LOD mode, and only shapes whose anchor is on the drawn ground: the board
|
|
143
|
+
* box grown by the 3D view's overscan. A depth layer isn't clipped by the draw distance,
|
|
144
|
+
* so a shape farther out would stand in the sky past the ground's end. With
|
|
145
|
+
* `limits.groundFlat` and a `heightAt`, a shape holding no 3D parameters whose centre is
|
|
146
|
+
* on raised ground is drawn too, lying flat at that height ({@link GROUND_FLAT_PARAMS}).
|
|
147
|
+
* Pure.
|
|
148
|
+
*/
|
|
149
|
+
export declare function selectShapes3d(input: {
|
|
150
|
+
shapes: readonly ShapeData[];
|
|
151
|
+
types: Css3dShapeTypes;
|
|
152
|
+
viewport: Viewport;
|
|
153
|
+
viewportBounds: BoundingBox;
|
|
154
|
+
/** Screen px the 3D view shows past the board box (`bg-grid:set-overscan`). */
|
|
155
|
+
overscanPx: number;
|
|
156
|
+
renderMode: RenderMode;
|
|
157
|
+
amount: number;
|
|
158
|
+
limits: Css3dShapeLimits;
|
|
159
|
+
/** The terrain's height (world units) for `limits.groundFlat`; absent = no terrain. */
|
|
160
|
+
heightAt?: (x: number, y: number) => number;
|
|
161
|
+
}): Shape3dEntry[];
|
|
162
|
+
export {};
|
|
163
|
+
//# sourceMappingURL=shapes-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shapes-layout.d.ts","sourceRoot":"","sources":["../src/shapes-layout.ts"],"names":[],"mappings":"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"}
|