@gustkit/mapbox-web 0.2.1 → 0.4.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.
@@ -43,6 +43,16 @@ export interface GustKitMapProps {
43
43
  * if the pointer stayed put — a drag/pan is a map gesture, not a long press.
44
44
  */
45
45
  onLongPress?: (info: GustKitMapHover) => void;
46
+ /** Fired when the camera settles — hosts re-derive camera-dependent layers. */
47
+ onCameraSettled?: () => void;
48
+ /**
49
+ * A plain tap/click on the map, suppressed when the gesture was a drag.
50
+ *
51
+ * Prefer this over {@link onLongPress} for anything people do often — dropping
52
+ * a forecast pin, for instance. A long press is a discoverability tax: nothing
53
+ * on screen says it exists, and on desktop it competes with text selection.
54
+ */
55
+ onPress?: (info: GustKitMapHover) => void;
46
56
  /** Long-press duration in ms (default 450). */
47
57
  longPressMs?: number;
48
58
  onFieldReady?: (rasterMs: number, pixels: number) => void;
@@ -52,5 +62,5 @@ export interface GustKitMapProps {
52
62
  * stack (field under labels, coastline, particles, isobars, arrows, centers),
53
63
  * and `loadView` on camera idle via {@link syncFieldSession}.
54
64
  */
55
- export declare function GustKitMap({ accessToken, source, product, timeMs, validTimes, layers, opacity, center, zoom, interactive, pad, marginTiles, particleCount, particleColor, downsample, arrowMode, styleURL, className, children, onMap, onHover, onLongPress, longPressMs, onFieldReady, }: GustKitMapProps): import("react/jsx-runtime").JSX.Element;
65
+ export declare function GustKitMap({ accessToken, source, product, timeMs, validTimes, layers, opacity, center, zoom, interactive, pad, marginTiles, particleCount, particleColor, downsample, arrowMode, styleURL, className, children, onMap, onHover, onLongPress, onPress, onCameraSettled, longPressMs, onFieldReady, }: GustKitMapProps): import("react/jsx-runtime").JSX.Element;
56
66
  //# sourceMappingURL=GustKitMap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GustKitMap.d.ts","sourceRoot":"","sources":["../src/GustKitMap.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGpE,OAAO,EACL,OAAO,EAMP,KAAK,aAAa,EACnB,MAAM,iBAAiB,CAAC;AAwBzB,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAgBD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,yEAAyE;IACzE,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,KAAK,IAAI,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IAC9C,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3D;AAoCD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,WAAW,EACX,MAAM,EACN,OAAO,EACP,MAAM,EACN,UAAU,EACV,MAAW,EACX,OAAa,EACb,MAAkB,EAClB,IAAQ,EACR,WAAkB,EAClB,GAAG,EACH,WAAW,EACX,aAAoB,EACpB,aAAuC,EACvC,UAAc,EACd,SAAkB,EAClB,QAAwB,EACxB,SAAS,EACT,QAAQ,EACR,KAAK,EACL,OAAO,EACP,WAAW,EACX,WAAiB,EACjB,YAAY,GACb,EAAE,eAAe,2CAwXjB"}
1
+ {"version":3,"file":"GustKitMap.d.ts","sourceRoot":"","sources":["../src/GustKitMap.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIpE,OAAO,EACL,OAAO,EASP,KAAK,aAAa,EACnB,MAAM,iBAAiB,CAAC;AAwBzB,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAgBD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,yEAAyE;IACzE,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,KAAK,IAAI,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IAC9C,+EAA+E;IAC/E,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IAC1C,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3D;AA+BD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,WAAW,EACX,MAAM,EACN,OAAO,EACP,MAAM,EACN,UAAU,EACV,MAAW,EACX,OAAa,EACb,MAAkB,EAClB,IAAQ,EACR,WAAkB,EAClB,GAAG,EACH,WAAW,EACX,aAAoB,EACpB,aAAuC,EACvC,UAAc,EACd,SAAkB,EAClB,QAAwB,EACxB,SAAS,EACT,QAAQ,EACR,KAAK,EACL,OAAO,EACP,WAAW,EACX,OAAO,EACP,eAAe,EACf,WAAiB,EACjB,YAAY,GACb,EAAE,eAAe,2CAyajB"}
@@ -2,7 +2,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useRef, useState } from "react";
3
3
  import mapboxgl from "mapbox-gl";
4
4
  import { CanvasParticleField } from "@gustkit/client/particles/canvas";
5
- import { Product, hasColorField, syncFieldSession, vectorAt, } from "@gustkit/client";
5
+ import { viewportBounds } from "./viewport";
6
+ import { Product, hasColorField, syncFieldSession, clipContours, contoursToGeoJSON, boundsToRegion, vectorAt, } from "@gustkit/client";
6
7
  import { fieldToDataUrl } from "./fieldPng.js";
7
8
  import { paintArrowGrid, paintArrowSpots, sparseArrowSpots } from "./arrows.js";
8
9
  import { ensureMapStyles } from "./styles.js";
@@ -37,10 +38,6 @@ function prefetchIsWorthIt() {
37
38
  return false;
38
39
  return !(c.effectiveType === "slow-2g" || c.effectiveType === "2g" || c.effectiveType === "3g");
39
40
  }
40
- function mapBounds(map) {
41
- const b = map.getBounds();
42
- return { west: b.getWest(), south: b.getSouth(), east: b.getEast(), north: b.getNorth() };
43
- }
44
41
  function quadOf(b) {
45
42
  return [
46
43
  [b.west, b.north],
@@ -51,7 +48,7 @@ function quadOf(b) {
51
48
  }
52
49
  function canvasAdapter(map) {
53
50
  return {
54
- getBounds: () => mapBounds(map),
51
+ getBounds: () => viewportBounds(map),
55
52
  getSize: () => {
56
53
  const el = map.getContainer();
57
54
  return { width: el.clientWidth, height: el.clientHeight };
@@ -73,13 +70,15 @@ function canvasAdapter(map) {
73
70
  * stack (field under labels, coastline, particles, isobars, arrows, centers),
74
71
  * and `loadView` on camera idle via {@link syncFieldSession}.
75
72
  */
76
- export function GustKitMap({ accessToken, source, product, timeMs, validTimes, layers = {}, opacity = 0.6, center = [-55, 32], zoom = 3, interactive = true, pad, marginTiles, particleCount = 1800, particleColor = "rgba(255,255,255,0.7)", downsample = 3, arrowMode = "grid", styleURL = DEFAULT_STYLE, className, children, onMap, onHover, onLongPress, longPressMs = 450, onFieldReady, }) {
73
+ export function GustKitMap({ accessToken, source, product, timeMs, validTimes, layers = {}, opacity = 0.6, center = [-55, 32], zoom = 3, interactive = true, pad, marginTiles, particleCount = 1800, particleColor = "rgba(255,255,255,0.7)", downsample = 3, arrowMode = "grid", styleURL = DEFAULT_STYLE, className, children, onMap, onHover, onLongPress, onPress, onCameraSettled, longPressMs = 450, onFieldReady, }) {
77
74
  const containerRef = useRef(null);
78
75
  const mapRef = useRef(null);
79
76
  const fieldRef = useRef(null);
80
77
  const arrowsCanvasRef = useRef(null);
81
78
  const markersRef = useRef([]);
82
79
  const [ready, setReady] = useState(false);
80
+ /** Bumped when the camera settles, so camera-clipped layers re-derive. */
81
+ const [cameraEpoch, setCameraEpoch] = useState(0);
83
82
  const propsRef = useRef({
84
83
  source,
85
84
  product,
@@ -95,6 +94,8 @@ export function GustKitMap({ accessToken, source, product, timeMs, validTimes, l
95
94
  onFieldReady,
96
95
  onHover,
97
96
  onLongPress,
97
+ onPress,
98
+ onCameraSettled,
98
99
  });
99
100
  propsRef.current = {
100
101
  source,
@@ -111,6 +112,8 @@ export function GustKitMap({ accessToken, source, product, timeMs, validTimes, l
111
112
  onFieldReady,
112
113
  onHover,
113
114
  onLongPress,
115
+ onPress,
116
+ onCameraSettled,
114
117
  };
115
118
  useEffect(() => {
116
119
  ensureMapStyles();
@@ -157,7 +160,7 @@ export function GustKitMap({ accessToken, source, product, timeMs, validTimes, l
157
160
  * the FIRST admin layer keeps them all above the weather.
158
161
  */
159
162
  const adminAnchor = map.getStyle().layers?.find((l) => l.id.startsWith("admin"))?.id;
160
- const b0 = mapBounds(map);
163
+ const b0 = viewportBounds(map);
161
164
  map.addSource("gk-field", { type: "image", url: TRANSPARENT_PX, coordinates: quadOf(b0) });
162
165
  map.addLayer({
163
166
  id: "gk-field",
@@ -194,7 +197,8 @@ export function GustKitMap({ accessToken, source, product, timeMs, validTimes, l
194
197
  particles.className = "gk-overlay gk-particles";
195
198
  cc.appendChild(particles);
196
199
  const field = new CanvasParticleField(particles, canvasAdapter(map), {
197
- sample: source.vectorSampler(product) ?? (() => null),
200
+ // Allocation-free: this loop samples twice per particle per frame.
201
+ sample: source.flowSampler(product) ?? source.vectorSampler(product) ?? (() => null),
198
202
  color: particleColor,
199
203
  count: particleCount,
200
204
  });
@@ -208,6 +212,9 @@ export function GustKitMap({ accessToken, source, product, timeMs, validTimes, l
208
212
  field.moveEnd();
209
213
  refreshField();
210
214
  drawArrows();
215
+ // Contours are clipped to the camera, so a new camera needs a new clip.
216
+ setCameraEpoch((n) => n + 1);
217
+ propsRef.current.onCameraSettled?.();
211
218
  });
212
219
  map.on("resize", () => {
213
220
  field.resize();
@@ -249,6 +256,27 @@ export function GustKitMap({ accessToken, source, product, timeMs, validTimes, l
249
256
  if (Math.hypot(e.point.x - pressStart.x, e.point.y - pressStart.y) > SLOP_PX)
250
257
  cancelPress();
251
258
  };
259
+ // A tap is a press that neither lingered nor travelled. Mapbox still emits
260
+ // `click` at the end of some drags, so the slop check is ours, not its.
261
+ let downPt = null;
262
+ let dragged = false;
263
+ const markDown = (e) => {
264
+ downPt = { x: e.point.x, y: e.point.y };
265
+ dragged = false;
266
+ };
267
+ const markMove = (e) => {
268
+ if (downPt && Math.hypot(e.point.x - downPt.x, e.point.y - downPt.y) > SLOP_PX)
269
+ dragged = true;
270
+ };
271
+ map.on("mousedown", markDown);
272
+ map.on("touchstart", markDown);
273
+ map.on("mousemove", markMove);
274
+ map.on("touchmove", markMove);
275
+ map.on("click", (e) => {
276
+ if (dragged)
277
+ return;
278
+ propsRef.current.onPress?.({ lon: e.lngLat.lng, lat: e.lngLat.lat, x: e.point.x, y: e.point.y });
279
+ });
252
280
  map.on("mousedown", beginPress);
253
281
  map.on("touchstart", beginPress);
254
282
  map.on("mousemove", movePress);
@@ -295,7 +323,7 @@ export function GustKitMap({ accessToken, source, product, timeMs, validTimes, l
295
323
  const h = el.clientHeight;
296
324
  if (w < 2 || h < 2 || p.timeMs <= 0)
297
325
  return;
298
- const bounds = mapBounds(map);
326
+ const bounds = viewportBounds(map);
299
327
  if (bounds.west === bounds.east || bounds.north <= bounds.south)
300
328
  return;
301
329
  const z = map.getZoom();
@@ -390,7 +418,7 @@ export function GustKitMap({ accessToken, source, product, timeMs, validTimes, l
390
418
  const field = fieldRef.current;
391
419
  if (!ready || !field)
392
420
  return;
393
- field.setSampler(source.vectorSampler(product) ?? (() => null));
421
+ field.setSampler(source.flowSampler(product) ?? source.vectorSampler(product) ?? (() => null));
394
422
  field.setEnabled((layers.particles ?? true) && product !== Product.Pressure);
395
423
  }, [ready, source, product, timeMs, layers.particles]);
396
424
  useEffect(() => {
@@ -399,27 +427,47 @@ export function GustKitMap({ accessToken, source, product, timeMs, validTimes, l
399
427
  return;
400
428
  const on = layers.isobars ?? false;
401
429
  map.setLayoutProperty("gk-isobars", "visibility", on ? "visible" : "none");
402
- if (!on)
430
+ // `timeMs` is 0 until the run's valid times arrive, and 0 formats as
431
+ // 1970-01-01 — a run that cannot exist. Fetching it is a guaranteed miss and
432
+ // a console error on every cold load.
433
+ if (!on || !(timeMs > 0))
403
434
  return;
404
435
  let cancelled = false;
405
436
  void source.fetchIsobars(timeMs).then((gj) => {
406
437
  if (cancelled)
407
438
  return;
408
439
  const src = map.getSource("gk-isobars");
409
- src?.setData(gj ?? EMPTY_FC);
440
+ if (!src)
441
+ return;
442
+ if (!gj) {
443
+ src.setData(EMPTY_FC);
444
+ return;
445
+ }
446
+ // Clip to the camera before handing it over. A published 4 hPa set is
447
+ // ~111k vertices, almost none of them on screen at a useful zoom, and every
448
+ // one of them costs GeoJSON parsing, tiling and a redraw inside Mapbox.
449
+ // Measured on this map: 111k -> a few thousand.
450
+ const el2 = map.getContainer();
451
+ const runs = clipContours({
452
+ contours: gj,
453
+ region: boundsToRegion(viewportBounds(map)),
454
+ width: Math.max(1, el2.clientWidth),
455
+ timeMs,
456
+ });
457
+ src.setData(contoursToGeoJSON(runs));
410
458
  });
411
459
  return () => {
412
460
  cancelled = true;
413
461
  };
414
- }, [ready, source, timeMs, layers.isobars]);
462
+ }, [ready, source, timeMs, layers.isobars, cameraEpoch]);
415
463
  useEffect(() => {
416
464
  const map = mapRef.current;
417
465
  if (!ready || !map)
418
466
  return;
419
467
  markersRef.current.forEach((m) => m.remove());
420
468
  markersRef.current = [];
421
- if (!layers.centers)
422
- return;
469
+ if (!layers.centers || !(timeMs > 0))
470
+ return; // see the 1970 note above
423
471
  let cancelled = false;
424
472
  void source.fetchCenters(timeMs).then((centers) => {
425
473
  if (cancelled)
@@ -1 +1 @@
1
- {"version":3,"file":"GustKitMap.js","sourceRoot":"","sources":["../src/GustKitMap.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GustKitMap.js","sourceRoot":"","sources":["../src/GustKitMap.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAiBA,wBAAgB,eAAe,IAAI,IAAI,CAOtC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAuBA,wBAAgB,eAAe,IAAI,IAAI,CAOtC"}
package/dist/styles.js CHANGED
@@ -1,5 +1,11 @@
1
1
  const CSS = `
2
- .gk-map-root{position:relative;width:100%;height:100%}
2
+ /* isolation: the map's internal z-indexes must not escape into the host page.
3
+ Markers, overlay canvases and chrome inside here carry z-indexes chosen to
4
+ order them against EACH OTHER; without a stacking context those numbers
5
+ compete with the embedding app's own UI, and a marker at z-index 30 paints
6
+ straight over a panel at 25. Isolating pins the whole map stack to this
7
+ element's level, where the host's ordering decides what sits on top. */
8
+ .gk-map-root{position:relative;width:100%;height:100%;isolation:isolate}
3
9
  .gk-map-canvas{position:absolute;inset:0}
4
10
  .gk-overlay{position:absolute;top:0;left:0;pointer-events:none}
5
11
  .gk-arrows{z-index:1}
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA,MAAM,GAAG,GAAG;;;;;;;;;;;;;CAaX,CAAC;AAEF,IAAI,QAAQ,GAAG,KAAK,CAAC;AAErB,MAAM,UAAU,eAAe;IAC7B,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO;IACxD,QAAQ,GAAG,IAAI,CAAC;IAChB,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC3C,EAAE,CAAC,OAAO,CAAC,OAAO,GAAG,YAAY,CAAC;IAClC,EAAE,CAAC,WAAW,GAAG,GAAG,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;CAmBX,CAAC;AAEF,IAAI,QAAQ,GAAG,KAAK,CAAC;AAErB,MAAM,UAAU,eAAe;IAC7B,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO;IACxD,QAAQ,GAAG,IAAI,CAAC;IAChB,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC3C,EAAE,CAAC,OAAO,CAAC,OAAO,GAAG,YAAY,CAAC;IAClC,EAAE,CAAC,WAAW,GAAG,GAAG,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { GeoBounds } from "@gustkit/client";
2
+ /**
3
+ * The little of a Mapbox map {@link viewportBounds} actually needs.
4
+ *
5
+ * Structural rather than `mapboxgl.Map` so the rule below can be tested without
6
+ * a WebGL context, a token or a DOM.
7
+ */
8
+ export interface ViewportMapLike {
9
+ getCanvas(): {
10
+ clientWidth: number;
11
+ clientHeight: number;
12
+ };
13
+ unproject(point: [number, number]): {
14
+ lng: number;
15
+ lat: number;
16
+ };
17
+ getBounds(): {
18
+ getWest(): number;
19
+ getSouth(): number;
20
+ getEast(): number;
21
+ getNorth(): number;
22
+ } | null;
23
+ }
24
+ /**
25
+ * The region the map actually PAINTS.
26
+ *
27
+ * Deliberately not `map.getBounds()`. That reports the bounds of the transform's
28
+ * PADDED rectangle, and `fitBounds(b, { padding })` — like any `easeTo` carrying
29
+ * padding — leaves that padding on the transform for good. One padded fit and
30
+ * `getBounds()` describes a box inset from the canvas from then on, so the tile
31
+ * plan, the raster quad and the particle sampler all get built for a region
32
+ * narrower than the view: down the side with the most padding the map shows a
33
+ * vertical band of bare basemap, no colour and no particles, and it never
34
+ * recovers on its own.
35
+ *
36
+ * Unprojecting the canvas corners ignores padding and cannot fall out of step
37
+ * with what is on screen. All four corners, so a rotated camera still yields a
38
+ * box that covers the view.
39
+ */
40
+ export declare function viewportBounds(map: ViewportMapLike): GeoBounds;
41
+ //# sourceMappingURL=viewport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewport.d.ts","sourceRoot":"","sources":["../src/viewport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,IAAI;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,SAAS,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACjE,SAAS,IAAI;QACX,OAAO,IAAI,MAAM,CAAC;QAClB,QAAQ,IAAI,MAAM,CAAC;QACnB,OAAO,IAAI,MAAM,CAAC;QAClB,QAAQ,IAAI,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;CACV;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,SAAS,CA+B9D"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The region the map actually PAINTS.
3
+ *
4
+ * Deliberately not `map.getBounds()`. That reports the bounds of the transform's
5
+ * PADDED rectangle, and `fitBounds(b, { padding })` — like any `easeTo` carrying
6
+ * padding — leaves that padding on the transform for good. One padded fit and
7
+ * `getBounds()` describes a box inset from the canvas from then on, so the tile
8
+ * plan, the raster quad and the particle sampler all get built for a region
9
+ * narrower than the view: down the side with the most padding the map shows a
10
+ * vertical band of bare basemap, no colour and no particles, and it never
11
+ * recovers on its own.
12
+ *
13
+ * Unprojecting the canvas corners ignores padding and cannot fall out of step
14
+ * with what is on screen. All four corners, so a rotated camera still yields a
15
+ * box that covers the view.
16
+ */
17
+ export function viewportBounds(map) {
18
+ const fromTransform = () => {
19
+ const b = map.getBounds();
20
+ return { west: b.getWest(), south: b.getSouth(), east: b.getEast(), north: b.getNorth() };
21
+ };
22
+ const c = map.getCanvas();
23
+ const w = c.clientWidth;
24
+ const h = c.clientHeight;
25
+ if (!(w >= 1) || !(h >= 1))
26
+ return fromTransform();
27
+ let west = Infinity;
28
+ let east = -Infinity;
29
+ let south = Infinity;
30
+ let north = -Infinity;
31
+ for (const pt of [
32
+ [0, 0],
33
+ [w, 0],
34
+ [w, h],
35
+ [0, h],
36
+ ]) {
37
+ const ll = map.unproject(pt);
38
+ // A steeply pitched camera can put a corner past the horizon, where
39
+ // unprojecting stops being meaningful. Rare, and padded bounds beat a
40
+ // garbage answer.
41
+ if (!Number.isFinite(ll.lng) || !Number.isFinite(ll.lat))
42
+ return fromTransform();
43
+ if (ll.lng < west)
44
+ west = ll.lng;
45
+ if (ll.lng > east)
46
+ east = ll.lng;
47
+ if (ll.lat < south)
48
+ south = ll.lat;
49
+ if (ll.lat > north)
50
+ north = ll.lat;
51
+ }
52
+ return { west, south, east, north };
53
+ }
54
+ //# sourceMappingURL=viewport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewport.js","sourceRoot":"","sources":["../src/viewport.ts"],"names":[],"mappings":"AAmBA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc,CAAC,GAAoB;IACjD,MAAM,aAAa,GAAG,GAAc,EAAE;QACpC,MAAM,CAAC,GAAG,GAAG,CAAC,SAAS,EAAG,CAAC;QAC3B,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC5F,CAAC,CAAC;IACF,MAAM,CAAC,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC;IAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC;IACzB,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,aAAa,EAAE,CAAC;IAEnD,IAAI,IAAI,GAAG,QAAQ,CAAC;IACpB,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC;IACrB,IAAI,KAAK,GAAG,QAAQ,CAAC;IACrB,IAAI,KAAK,GAAG,CAAC,QAAQ,CAAC;IACtB,KAAK,MAAM,EAAE,IAAI;QACf,CAAC,CAAC,EAAE,CAAC,CAAC;QACN,CAAC,CAAC,EAAE,CAAC,CAAC;QACN,CAAC,CAAC,EAAE,CAAC,CAAC;QACN,CAAC,CAAC,EAAE,CAAC,CAAC;KACe,EAAE,CAAC;QACxB,MAAM,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC7B,oEAAoE;QACpE,sEAAsE;QACtE,kBAAkB;QAClB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC;YAAE,OAAO,aAAa,EAAE,CAAC;QACjF,IAAI,EAAE,CAAC,GAAG,GAAG,IAAI;YAAE,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC;QACjC,IAAI,EAAE,CAAC,GAAG,GAAG,IAAI;YAAE,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC;QACjC,IAAI,EAAE,CAAC,GAAG,GAAG,KAAK;YAAE,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC;QACnC,IAAI,EAAE,CAAC,GAAG,GAAG,KAAK;YAAE,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC;IACrC,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACtC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gustkit/mapbox-web",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "description": "GustKitMap for the web — wraps Mapbox GL JS (ADR-016). Weather stack + loadView on camera idle; hosts pass token, camera, layers, children.",
5
5
  "license": "MIT",
6
6
  "author": "SeaPeople",
@@ -34,7 +34,7 @@
34
34
  "src"
35
35
  ],
36
36
  "dependencies": {
37
- "@gustkit/client": "0.2.1"
37
+ "@gustkit/client": "0.4.0"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "mapbox-gl": "^3.0.0",
@@ -46,11 +46,13 @@
46
46
  "@types/mapbox-gl": "^3.4.1",
47
47
  "@types/react": "^19.1.0",
48
48
  "mapbox-gl": "^3.9.0",
49
- "typescript": "^5.7.0"
49
+ "typescript": "^5.7.0",
50
+ "vitest": "^2.1.0"
50
51
  },
51
52
  "scripts": {
52
53
  "build": "rm -rf dist && tsc -p tsconfig.json",
53
54
  "typecheck": "tsc -p tsconfig.json --noEmit",
55
+ "test": "vitest run",
54
56
  "lint": "echo 'no lint configured (mapbox-web)'"
55
57
  }
56
58
  }
@@ -1,10 +1,14 @@
1
1
  import { useEffect, useRef, useState, type ReactNode } from "react";
2
2
  import mapboxgl from "mapbox-gl";
3
3
  import { CanvasParticleField, type CanvasProjectionAdapter } from "@gustkit/client/particles/canvas";
4
+ import { viewportBounds } from "./viewport";
4
5
  import {
5
6
  Product,
6
7
  hasColorField,
7
8
  syncFieldSession,
9
+ clipContours,
10
+ contoursToGeoJSON,
11
+ boundsToRegion,
8
12
  vectorAt,
9
13
  type FieldSessionRequest,
10
14
  type GeoBounds,
@@ -92,16 +96,21 @@ export interface GustKitMapProps {
92
96
  * if the pointer stayed put — a drag/pan is a map gesture, not a long press.
93
97
  */
94
98
  onLongPress?: (info: GustKitMapHover) => void;
99
+ /** Fired when the camera settles — hosts re-derive camera-dependent layers. */
100
+ onCameraSettled?: () => void;
101
+ /**
102
+ * A plain tap/click on the map, suppressed when the gesture was a drag.
103
+ *
104
+ * Prefer this over {@link onLongPress} for anything people do often — dropping
105
+ * a forecast pin, for instance. A long press is a discoverability tax: nothing
106
+ * on screen says it exists, and on desktop it competes with text selection.
107
+ */
108
+ onPress?: (info: GustKitMapHover) => void;
95
109
  /** Long-press duration in ms (default 450). */
96
110
  longPressMs?: number;
97
111
  onFieldReady?: (rasterMs: number, pixels: number) => void;
98
112
  }
99
113
 
100
- function mapBounds(map: mapboxgl.Map): GeoBounds {
101
- const b = map.getBounds()!;
102
- return { west: b.getWest(), south: b.getSouth(), east: b.getEast(), north: b.getNorth() };
103
- }
104
-
105
114
  function quadOf(b: GeoBounds): [[number, number], [number, number], [number, number], [number, number]] {
106
115
  return [
107
116
  [b.west, b.north],
@@ -113,7 +122,7 @@ function quadOf(b: GeoBounds): [[number, number], [number, number], [number, num
113
122
 
114
123
  function canvasAdapter(map: mapboxgl.Map): CanvasProjectionAdapter {
115
124
  return {
116
- getBounds: () => mapBounds(map),
125
+ getBounds: () => viewportBounds(map),
117
126
  getSize: () => {
118
127
  const el = map.getContainer();
119
128
  return { width: el.clientWidth, height: el.clientHeight };
@@ -159,6 +168,8 @@ export function GustKitMap({
159
168
  onMap,
160
169
  onHover,
161
170
  onLongPress,
171
+ onPress,
172
+ onCameraSettled,
162
173
  longPressMs = 450,
163
174
  onFieldReady,
164
175
  }: GustKitMapProps) {
@@ -168,6 +179,8 @@ export function GustKitMap({
168
179
  const arrowsCanvasRef = useRef<HTMLCanvasElement | null>(null);
169
180
  const markersRef = useRef<mapboxgl.Marker[]>([]);
170
181
  const [ready, setReady] = useState(false);
182
+ /** Bumped when the camera settles, so camera-clipped layers re-derive. */
183
+ const [cameraEpoch, setCameraEpoch] = useState(0);
171
184
  const propsRef = useRef({
172
185
  source,
173
186
  product,
@@ -183,6 +196,8 @@ export function GustKitMap({
183
196
  onFieldReady,
184
197
  onHover,
185
198
  onLongPress,
199
+ onPress,
200
+ onCameraSettled,
186
201
  });
187
202
  propsRef.current = {
188
203
  source,
@@ -199,6 +214,8 @@ export function GustKitMap({
199
214
  onFieldReady,
200
215
  onHover,
201
216
  onLongPress,
217
+ onPress,
218
+ onCameraSettled,
202
219
  };
203
220
 
204
221
  useEffect(() => {
@@ -247,7 +264,7 @@ export function GustKitMap({
247
264
  * the FIRST admin layer keeps them all above the weather.
248
265
  */
249
266
  const adminAnchor = map.getStyle().layers?.find((l) => l.id.startsWith("admin"))?.id;
250
- const b0 = mapBounds(map);
267
+ const b0 = viewportBounds(map);
251
268
  map.addSource("gk-field", { type: "image", url: TRANSPARENT_PX, coordinates: quadOf(b0) });
252
269
  map.addLayer(
253
270
  {
@@ -292,7 +309,8 @@ export function GustKitMap({
292
309
  particles.className = "gk-overlay gk-particles";
293
310
  cc.appendChild(particles);
294
311
  const field = new CanvasParticleField(particles, canvasAdapter(map), {
295
- sample: source.vectorSampler(product) ?? (() => null),
312
+ // Allocation-free: this loop samples twice per particle per frame.
313
+ sample: source.flowSampler(product) ?? source.vectorSampler(product) ?? (() => null),
296
314
  color: particleColor,
297
315
  count: particleCount,
298
316
  });
@@ -307,6 +325,9 @@ export function GustKitMap({
307
325
  field.moveEnd();
308
326
  refreshField();
309
327
  drawArrows();
328
+ // Contours are clipped to the camera, so a new camera needs a new clip.
329
+ setCameraEpoch((n) => n + 1);
330
+ propsRef.current.onCameraSettled?.();
310
331
  });
311
332
  map.on("resize", () => {
312
333
  field.resize();
@@ -345,6 +366,26 @@ export function GustKitMap({
345
366
  if (!pressStart) return;
346
367
  if (Math.hypot(e.point.x - pressStart.x, e.point.y - pressStart.y) > SLOP_PX) cancelPress();
347
368
  };
369
+ // A tap is a press that neither lingered nor travelled. Mapbox still emits
370
+ // `click` at the end of some drags, so the slop check is ours, not its.
371
+ let downPt: { x: number; y: number } | null = null;
372
+ let dragged = false;
373
+ const markDown = (e: mapboxgl.MapMouseEvent | mapboxgl.MapTouchEvent) => {
374
+ downPt = { x: e.point.x, y: e.point.y };
375
+ dragged = false;
376
+ };
377
+ const markMove = (e: mapboxgl.MapMouseEvent | mapboxgl.MapTouchEvent) => {
378
+ if (downPt && Math.hypot(e.point.x - downPt.x, e.point.y - downPt.y) > SLOP_PX) dragged = true;
379
+ };
380
+ map.on("mousedown", markDown);
381
+ map.on("touchstart", markDown);
382
+ map.on("mousemove", markMove);
383
+ map.on("touchmove", markMove);
384
+ map.on("click", (e) => {
385
+ if (dragged) return;
386
+ propsRef.current.onPress?.({ lon: e.lngLat.lng, lat: e.lngLat.lat, x: e.point.x, y: e.point.y });
387
+ });
388
+
348
389
  map.on("mousedown", beginPress);
349
390
  map.on("touchstart", beginPress);
350
391
  map.on("mousemove", movePress);
@@ -393,7 +434,7 @@ export function GustKitMap({
393
434
  const w = el.clientWidth;
394
435
  const h = el.clientHeight;
395
436
  if (w < 2 || h < 2 || p.timeMs <= 0) return;
396
- const bounds = mapBounds(map);
437
+ const bounds = viewportBounds(map);
397
438
  if (bounds.west === bounds.east || bounds.north <= bounds.south) return;
398
439
  const z = map.getZoom();
399
440
  const gen = ((map as unknown as { _gkFieldGen?: number })._gkFieldGen ?? 0) + 1;
@@ -481,7 +522,7 @@ export function GustKitMap({
481
522
  useEffect(() => {
482
523
  const field = fieldRef.current;
483
524
  if (!ready || !field) return;
484
- field.setSampler(source.vectorSampler(product) ?? (() => null));
525
+ field.setSampler(source.flowSampler(product) ?? source.vectorSampler(product) ?? (() => null));
485
526
  field.setEnabled((layers.particles ?? true) && product !== Product.Pressure);
486
527
  }, [ready, source, product, timeMs, layers.particles]);
487
528
 
@@ -490,24 +531,43 @@ export function GustKitMap({
490
531
  if (!ready || !map || !map.getLayer("gk-isobars")) return;
491
532
  const on = layers.isobars ?? false;
492
533
  map.setLayoutProperty("gk-isobars", "visibility", on ? "visible" : "none");
493
- if (!on) return;
534
+ // `timeMs` is 0 until the run's valid times arrive, and 0 formats as
535
+ // 1970-01-01 — a run that cannot exist. Fetching it is a guaranteed miss and
536
+ // a console error on every cold load.
537
+ if (!on || !(timeMs > 0)) return;
494
538
  let cancelled = false;
495
539
  void source.fetchIsobars(timeMs).then((gj) => {
496
540
  if (cancelled) return;
497
541
  const src = map.getSource("gk-isobars") as mapboxgl.GeoJSONSource | undefined;
498
- src?.setData(gj ?? EMPTY_FC);
542
+ if (!src) return;
543
+ if (!gj) {
544
+ src.setData(EMPTY_FC);
545
+ return;
546
+ }
547
+ // Clip to the camera before handing it over. A published 4 hPa set is
548
+ // ~111k vertices, almost none of them on screen at a useful zoom, and every
549
+ // one of them costs GeoJSON parsing, tiling and a redraw inside Mapbox.
550
+ // Measured on this map: 111k -> a few thousand.
551
+ const el2 = map.getContainer();
552
+ const runs = clipContours({
553
+ contours: gj,
554
+ region: boundsToRegion(viewportBounds(map)),
555
+ width: Math.max(1, el2.clientWidth),
556
+ timeMs,
557
+ });
558
+ src.setData(contoursToGeoJSON(runs) as unknown as GeoJSON.FeatureCollection);
499
559
  });
500
560
  return () => {
501
561
  cancelled = true;
502
562
  };
503
- }, [ready, source, timeMs, layers.isobars]);
563
+ }, [ready, source, timeMs, layers.isobars, cameraEpoch]);
504
564
 
505
565
  useEffect(() => {
506
566
  const map = mapRef.current;
507
567
  if (!ready || !map) return;
508
568
  markersRef.current.forEach((m) => m.remove());
509
569
  markersRef.current = [];
510
- if (!layers.centers) return;
570
+ if (!layers.centers || !(timeMs > 0)) return; // see the 1970 note above
511
571
  let cancelled = false;
512
572
  void source.fetchCenters(timeMs).then((centers) => {
513
573
  if (cancelled) return;
package/src/styles.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  const CSS = `
2
- .gk-map-root{position:relative;width:100%;height:100%}
2
+ /* isolation: the map's internal z-indexes must not escape into the host page.
3
+ Markers, overlay canvases and chrome inside here carry z-indexes chosen to
4
+ order them against EACH OTHER; without a stacking context those numbers
5
+ compete with the embedding app's own UI, and a marker at z-index 30 paints
6
+ straight over a panel at 25. Isolating pins the whole map stack to this
7
+ element's level, where the host's ordering decides what sits on top. */
8
+ .gk-map-root{position:relative;width:100%;height:100%;isolation:isolate}
3
9
  .gk-map-canvas{position:absolute;inset:0}
4
10
  .gk-overlay{position:absolute;top:0;left:0;pointer-events:none}
5
11
  .gk-arrows{z-index:1}
@@ -0,0 +1,93 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { viewportBounds, type ViewportMapLike } from "./viewport";
3
+
4
+ /**
5
+ * A north-up Web-Mercator camera, modelled the way Mapbox behaves.
6
+ *
7
+ * The point of the fake is the split that caused the bug: `unproject` works off
8
+ * the whole canvas, while `getBounds` reports only the padded rectangle. Both
9
+ * are derived from one camera here, so the test cannot drift from the real
10
+ * relationship between them.
11
+ */
12
+ function fakeMap({
13
+ width,
14
+ height,
15
+ west,
16
+ east,
17
+ north,
18
+ south,
19
+ padding = { top: 0, right: 0, bottom: 0, left: 0 },
20
+ }: {
21
+ width: number;
22
+ height: number;
23
+ west: number;
24
+ east: number;
25
+ north: number;
26
+ south: number;
27
+ padding?: { top: number; right: number; bottom: number; left: number };
28
+ }): ViewportMapLike {
29
+ // Linear in lon/lat is not Mercator, but it is monotonic in both axes, which
30
+ // is all the corner-picking under test depends on.
31
+ const at = ([x, y]: [number, number]) => ({
32
+ lng: west + ((east - west) * x) / width,
33
+ lat: north - ((north - south) * y) / height,
34
+ });
35
+ return {
36
+ getCanvas: () => ({ clientWidth: width, clientHeight: height }),
37
+ unproject: at,
38
+ getBounds: () => {
39
+ const tl = at([padding.left, padding.top]);
40
+ const br = at([width - padding.right, height - padding.bottom]);
41
+ return {
42
+ getWest: () => tl.lng,
43
+ getNorth: () => tl.lat,
44
+ getEast: () => br.lng,
45
+ getSouth: () => br.lat,
46
+ };
47
+ },
48
+ };
49
+ }
50
+
51
+ const VIEW = { width: 375, height: 812, west: -64, east: -60, north: 46, south: 43 };
52
+
53
+ describe("viewportBounds", () => {
54
+ it("matches the canvas when no padding is set", () => {
55
+ const b = viewportBounds(fakeMap(VIEW));
56
+ expect(b).toEqual({ west: -64, east: -60, north: 46, south: 43 });
57
+ });
58
+
59
+ it("still covers the whole canvas after a padded fitBounds", () => {
60
+ // The regression. `fitBounds(b, { padding })` leaves the padding on the
61
+ // transform, so `getBounds()` now describes an inset box — on a 375px phone
62
+ // the route panel's 82px right padding left a vertical band of the map with
63
+ // no forecast and no particles.
64
+ const padded = fakeMap({ ...VIEW, padding: { top: 96, right: 82, bottom: 240, left: 37 } });
65
+
66
+ const reported = padded.getBounds()!;
67
+ expect(reported.getEast()).toBeLessThan(VIEW.east); // the trap is real
68
+ expect(reported.getWest()).toBeGreaterThan(VIEW.west);
69
+
70
+ const b = viewportBounds(padded);
71
+ expect(b.west).toBeCloseTo(VIEW.west, 10);
72
+ expect(b.east).toBeCloseTo(VIEW.east, 10);
73
+ expect(b.north).toBeCloseTo(VIEW.north, 10);
74
+ expect(b.south).toBeCloseTo(VIEW.south, 10);
75
+ });
76
+
77
+ it("falls back to the reported bounds when the canvas has no size", () => {
78
+ // Before the first layout there are no corners worth unprojecting.
79
+ const m = fakeMap({ ...VIEW, width: 0, height: 0 });
80
+ expect(() => viewportBounds(m)).not.toThrow();
81
+ });
82
+
83
+ it("falls back to the reported bounds when a corner unprojects past the horizon", () => {
84
+ const base = fakeMap(VIEW);
85
+ const m: ViewportMapLike = {
86
+ ...base,
87
+ unproject: (p) => (p[1] === 0 ? { lng: NaN, lat: NaN } : base.unproject(p)),
88
+ };
89
+ const b = viewportBounds(m);
90
+ expect(Number.isFinite(b.west)).toBe(true);
91
+ expect(Number.isFinite(b.north)).toBe(true);
92
+ });
93
+ });
@@ -0,0 +1,67 @@
1
+ import type { GeoBounds } from "@gustkit/client";
2
+
3
+ /**
4
+ * The little of a Mapbox map {@link viewportBounds} actually needs.
5
+ *
6
+ * Structural rather than `mapboxgl.Map` so the rule below can be tested without
7
+ * a WebGL context, a token or a DOM.
8
+ */
9
+ export interface ViewportMapLike {
10
+ getCanvas(): { clientWidth: number; clientHeight: number };
11
+ unproject(point: [number, number]): { lng: number; lat: number };
12
+ getBounds(): {
13
+ getWest(): number;
14
+ getSouth(): number;
15
+ getEast(): number;
16
+ getNorth(): number;
17
+ } | null;
18
+ }
19
+
20
+ /**
21
+ * The region the map actually PAINTS.
22
+ *
23
+ * Deliberately not `map.getBounds()`. That reports the bounds of the transform's
24
+ * PADDED rectangle, and `fitBounds(b, { padding })` — like any `easeTo` carrying
25
+ * padding — leaves that padding on the transform for good. One padded fit and
26
+ * `getBounds()` describes a box inset from the canvas from then on, so the tile
27
+ * plan, the raster quad and the particle sampler all get built for a region
28
+ * narrower than the view: down the side with the most padding the map shows a
29
+ * vertical band of bare basemap, no colour and no particles, and it never
30
+ * recovers on its own.
31
+ *
32
+ * Unprojecting the canvas corners ignores padding and cannot fall out of step
33
+ * with what is on screen. All four corners, so a rotated camera still yields a
34
+ * box that covers the view.
35
+ */
36
+ export function viewportBounds(map: ViewportMapLike): GeoBounds {
37
+ const fromTransform = (): GeoBounds => {
38
+ const b = map.getBounds()!;
39
+ return { west: b.getWest(), south: b.getSouth(), east: b.getEast(), north: b.getNorth() };
40
+ };
41
+ const c = map.getCanvas();
42
+ const w = c.clientWidth;
43
+ const h = c.clientHeight;
44
+ if (!(w >= 1) || !(h >= 1)) return fromTransform();
45
+
46
+ let west = Infinity;
47
+ let east = -Infinity;
48
+ let south = Infinity;
49
+ let north = -Infinity;
50
+ for (const pt of [
51
+ [0, 0],
52
+ [w, 0],
53
+ [w, h],
54
+ [0, h],
55
+ ] as [number, number][]) {
56
+ const ll = map.unproject(pt);
57
+ // A steeply pitched camera can put a corner past the horizon, where
58
+ // unprojecting stops being meaningful. Rare, and padded bounds beat a
59
+ // garbage answer.
60
+ if (!Number.isFinite(ll.lng) || !Number.isFinite(ll.lat)) return fromTransform();
61
+ if (ll.lng < west) west = ll.lng;
62
+ if (ll.lng > east) east = ll.lng;
63
+ if (ll.lat < south) south = ll.lat;
64
+ if (ll.lat > north) north = ll.lat;
65
+ }
66
+ return { west, south, east, north };
67
+ }