@nika-js/onlymap 0.6.17 → 0.6.18
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/CHANGELOG.md +11 -0
- package/dist/{LercDecode.es-DjPA9zLm.js → LercDecode.es-CFkuAghv.js} +1 -1
- package/dist/{basemap-DwN5jPCj.js → basemap-BYsWqrqp.js} +9 -1
- package/dist/basemap.d.ts +6 -0
- package/dist/declarative-filter.d.ts +1 -0
- package/dist/effects.d.ts +14 -2
- package/dist/elements/om-map.d.ts +15 -0
- package/dist/elements/om-story.d.ts +3 -1
- package/dist/{geoparquet-DG3VtNgs.js → geoparquet-C5ezOpDN.js} +1 -1
- package/dist/{index-DlXIfdhF.js → index-B0qtzfOX.js} +1 -1
- package/dist/{index-DceORL-v.js → index-C7pRTBjN.js} +2 -2
- package/dist/{index-Yl9rVUWh.js → index-PHDt5jos.js} +1 -1
- package/dist/{index-BM-txQRw.js → index-T1jT84TY.js} +1 -1
- package/dist/{index-CX4qxgVT.js → index-h5A4LBtR.js} +11532 -11299
- package/dist/{lerc-BD1Any2Z.js → lerc-B8gvl7FV.js} +2 -2
- package/dist/onlymap.standalone.js +21863 -21622
- package/dist/onlymapjs.js +1 -1
- package/dist/paced-flyby.d.ts +18 -0
- package/dist/programmatic.d.ts +9 -0
- package/dist/{raster-Cv5w_kS7.js → raster-B8bDaA3c.js} +2 -2
- package/dist/{raster-pipeline-Nl0EF5em.js → raster-pipeline-BLKrUZxU.js} +1 -1
- package/dist/runtime-core.d.ts +15 -0
- package/dist/surface-anchor.d.ts +17 -0
- package/dist/version.d.ts +1 -1
- package/dist/{zarr-aau6eARi.js → zarr-Y8OewWSs.js} +2 -2
- package/docs/design/trace-link-failure.md +20 -0
- package/llms.txt +2 -0
- package/onlymapjs.html-data.json +31 -0
- package/package.json +1 -1
- package/skills/onlymapjs/SKILL.md +1 -1
- package/skills/onlymapjs/references/syntax.md +4 -2
package/dist/onlymapjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { aA as e, aB as r, aC as t, aD as o, aE as b, aF as i, ap as l, aG as n, aH as S, aI as g, aJ as c, aK as E, aL as L, aM as T, aN as A, aO as d, aP as p, aQ as m, aR as _, aS as I, aT as u, aU as M, aV as y, aW as D, ao as O, aX as R, aw as f, aY as N, aZ as P, a_ as h, W as F, a$ as B, b0 as C, b1 as v, b2 as G, b3 as U, b4 as W, b5 as w, b6 as x, b7 as Y, b8 as H, b9 as X, ba as k, bb as J, bc as K, bd as V, be as z, bf as Q, bg as Z, bh as $, bi as j, bj as q, bk as aa, bl as sa, bm as ea, bn as ra, bo as ta, bp as oa, bq as ba, br as ia, bs as la, bt as na, bu as Sa, bv as ga, bw as ca, bx as Ea, by as La, bz as Ta, bA as Aa, bB as da, bC as pa, bD as ma, bE as _a, bF as Ia, bG as ua, bH as Ma, bI as ya, bJ as Da, bK as Oa, bL as Ra, bM as fa, bN as Na, bO as Pa, bP as ha, bQ as Fa, bR as Ba, bS as Ca, bT as va, bU as Ga, bV as Ua, bW as Wa, bX as wa, bY as xa, bZ as Ya, b_ as Ha, b$ as Xa, c0 as ka, c1 as Ja, c2 as Ka, c3 as Va, c4 as za, c5 as Qa, c6 as Za } from "./index-
|
|
1
|
+
import { aA as e, aB as r, aC as t, aD as o, aE as b, aF as i, ap as l, aG as n, aH as S, aI as g, aJ as c, aK as E, aL as L, aM as T, aN as A, aO as d, aP as p, aQ as m, aR as _, aS as I, aT as u, aU as M, aV as y, aW as D, ao as O, aX as R, aw as f, aY as N, aZ as P, a_ as h, W as F, a$ as B, b0 as C, b1 as v, b2 as G, b3 as U, b4 as W, b5 as w, b6 as x, b7 as Y, b8 as H, b9 as X, ba as k, bb as J, bc as K, bd as V, be as z, bf as Q, bg as Z, bh as $, bi as j, bj as q, bk as aa, bl as sa, bm as ea, bn as ra, bo as ta, bp as oa, bq as ba, br as ia, bs as la, bt as na, bu as Sa, bv as ga, bw as ca, bx as Ea, by as La, bz as Ta, bA as Aa, bB as da, bC as pa, bD as ma, bE as _a, bF as Ia, bG as ua, bH as Ma, bI as ya, bJ as Da, bK as Oa, bL as Ra, bM as fa, bN as Na, bO as Pa, bP as ha, bQ as Fa, bR as Ba, bS as Ca, bT as va, bU as Ga, bV as Ua, bW as Wa, bX as wa, bY as xa, bZ as Ya, b_ as Ha, b$ as Xa, c0 as ka, c1 as Ja, c2 as Ka, c3 as Va, c4 as za, c5 as Qa, c6 as Za } from "./index-h5A4LBtR.js";
|
|
2
2
|
export {
|
|
3
3
|
e as ALL_POSITION_VALUES,
|
|
4
4
|
r as AUDIT_EXEMPTIONS,
|
package/dist/paced-flyby.d.ts
CHANGED
|
@@ -49,3 +49,21 @@ export interface PacedFlybyDeps {
|
|
|
49
49
|
maxWaitPerFrameMs?: number;
|
|
50
50
|
}
|
|
51
51
|
export declare function runPacedFlyby(deps: PacedFlybyDeps): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* One settle pass (issue #37's whenSettled contract, shared with the paced
|
|
54
|
+
* driver's per-frame gate): resolve once `loaded()` reports true AND one
|
|
55
|
+
* further animation frame has been drawn — loaded tile data still needs a
|
|
56
|
+
* draw to reach pixels. Times out to {settled:false} rather than rejecting
|
|
57
|
+
* (the paced-max-hold degradation posture: a late frame is ordinary pop-in,
|
|
58
|
+
* not an error).
|
|
59
|
+
*/
|
|
60
|
+
export declare function settleOnce(deps: {
|
|
61
|
+
loaded(): boolean;
|
|
62
|
+
timeoutMs: number;
|
|
63
|
+
aborted?(): boolean;
|
|
64
|
+
raf?(): Promise<void>;
|
|
65
|
+
now?(): number;
|
|
66
|
+
}): Promise<{
|
|
67
|
+
settled: boolean;
|
|
68
|
+
waitedMs: number;
|
|
69
|
+
}>;
|
package/dist/programmatic.d.ts
CHANGED
|
@@ -171,6 +171,7 @@ export type PickListener = (selection: Selection | null) => void;
|
|
|
171
171
|
* DOM-manifest concern. One controller per map container.
|
|
172
172
|
*/
|
|
173
173
|
export declare class MapController {
|
|
174
|
+
private firstSettleDrawDone;
|
|
174
175
|
private core;
|
|
175
176
|
private mount;
|
|
176
177
|
private layerIRs;
|
|
@@ -321,5 +322,13 @@ export declare class MapController {
|
|
|
321
322
|
resume(): void;
|
|
322
323
|
/** Projects a lng/lat through the current viewport — undefined before the viewport resolves. */
|
|
323
324
|
project(lngLat: [number, number]): [number, number] | undefined;
|
|
325
|
+
/** Issue #37 — the controller-lane twin of om-map.whenSettled(): resolves once every live 3D tileset has refined for the current view plus one painted frame; {settled:false} + warning on timeout. */
|
|
326
|
+
whenSettled(opts?: {
|
|
327
|
+
timeout?: number;
|
|
328
|
+
}): Promise<{
|
|
329
|
+
settled: boolean;
|
|
330
|
+
}>;
|
|
331
|
+
/** Issue #37 — the determinism switch: while on, camera moves land instantly, effect verbs snap to end state, and GPU transitions are disabled, so a captured frame is a pure function of story time. */
|
|
332
|
+
setDeterministic(on: boolean): void;
|
|
324
333
|
destroy(): void;
|
|
325
334
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as re, t as Ae, i as nt, a as Re, s as rt, C as ot, b as it, F as at, A as st, d as lt, R as he, e as ct, p as ut, m as dt, f as ht, g as pt, h as gt } from "./raster-pipeline-
|
|
1
|
+
import { c as re, t as Ae, i as nt, a as Re, s as rt, C as ot, b as it, F as at, A as st, d as lt, R as he, e as ct, p as ut, m as dt, f as ht, g as pt, h as gt } from "./raster-pipeline-BLKrUZxU.js";
|
|
2
2
|
import pe from "./index-CW1n5LdO.js";
|
|
3
3
|
function mt(e, t) {
|
|
4
4
|
const n = e.length / 3, r = new Uint8ClampedArray(n * 4), o = 0, i = n, a = n * 2;
|
|
@@ -1069,7 +1069,7 @@ A.set(m.Zstd, () => import("./zstd-jXobGRcq.js").then((e) => e.decode));
|
|
|
1069
1069
|
A.set(m.Jpeg, () => Promise.resolve(oe));
|
|
1070
1070
|
A.set(m.Jpeg6, () => Promise.resolve(oe));
|
|
1071
1071
|
A.set(m.Webp, () => Promise.resolve(oe));
|
|
1072
|
-
A.set(m.Lerc, () => import("./lerc-
|
|
1072
|
+
A.set(m.Lerc, () => import("./lerc-B8gvl7FV.js").then((e) => e.l).then((e) => e.decode));
|
|
1073
1073
|
async function ie(e, t, n) {
|
|
1074
1074
|
const r = A.get(t);
|
|
1075
1075
|
if (!r)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { w as ae } from "./mgrs-BY9bIvp4.js";
|
|
2
|
-
import { am as ce, an as le, ao as ee, ap as te, aq as ue, b as he, ar as de, l as Z, as as fe, d as pe, at as me, au as ge, av as ve, aw as ne } from "./index-
|
|
2
|
+
import { am as ce, an as le, ao as ee, ap as te, aq as ue, b as he, ar as de, l as Z, as as fe, d as pe, at as me, au as ge, av as ve, aw as ne } from "./index-h5A4LBtR.js";
|
|
3
3
|
function Pe(o, e, t) {
|
|
4
4
|
const { projectedCorners: n } = e, { topLeft: s, topRight: r, bottomRight: a, bottomLeft: i } = n, c = t(s[0], s[1]), u = t(r[0], r[1]), l = t(a[0], a[1]), d = t(i[0], i[1]), f = [
|
|
5
5
|
c,
|
package/dist/runtime-core.d.ts
CHANGED
|
@@ -277,6 +277,15 @@ export declare class RuntimeCore {
|
|
|
277
277
|
private headless?;
|
|
278
278
|
/** Animated-props flush coalescing (see patchAnimatedProps): patches since the last rebuild / a microtask flush already queued. */
|
|
279
279
|
private animatedDirty;
|
|
280
|
+
/**
|
|
281
|
+
* The determinism switch (issue #37; set from om-map's data-om-recording
|
|
282
|
+
* attribute or MapController.setDeterministic): while on, NOTHING animates
|
|
283
|
+
* on the wall clock — camera moves land instantly, effect verbs snap to
|
|
284
|
+
* their end state, GPU transitions are zeroed at parse — so a frame
|
|
285
|
+
* captured after whenSettled() is a pure function of story time, and
|
|
286
|
+
* frame N renders byte-identically across processes and orderings.
|
|
287
|
+
*/
|
|
288
|
+
private deterministic;
|
|
280
289
|
/** layerId → live loaders.gl Tileset3D (see tilesetHook in buildLayers). */
|
|
281
290
|
private liveTilesets;
|
|
282
291
|
/** The lastIRs reference getLiveTilesets last pruned against (see its comment). */
|
|
@@ -509,6 +518,10 @@ export declare class RuntimeCore {
|
|
|
509
518
|
* consumers rendering exports must add provider credits themselves.
|
|
510
519
|
* Headless rejects (no renderer); pre-ready rejects (await map.ready).
|
|
511
520
|
*/
|
|
521
|
+
/** deck's own per-layer readiness (async layer/pipeline init) — whenSettled gates on this too; a capture before it is stably missing content (issue #37's flaky first frame). Headless/basemap-pending count as ready. */
|
|
522
|
+
layersReady(): boolean;
|
|
523
|
+
/** Force one renderer draw without capturing (issue #37 — whenSettled's completed-render guarantee; a fresh page's first capture otherwise misses content that has never drawn). */
|
|
524
|
+
forceDraw(): void;
|
|
512
525
|
snapshot(): Promise<HTMLCanvasElement>;
|
|
513
526
|
/**
|
|
514
527
|
* Live basemap change (spec: "Basemap presets & switching"), both paths:
|
|
@@ -616,6 +629,8 @@ export declare class RuntimeCore {
|
|
|
616
629
|
* center/zoom delegate to the basemap's camera (which owns the view) and
|
|
617
630
|
* pitch/bearing are a documented not-yet gap there.
|
|
618
631
|
*/
|
|
632
|
+
setDeterministic(on: boolean): void;
|
|
633
|
+
isDeterministic(): boolean;
|
|
619
634
|
setViewState(partial: Partial<ViewState>, opts?: CameraOptions): void;
|
|
620
635
|
/**
|
|
621
636
|
* Recenters and rezooms to fit a `[[minLng,minLat],[maxLng,maxLat]]` box —
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `anchor="surface"` (universal layer attribute, the classify/filter
|
|
3
|
+
* pattern): installs a `getPosition` that anchors each row INSIDE its own
|
|
4
|
+
* polygon — on-map annotations (TextLayer labels on shapes) without a
|
|
5
|
+
* card/popup and without authoring per-row coordinates. Resolved where the
|
|
6
|
+
* rows are in hand (parse-manifest / descriptorToIR); an authored
|
|
7
|
+
* `get-position` wins. Placement: centroid of the largest ring, verified
|
|
8
|
+
* inside; a concave polygon whose centroid falls outside gets the midpoint
|
|
9
|
+
* of the widest interior run of a horizontal line through the centroid
|
|
10
|
+
* latitude (polylabel-lite — cheap and always inside).
|
|
11
|
+
*/
|
|
12
|
+
import type { LayerData } from "./ir";
|
|
13
|
+
import type { Shape } from "./expr";
|
|
14
|
+
/** A point guaranteed inside the largest ring of the geometry (see module doc). */
|
|
15
|
+
export declare function pointOnSurface(coords: unknown): [number, number] | null;
|
|
16
|
+
/** Installs the surface-anchored getPosition (no-ops: no anchor, authored position, no rows yet). */
|
|
17
|
+
export declare function applySurfaceAnchor(props: Record<string, unknown>, anchor: string | undefined, data: LayerData, shape: Shape, warnLabel: string): void;
|
package/dist/version.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as ur, d as lr, R as zt, e as fr, m as dr, p as St, f as hr, g as pr, h as mr } from "./raster-pipeline-
|
|
2
|
-
import { ap as gr } from "./index-
|
|
1
|
+
import { A as ur, d as lr, R as zt, e as fr, m as dr, p as St, f as hr, g as pr, h as mr } from "./raster-pipeline-BLKrUZxU.js";
|
|
2
|
+
import { ap as gr } from "./index-h5A4LBtR.js";
|
|
3
3
|
import $t from "./index-CW1n5LdO.js";
|
|
4
4
|
var Et;
|
|
5
5
|
function h(e, t, n) {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# RESOLVED — per-feature trace link failure was schema-default array aliasing
|
|
2
|
+
|
|
3
|
+
Root cause (found by birth-tagging arrays + in-browser constructor
|
|
4
|
+
instrumentation): schema descriptors carry deck's own defaultProps values,
|
|
5
|
+
and the defaults pass assigned container defaults (`extensions: []`) BY
|
|
6
|
+
REFERENCE — one shared array per layer type, mutated by every layer's
|
|
7
|
+
extension push. A trace temp that verifiably skipped filter wiring still
|
|
8
|
+
built with a DataFilterExtension from the polluted shared array; with the
|
|
9
|
+
extra attributes the temp TripsLayer's pipeline exceeded the vertex-
|
|
10
|
+
attribute budget on Metal-ANGLE and failed to link ("Too many attributes
|
|
11
|
+
(instancePickingColors)") — traces swept their clock invisibly. Parse
|
|
12
|
+
order decided the pollution, hence the non-determinism, and hence
|
|
13
|
+
"the story-map example traces fine" (no categorical filters there).
|
|
14
|
+
|
|
15
|
+
Fix: `cloneDefault` — schema defaults assigned by value in BOTH front-ends
|
|
16
|
+
(attribute-resolution + programmatic). Regression tests pin independence
|
|
17
|
+
of per-layer extensions arrays in both lanes. The trace-temp filter-skip
|
|
18
|
+
and rounded-cap variant from the investigation are kept as hardening.
|
|
19
|
+
Verified: zero link errors across full probe runs; outlines draw visibly
|
|
20
|
+
(dev/.probe-atlas-draw1.png).
|
package/llms.txt
CHANGED
|
@@ -44,6 +44,8 @@ Programmatic/native bridge rule: `MapController.setLayers()` accepts normal func
|
|
|
44
44
|
- Undo/redo is built in: user-facing manifest changes (layer toggles, filter changes, basemap switches, element add/remove, drawn sketches) are recorded automatically — the manifest is the state. `<om-widget type="undo-redo">` renders the buttons; Cmd/Ctrl-Z, Shift-Cmd/Ctrl-Z, and Ctrl-Y work on any map (text inputs keep their native undo). Camera moves, hover effects, and story playback are deliberately NOT undo steps. Widget scripts: `ctx.history.canUndo/canRedo` with watch token `history`; `ctx.emit("undo")`/`ctx.emit("redo")`.
|
|
45
45
|
- `<om-fallback>` — static no-JS fallback, direct child of `<om-map>` (one per map, no attributes, plain HTML content — links allowed). Shown ONLY where scripts never run (chat-app/email file previews — iOS QuickLook renders HTML attachments with JS off — file managers, sandboxed webviews); hidden automatically once the map boots. GOOD PRACTICE: include one on every complete page, especially pages that may be shared as a file ("This interactive map requires JavaScript — open this file in a web browser", plus a hosted-version link when one exists). Without one, the stylesheet shows a generic text-only banner. The gate is pure CSS (`om-map:not(:defined)` in onlymapjs.css), so the CSS must load without JS — a real `<link rel="stylesheet">` or inlined `<style>` on no-build pages; a bundler-emitted stylesheet is fine in npm projects.
|
|
46
46
|
- Animation: `transition="get-fill-color 800ms, get-radius 400ms"` on a layer GPU-animates prop changes (also smooths streaming updates via `get-position`). Camera: the `fly-to` action takes `center`/`zoom`/`pitch`/`bearing`/`duration` (e.g. `duration="2s"`) — use it in behaviors or `data-emit` buttons; `zoom-to-feature` also accepts `duration`.
|
|
47
|
+
- Pull-model frame rendering (external video frameworks such as Remotion): mark the map `data-om-recording` (the determinism switch — instant camera, effects snap to end state, no transitions/gesture interrupts, byte-stable `snapshot()`), then per frame `story.seek(t, {interpolateCamera: true})` + `await mapEl.whenSettled()` + capture; the same frame is byte-identical across processes and orderings. `onlymapjs record` remains the built-in push-model path.
|
|
48
|
+
- Travel-map animation: a `trace` story step takes `follow` (camera rides the drawing tip along the path) and `easing="linear|ease-in|ease-out|ease-in-out"`; combine with a TripsLayer route + pins toggled by later steps, and export with `npx onlymapjs record`.
|
|
47
49
|
- Fixed-route 3D-tile pre-loading: `<om-story warm-tiles>` pre-fetches AND parses every 3D tileset's tiles along the story's fly-to route in the background at load (deck's own flight arc, sampled), so a flyby plays sharp instead of "blurry then clear" — or dispatch the `warm-tiles` action (`{story?, samples?, budget?}`; default budget raises each tileset cache to 256 MB, raise-only) manually before a take. Completion: `om-tiles-warmed` on `<om-map>`. Persistent per-layer knob: `load-options='{"tileset":{"maximumMemoryUsage":512}}'`.
|
|
48
50
|
- Load-paced ("clean") flyby: `<om-story paced>` steps its own clock frame by frame (optionally `paced="60"` story-fps, default 30), drives the camera itself along the fly-to route, and never advances while any 3D tileset is still refining — NO frame ever shows unrefined tiles, at the cost of wall-clock time (playback is not real-time; use for recorded takes or heavy tilesets — Google Photorealistic 3D Tiles — where no pre-warm fits the flight in cache). Per-frame `om-paced-tick` on the story (`detail = {t, waitedMs}`; `waitedMs > 0` = that frame paused for tiles). Composes with `warm-tiles` (warm first → shorter waits). Paced runs: only `fly-to` steps steer the camera (`zoom-to-feature` etc. are skipped with a warning), and user gestures do NOT pause playback — use the player widget or `story-pause`. VIDEO OUTPUT: `npx onlymapjs record map.html --out flyby.mp4` (needs dev-installed playwright; ffmpeg for assembly, else PNG frames + the command to run) plays the story paced in headless Chromium and writes a video where every frame is fully refined — widgets/overlays/attribution included; options `--story/--fps/--width/--height/--scale/--gpu/--keep-frames/--timeout/--max-hold` (`--gpu` = hardware rendering instead of headless software GL — ~3× shorter tile holds on heavy 3D scenes, recommended); frames survive a deadline hit in `<out>.frames/` for salvage. Per-frame tile waits are capped by `paced-max-hold` on `<om-story>` (duration grammar, default 10s; `--max-hold` sets it) — frames that keep hitting the cap may stay slightly blurry; raise it, or set `"none"` (`--max-hold none`) for an absolute gate: guaranteed-sharp takes, only the overall timeout bounds the run. Custom recorders: `storyEl.setPacedCapture(async (tick) => {...})` — awaited per frame BEFORE that frame's om-paced-tick, so capture is race-free and the ended-state tick means all frames captured.
|
|
49
51
|
- `<om-story id="tour" autoplay loop interrupt="pause|ignore">` — a storyboard of `<om-step>` children. Each step: `action="..."` + payload attributes (same kebab-case rule as behaviors) + `duration`/`delay`/`parallel` timing. Steps REFERENCE layers/overlays by id (`layer=`/`target=`) — a step must NEVER contain elements (validation error). Control: `<om-widget type="player" story="tour">`, the story-play/story-pause/story-seek actions, or `storyEl.play()/pause()/seek(ms)`. Seeking restores initial state then applies steps before T; use declarative payloads (e.g. `action="toggle-layer" visible="true"`, not bare toggles) so scrubbing is deterministic. Scene actions are story-steppable AND scrub-capturable: `set-basemap`, `set-lighting` (a sunset story: steps walking sun-elevation down; a bare preset step is a clean reset), and `set-terrain` all rewind on seek — the story captures the map's scene attributes before first play. Effect verbs as bare step attributes: `<om-step fade layer="regions" duration="1s">` (opacity reveal — start the layer at `opacity="0"`), `pulse` (attention flash), `trace` (progressive draw — whole-layer needs a TripsLayer; add `feature-id="..."` to make ONE polygon/line draw itself on inside any layer, or use it from a click behavior for click-to-trace), `populate` (rows drop in one by one — ordered by the authored filter-field, a payload `field`, or data order).
|
package/onlymapjs.html-data.json
CHANGED
|
@@ -546,6 +546,15 @@
|
|
|
546
546
|
"name": "site-scale",
|
|
547
547
|
"description": "Georeferencing: uniform scale multiplier (default 1)."
|
|
548
548
|
},
|
|
549
|
+
{
|
|
550
|
+
"name": "anchor",
|
|
551
|
+
"description": "anchor=\"surface\": anchor each row INSIDE its own polygon (point-on-surface) — on-map labels/annotations with no authored coordinates. An authored get-position wins.",
|
|
552
|
+
"values": [
|
|
553
|
+
{
|
|
554
|
+
"name": "surface"
|
|
555
|
+
}
|
|
556
|
+
]
|
|
557
|
+
},
|
|
549
558
|
{
|
|
550
559
|
"name": "get-position",
|
|
551
560
|
"description": "Accessor for deck.gl getPosition — expression language: $field, scale(), formatDate(), arithmetic."
|
|
@@ -2532,6 +2541,28 @@
|
|
|
2532
2541
|
"name": "delay",
|
|
2533
2542
|
"description": "Stagger before the step starts."
|
|
2534
2543
|
},
|
|
2544
|
+
{
|
|
2545
|
+
"name": "follow",
|
|
2546
|
+
"description": "trace steps: lock the camera to the line's drawing tip for the step's duration (the travel-map move)."
|
|
2547
|
+
},
|
|
2548
|
+
{
|
|
2549
|
+
"name": "easing",
|
|
2550
|
+
"description": "trace steps: clock curve for the draw.",
|
|
2551
|
+
"values": [
|
|
2552
|
+
{
|
|
2553
|
+
"name": "linear"
|
|
2554
|
+
},
|
|
2555
|
+
{
|
|
2556
|
+
"name": "ease-in"
|
|
2557
|
+
},
|
|
2558
|
+
{
|
|
2559
|
+
"name": "ease-out"
|
|
2560
|
+
},
|
|
2561
|
+
{
|
|
2562
|
+
"name": "ease-in-out"
|
|
2563
|
+
}
|
|
2564
|
+
]
|
|
2565
|
+
},
|
|
2535
2566
|
{
|
|
2536
2567
|
"name": "parallel",
|
|
2537
2568
|
"description": "Start with the previous step instead of after everything before it."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nika-js/onlymap",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.18",
|
|
4
4
|
"description": "Declarative deck.gl maps for HTML and React — interactive WebGL mapping with GeoJSON/CSV/Arrow data, MapLibre basemaps, widgets, popups, and live streams from a custom-element manifest or typed React components. TypeScript, no build step.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"publishConfig": {
|
|
@@ -23,7 +23,7 @@ Use OnlyMapJS as a declarative HTML map library. Write custom elements such as `
|
|
|
23
23
|
</script>
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
For no-build CDN pages, use the single-file standalone bundle from a raw-file CDN — `https://unpkg.com/@nika-js/onlymap@0.6.
|
|
26
|
+
For no-build CDN pages, use the single-file standalone bundle from a raw-file CDN — `https://unpkg.com/@nika-js/onlymap@0.6.18` (the bare package URL serves `dist/onlymap.standalone.js`) — plus `<link rel="stylesheet" href="https://unpkg.com/@nika-js/onlymap@0.6.18/dist/onlymapjs.css">`. Never a rebundling CDN (esm.sh, skypack): re-bundling duplicates the deck.gl/luma.gl runtime and every layer fails shader compilation.
|
|
27
27
|
|
|
28
28
|
## React Projects
|
|
29
29
|
|
|
@@ -16,8 +16,8 @@ Vite/npm project:
|
|
|
16
16
|
Static CDN page (raw-file CDNs only — unpkg/jsDelivr; never esm.sh or another rebundling CDN, which duplicates the WebGL runtime and breaks layer shaders):
|
|
17
17
|
|
|
18
18
|
```html
|
|
19
|
-
<link rel="stylesheet" href="https://unpkg.com/@nika-js/onlymap@0.6.
|
|
20
|
-
<script type="module" src="https://unpkg.com/@nika-js/onlymap@0.6.
|
|
19
|
+
<link rel="stylesheet" href="https://unpkg.com/@nika-js/onlymap@0.6.18/dist/onlymapjs.css">
|
|
20
|
+
<script type="module" src="https://unpkg.com/@nika-js/onlymap@0.6.18"></script>
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
Always include `onlymapjs.css` — it carries the MapLibre basemap styles and the no-JS fallback rules (`<om-fallback>` / default banner). For the fallback to work in script-disabled previews it must load without JavaScript: a real `<link rel="stylesheet">` or inlined `<style>` on no-build pages (a bundler-emitted stylesheet is fine in npm projects).
|
|
@@ -668,6 +668,8 @@ Example:
|
|
|
668
668
|
|
|
669
669
|
### Stories
|
|
670
670
|
|
|
671
|
+
Trace steps take `follow` (camera rides the line's drawing tip — the travel-map move) and `easing="linear|ease-in|ease-out|ease-in-out"`. On-map annotations without popups: `anchor="surface"` on a `TextLayer` over polygon GeoJSON anchors each row's text inside its own shape (`get-text="$name"`); pair with `font-settings='{"sdf":true}' outline-width="4" outline-color="..."` for a legible halo.
|
|
672
|
+
|
|
671
673
|
Add `warm-tiles` on `<om-story>` to pre-load 3D tilesets along the story's fly-to route in the background at load — flybys play sharp instead of refining from blurry. Manual form: the `warm-tiles` action (`{story?, samples?, budget?}`); completion fires `om-tiles-warmed` on `<om-map>`. Persistent knob: `load-options='{"tileset":{"maximumMemoryUsage":512}}'` on the tiles layer.
|
|
672
674
|
|
|
673
675
|
Add `paced` on `<om-story>` for load-paced playback: the story steps its own clock frame by frame (optionally `paced="60"` story-fps, default 30), drives the camera itself along the fly-to route, and never advances a frame while any 3D tileset is still refining — no frame ever shows unrefined tiles, at the cost of wall-clock time (playback is not real-time; use it for recorded takes or heavy tilesets like Google Photorealistic 3D Tiles, where no amount of pre-warming fits the flight in cache). Emits `om-paced-tick` (`detail = {t, waitedMs}`) on the story per frame; `waitedMs > 0` means that frame paused for tiles. Composes with `warm-tiles` (warm first → far shorter waits). During a paced run only `fly-to` steps steer the camera (data-dependent camera steps like `zoom-to-feature` are skipped with a warning) and user gestures don't pause playback — pause via the player widget or `story-pause`.
|