@expofp/wayfinding 3.33.0 → 3.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -5
- package/dist/createWayfinding.d.ts +4 -3
- package/dist/createWayfinding.js +2 -3
- package/dist/index.d.ts +6 -2
- package/dist/index.js +4 -1
- package/dist/renderer/createWayfindingRenderer.d.ts +2 -1
- package/dist/renderer/createWayfindingRenderer.js +7 -4
- package/dist/renderer/iconManager.d.ts +10 -3
- package/dist/renderer/iconManager.js +51 -15
- package/dist/renderer/index.d.ts +2 -0
- package/dist/renderer/index.js +1 -0
- package/dist/renderer/layerManager.d.ts +11 -13
- package/dist/renderer/layerManager.js +7 -23
- package/dist/renderer/layers.d.ts +39 -0
- package/dist/renderer/layers.js +62 -0
- package/dist/renderer/routeLineManager.d.ts +5 -5
- package/dist/renderer/routeLineManager.js +49 -33
- package/dist/renderer/trailManager.d.ts +5 -6
- package/dist/renderer/trailManager.js +26 -44
- package/dist/renderer/types.d.ts +25 -40
- package/dist/runtime/createWayfindingRuntime.d.ts +1 -1
- package/dist/runtime/createWayfindingRuntime.js +4 -15
- package/dist/runtime/endpointView.d.ts +1 -2
- package/dist/runtime/endpointView.js +1 -3
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/positionTrailView.d.ts +1 -2
- package/dist/runtime/positionTrailView.js +2 -2
- package/dist/runtime/positionView.d.ts +1 -2
- package/dist/runtime/positionView.js +3 -2
- package/dist/runtime/routeLinesView.d.ts +1 -3
- package/dist/runtime/routeLinesView.js +3 -11
- package/dist/runtime/trailView.d.ts +1 -2
- package/dist/runtime/trailView.js +2 -5
- package/dist/runtime/transitionView.d.ts +1 -2
- package/dist/runtime/transitionView.js +1 -2
- package/dist/runtime/types.d.ts +0 -8
- package/package.json +4 -4
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
import { animateLineSegments } from './lineAnimation.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds one route line. The points are copied rather than aliased: the caller keeps its segments,
|
|
4
|
+
* and the animated overlay replaces its own `points` as the head travels.
|
|
5
|
+
* @param seg - The segment to draw.
|
|
6
|
+
* @param color - Stroke color.
|
|
7
|
+
* @returns The def.
|
|
8
|
+
*/
|
|
9
|
+
function lineDef({ p0, p1 }, color) {
|
|
10
|
+
return { points: { p0: { x: p0.x, y: p0.y }, p1: { x: p1.x, y: p1.y } }, color, width: 10 };
|
|
11
|
+
}
|
|
2
12
|
/**
|
|
3
13
|
* Create a {@link RouteLineManager} that renders `LineDef` segments
|
|
4
14
|
* into layers managed by the given {@link LayerManager}.
|
|
5
|
-
* @param layerManager -
|
|
15
|
+
* @param layerManager - Tracks what changed.
|
|
6
16
|
* @param colors - The route palette.
|
|
7
17
|
* @param port - The commit function the animation ticks through.
|
|
18
|
+
* @param layers - The two line layers to draw into.
|
|
8
19
|
* @returns The manager.
|
|
9
20
|
*/
|
|
10
|
-
export function createRouteLineManager(layerManager, colors, port) {
|
|
21
|
+
export function createRouteLineManager(layerManager, colors, port, layers) {
|
|
22
|
+
const linesLayer = layers.lines;
|
|
23
|
+
const animatedLayer = layers.linesAnimated;
|
|
11
24
|
let animationHandle = null;
|
|
12
|
-
let lastLinesLayer = null;
|
|
13
|
-
let lastAnimatedLayer = null;
|
|
14
25
|
/**
|
|
15
26
|
* The pixel size the chase animation modulates its speed by. Route lines need no layout of their
|
|
16
27
|
* own — `LineDef.width` is already in screen pixels — so this is the one thing the animated layer's
|
|
@@ -28,40 +39,38 @@ export function createRouteLineManager(layerManager, colors, port) {
|
|
|
28
39
|
currentPixelSize = pixelSize;
|
|
29
40
|
}
|
|
30
41
|
/**
|
|
31
|
-
* Empties one lines layer, hiding
|
|
32
|
-
*
|
|
33
|
-
* The hide is not redundant with the removal. The renderer commits a def write synchronously but
|
|
34
|
-
* defers a membership sweep — renderer's `useStagedChildren` (`objects/layer/
|
|
35
|
-
* mount-scheduler.ts`) pipes a layer's children through `useDeferredValue`, so the unmount that
|
|
36
|
-
* releases the removed instances lands a transition commit later. Lines that were only removed
|
|
37
|
-
* therefore outlived the route's icons — which `hideIcon` hides in place — by a frame or more,
|
|
38
|
-
* and the cleared route's line visibly lingered behind its pins. Hiding first puts the whole
|
|
39
|
-
* teardown in the same synchronous commit; the deferred sweep then releases slots that are
|
|
40
|
-
* already invisible. Drop the hides if the renderer ever hides departed defs urgently itself
|
|
41
|
-
* (the place to do it is `useStagedChildren`, where the fresh snapshot and the deferred children
|
|
42
|
-
* are both at hand).
|
|
43
|
-
* @param layer - The layer to empty, when it is known yet.
|
|
42
|
+
* Empties one lines layer, hiding what it held first — see {@link hideDeparting}.
|
|
43
|
+
* @param layer - The layer to empty.
|
|
44
44
|
*/
|
|
45
45
|
function wipe(layer) {
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
hideDeparting(layer);
|
|
47
|
+
layer.children = [];
|
|
48
|
+
layerManager.touchLayer(layer);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Hides every line a layer still holds, before whatever replaces them.
|
|
52
|
+
*
|
|
53
|
+
* The renderer commits a def write synchronously but defers the membership sweep — renderer's
|
|
54
|
+
* `useStagedChildren` (`objects/layer/mount-scheduler.ts`) pipes a layer's children through
|
|
55
|
+
* `useDeferredValue` — so lines that were only removed outlive the route's icons, which
|
|
56
|
+
* `hideIcon` hides in place, by a frame or more. That is how a cleared route's line lingered
|
|
57
|
+
* behind its pins. Drop this if the renderer ever hides departed defs urgently itself.
|
|
58
|
+
* @param layer - The layer whose current lines are on their way out.
|
|
59
|
+
*/
|
|
60
|
+
function hideDeparting(layer) {
|
|
48
61
|
for (const def of layer.children) {
|
|
49
62
|
def.hidden = true;
|
|
50
63
|
layerManager.touchDef(def);
|
|
51
64
|
}
|
|
52
|
-
layer.children = [];
|
|
53
|
-
layerManager.touchedLayers.set(layer.name, layer);
|
|
54
65
|
}
|
|
55
66
|
return {
|
|
56
67
|
setRouteLines(passed, remaining, options) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// Declared
|
|
60
|
-
//
|
|
68
|
+
layerManager.touchLayer(linesLayer);
|
|
69
|
+
layerManager.touchLayer(animatedLayer);
|
|
70
|
+
// Declared on every call rather than at construction: the `update(layer)` a flush performs is
|
|
71
|
+
// what makes the renderer register the layer under this handler.
|
|
61
72
|
animatedLayer.onScale = ({ pixelSize }) => readPixelSize(pixelSize);
|
|
62
|
-
|
|
63
|
-
lastAnimatedLayer = animatedLayer;
|
|
64
|
-
const reset = options.resetAnimation ?? true;
|
|
73
|
+
const reset = options?.resetAnimation ?? true;
|
|
65
74
|
let resumeFrom = 0;
|
|
66
75
|
if (animationHandle) {
|
|
67
76
|
if (!reset)
|
|
@@ -69,8 +78,12 @@ export function createRouteLineManager(layerManager, colors, port) {
|
|
|
69
78
|
animationHandle.stop();
|
|
70
79
|
animationHandle = null;
|
|
71
80
|
}
|
|
72
|
-
|
|
73
|
-
|
|
81
|
+
// Every call replaces both layers wholesale, so the lines on their way out are hidden first
|
|
82
|
+
// — `setRouteLines([], [])` is how a route is cleared.
|
|
83
|
+
hideDeparting(linesLayer);
|
|
84
|
+
hideDeparting(animatedLayer);
|
|
85
|
+
const passedDefs = passed.map((seg) => lineDef(seg, colors.passed));
|
|
86
|
+
const remainingDefs = remaining.map((seg) => lineDef(seg, colors.remaining));
|
|
74
87
|
linesLayer.children = [...passedDefs, ...remainingDefs];
|
|
75
88
|
if (!remainingDefs.length) {
|
|
76
89
|
animatedLayer.children = [];
|
|
@@ -80,7 +93,7 @@ export function createRouteLineManager(layerManager, colors, port) {
|
|
|
80
93
|
// `points` object: the chase moves these in place, and the static line beneath must not move
|
|
81
94
|
// with them. They start hidden, and the animation shows each as the head reaches it.
|
|
82
95
|
const animatedDefs = remaining.map((seg) => ({
|
|
83
|
-
...
|
|
96
|
+
...lineDef(seg, colors.active),
|
|
84
97
|
hidden: true,
|
|
85
98
|
}));
|
|
86
99
|
// Mounted once. The chase moves these defs rather than rewriting this array, so no instance is
|
|
@@ -94,11 +107,14 @@ export function createRouteLineManager(layerManager, colors, port) {
|
|
|
94
107
|
animationHandle.stop();
|
|
95
108
|
animationHandle = null;
|
|
96
109
|
}
|
|
97
|
-
wipe(
|
|
98
|
-
wipe(
|
|
110
|
+
wipe(linesLayer);
|
|
111
|
+
wipe(animatedLayer);
|
|
99
112
|
},
|
|
100
113
|
destroy() {
|
|
101
114
|
this.clearLines();
|
|
115
|
+
// The layer outlives this manager, so the handler goes with it: left in place it keeps the
|
|
116
|
+
// manager reachable and runs on every camera step.
|
|
117
|
+
animatedLayer.onScale = undefined;
|
|
102
118
|
},
|
|
103
119
|
};
|
|
104
120
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Point2Like } from '@expofp/geometry';
|
|
2
|
+
import type { ImageDef, LayerDef } from '@expofp/renderer';
|
|
2
3
|
import type { LayerManager } from './layerManager.js';
|
|
3
|
-
import type { RendererPort } from './types.js';
|
|
4
4
|
/**
|
|
5
5
|
* Manages named trails of evenly-spaced dots between two points.
|
|
6
6
|
*
|
|
@@ -16,16 +16,15 @@ export interface TrailManager {
|
|
|
16
16
|
*/
|
|
17
17
|
setTrail(name: string, from: Point2Like | null, to: Point2Like | null, options?: {
|
|
18
18
|
readonly canvas: HTMLCanvasElement;
|
|
19
|
-
readonly layer: string;
|
|
20
19
|
}): void;
|
|
21
20
|
/** Remove all trails. */
|
|
22
21
|
destroy(): void;
|
|
23
22
|
}
|
|
24
23
|
/**
|
|
25
|
-
* Create a {@link TrailManager} that renders dot trails into
|
|
26
|
-
*
|
|
27
|
-
* @param
|
|
24
|
+
* Create a {@link TrailManager} that renders dot trails into the block's trail layer.
|
|
25
|
+
* @param layerManager - Tracks what changed.
|
|
26
|
+
* @param layer - The layer the dots go in.
|
|
28
27
|
* @returns The manager.
|
|
29
28
|
*/
|
|
30
|
-
export declare function createTrailManager(layerManager: LayerManager,
|
|
29
|
+
export declare function createTrailManager(layerManager: LayerManager, layer: LayerDef<ImageDef>): TrailManager;
|
|
31
30
|
//# sourceMappingURL=trailManager.d.ts.map
|
|
@@ -3,12 +3,12 @@ import { computeTrailPoints } from '../core/index.js';
|
|
|
3
3
|
/** Distance between trail dots at a pixel size of 1, in the same units as route points. */
|
|
4
4
|
const TRAIL_INTERVAL_AT_BASE_PIXEL_SIZE = 40;
|
|
5
5
|
/**
|
|
6
|
-
* Create a {@link TrailManager} that renders dot trails into
|
|
7
|
-
*
|
|
8
|
-
* @param
|
|
6
|
+
* Create a {@link TrailManager} that renders dot trails into the block's trail layer.
|
|
7
|
+
* @param layerManager - Tracks what changed.
|
|
8
|
+
* @param layer - The layer the dots go in.
|
|
9
9
|
* @returns The manager.
|
|
10
10
|
*/
|
|
11
|
-
export function createTrailManager(layerManager,
|
|
11
|
+
export function createTrailManager(layerManager, layer) {
|
|
12
12
|
const trails = new Map();
|
|
13
13
|
/**
|
|
14
14
|
* The pixel size the trails currently hold their spacing for.
|
|
@@ -20,31 +20,26 @@ export function createTrailManager(layerManager, port) {
|
|
|
20
20
|
*/
|
|
21
21
|
let currentPixelSize = 1;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Whether this manager has declared its `onScale` on the layer.
|
|
24
24
|
*
|
|
25
25
|
* Declaring the handler is not enough to be called: `useLayoutTargets` registers a layer as a
|
|
26
26
|
* layout target from a render, so the layer has to be committed once after the handler appears.
|
|
27
|
-
* That commit is a membership change, which is why it happens once
|
|
28
|
-
* redraw.
|
|
27
|
+
* That commit is a membership change, which is why it happens once rather than per redraw.
|
|
29
28
|
*/
|
|
30
|
-
|
|
29
|
+
let wired = false;
|
|
31
30
|
/**
|
|
32
31
|
* Lays every trail on one layer out for a new pixel size — what each trail layer's `onScale`
|
|
33
32
|
* closure delegates to.
|
|
34
33
|
*
|
|
35
|
-
* One function per manager, not per def: what it reads is this manager's trails
|
|
36
|
-
* hands it the one layer it serves.
|
|
37
|
-
* @param layer - The trail layer.
|
|
34
|
+
* One function per manager, not per def: what it reads is this manager's trails.
|
|
38
35
|
* @param pixelSize - Plan units per device pixel.
|
|
39
36
|
* @returns The dots that were written, plus the layer when the dot count changed with them.
|
|
40
37
|
*/
|
|
41
|
-
function layOutTrails(
|
|
38
|
+
function layOutTrails(pixelSize) {
|
|
42
39
|
currentPixelSize = pixelSize;
|
|
43
40
|
const changed = [];
|
|
44
41
|
let membershipChanged = false;
|
|
45
42
|
for (const record of trails.values()) {
|
|
46
|
-
if (record.layerName !== layer.name)
|
|
47
|
-
continue;
|
|
48
43
|
const result = redraw(record);
|
|
49
44
|
changed.push(...result.changed);
|
|
50
45
|
membershipChanged ||= result.membershipChanged;
|
|
@@ -66,26 +61,20 @@ export function createTrailManager(layerManager, port) {
|
|
|
66
61
|
function removeDots(record, dots) {
|
|
67
62
|
if (!dots.length)
|
|
68
63
|
return;
|
|
69
|
-
const layer = layerManager.touchLayer(record.layerName);
|
|
70
64
|
const dropped = new Set(dots);
|
|
71
65
|
for (const dot of dropped)
|
|
72
66
|
dot.hidden = true;
|
|
73
67
|
layer.children = layer.children.filter((child) => !dropped.has(child));
|
|
68
|
+
layerManager.touchLayer(layer);
|
|
74
69
|
}
|
|
75
|
-
/**
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const layer = layerManager.resolveLayer(name);
|
|
82
|
-
if (wiredLayers.has(name))
|
|
83
|
-
return layer;
|
|
84
|
-
layer.onScale = ({ pixelSize }) => layOutTrails(layer, pixelSize);
|
|
85
|
-
wiredLayers.add(name);
|
|
70
|
+
/** Declares this manager's `onScale` on the layer, once. */
|
|
71
|
+
function wireLayer() {
|
|
72
|
+
if (wired)
|
|
73
|
+
return;
|
|
74
|
+
layer.onScale = ({ pixelSize }) => layOutTrails(pixelSize);
|
|
75
|
+
wired = true;
|
|
86
76
|
// Committed with the layer, which is what makes the renderer register the handler.
|
|
87
|
-
layerManager.touchLayer(
|
|
88
|
-
return layer;
|
|
77
|
+
layerManager.touchLayer(layer);
|
|
89
78
|
}
|
|
90
79
|
/**
|
|
91
80
|
* Lays one trail out at the current pixel size, reusing the dots it already holds.
|
|
@@ -97,7 +86,7 @@ export function createTrailManager(layerManager, port) {
|
|
|
97
86
|
* @returns The dots that were written, and whether the layer's membership changed with them.
|
|
98
87
|
*/
|
|
99
88
|
function redraw(record) {
|
|
100
|
-
|
|
89
|
+
wireLayer();
|
|
101
90
|
const interval = TRAIL_INTERVAL_AT_BASE_PIXEL_SIZE * currentPixelSize;
|
|
102
91
|
const points = computeTrailPoints(record.from, record.to, interval);
|
|
103
92
|
const canvas = record.canvas;
|
|
@@ -113,10 +102,10 @@ export function createTrailManager(layerManager, port) {
|
|
|
113
102
|
if (points.length > kept) {
|
|
114
103
|
const added = points
|
|
115
104
|
.slice(kept)
|
|
116
|
-
.map((point) =>
|
|
105
|
+
.map((point) => ({ source: canvas, bounds: new Rect({ x: point.x, y: point.y }, size) }));
|
|
117
106
|
layer.children.push(...added);
|
|
118
107
|
dots.push(...added);
|
|
119
|
-
layerManager.touchLayer(
|
|
108
|
+
layerManager.touchLayer(layer);
|
|
120
109
|
return { changed, membershipChanged: true };
|
|
121
110
|
}
|
|
122
111
|
if (dots.length > kept) {
|
|
@@ -161,21 +150,15 @@ export function createTrailManager(layerManager, port) {
|
|
|
161
150
|
throw new Error(`renderer: setTrail("${name}") requires options when from/to are non-null`);
|
|
162
151
|
const existing = trails.get(name);
|
|
163
152
|
if (existing) {
|
|
164
|
-
if (existing.canvas !== options.canvas
|
|
165
|
-
throw new Error(`renderer: trail "${name}" cannot change canvas
|
|
153
|
+
if (existing.canvas !== options.canvas) {
|
|
154
|
+
throw new Error(`renderer: trail "${name}" cannot change canvas after first call`);
|
|
166
155
|
}
|
|
167
156
|
existing.from = from;
|
|
168
157
|
existing.to = to;
|
|
169
158
|
bufferRedraw(redraw(existing));
|
|
170
159
|
return;
|
|
171
160
|
}
|
|
172
|
-
const record = {
|
|
173
|
-
from,
|
|
174
|
-
to,
|
|
175
|
-
canvas: options.canvas,
|
|
176
|
-
layerName: options.layer,
|
|
177
|
-
dotDefs: [],
|
|
178
|
-
};
|
|
161
|
+
const record = { from, to, canvas: options.canvas, dotDefs: [] };
|
|
179
162
|
trails.set(name, record);
|
|
180
163
|
bufferRedraw(redraw(record));
|
|
181
164
|
},
|
|
@@ -183,10 +166,9 @@ export function createTrailManager(layerManager, port) {
|
|
|
183
166
|
for (const trailName of [...trails.keys()])
|
|
184
167
|
drop(trailName);
|
|
185
168
|
// The layer outlives this manager, so the handler has to go with it: left in place it keeps
|
|
186
|
-
// the manager, its
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
wiredLayers.clear();
|
|
169
|
+
// the manager, its layer and its canvases reachable, and runs on every camera step.
|
|
170
|
+
layer.onScale = undefined;
|
|
171
|
+
wired = false;
|
|
190
172
|
},
|
|
191
173
|
};
|
|
192
174
|
}
|
package/dist/renderer/types.d.ts
CHANGED
|
@@ -1,29 +1,17 @@
|
|
|
1
|
-
import type { Point2Like
|
|
2
|
-
import type { ImageDef,
|
|
1
|
+
import type { Point2Like } from '@expofp/geometry';
|
|
2
|
+
import type { ImageDef, RenderableDef } from '@expofp/renderer';
|
|
3
3
|
/**
|
|
4
|
-
* What the wayfinding renderer needs from whatever is drawing the scene
|
|
5
|
-
*
|
|
6
|
-
* The def factories are injected rather than imported because they live in the host
|
|
7
|
-
* (floorplan's `src/renderer`), which depends on this package — importing them back would close a
|
|
8
|
-
* cycle.
|
|
4
|
+
* What the wayfinding renderer needs from whatever is drawing the scene — the rules only the host
|
|
5
|
+
* can answer for. The defs themselves are plain objects this package builds where it uses them.
|
|
9
6
|
*/
|
|
10
7
|
export interface RendererPort {
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
cardinalSnap?: boolean;
|
|
19
|
-
}): ImageDef;
|
|
20
|
-
/** Builds a line def between two points. */
|
|
21
|
-
createLineDef(line: {
|
|
22
|
-
p0: Point2Like;
|
|
23
|
-
p1: Point2Like;
|
|
24
|
-
}, color?: string, width?: number): LineDef;
|
|
25
|
-
/** The scene's root layers; the `wf-*` layers are resolved out of these by name. */
|
|
26
|
-
readonly layers: readonly LayerDef[];
|
|
8
|
+
/**
|
|
9
|
+
* Declares the host's camera-roll rule on a def that has to stay readable, for
|
|
10
|
+
* {@link IconConfig.cardinalSnap}. The rule is the host's because the plan's own labels turn by
|
|
11
|
+
* it, and one plan turns one way.
|
|
12
|
+
* @param def - The def to keep upright.
|
|
13
|
+
*/
|
|
14
|
+
attachCardinalSnap(def: ImageDef): void;
|
|
27
15
|
/**
|
|
28
16
|
* Commits changed defs.
|
|
29
17
|
*
|
|
@@ -40,14 +28,14 @@ export interface RouteColors {
|
|
|
40
28
|
export interface IconConfig {
|
|
41
29
|
readonly canvas: HTMLCanvasElement;
|
|
42
30
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
31
|
+
* Draw the icon on the level above the other icons rather than among them — the live position,
|
|
32
|
+
* which an endpoint pin must never cover. Two icon layers exist because the draw order inside one
|
|
33
|
+
* is the slot a def was given, which no caller can set.
|
|
45
34
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* will own layer creation by icon name.
|
|
35
|
+
* Fixed at first setIcon for an icon key: a later call that changes it throws, since moving a def
|
|
36
|
+
* between layers would mean removing it from one and adding it to another.
|
|
49
37
|
*/
|
|
50
|
-
readonly
|
|
38
|
+
readonly onTop?: boolean;
|
|
51
39
|
readonly x: number;
|
|
52
40
|
readonly y: number;
|
|
53
41
|
/** Rotation in radians. */
|
|
@@ -60,7 +48,7 @@ export interface IconConfig {
|
|
|
60
48
|
*/
|
|
61
49
|
readonly origin?: [number, number];
|
|
62
50
|
/**
|
|
63
|
-
* Keeps the icon readable as the camera rolls; the host
|
|
51
|
+
* Keeps the icon readable as the camera rolls; the host attaches the rule.
|
|
64
52
|
* The turn is relative — the icon holds its starting heading plus whole quarters — so do NOT
|
|
65
53
|
* enable it where `rotation` carries meaning (position arrow, kiosk heading).
|
|
66
54
|
*
|
|
@@ -82,21 +70,20 @@ export interface WayfindingRendererConfig {
|
|
|
82
70
|
*/
|
|
83
71
|
export interface WayfindingRenderer {
|
|
84
72
|
/**
|
|
85
|
-
* Place or update an icon by `(name, key)`.
|
|
86
|
-
*
|
|
87
|
-
*
|
|
73
|
+
* Place or update an icon by `(name, key)`. The first call creates it, later calls mutate it in
|
|
74
|
+
* place, and `config: null` hides it. `config.onTop` must stay stable for a `(name, key)`.
|
|
75
|
+
* Buffered — `flush()` to commit.
|
|
88
76
|
*/
|
|
89
77
|
setIcon(name: string, config: IconConfig | null, key?: string | number): void;
|
|
90
78
|
/** Hide every icon sharing one of `names` (kept alive for reuse). Buffered. */
|
|
91
79
|
clearIcons(names: string | readonly string[]): void;
|
|
92
80
|
/**
|
|
93
81
|
* Place or update a named dot trail between two points; `from/to = null`
|
|
94
|
-
* clears it. `options` required when non-null; `canvas
|
|
95
|
-
*
|
|
82
|
+
* clears it. `options` required when non-null; `canvas` must stay stable.
|
|
83
|
+
* Buffered — `flush()` to commit.
|
|
96
84
|
*/
|
|
97
85
|
setTrail(name: string, from: Point2Like | null, to: Point2Like | null, options?: {
|
|
98
86
|
readonly canvas: HTMLCanvasElement;
|
|
99
|
-
readonly layer: string;
|
|
100
87
|
}): void;
|
|
101
88
|
/**
|
|
102
89
|
* Replace static route lines (passed + remaining) and (re)start the remaining
|
|
@@ -108,9 +95,7 @@ export interface WayfindingRenderer {
|
|
|
108
95
|
}[], remaining: readonly {
|
|
109
96
|
readonly p0: Point2Like;
|
|
110
97
|
readonly p1: Point2Like;
|
|
111
|
-
}[], options
|
|
112
|
-
readonly linesLayer: string;
|
|
113
|
-
readonly animatedLinesLayer: string;
|
|
98
|
+
}[], options?: {
|
|
114
99
|
readonly resetAnimation?: boolean;
|
|
115
100
|
}): void;
|
|
116
101
|
/**
|
|
@@ -124,7 +109,7 @@ export interface WayfindingRenderer {
|
|
|
124
109
|
clearRoute(): void;
|
|
125
110
|
/** Commit buffered mutations to the renderer (via the injected `update`). */
|
|
126
111
|
flush(): void;
|
|
127
|
-
/** Full teardown
|
|
112
|
+
/** Full teardown: empties the host's layers, commits that, and clears the managers. */
|
|
128
113
|
destroy(): void;
|
|
129
114
|
}
|
|
130
115
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { WayfindingRuntime, WayfindingRuntimeConfig } from './types.js';
|
|
2
|
-
export declare function createWayfindingRuntime({ engine, renderer, iconProvider, floorContext,
|
|
2
|
+
export declare function createWayfindingRuntime({ engine, renderer, iconProvider, floorContext, snapThreshold, rerouteThreshold, onTransitionClick, onRouteUpdate, onRouteDistance, }: WayfindingRuntimeConfig): WayfindingRuntime;
|
|
3
3
|
//# sourceMappingURL=createWayfindingRuntime.d.ts.map
|
|
@@ -11,35 +11,24 @@ import { snapPositionToRoute } from './snapPositionToRoute.js';
|
|
|
11
11
|
import { createTrailView } from './trailView.js';
|
|
12
12
|
import { createTransitionView } from './transitionView.js';
|
|
13
13
|
const linesToPoints = (lines) => lines.flatMap((line) => [line.p0, line.p1]);
|
|
14
|
-
export function createWayfindingRuntime({ engine, renderer, iconProvider, floorContext,
|
|
14
|
+
export function createWayfindingRuntime({ engine, renderer, iconProvider, floorContext, snapThreshold, rerouteThreshold, onTransitionClick, onRouteUpdate, onRouteDistance, }) {
|
|
15
15
|
const rerouteController = createRerouteController(rerouteThreshold);
|
|
16
|
-
const endpoints = createEndpointView({
|
|
17
|
-
renderer,
|
|
18
|
-
iconProvider,
|
|
19
|
-
floorContext,
|
|
20
|
-
layer: layers.points,
|
|
21
|
-
});
|
|
16
|
+
const endpoints = createEndpointView({ renderer, iconProvider, floorContext });
|
|
22
17
|
const transitions = createTransitionView({
|
|
23
18
|
renderer,
|
|
24
19
|
iconProvider,
|
|
25
20
|
floorContext,
|
|
26
21
|
onTransitionClick,
|
|
27
|
-
layer: layers.points,
|
|
28
22
|
});
|
|
29
|
-
const trails = createTrailView({ renderer, iconProvider, floorContext
|
|
23
|
+
const trails = createTrailView({ renderer, iconProvider, floorContext });
|
|
30
24
|
const positionTrails = createPositionTrailView({
|
|
31
25
|
renderer,
|
|
32
26
|
iconProvider,
|
|
33
27
|
floorContext,
|
|
34
28
|
trails,
|
|
35
|
-
iconLayer: layers.currentPosition,
|
|
36
29
|
snapThreshold,
|
|
37
30
|
});
|
|
38
|
-
const routeLinesView = createRouteLinesView({
|
|
39
|
-
renderer,
|
|
40
|
-
linesLayer: layers.lines,
|
|
41
|
-
animatedLinesLayer: layers.linesAnimated,
|
|
42
|
-
});
|
|
31
|
+
const routeLinesView = createRouteLinesView({ renderer });
|
|
43
32
|
let routeLines = [];
|
|
44
33
|
let currentFrom = null;
|
|
45
34
|
let currentTo = null;
|
|
@@ -10,11 +10,10 @@ interface EndpointView {
|
|
|
10
10
|
place(from: RouteEndpoint, to: RouteEndpoint, visibleRoutePoints: readonly RoutePoint[], snapped: boolean): void;
|
|
11
11
|
hide(): void;
|
|
12
12
|
}
|
|
13
|
-
export declare function createEndpointView({ renderer, iconProvider, floorContext,
|
|
13
|
+
export declare function createEndpointView({ renderer, iconProvider, floorContext, }: {
|
|
14
14
|
renderer: Pick<WayfindingRenderer, 'setIcon'>;
|
|
15
15
|
iconProvider: Pick<IconProvider, 'getIcon'>;
|
|
16
16
|
floorContext: Pick<FloorContext, 'isLayerVisible'>;
|
|
17
|
-
layer: string;
|
|
18
17
|
}): EndpointView;
|
|
19
18
|
export {};
|
|
20
19
|
//# sourceMappingURL=endpointView.d.ts.map
|
|
@@ -3,7 +3,7 @@ function isSourceIconHidden(from, onFloor) {
|
|
|
3
3
|
// Hide only a kiosk anchor — an off-graph origin that isn't the live current position.
|
|
4
4
|
return !onFloor || (!from.bounds && from.id !== CURRENT_POSITION_POINT_ID);
|
|
5
5
|
}
|
|
6
|
-
export function createEndpointView({ renderer, iconProvider, floorContext,
|
|
6
|
+
export function createEndpointView({ renderer, iconProvider, floorContext, }) {
|
|
7
7
|
return {
|
|
8
8
|
place(from, to, visibleRoutePoints, snapped) {
|
|
9
9
|
if (!visibleRoutePoints.length)
|
|
@@ -15,7 +15,6 @@ export function createEndpointView({ renderer, iconProvider, floorContext, layer
|
|
|
15
15
|
const sourceInactive = from.id === CURRENT_POSITION_POINT_ID && snapped;
|
|
16
16
|
renderer.setIcon('source', {
|
|
17
17
|
canvas: iconProvider.getIcon(sourceInactive ? 'source_inactive' : 'source').canvas,
|
|
18
|
-
layer,
|
|
19
18
|
x: sourcePosition.x,
|
|
20
19
|
y: sourcePosition.y,
|
|
21
20
|
hidden: isSourceIconHidden(from, fromOnFloor),
|
|
@@ -24,7 +23,6 @@ export function createEndpointView({ renderer, iconProvider, floorContext, layer
|
|
|
24
23
|
});
|
|
25
24
|
renderer.setIcon('destination', {
|
|
26
25
|
canvas: iconProvider.getIcon('destination').canvas,
|
|
27
|
-
layer,
|
|
28
26
|
x: destPosition.x,
|
|
29
27
|
y: destPosition.y,
|
|
30
28
|
hidden: !toOnFloor || !to.bounds,
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { createWayfindingRuntime } from './createWayfindingRuntime.js';
|
|
2
2
|
export { CURRENT_POSITION_POINT_ID } from './positionView.js';
|
|
3
|
-
export type { FloorContext, IconAsset, IconName, IconProvider,
|
|
3
|
+
export type { FloorContext, IconAsset, IconName, IconProvider, PositionInput, SetRouteInput, WayfindingRuntime, WayfindingRuntimeConfig, } from './types.js';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -40,12 +40,11 @@ interface PositionTrailView {
|
|
|
40
40
|
/** Clear the trail slot (does not touch the icon). */
|
|
41
41
|
clearTrail(): void;
|
|
42
42
|
}
|
|
43
|
-
export declare function createPositionTrailView({ renderer, iconProvider, floorContext, trails,
|
|
43
|
+
export declare function createPositionTrailView({ renderer, iconProvider, floorContext, trails, snapThreshold, }: {
|
|
44
44
|
renderer: Pick<WayfindingRenderer, 'setIcon'>;
|
|
45
45
|
iconProvider: Pick<IconProvider, 'getIcon'>;
|
|
46
46
|
floorContext: Pick<FloorContext, 'isLayerVisible'>;
|
|
47
47
|
trails: TrailView;
|
|
48
|
-
iconLayer: string;
|
|
49
48
|
snapThreshold: number;
|
|
50
49
|
}): PositionTrailView;
|
|
51
50
|
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createPositionView } from './positionView.js';
|
|
2
2
|
import { snapPositionToRoute } from './snapPositionToRoute.js';
|
|
3
3
|
const TRAIL_SLOT = 'trail';
|
|
4
|
-
export function createPositionTrailView({ renderer, iconProvider, floorContext, trails,
|
|
5
|
-
const positionIcon = createPositionView({ renderer, iconProvider
|
|
4
|
+
export function createPositionTrailView({ renderer, iconProvider, floorContext, trails, snapThreshold, }) {
|
|
5
|
+
const positionIcon = createPositionView({ renderer, iconProvider });
|
|
6
6
|
return {
|
|
7
7
|
placeIcon(position) {
|
|
8
8
|
const hidden = !floorContext.isLayerVisible(position.layer);
|
|
@@ -14,10 +14,9 @@ interface PositionView {
|
|
|
14
14
|
place(input: PositionInput, hidden: boolean): void;
|
|
15
15
|
hide(): void;
|
|
16
16
|
}
|
|
17
|
-
export declare function createPositionView({ renderer, iconProvider,
|
|
17
|
+
export declare function createPositionView({ renderer, iconProvider, }: {
|
|
18
18
|
renderer: Pick<WayfindingRenderer, 'setIcon'>;
|
|
19
19
|
iconProvider: Pick<IconProvider, 'getIcon'>;
|
|
20
|
-
layer: string;
|
|
21
20
|
}): PositionView;
|
|
22
21
|
export {};
|
|
23
22
|
//# sourceMappingURL=positionView.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { degToRad } from '@expofp/geometry';
|
|
2
2
|
export const CURRENT_POSITION_POINT_ID = 'current-position';
|
|
3
3
|
const POSITION_ICON_KEY = 'position';
|
|
4
|
-
export function createPositionView({ renderer, iconProvider,
|
|
4
|
+
export function createPositionView({ renderer, iconProvider, }) {
|
|
5
5
|
return {
|
|
6
6
|
place(input, hidden) {
|
|
7
7
|
const hasHeading = Number.isFinite(input.heading);
|
|
@@ -9,7 +9,8 @@ export function createPositionView({ renderer, iconProvider, layer, }) {
|
|
|
9
9
|
const rotation = hasHeading ? degToRad(input.heading) : undefined;
|
|
10
10
|
renderer.setIcon(POSITION_ICON_KEY, {
|
|
11
11
|
canvas: iconProvider.getIcon(iconName).canvas,
|
|
12
|
-
|
|
12
|
+
// Above the route icons: the live position must never end up under an endpoint pin.
|
|
13
|
+
onTop: true,
|
|
13
14
|
x: input.x,
|
|
14
15
|
y: input.y,
|
|
15
16
|
rotation,
|
|
@@ -9,10 +9,8 @@ interface RouteLinesView {
|
|
|
9
9
|
/** Clear all rendered route lines + animated segments. */
|
|
10
10
|
clear(): void;
|
|
11
11
|
}
|
|
12
|
-
export declare function createRouteLinesView({ renderer,
|
|
12
|
+
export declare function createRouteLinesView({ renderer, }: {
|
|
13
13
|
renderer: Pick<WayfindingRenderer, 'setRouteLines'>;
|
|
14
|
-
linesLayer: string;
|
|
15
|
-
animatedLinesLayer: string;
|
|
16
14
|
}): RouteLinesView;
|
|
17
15
|
export {};
|
|
18
16
|
//# sourceMappingURL=routeLinesView.d.ts.map
|
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
export function createRouteLinesView({ renderer,
|
|
1
|
+
export function createRouteLinesView({ renderer, }) {
|
|
2
2
|
return {
|
|
3
3
|
draw({ passed, remaining }, preserveProgress = false) {
|
|
4
|
-
renderer.setRouteLines(passed, remaining, {
|
|
5
|
-
linesLayer,
|
|
6
|
-
animatedLinesLayer,
|
|
7
|
-
resetAnimation: !preserveProgress,
|
|
8
|
-
});
|
|
4
|
+
renderer.setRouteLines(passed, remaining, { resetAnimation: !preserveProgress });
|
|
9
5
|
},
|
|
10
6
|
clear() {
|
|
11
|
-
renderer.setRouteLines([], [], {
|
|
12
|
-
linesLayer,
|
|
13
|
-
animatedLinesLayer,
|
|
14
|
-
resetAnimation: true,
|
|
15
|
-
});
|
|
7
|
+
renderer.setRouteLines([], [], { resetAnimation: true });
|
|
16
8
|
},
|
|
17
9
|
};
|
|
18
10
|
}
|
|
@@ -11,10 +11,9 @@ export interface TrailView {
|
|
|
11
11
|
clear(slot: string): void;
|
|
12
12
|
clearAll(): void;
|
|
13
13
|
}
|
|
14
|
-
export declare function createTrailView({ renderer, iconProvider, floorContext,
|
|
14
|
+
export declare function createTrailView({ renderer, iconProvider, floorContext, }: {
|
|
15
15
|
renderer: Pick<WayfindingRenderer, 'setTrail'>;
|
|
16
16
|
iconProvider: Pick<IconProvider, 'getIcon'>;
|
|
17
17
|
floorContext: Pick<FloorContext, 'showAllFloors' | 'getActiveFloor'>;
|
|
18
|
-
layer: string;
|
|
19
18
|
}): TrailView;
|
|
20
19
|
//# sourceMappingURL=trailView.d.ts.map
|