@fxi/zartigl 0.6.0 → 0.7.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 +79 -39
- package/dist/backdrop-DctkJ45Q.js +79 -0
- package/dist/catalog.d.ts +136 -15
- package/dist/catalog.js +246 -90
- package/dist/engine.d.ts +324 -22
- package/dist/engine.js +78 -25
- package/dist/{geovideo-index-CD5wflJT.js → geovideo-index-CMGVia5M.js} +567 -252
- package/dist/zartigl.d.ts +168 -18
- package/dist/zartigl.js +2057 -1890
- package/package.json +8 -20
- package/dist/GeoVideoScalarSource-DoQAnyTy.js +0 -38
- package/dist/land-50m-BX3pQS4x.js +0 -15
- package/dist/projversor.d.ts +0 -919
- package/dist/projversor.js +0 -2374
- package/dist/scalar-color-domain-PEK8Hxg1.js +0 -12
package/dist/projversor.d.ts
DELETED
|
@@ -1,919 +0,0 @@
|
|
|
1
|
-
import { GeoRawProjection } from 'd3';
|
|
2
|
-
|
|
3
|
-
/** Interpolation state of the projection between two world projections. */
|
|
4
|
-
declare interface Blend {
|
|
5
|
-
a: ProjectionDef;
|
|
6
|
-
b: ProjectionDef;
|
|
7
|
-
/** Fit scales (pixels per raw unit) of a and b. */
|
|
8
|
-
ka: number;
|
|
9
|
-
kb: number;
|
|
10
|
-
/** 0 = a, 1 = b. */
|
|
11
|
-
t: number;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
declare interface CatalogEntry {
|
|
15
|
-
id: string;
|
|
16
|
-
aliases?: string[];
|
|
17
|
-
title: LocalizedText;
|
|
18
|
-
description?: LocalizedText;
|
|
19
|
-
category: string;
|
|
20
|
-
tags?: string[];
|
|
21
|
-
kind: "scalar" | "vector";
|
|
22
|
-
sources: CatalogSource[];
|
|
23
|
-
defaults: {
|
|
24
|
-
sourceId: string;
|
|
25
|
-
querySourceId?: string;
|
|
26
|
-
palette?: string;
|
|
27
|
-
renderMode?: "particles" | "raster" | "raster+particles";
|
|
28
|
-
particles?: {
|
|
29
|
-
density?: number;
|
|
30
|
-
speed?: number;
|
|
31
|
-
fade?: number;
|
|
32
|
-
};
|
|
33
|
-
raster?: {
|
|
34
|
-
opacity?: number;
|
|
35
|
-
logScale?: boolean;
|
|
36
|
-
vibrance?: number;
|
|
37
|
-
colorDomain?: [number, number];
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* An incremental archive of calendar-aligned artifacts listed by a mutable
|
|
44
|
-
* index; zartigl resolves it to the chunk covering the requested time.
|
|
45
|
-
*/
|
|
46
|
-
declare interface CatalogGeoVideoArchiveSource extends CatalogSourceBase {
|
|
47
|
-
type: "geovideo";
|
|
48
|
-
indexUrl: string;
|
|
49
|
-
manifestUrl?: never;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/** One published artifact. */
|
|
53
|
-
declare interface CatalogGeoVideoSource extends CatalogSourceBase {
|
|
54
|
-
type: "geovideo";
|
|
55
|
-
manifestUrl: string;
|
|
56
|
-
indexUrl?: never;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
declare type CatalogSource = CatalogZarrSource | CatalogWmtsSource | CatalogGeoVideoSource | CatalogGeoVideoArchiveSource;
|
|
60
|
-
|
|
61
|
-
declare interface CatalogSourceBase {
|
|
62
|
-
id: string;
|
|
63
|
-
title: LocalizedText;
|
|
64
|
-
provenance?: CatalogSourceProvenance;
|
|
65
|
-
temporal?: CatalogTemporalSummary;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
declare interface CatalogSourceProvenance {
|
|
69
|
-
provider: string;
|
|
70
|
-
identifiers?: Record<string, string>;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
declare interface CatalogTemporalSummary {
|
|
74
|
-
cadence?: string;
|
|
75
|
-
mode: "historical" | "near-real-time" | "analysis-forecast" | "fixed";
|
|
76
|
-
start?: string;
|
|
77
|
-
end?: string;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
declare type CatalogVariables = {
|
|
81
|
-
kind: "scalar";
|
|
82
|
-
value: string;
|
|
83
|
-
} | {
|
|
84
|
-
kind: "vector";
|
|
85
|
-
u?: string;
|
|
86
|
-
v?: string;
|
|
87
|
-
derivation?: CatalogVectorDerivation;
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
declare interface CatalogVectorDerivation {
|
|
91
|
-
kind: "direction_magnitude";
|
|
92
|
-
direction_variable: string;
|
|
93
|
-
magnitude_variable: string;
|
|
94
|
-
direction_convention: "from" | "toward";
|
|
95
|
-
output_direction: "from" | "toward";
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
declare interface CatalogWmtsSource extends CatalogSourceBase {
|
|
99
|
-
type: "wmts";
|
|
100
|
-
capabilitiesUrl: string;
|
|
101
|
-
baseUrl?: string;
|
|
102
|
-
layer: string;
|
|
103
|
-
tileMatrixSet?: string;
|
|
104
|
-
format?: string;
|
|
105
|
-
style?: string;
|
|
106
|
-
tileUrlTemplate?: string;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
declare interface CatalogZarrSource extends CatalogSourceBase {
|
|
110
|
-
type: "zarr";
|
|
111
|
-
endpoints: {
|
|
112
|
-
field: string;
|
|
113
|
-
pointSeries?: string;
|
|
114
|
-
};
|
|
115
|
-
variables: CatalogVariables;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Chunk picker label, as short as a month one: "Sep ’26" for a chunk of a
|
|
120
|
-
* month at most, else the years its samples cover, "’20–’26".
|
|
121
|
-
*/
|
|
122
|
-
export declare function chunkLabel(start?: string, end?: string): string;
|
|
123
|
-
|
|
124
|
-
export declare function clampZoom(zoom: number): number;
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Optional color grade applied when particle trails are composited
|
|
128
|
-
* (`shaders/color-grade.glsl`): more intense highlights, deeper shadows and
|
|
129
|
-
* richer colors, without hard clipping. Off by default; when off, the
|
|
130
|
-
* composite returns the trail colors unchanged.
|
|
131
|
-
*/
|
|
132
|
-
declare interface ColorGrade {
|
|
133
|
-
enabled: boolean;
|
|
134
|
-
/** Mid-tone lift [0, 4]; 0 keeps the tones. */
|
|
135
|
-
exposure: number;
|
|
136
|
-
/** S-curve strength [0, 1]. */
|
|
137
|
-
contrast: number;
|
|
138
|
-
/** Vibrance-weighted saturation [-1, 1]. */
|
|
139
|
-
saturation: number;
|
|
140
|
-
/** Push of the bright half toward white [0, 1]. */
|
|
141
|
-
highlights: number;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Valid fields of a hash written by {@link encodeShare}; the caller checks the
|
|
146
|
-
* layer, preset and palette ids and the speed against its choices.
|
|
147
|
-
*/
|
|
148
|
-
export declare function decodeShare(hash: string): Partial<ShareState>;
|
|
149
|
-
|
|
150
|
-
/** Readable url hash, without the leading "#". */
|
|
151
|
-
export declare function encodeShare(state: ShareState): string;
|
|
152
|
-
|
|
153
|
-
/** Layer of a share key: a layer id, or the entry id older links carry. */
|
|
154
|
-
export declare function findLayer(key: string | undefined, layers?: readonly ProjversorLayer[]): ProjversorLayer | undefined;
|
|
155
|
-
|
|
156
|
-
export declare function findPreset(id: string | undefined): Preset | undefined;
|
|
157
|
-
|
|
158
|
-
/** "m s-1" → "m/s", "degrees_C" → "°C". */
|
|
159
|
-
export declare function formatUnit(unit: string | undefined): string;
|
|
160
|
-
|
|
161
|
-
declare type GeoVideoBounds = [
|
|
162
|
-
west: number,
|
|
163
|
-
south: number,
|
|
164
|
-
east: number,
|
|
165
|
-
north: number
|
|
166
|
-
];
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* GeoVideo frames as float textures, decoded ahead of the playhead: vector
|
|
170
|
-
* frames as (u, v, validity, 0), scalar frames as (value, validity). Binds
|
|
171
|
-
* two consecutive time steps and their mix under VELOCITY_UNIFORMS for a
|
|
172
|
-
* vector field, TINT_UNIFORMS for a scalar one.
|
|
173
|
-
*/
|
|
174
|
-
export declare class GeoVideoField {
|
|
175
|
-
private readonly gl;
|
|
176
|
-
readonly manifest: GeoVideoManifest;
|
|
177
|
-
readonly times: number[];
|
|
178
|
-
readonly bounds: GeoVideoBounds;
|
|
179
|
-
private readonly source;
|
|
180
|
-
private readonly texels;
|
|
181
|
-
/** 4 for vector texels, 2 for scalar ones. */
|
|
182
|
-
private readonly channels;
|
|
183
|
-
private readonly uniforms;
|
|
184
|
-
private readonly textures;
|
|
185
|
-
private readonly pending;
|
|
186
|
-
private pair;
|
|
187
|
-
private destroyed;
|
|
188
|
-
constructor(gl: WebGL2RenderingContext, manifest: GeoVideoManifest);
|
|
189
|
-
/** Vector field (particles); false for a scalar one (raster or tint). */
|
|
190
|
-
get vector(): boolean;
|
|
191
|
-
/** Fixed catalog color domain of a scalar field. */
|
|
192
|
-
get domain(): [number, number];
|
|
193
|
-
/** Top of the color ramp and of the particle speed normalization. */
|
|
194
|
-
get maxSpeed(): number;
|
|
195
|
-
/** Resolves once the step at `ms` is uploaded. */
|
|
196
|
-
prime(ms: number): Promise<void>;
|
|
197
|
-
/** True once the frames interpolated at `ms` are uploaded. */
|
|
198
|
-
ready(ms: number): boolean;
|
|
199
|
-
/**
|
|
200
|
-
* Latest wins while scrubbing: drop queued decodes outside the frames at
|
|
201
|
-
* `ms`, then request those first.
|
|
202
|
-
*/
|
|
203
|
-
focus(ms: number): void;
|
|
204
|
-
/** False until a first frame is available. */
|
|
205
|
-
bind(program: Program, ms: number, unit?: number): boolean;
|
|
206
|
-
destroy(): void;
|
|
207
|
-
private request;
|
|
208
|
-
private upload;
|
|
209
|
-
/** Keep a small window around the playhead. */
|
|
210
|
-
private evict;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
declare interface GeoVideoManifest {
|
|
214
|
-
schemaVersion: 3;
|
|
215
|
-
id: string;
|
|
216
|
-
type: "geovideo";
|
|
217
|
-
projection: "equirectangular";
|
|
218
|
-
bounds: GeoVideoBounds;
|
|
219
|
-
media: {
|
|
220
|
-
url: string;
|
|
221
|
-
mimeType: "video/mp4" | string;
|
|
222
|
-
width: number;
|
|
223
|
-
height: number;
|
|
224
|
-
fps: number;
|
|
225
|
-
durationSeconds: number;
|
|
226
|
-
codec: "h264" | string;
|
|
227
|
-
};
|
|
228
|
-
encoding: GeoVideoScalarEncoding | GeoVideoVectorEncoding;
|
|
229
|
-
mask: {
|
|
230
|
-
kind: "static-validity";
|
|
231
|
-
url: string;
|
|
232
|
-
mimeType: "image/png" | string;
|
|
233
|
-
width: number;
|
|
234
|
-
height: number;
|
|
235
|
-
threshold: number;
|
|
236
|
-
};
|
|
237
|
-
timeline: GeoVideoRangeTimeline | GeoVideoSnapshotLoopTimeline | GeoVideoSampleSequenceTimeline;
|
|
238
|
-
provenance: {
|
|
239
|
-
catalogEntryId: string;
|
|
240
|
-
inputSourceId: string;
|
|
241
|
-
provider?: string;
|
|
242
|
-
identifiers?: Record<string, string>;
|
|
243
|
-
variables: string[];
|
|
244
|
-
generatedAt: string;
|
|
245
|
-
};
|
|
246
|
-
style: {
|
|
247
|
-
palette: string;
|
|
248
|
-
colorDomain: [number, number];
|
|
249
|
-
unit?: string;
|
|
250
|
-
logScale?: boolean;
|
|
251
|
-
vibrance?: number;
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
declare interface GeoVideoRangeTimeline {
|
|
256
|
-
kind: "range";
|
|
257
|
-
dateStart: string;
|
|
258
|
-
dateEnd: string;
|
|
259
|
-
interpolation: "linear" | "nearest";
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
declare interface GeoVideoSampleSequenceTimeline {
|
|
263
|
-
kind: "sample-sequence";
|
|
264
|
-
values: string[];
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
declare interface GeoVideoScalarEncoding {
|
|
268
|
-
kind: "scalar-luma";
|
|
269
|
-
bits: 8;
|
|
270
|
-
codeMin: number;
|
|
271
|
-
codeMax: number;
|
|
272
|
-
valueMin: number;
|
|
273
|
-
valueMax: number;
|
|
274
|
-
transfer: "linear";
|
|
275
|
-
colorSpace: "bt709";
|
|
276
|
-
colorRange: "limited" | "full";
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
declare interface GeoVideoSnapshotLoopTimeline {
|
|
280
|
-
kind: "snapshot-loop";
|
|
281
|
-
date: string;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* u and v stacked vertically in luma (u rows on top). Each component maps
|
|
286
|
-
* [-valueDomain, valueDomain] to [codeMin, codeMax]; "sqrt" stores
|
|
287
|
-
* sign(x)·sqrt(|x|/valueDomain) to keep precision on slow flows. The static
|
|
288
|
-
* mask covers one component (media height / 2).
|
|
289
|
-
*/
|
|
290
|
-
declare interface GeoVideoVectorEncoding {
|
|
291
|
-
kind: "vector-luma";
|
|
292
|
-
bits: 8;
|
|
293
|
-
codeMin: number;
|
|
294
|
-
codeMax: number;
|
|
295
|
-
valueDomain: number;
|
|
296
|
-
transfer: "linear" | "sqrt";
|
|
297
|
-
layout: "stacked-uv";
|
|
298
|
-
colorSpace: "bt709";
|
|
299
|
-
colorRange: "limited" | "full";
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/** Margins of the free zone the sphere is centered and fitted in, css px. */
|
|
303
|
-
export declare interface Inset {
|
|
304
|
-
top: number;
|
|
305
|
-
right: number;
|
|
306
|
-
bottom: number;
|
|
307
|
-
left: number;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
export declare function isTintEntry(id: string | undefined): id is string;
|
|
311
|
-
|
|
312
|
-
export declare function layerPalettes(layer: ProjversorLayer): PaletteMeta[];
|
|
313
|
-
|
|
314
|
-
declare interface LegendField {
|
|
315
|
-
readonly vector: boolean;
|
|
316
|
-
readonly domain: [number, number];
|
|
317
|
-
readonly maxSpeed: number;
|
|
318
|
-
readonly manifest: {
|
|
319
|
-
style: {
|
|
320
|
-
unit?: string;
|
|
321
|
-
};
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Legend ends rounded to the precision of their range (about a hundredth of
|
|
327
|
-
* it), so a domain of 0.00000537–0.665 reads "0" and "0.67".
|
|
328
|
-
*/
|
|
329
|
-
export declare function legendLabels(min: number, max: number, locale?: string): [string, string];
|
|
330
|
-
|
|
331
|
-
/** The colored quantity of a month: its range, unit and ramp. */
|
|
332
|
-
export declare interface LegendScale {
|
|
333
|
-
min: number;
|
|
334
|
-
max: number;
|
|
335
|
-
unit: string;
|
|
336
|
-
/** Linear over a scalar domain; square root over a particle speed. */
|
|
337
|
-
ramp: "linear" | "sqrt";
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/** Rounded legend values spread evenly along a square-root ramp. */
|
|
341
|
-
export declare function legendTicks(max: number): number[];
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* Round values (1, 2, 2.5 or 5 × 10ⁿ apart, about five intervals) within
|
|
345
|
-
* [min, max], with their linear position on the ramp.
|
|
346
|
-
*/
|
|
347
|
-
export declare function linearTicks(min: number, max: number): {
|
|
348
|
-
value: number;
|
|
349
|
-
position: number;
|
|
350
|
-
}[];
|
|
351
|
-
|
|
352
|
-
declare type LocalizedText = Record<string, string>;
|
|
353
|
-
|
|
354
|
-
/** Column-major 3×3, as WebGL uniformMatrix3fv expects. */
|
|
355
|
-
declare type Mat3 = [
|
|
356
|
-
number,
|
|
357
|
-
number,
|
|
358
|
-
number,
|
|
359
|
-
number,
|
|
360
|
-
number,
|
|
361
|
-
number,
|
|
362
|
-
number,
|
|
363
|
-
number,
|
|
364
|
-
number
|
|
365
|
-
];
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* What the colors of a month mean: the raster of a scalar layer, else the
|
|
369
|
-
* tint coloring the particles, over its domain; else the particle speed.
|
|
370
|
-
*/
|
|
371
|
-
export declare function monthLegend(month: {
|
|
372
|
-
field: LegendField;
|
|
373
|
-
tint: LegendField | null;
|
|
374
|
-
}): LegendScale;
|
|
375
|
-
|
|
376
|
-
export declare const NO_INSET: Inset;
|
|
377
|
-
|
|
378
|
-
/** Wrap degrees into [-180, 180). */
|
|
379
|
-
export declare function normalizeBearing(deg: number): number;
|
|
380
|
-
|
|
381
|
-
declare interface PaletteMeta {
|
|
382
|
-
id: string;
|
|
383
|
-
label: string;
|
|
384
|
-
tags: string[];
|
|
385
|
-
colors: string[];
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
/** Validate a view's config against the projversor layers and presets. */
|
|
389
|
-
export declare function parseProjversorView(view: ProjversorViewDefinition): ProjversorViewConfig;
|
|
390
|
-
|
|
391
|
-
/** zartigl particle settings, as in catalog `defaults.particles`. */
|
|
392
|
-
declare interface ParticleSettings {
|
|
393
|
-
/** Particles per device pixel. */
|
|
394
|
-
density: number;
|
|
395
|
-
/** Css px per frame at the top of the speed range. */
|
|
396
|
-
speed: number;
|
|
397
|
-
/** Trail length, 0–1 (20 to 600 frames). */
|
|
398
|
-
fade: number;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* Playhead date and hour on a timeline stepping `stepMs`: the hour only
|
|
403
|
-
* below daily steps (else ""), the day only below monthly ones.
|
|
404
|
-
*/
|
|
405
|
-
export declare function playheadLabel(ms: number, stepMs: number): {
|
|
406
|
-
date: string;
|
|
407
|
-
hour: string;
|
|
408
|
-
};
|
|
409
|
-
|
|
410
|
-
/** Screen angle of (x, y) around (cx, cy), clockwise from up, in degrees. */
|
|
411
|
-
export declare function pointerBearing(cx: number, cy: number, x: number, y: number): number;
|
|
412
|
-
|
|
413
|
-
/** A named projection with its default rotation and zoom. */
|
|
414
|
-
export declare interface Preset {
|
|
415
|
-
id: string;
|
|
416
|
-
label: string;
|
|
417
|
-
projection: ProjectionId;
|
|
418
|
-
rotate: [number, number, number];
|
|
419
|
-
zoom: number;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
export declare const PRESETS: Preset[];
|
|
423
|
-
|
|
424
|
-
/** WebGL2 program with cached uniform locations. */
|
|
425
|
-
declare class Program {
|
|
426
|
-
readonly gl: WebGL2RenderingContext;
|
|
427
|
-
readonly program: WebGLProgram;
|
|
428
|
-
private readonly locations;
|
|
429
|
-
constructor(gl: WebGL2RenderingContext, vert: string, frag: string);
|
|
430
|
-
use(): this;
|
|
431
|
-
private loc;
|
|
432
|
-
int(name: string, v: number): void;
|
|
433
|
-
uint(name: string, v: number): void;
|
|
434
|
-
float(name: string, v: number): void;
|
|
435
|
-
vec2(name: string, x: number, y: number): void;
|
|
436
|
-
vec4(name: string, v: readonly number[]): void;
|
|
437
|
-
mat3(name: string, m: Mat3): void;
|
|
438
|
-
texture(name: string, unit: number, texture: WebGLTexture, target?: number): void;
|
|
439
|
-
/** Uniforms of shaders/project.glsl. */
|
|
440
|
-
projection(frame: ViewFrame): void;
|
|
441
|
-
delete(): void;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
declare interface ProjectionDef {
|
|
445
|
-
id: ProjectionId;
|
|
446
|
-
label: string;
|
|
447
|
-
glslId: number;
|
|
448
|
-
raw: GeoRawProjection;
|
|
449
|
-
/** Half width and half height of the world outline, in raw units. */
|
|
450
|
-
extent: [number, number];
|
|
451
|
-
/** Hemisphere-limited projections clip at this angle (degrees). */
|
|
452
|
-
clipAngle: number;
|
|
453
|
-
/** Azimuthal projections are cut around the antipode, not along a meridian. */
|
|
454
|
-
azimuthal: boolean;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
/**
|
|
458
|
-
* World projections shared by d3 (overlay) and GLSL (raster, particles).
|
|
459
|
-
* Each raw formula has a twin in shaders/project.glsl keyed by `glslId`;
|
|
460
|
-
* both sides must stay identical or the coastlines drift off the raster.
|
|
461
|
-
*/
|
|
462
|
-
export declare type ProjectionId = "equirectangular" | "equalEarth" | "mollweide" | "azimuthalEqualArea" | "azimuthalEquidistant" | "orthographic";
|
|
463
|
-
|
|
464
|
-
export declare const PROJECTIONS: Record<ProjectionId, ProjectionDef>;
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
* GeoVideo archives on a sphere that morphs between projections: particles
|
|
468
|
-
* for vector layers, a raster for scalar ones. Owns the GL context, the
|
|
469
|
-
* frame loop, archive loading and the view; controls stay with the caller.
|
|
470
|
-
*/
|
|
471
|
-
export declare class Projversor {
|
|
472
|
-
private readonly canvases;
|
|
473
|
-
private readonly gl;
|
|
474
|
-
private readonly particles;
|
|
475
|
-
private readonly raster;
|
|
476
|
-
private readonly overlay;
|
|
477
|
-
private readonly trailFade;
|
|
478
|
-
private readonly listeners;
|
|
479
|
-
private readonly resizer;
|
|
480
|
-
private frameId;
|
|
481
|
-
private destroyed;
|
|
482
|
-
/** Drop-rate boost after a view change, and the view it was measured on. */
|
|
483
|
-
private redistribution;
|
|
484
|
-
private lastScale;
|
|
485
|
-
private lastCenter;
|
|
486
|
-
/** Frames left to animate while paused. */
|
|
487
|
-
private settle;
|
|
488
|
-
private north;
|
|
489
|
-
private readonly speeds;
|
|
490
|
-
private paletteId;
|
|
491
|
-
private ramp;
|
|
492
|
-
private gradeValue;
|
|
493
|
-
private layerValue;
|
|
494
|
-
private opened;
|
|
495
|
-
private presetValue;
|
|
496
|
-
private rasterOpacity;
|
|
497
|
-
private rasterVibrance;
|
|
498
|
-
private field;
|
|
499
|
-
private tint;
|
|
500
|
-
private tintIdValue;
|
|
501
|
-
private tintChunks;
|
|
502
|
-
private chunksValue;
|
|
503
|
-
private chunkIndexValue;
|
|
504
|
-
private particleSettings;
|
|
505
|
-
private upcoming;
|
|
506
|
-
/** Bumped on every layer or month switch; stale loads drop out. */
|
|
507
|
-
private loadId;
|
|
508
|
-
private readonly view;
|
|
509
|
-
private dpr;
|
|
510
|
-
private ms;
|
|
511
|
-
private playingValue;
|
|
512
|
-
private held;
|
|
513
|
-
private pendingRespawn;
|
|
514
|
-
private overlayKey;
|
|
515
|
-
private lastMove;
|
|
516
|
-
private detailed;
|
|
517
|
-
private last;
|
|
518
|
-
private insetTransition;
|
|
519
|
-
private transition;
|
|
520
|
-
private drag;
|
|
521
|
-
constructor(canvases: ProjversorCanvases, initial?: Partial<ShareState>);
|
|
522
|
-
/** Listen to an event; returns the unsubscribe function. */
|
|
523
|
-
on<K extends keyof ProjversorEvents>(type: K, listener: (detail: ProjversorEvents[K]) => void): () => void;
|
|
524
|
-
private emit;
|
|
525
|
-
get layer(): ProjversorLayer;
|
|
526
|
-
/** Scalar entry id coloring the particles, or null. */
|
|
527
|
-
get tintId(): string | null;
|
|
528
|
-
get palette(): string;
|
|
529
|
-
get grade(): ColorGrade;
|
|
530
|
-
get preset(): Preset;
|
|
531
|
-
get playing(): boolean;
|
|
532
|
-
/** Playback speed multiplier of the open layer. */
|
|
533
|
-
get speed(): number;
|
|
534
|
-
/** Month chunks of the open layer and the displayed one. */
|
|
535
|
-
get chunks(): readonly CatalogGeoVideoSource[];
|
|
536
|
-
get chunkIndex(): number;
|
|
537
|
-
/** Playhead, epoch ms. */
|
|
538
|
-
get time(): number;
|
|
539
|
-
/** Frame times of the displayed month. */
|
|
540
|
-
get times(): readonly number[];
|
|
541
|
-
/** Playhead position in the displayed month, 0–1. */
|
|
542
|
-
get progress(): number;
|
|
543
|
-
get rotate(): Rotate;
|
|
544
|
-
get zoom(): number;
|
|
545
|
-
get bearing(): number;
|
|
546
|
-
/** Drags keep north up (gamma 0), as d3-geo-zoom's northUp. */
|
|
547
|
-
get northLocked(): boolean;
|
|
548
|
-
set northLocked(locked: boolean);
|
|
549
|
-
/** Everything needed to reproduce the displayed view. */
|
|
550
|
-
getState(): ShareState;
|
|
551
|
-
/**
|
|
552
|
-
* Show a state: unknown ids fall back to the layer's own choices. The
|
|
553
|
-
* layer reopens only when it or its tint changes. A view in the state
|
|
554
|
-
* keeps its own framing, else a regional layer is framed.
|
|
555
|
-
*/
|
|
556
|
-
apply(state: Partial<ShareState>, options?: {
|
|
557
|
-
animate?: boolean;
|
|
558
|
-
durationMs?: number;
|
|
559
|
-
}): Promise<void>;
|
|
560
|
-
/**
|
|
561
|
-
* Switch layer, opening the month that holds `at`, else the displayed
|
|
562
|
-
* month when the archive has it, else the latest. Palette and tint default
|
|
563
|
-
* to the layer's own; `frame` centers the view on a regional layer.
|
|
564
|
-
*/
|
|
565
|
-
open(layerOrId: ProjversorLayer | string, options?: {
|
|
566
|
-
at?: number;
|
|
567
|
-
palette?: string;
|
|
568
|
-
tint?: string | null;
|
|
569
|
-
/** Playback speed, applied with the layer when it is one of its kind. */
|
|
570
|
-
speed?: number;
|
|
571
|
-
frame?: boolean;
|
|
572
|
-
}): Promise<void>;
|
|
573
|
-
/** Open month `index` of the open layer at its start. */
|
|
574
|
-
openMonth(index: number): Promise<void>;
|
|
575
|
-
/** Move the playhead, opening the month that holds `ms` when needed. */
|
|
576
|
-
seek(ms: number): Promise<void>;
|
|
577
|
-
/** Move the playhead within the displayed month. */
|
|
578
|
-
scrub(ms: number): void;
|
|
579
|
-
/**
|
|
580
|
-
* Warm the HTTP cache with a layer's index and the manifest of the month
|
|
581
|
-
* holding `at`, so a later {@link open} starts sooner.
|
|
582
|
-
*/
|
|
583
|
-
preload(layerId: string, at?: number): Promise<void>;
|
|
584
|
-
/** Open a month at `at`, or at its start. */
|
|
585
|
-
private openChunk;
|
|
586
|
-
/**
|
|
587
|
-
* Field of a month and, when a tint is chosen, the tint for the same
|
|
588
|
-
* month. A missing or unreadable tint falls back to speed colors.
|
|
589
|
-
*/
|
|
590
|
-
private loadMonth;
|
|
591
|
-
/** Manifest and first decoded frame (at `at`, else the start) of a month. */
|
|
592
|
-
private loadField;
|
|
593
|
-
private adopt;
|
|
594
|
-
/**
|
|
595
|
-
* Decode the next month in the background so playback runs through the
|
|
596
|
-
* whole archive like a film, wrapping to the first month after the last.
|
|
597
|
-
*/
|
|
598
|
-
private prefetchNext;
|
|
599
|
-
private dropUpcoming;
|
|
600
|
-
/** Recolor the particles or the raster. */
|
|
601
|
-
setPalette(id: string): void;
|
|
602
|
-
/** Particle color grade, applied when the trails are composited. */
|
|
603
|
-
setGrade(grade: ColorGrade): void;
|
|
604
|
-
/** Set a kind's speed when it is one of that kind's {@link SPEEDS}. */
|
|
605
|
-
private setKindSpeed;
|
|
606
|
-
/** Playback speed multiplier of the open layer's kind. */
|
|
607
|
-
setSpeed(speed: number): void;
|
|
608
|
-
setPlaying(playing: boolean): void;
|
|
609
|
-
/** Hold playback, e.g. while a timeline thumb is held. */
|
|
610
|
-
setHeld(held: boolean): void;
|
|
611
|
-
private setStatus;
|
|
612
|
-
/**
|
|
613
|
-
* Morph to a preset (with its own rotation and zoom unless given), or
|
|
614
|
-
* ease rotation and zoom alone.
|
|
615
|
-
*/
|
|
616
|
-
goTo(target: ProjversorViewTarget): void;
|
|
617
|
-
/** Show a preset, rotation and zoom at once. */
|
|
618
|
-
jumpTo(target: ProjversorViewTarget): void;
|
|
619
|
-
private morph;
|
|
620
|
-
private setPreset;
|
|
621
|
-
/**
|
|
622
|
-
* Ease rotation and zoom from the current view; repeated calls chain from
|
|
623
|
-
* the previous target. Waits out a projection morph.
|
|
624
|
-
*/
|
|
625
|
-
easeTo(rotate: Rotate, zoom: number, duration?: number): void;
|
|
626
|
-
zoomBy(factor: number): void;
|
|
627
|
-
/** Spin the globe around its axis; positive moves the map content right. */
|
|
628
|
-
rotateBy(deg: number): void;
|
|
629
|
-
/** Rotate the map around the view center; frees the bearing. */
|
|
630
|
-
setBearing(deg: number): void;
|
|
631
|
-
/** Free the bearing, or ease back to north up and lock it. */
|
|
632
|
-
toggleNorth(): void;
|
|
633
|
-
/** Where the running view easing ends, else the current view. */
|
|
634
|
-
target(): {
|
|
635
|
-
rotate: Rotate;
|
|
636
|
-
zoom: number;
|
|
637
|
-
};
|
|
638
|
-
/** Lock north up for a near-zero bearing, and snap it to zero. */
|
|
639
|
-
private lockNorth;
|
|
640
|
-
/**
|
|
641
|
-
* Ease the free zone to `inset` (at once for a zero duration); the sphere
|
|
642
|
-
* slides and refits with it.
|
|
643
|
-
*/
|
|
644
|
-
setInset(inset: Inset, durationMs?: number): void;
|
|
645
|
-
/** Free zone, css px. */
|
|
646
|
-
get inset(): Inset;
|
|
647
|
-
/**
|
|
648
|
-
* Screen direction of north at the center of the free zone, degrees
|
|
649
|
-
* clockwise from up; null near a pole, where it has none.
|
|
650
|
-
*/
|
|
651
|
-
northAngle(): number | null;
|
|
652
|
-
/**
|
|
653
|
-
* Outline of the projected sphere, css px: the globe limb, or the edge of
|
|
654
|
-
* a world map. The largest ring when the projection splits it.
|
|
655
|
-
*/
|
|
656
|
-
outline(): [number, number][];
|
|
657
|
-
/** Fit scales of both blended projections to the free zone. */
|
|
658
|
-
private refit;
|
|
659
|
-
private animateInset;
|
|
660
|
-
private animate;
|
|
661
|
-
private resize;
|
|
662
|
-
/**
|
|
663
|
-
* Versor drag, pinch and wheel zoom on the front canvas; the stage gets
|
|
664
|
-
* the `dragging` class during a drag. Returns the detach function.
|
|
665
|
-
*/
|
|
666
|
-
attachInteraction(): () => void;
|
|
667
|
-
private invert;
|
|
668
|
-
/** Playing and not held. */
|
|
669
|
-
private get advancing();
|
|
670
|
-
private tick;
|
|
671
|
-
/** Trail length in frames, capped: how long a paused view keeps animating. */
|
|
672
|
-
private settleFrames;
|
|
673
|
-
/** Clear the GL canvas, then draw the open field as particles or a raster. */
|
|
674
|
-
private drawField;
|
|
675
|
-
/**
|
|
676
|
-
* zartigl's particle pipeline: advect, fade the trails, draw the new
|
|
677
|
-
* segments, composite. While paused, particles only animate for a while
|
|
678
|
-
* after a change, to rebuild trails, then the image holds.
|
|
679
|
-
*/
|
|
680
|
-
private drawParticles;
|
|
681
|
-
/** zartigl's drop-rate boost, from the per-frame zoom and center change. */
|
|
682
|
-
private redistribute;
|
|
683
|
-
/** Coastlines and graticule: coarse while the view moves, then detailed. */
|
|
684
|
-
private drawOverlay;
|
|
685
|
-
private advanceTime;
|
|
686
|
-
/** Stop the frame loop and free GL resources and listeners. */
|
|
687
|
-
destroy(): void;
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
export declare const PROJVERSOR_LAYERS: ProjversorLayer[];
|
|
691
|
-
|
|
692
|
-
/** The stage and its three stacked canvases: land below, GL, lines above. */
|
|
693
|
-
export declare interface ProjversorCanvases {
|
|
694
|
-
stage: HTMLElement;
|
|
695
|
-
back: HTMLCanvasElement;
|
|
696
|
-
gl: HTMLCanvasElement;
|
|
697
|
-
front: HTMLCanvasElement;
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
/** Events and their payloads. */
|
|
701
|
-
export declare interface ProjversorEvents {
|
|
702
|
-
status: string;
|
|
703
|
-
/** A layer was chosen; its month chunks are known, not yet decoded. */
|
|
704
|
-
layer: ProjversorLayer;
|
|
705
|
-
/** A month was decoded and is displayed. */
|
|
706
|
-
month: ProjversorMonth;
|
|
707
|
-
palette: string;
|
|
708
|
-
playing: boolean;
|
|
709
|
-
preset: Preset;
|
|
710
|
-
north: boolean;
|
|
711
|
-
/** After each drawn frame. */
|
|
712
|
-
frame: undefined;
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
/**
|
|
716
|
-
* A catalog entry with a GeoVideo archive, with the styling this projversor
|
|
717
|
-
* renderer gives it: vector entries play as particles, scalar ones as a raster.
|
|
718
|
-
*/
|
|
719
|
-
export declare interface ProjversorLayer {
|
|
720
|
-
/** Picker and share key: the entry's first alias, else its id. */
|
|
721
|
-
id: string;
|
|
722
|
-
/** zartigl catalog entry id. */
|
|
723
|
-
entryId: string;
|
|
724
|
-
kind: CatalogEntry["kind"];
|
|
725
|
-
label: string;
|
|
726
|
-
palette: string;
|
|
727
|
-
/** Draw land opaque: off for fields that also cover land. */
|
|
728
|
-
fillLand: boolean;
|
|
729
|
-
/** Overrides of the catalog entry `defaults.particles` (density, speed, fade). */
|
|
730
|
-
particles?: Partial<ParticleSettings>;
|
|
731
|
-
/**
|
|
732
|
-
* Default scalar entry id whose GeoVideo archive colors the particles (over
|
|
733
|
-
* its catalog color domain); speed then sets their brightness. Its monthly
|
|
734
|
-
* chunks pair with the vector ones by calendar period.
|
|
735
|
-
*/
|
|
736
|
-
tint?: string;
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
/** The fields of one month: the layer field and its optional tint. */
|
|
740
|
-
export declare interface ProjversorMonth {
|
|
741
|
-
field: GeoVideoField;
|
|
742
|
-
tint: GeoVideoField | null;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
/** The projversor state a view config shows. */
|
|
746
|
-
export declare function projversorState(config: ProjversorViewConfig): Partial<ShareState>;
|
|
747
|
-
|
|
748
|
-
/**
|
|
749
|
-
* Story view on one persistent projversor: each scene morphs the view from
|
|
750
|
-
* the previous one, and the layer reopens only when it changes.
|
|
751
|
-
*/
|
|
752
|
-
export declare class ProjversorStoryView {
|
|
753
|
-
private readonly projversor;
|
|
754
|
-
private readonly animate;
|
|
755
|
-
private readonly onError;
|
|
756
|
-
/**
|
|
757
|
-
* @param animate Morph between views; off for still frames and reduced
|
|
758
|
-
* motion, where each view is shown at once.
|
|
759
|
-
* @param onError Reports a failed time seek.
|
|
760
|
-
*/
|
|
761
|
-
constructor(projversor: Projversor, animate?: boolean, onError?: (error: unknown) => void);
|
|
762
|
-
activate(view: ProjversorViewDefinition): Promise<void>;
|
|
763
|
-
/** Warm the cache for a view shown next. */
|
|
764
|
-
preload(view: ProjversorViewDefinition): Promise<void>;
|
|
765
|
-
play(): void;
|
|
766
|
-
pause(): void;
|
|
767
|
-
setTime(time: number): void;
|
|
768
|
-
destroy(): void;
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
/** `config` of a `projversor` view, validated by {@link parseProjversorView}. */
|
|
772
|
-
export declare interface ProjversorViewConfig {
|
|
773
|
-
/** projversor layer id (catalog alias, or a tinted pairing id). */
|
|
774
|
-
layer: string;
|
|
775
|
-
preset: string;
|
|
776
|
-
rotate?: [number, number, number];
|
|
777
|
-
zoom?: number;
|
|
778
|
-
palette?: string;
|
|
779
|
-
/** Scalar entry id coloring the particles; "" colors them by speed. */
|
|
780
|
-
tint?: string;
|
|
781
|
-
speed?: number;
|
|
782
|
-
/** ISO date of the playhead; the latest month when omitted. */
|
|
783
|
-
time?: string;
|
|
784
|
-
/** Projection morph duration from the previous scene. */
|
|
785
|
-
transitionMs?: number;
|
|
786
|
-
/** Vibrant particle color grade. */
|
|
787
|
-
vibrant?: boolean;
|
|
788
|
-
/** Side layouts: the paragraph follows the globe limb. */
|
|
789
|
-
wrap?: boolean;
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
/**
|
|
793
|
-
* A story view, as `@fxi/zartigl/story` defines it. Declared here so this
|
|
794
|
-
* entry stays independent: the adapter fits the story registry structurally.
|
|
795
|
-
*/
|
|
796
|
-
export declare interface ProjversorViewDefinition {
|
|
797
|
-
id: string;
|
|
798
|
-
config: Record<string, unknown>;
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
/** View target: a preset morphs, rotate and zoom alone ease. */
|
|
802
|
-
export declare interface ProjversorViewTarget {
|
|
803
|
-
preset?: string;
|
|
804
|
-
rotate?: Rotate;
|
|
805
|
-
zoom?: number;
|
|
806
|
-
/** Free zone the sphere is centered and fitted in; eases with the view. */
|
|
807
|
-
inset?: Inset;
|
|
808
|
-
durationMs?: number;
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
/**
|
|
812
|
-
* Css gradient of a palette, bottom to top. Stops are sorted numerically:
|
|
813
|
-
* integer-like keys ("0", "1") would otherwise enumerate first and scramble
|
|
814
|
-
* the gradient.
|
|
815
|
-
*/
|
|
816
|
-
export declare function rampGradient(palette: string): string;
|
|
817
|
-
|
|
818
|
-
/** Position on the ramp of a value; the shaders color by sqrt(value / max). */
|
|
819
|
-
export declare function rampPosition(value: number, max: number): number;
|
|
820
|
-
|
|
821
|
-
declare type Rotate = [number, number, number];
|
|
822
|
-
|
|
823
|
-
/**
|
|
824
|
-
* Screen direction of north at css point `at`, in degrees clockwise from
|
|
825
|
-
* up: the angle toward a point just north of it. Unlike the rotation's
|
|
826
|
-
* bearing, it holds on any projection, tilted or not. Null off the map and
|
|
827
|
-
* near a pole, where every direction is north (or south).
|
|
828
|
-
*/
|
|
829
|
-
export declare function screenNorth(projection: ScreenProjection, at: [number, number]): number | null;
|
|
830
|
-
|
|
831
|
-
/** A projection from [lon, lat] to css px, with its inverse. */
|
|
832
|
-
export declare interface ScreenProjection {
|
|
833
|
-
(point: [number, number]): [number, number] | null;
|
|
834
|
-
invert?(point: [number, number]): [number, number] | null;
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
/** Everything needed to reproduce the displayed view. */
|
|
838
|
-
export declare interface ShareState {
|
|
839
|
-
/** zartigl catalog entry id. */
|
|
840
|
-
layer: string;
|
|
841
|
-
/** Playhead, epoch ms. */
|
|
842
|
-
time: number;
|
|
843
|
-
/** Projection preset id. */
|
|
844
|
-
preset: string;
|
|
845
|
-
rotate: [number, number, number];
|
|
846
|
-
zoom: number;
|
|
847
|
-
playing: boolean;
|
|
848
|
-
/** Playback speed multiplier. */
|
|
849
|
-
speed: number;
|
|
850
|
-
/** Palette id. */
|
|
851
|
-
palette: string;
|
|
852
|
-
/** Scalar entry id coloring the particles; "" colors them by speed. */
|
|
853
|
-
tint: string;
|
|
854
|
-
/** Particle color grade; written only when enabled. */
|
|
855
|
-
grade?: ColorGrade;
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
/**
|
|
859
|
-
* Playback speeds and defaults per layer kind: particles need slow steps to
|
|
860
|
-
* keep stable trails, while a raster only shows change when played faster.
|
|
861
|
-
*/
|
|
862
|
-
export declare const SPEEDS: Record<ProjversorLayer["kind"], number[]>;
|
|
863
|
-
|
|
864
|
-
export declare interface TimeTick {
|
|
865
|
-
label: string;
|
|
866
|
-
position: number;
|
|
867
|
-
major: boolean;
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
/**
|
|
871
|
-
* UTC marks as positions along [first, last], at a unit fitting the span:
|
|
872
|
-
* days (the 1st and every 5th major) up to two months, months (quarters
|
|
873
|
-
* major, January labelled with its year) up to two and a half years, else
|
|
874
|
-
* years (every one major, every 5th past twelve years).
|
|
875
|
-
*/
|
|
876
|
-
export declare function timeTicks(first: number, last: number): TimeTick[];
|
|
877
|
-
|
|
878
|
-
/** Scalar layers offered to color the particles. */
|
|
879
|
-
export declare const TINT_LAYERS: ProjversorLayer[];
|
|
880
|
-
|
|
881
|
-
/** Projection morph duration. */
|
|
882
|
-
export declare const TRANSITION_MS = 2200;
|
|
883
|
-
|
|
884
|
-
/** Everything that places the sphere on screen. */
|
|
885
|
-
declare interface View {
|
|
886
|
-
blend: Blend;
|
|
887
|
-
/** d3 rotate([λ, φ, γ]) in degrees. */
|
|
888
|
-
rotate: [number, number, number];
|
|
889
|
-
zoom: number;
|
|
890
|
-
/** Css px. */
|
|
891
|
-
width: number;
|
|
892
|
-
height: number;
|
|
893
|
-
/** Free zone; the whole viewport when omitted. */
|
|
894
|
-
inset?: Inset;
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
/** Easing of compass, zoom and rotate controls. */
|
|
898
|
-
export declare const VIEW_MS = 450;
|
|
899
|
-
|
|
900
|
-
/** The free zone: its center and size in css px, at least 1 px wide. */
|
|
901
|
-
export declare function viewArea(view: View): {
|
|
902
|
-
cx: number;
|
|
903
|
-
cy: number;
|
|
904
|
-
width: number;
|
|
905
|
-
height: number;
|
|
906
|
-
};
|
|
907
|
-
|
|
908
|
-
/** Values derived once per frame from a View, shared by every pass. */
|
|
909
|
-
declare interface ViewFrame extends View {
|
|
910
|
-
/** Clip angle in degrees; 180 = antimeridian cut only. */
|
|
911
|
-
clipAngle: number;
|
|
912
|
-
/** Geographic → rotated frame, and its inverse. */
|
|
913
|
-
rot: Mat3;
|
|
914
|
-
rotInv: Mat3;
|
|
915
|
-
/** Approximate px per radian at the projection center. */
|
|
916
|
-
pxPerRadian: number;
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
export { }
|