@expofp/renderer 3.31.3 → 3.31.5

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.
@@ -1,28 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Canvas } from '@react-three/fiber';
3
3
  import { lazy, Suspense, use } from 'react';
4
- /**
5
- * The one debug chunk, shared by every consumer: the internal mount's context-patch gate, the
6
- * overlay in both mounts' trees, and {@link prepareDebug}. Memoized so `use()` sees a stable
7
- * promise and the chunk is fetched once.
8
- */
9
- let debugChunk;
10
- function loadDebugChunk() {
11
- debugChunk ??= import('./components/DebugTools');
12
- return debugChunk;
13
- }
14
- /**
15
- * Loads the debug chunk ahead of time — for a host that creates its own WebGL context.
16
- *
17
- * The chunk's evaluation is what instruments context creation for the GPU-memory panel
18
- * (webgl-memory patches `getContext` as it loads), so a context created before it exists can never
19
- * report memory figures. The renderer's own mount orders this itself; a MapLibre host does it by
20
- * awaiting this before constructing the map, when debug is on. Idempotent, and the only eager cost
21
- * is the call: the debug code still lives in its own lazy chunk.
22
- */
23
- export async function prepareDebug() {
24
- await loadDebugChunk();
25
- }
4
+ import { loadDebugChunk } from './debug-chunk';
26
5
  const DebugTools = lazy(() => import('./components/DebugTools').then((module) => ({ default: module.DebugTools })));
27
6
  /**
28
7
  * The renderer's own Canvas with the debug ordering folded in: when `debugEnabled`, it suspends —
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { type CameraAPI, type CameraAxes, type CameraState, type ControlsConfig, type InertiaConfig, type PanConfig, type RollConfig, type TransitionOptions, useCameraAPI, useCameraMoveStart, useCameraState, type ZoomToOptions, } from './controls';
2
- export { prepareDebug } from './debug';
2
+ export { prepareDebug } from './debug/debug-chunk';
3
3
  export * from './Renderer';
4
4
  export { type CameraProps, type SmoothTime } from './space/Camera';
5
5
  export { type CanvasPoint, type CanvasPointLike, type PlanPoint, type PlanPointLike, } from './space/Space';
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  // renderer's internals.
4
4
  export { useCameraAPI, useCameraMoveStart, useCameraState, } from './controls';
5
5
  // The debug chunk's preload, for an external host that must create its context instrumented.
6
- export { prepareDebug } from './debug';
6
+ export { prepareDebug } from './debug/debug-chunk';
7
7
  export * from './Renderer';
8
8
  export { useViewport } from './space/viewport';
9
9
  export * from './types/defs';
@@ -42,31 +42,4 @@ export interface VisibleRectProps {
42
42
  * @returns Nothing; this renders no scene node.
43
43
  */
44
44
  export declare function VisibleRect(props: VisibleRectProps): null;
45
- /**
46
- * How far the plan has to shrink to fit inside the rect: `1` when it already does.
47
- *
48
- * **Measured against the plan's own footprint, not the canvas's.** Fitting the canvas into the rect
49
- * would compose two contain-fits — plan into canvas, then canvas into rect — and a product of two
50
- * independent minima is not the minimum the imperative renderer took over the same pair. The two
51
- * agree only when the same axis binds both, and disagree in the commonest configuration there is: a
52
- * wide hall on a portrait phone, where the plan already fits the clear band and fitting the canvas
53
- * into it would shrink the plan by two thirds for nothing.
54
- *
55
- * Measured against the plan, the factorization telescopes back to what the imperative renderer
56
- * computed in one step:
57
- *
58
- * ```
59
- * fitScale · framingScale = min(W/a, H/b) · min(w/(a·fit), h/(b·fit)) = min(w/a, h/b)
60
- * ```
61
- *
62
- * The clamp only guards a rect larger than the canvas; for a rect inside it the result is already
63
- * at most `1`, because the fit leaves the plan touching at least one edge.
64
- * @param rect - The region to frame the plan inside, in css pixels.
65
- * @param viewbox - The scene's viewbox, in plan units.
66
- * @param width - The canvas width in css pixels.
67
- * @param height - The canvas height in css pixels.
68
- * @param dpr - Device pixels per css pixel.
69
- * @returns The scale, in `(0, 1]`.
70
- */
71
- export declare function framingScale(rect: Box, viewbox: Box, width: number, height: number, dpr: number): number;
72
45
  //# sourceMappingURL=VisibleRect.d.ts.map
@@ -92,7 +92,7 @@ export function VisibleRect(props) {
92
92
  * @param dpr - Device pixels per css pixel.
93
93
  * @returns The scale, in `(0, 1]`.
94
94
  */
95
- export function framingScale(rect, viewbox, width, height, dpr) {
95
+ function framingScale(rect, viewbox, width, height, dpr) {
96
96
  const fit = fitScale(viewbox, width * dpr, height * dpr);
97
97
  // The plan's footprint on the canvas at zoom 1, in device pixels — the viewbox fit sizes one
98
98
  // world unit to one device pixel, so this is the viewbox scaled and nothing more.
@@ -1,5 +1,5 @@
1
1
  import { type Camera } from 'three';
2
- import { type CameraControlsImpl } from '../controls/CameraControls';
2
+ import { type CameraControlsImpl } from '../controls';
3
3
  import { type Space } from './Space';
4
4
  /**
5
5
  * How much of the plan one device pixel spans, in plan units — what everything sized in pixels is
@@ -1,6 +1,6 @@
1
1
  import { Point } from '@expofp/geometry';
2
2
  import { Matrix4, Ray, Vector2, Vector4 } from 'three';
3
- import { bearing } from '../controls/CameraControls';
3
+ import { bearing } from '../controls';
4
4
  import { euclideanModulo } from '../utils/math';
5
5
  import { isOrthographic, isPerspective } from './camera-kind';
6
6
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expofp/renderer",
3
- "version": "3.31.3",
3
+ "version": "3.31.5",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/expofp/efp-app.git",
@@ -42,7 +42,7 @@
42
42
  "troika-three-text": "^0.52.5",
43
43
  "tslib": "^2.3.0",
44
44
  "webgl-memory": "^1.1.3",
45
- "@expofp/geometry": "3.31.3"
45
+ "@expofp/geometry": "3.31.5"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@react-three/test-renderer": "^9.1.0",
@@ -1,13 +0,0 @@
1
- /**
2
- * Runs a handler when a camera movement begins — a gesture and a command alike, one call per
3
- * movement rather than one per frame. The event the imperative renderer published as
4
- * `navigation:change`, under a name that says what happened.
5
- *
6
- * A camera-level event rather than the controls themselves, so a caller resetting an idle timer or
7
- * dismissing an overlay never learns which library drives the camera. For as long as the component
8
- * is mounted; where the camera *is* once it settles is `useCameraState`'s business.
9
- * @param handler - Called as each movement starts. Re-subscribed when its identity changes, so pass
10
- * a stable function — under the React Compiler an inline closure over stable values is one.
11
- */
12
- export declare function useCameraMoveStart(handler: () => void): void;
13
- //# sourceMappingURL=camera-move.d.ts.map
@@ -1,18 +0,0 @@
1
- import { useControlsEffect } from './CameraControls';
2
- /**
3
- * Runs a handler when a camera movement begins — a gesture and a command alike, one call per
4
- * movement rather than one per frame. The event the imperative renderer published as
5
- * `navigation:change`, under a name that says what happened.
6
- *
7
- * A camera-level event rather than the controls themselves, so a caller resetting an idle timer or
8
- * dismissing an overlay never learns which library drives the camera. For as long as the component
9
- * is mounted; where the camera *is* once it settles is `useCameraState`'s business.
10
- * @param handler - Called as each movement starts. Re-subscribed when its identity changes, so pass
11
- * a stable function — under the React Compiler an inline closure over stable values is one.
12
- */
13
- export function useCameraMoveStart(handler) {
14
- useControlsEffect((controls) => {
15
- controls.addEventListener('transitionstart', handler);
16
- return () => controls.removeEventListener('transitionstart', handler);
17
- });
18
- }
@@ -1,40 +0,0 @@
1
- import { Point } from '@expofp/geometry';
2
- /** Where the camera is, at the moment it was asked. */
3
- export interface CameraState {
4
- /** The point on the plan it is looking at, in plan units. */
5
- center: Point;
6
- /** How far in it is zoomed, as a factor: `1` frames the whole viewbox. */
7
- zoom: number;
8
- /** Which way the plan is turned, in degrees clockwise from north, in `[0, 360)`. */
9
- roll: number;
10
- /** How far the plan is tilted away from face-on, in degrees. */
11
- pitch: number;
12
- /**
13
- * How much of the plan one device pixel spans, in plan units — the factor anything sized in
14
- * pixels is laid out against, and the quantity the imperative renderer published as `ptScale`.
15
- */
16
- pixelSize: number;
17
- }
18
- /**
19
- * Reads where the camera is.
20
- *
21
- * A **getter**, not a value: nothing here belongs in render output — a component that re-rendered
22
- * whenever the camera moved would re-render on every frame of every pan — and every caller wants it
23
- * at a moment of its own choosing, in an event handler, an effect, or a snapshot a host asked for.
24
- * That is the same reading discipline `Space` documents, for the same reason.
25
- *
26
- * The five numbers come from four different places, which is why this exists at all rather than
27
- * being arithmetic a caller could do: the target from the controls and the plan it lands on from the
28
- * space, the zoom factor from the camera's handle, and the pixel size from the re-layout registry —
29
- * which is what the plan's own labels are sized against, so a caller measuring against anything else
30
- * would disagree with what is drawn.
31
- *
32
- * Outside a mounted scene, or in the frames before the controls publish themselves, it reports the
33
- * camera at rest: the middle of the plan, framed whole, facing north.
34
- *
35
- * As with {@link useCameraAPI}, the reader is **new on every render** and this module memoizes
36
- * nothing; a consumer that needs a settled identity holds it in a ref.
37
- * @returns A function that reads the current state.
38
- */
39
- export declare function useCameraState(): () => CameraState;
40
- //# sourceMappingURL=camera-state.d.ts.map
@@ -1,65 +0,0 @@
1
- import { Point, radToDeg } from '@expofp/geometry';
2
- import { use } from 'react';
3
- import { Vector3 } from 'three';
4
- import { LayoutTargetsContext } from '../events/layout-targets';
5
- import { useCamera } from '../space/camera-handle';
6
- import { useSpace } from '../space/Space';
7
- import { bearing, useCameraControls } from './CameraControls';
8
- /**
9
- * Reads where the camera is.
10
- *
11
- * A **getter**, not a value: nothing here belongs in render output — a component that re-rendered
12
- * whenever the camera moved would re-render on every frame of every pan — and every caller wants it
13
- * at a moment of its own choosing, in an event handler, an effect, or a snapshot a host asked for.
14
- * That is the same reading discipline `Space` documents, for the same reason.
15
- *
16
- * The five numbers come from four different places, which is why this exists at all rather than
17
- * being arithmetic a caller could do: the target from the controls and the plan it lands on from the
18
- * space, the zoom factor from the camera's handle, and the pixel size from the re-layout registry —
19
- * which is what the plan's own labels are sized against, so a caller measuring against anything else
20
- * would disagree with what is drawn.
21
- *
22
- * Outside a mounted scene, or in the frames before the controls publish themselves, it reports the
23
- * camera at rest: the middle of the plan, framed whole, facing north.
24
- *
25
- * As with {@link useCameraAPI}, the reader is **new on every render** and this module memoizes
26
- * nothing; a consumer that needs a settled identity holds it in a ref.
27
- * @returns A function that reads the current state.
28
- */
29
- export function useCameraState() {
30
- const controls = useCameraControls();
31
- const camera = useCamera();
32
- const space = useSpace();
33
- const targets = use(LayoutTargetsContext);
34
- return () => readCameraState({ controls, camera, space, targets });
35
- }
36
- /**
37
- * Reads the camera, from whatever the scene holds at the moment of asking.
38
- * @param context - What the scene holds.
39
- * @returns Where the camera is.
40
- */
41
- function readCameraState(context) {
42
- const { controls, camera, space, targets } = context;
43
- const pixelSize = targets?.pixelSize ?? 1;
44
- // A fresh centre every time: a caller that keeps the point it was handed must never find it
45
- // moved under them.
46
- if (!controls)
47
- return { ...atRest(), pixelSize };
48
- controls.getTarget(_target);
49
- return {
50
- center: space.worldToPlan(_target, new Point()),
51
- zoom: camera?.zoomFactor ?? 1,
52
- roll: radToDeg(bearing(controls)),
53
- pitch: radToDeg(controls.polarAngle),
54
- pixelSize,
55
- };
56
- }
57
- /**
58
- * The camera as it stands before anything has moved it, which is what a read outside a mounted
59
- * scene reports: the middle of the plan, framed whole, facing north.
60
- * @returns The state.
61
- */
62
- function atRest() {
63
- return { center: new Point(), zoom: 1, roll: 0, pitch: 0, pixelSize: 1 };
64
- }
65
- const _target = new Vector3();