canvas-globe 0.1.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.
@@ -0,0 +1,696 @@
1
+ export interface Marker {
2
+ /** Latitude in degrees (-90…90). */
3
+ lat: number;
4
+ /** Longitude in degrees (-180…180). */
5
+ lon: number;
6
+ /** Base dot radius in px before scaling. Defaults to 3.4. */
7
+ size?: number;
8
+ /** Weight used to size the marker relative to the largest one. */
9
+ count?: number;
10
+ /** Emoji or short glyph drawn inside a bubble marker. */
11
+ emoji?: string;
12
+ /** Logo or avatar, drawn as a circular crop. Wins over `emoji`. */
13
+ image?: string | CanvasImageSource;
14
+ /** Radius of an image marker in px. Default 19. */
15
+ imageSize?: number;
16
+ /** When this happened, for `timeline`. Anything `new Date()` accepts. */
17
+ date?: string | number | Date;
18
+ /** Draws a pulsing ring: use for "active right now". */
19
+ live?: boolean;
20
+ /** Overrides the theme marker colour. */
21
+ color?: string;
22
+ /** Anything you want back in onHover/onClick. */
23
+ [key: string]: unknown;
24
+ }
25
+
26
+ /** Synthetic marker produced when `cluster` is on. */
27
+ export interface ClusterMarker {
28
+ cluster: true;
29
+ count: number;
30
+ markers: Marker[];
31
+ lat: number;
32
+ lon: number;
33
+ }
34
+
35
+ export type Coordinate = { lat: number; lon: number } | [lon: number, lat: number];
36
+
37
+ export interface Arc {
38
+ from: Coordinate;
39
+ to: Coordinate;
40
+ /** Stroke colour. Defaults to the theme's `arc`. */
41
+ color?: string;
42
+ /** Colour of the animated leading segment. Defaults to `color`. */
43
+ headColor?: string;
44
+ /** Line width in px. Default 1.6. */
45
+ width?: number;
46
+ /** Peak height above the sphere as a fraction of the radius. Default 0.28. */
47
+ lift?: number;
48
+ /** Great-circle sample count. Default 72. */
49
+ steps?: number;
50
+ /** Milliseconds for one travel cycle. Default 2400. */
51
+ duration?: number;
52
+ /** Length of the moving segment, 0…1. Default 0.22. */
53
+ headLength?: number;
54
+ /** Opacity of the static base line, 0…1. Default 0.28. */
55
+ baseAlpha?: number;
56
+ /** Set false to draw a plain static line. */
57
+ animate?: boolean;
58
+ /** Emoji drawn at the travelling head instead of a dot. */
59
+ icon?: string;
60
+ [key: string]: unknown;
61
+ }
62
+
63
+ /** A country as carried by the bundled geometry. */
64
+ export interface CountryShape {
65
+ id?: string | number;
66
+ name?: string;
67
+ iso?: string;
68
+ geometry: unknown;
69
+ }
70
+
71
+ export interface Theme {
72
+ /** [inner, outer] ocean gradient stops. */
73
+ ocean: [string, string];
74
+ land: string;
75
+ border: string;
76
+ graticule: string;
77
+ atmosphere: string;
78
+ rim: string;
79
+ marker: string;
80
+ markerGlow: string;
81
+ live: string;
82
+ bubble: string;
83
+ label: string;
84
+ stars: string;
85
+ /** Colour of the land dots when `landStyle` is "dots". */
86
+ dot: string;
87
+ /** Halo colour when `landStyle` is "glow". */
88
+ glow: string;
89
+ /** Colour of decorative orbit rings. */
90
+ orbit: string;
91
+ /** Base colour for great-circle arcs. */
92
+ arc: string;
93
+ /** Colour of the comet head on animated arcs. */
94
+ arcHead: string;
95
+ /** Overlay painted on the night side when `terminator` is on. */
96
+ night: string;
97
+ cluster: string;
98
+ clusterLabel: string;
99
+ /** Ring drawn around the keyboard-focused marker. */
100
+ focus: string;
101
+ /** Wash painted over the hovered country. */
102
+ countryHover: string;
103
+ shade: boolean;
104
+ }
105
+
106
+ export type ThemeName = "atlas" | "midnight" | "mono" | "hologram" | "neon" | "blueprint" | "aurora" | "noir" | "political";
107
+ export type PresetName = ThemeName | "constellation";
108
+ export type SceneName = "signups" | "launch" | "logos" | "team" | "coverage" | "review" | "routes";
109
+ export type MapProjection = "equirectangular" | "mercator" | "naturalEarth";
110
+ /** How landmasses are drawn: solid, halftone dots, line art, neon glow, or nothing. */
111
+ export type LandStyle = "fill" | "dots" | "outline" | "glow" | "none";
112
+
113
+ export interface ViewerLocation {
114
+ lat: number;
115
+ lon: number;
116
+ /** IANA zone the browser reported, when available. */
117
+ timeZone: string | null;
118
+ /** ISO 3166-1 alpha-2, when known. */
119
+ country: string | null;
120
+ source: "timezone" | "locale" | "geolocation";
121
+ accuracy: "region" | "country" | "precise";
122
+ /** Radius the position is good to. Null until the globe derives one. */
123
+ accuracyMeters: number | null;
124
+ /** Which reference point the pin was placed on. */
125
+ anchor?: "gps" | "country" | "timezone";
126
+ }
127
+
128
+ export interface ShowViewerOptions {
129
+ /** Glyph for the pin. Defaults to a map marker. */
130
+ emoji?: string;
131
+ label?: string;
132
+ color?: string;
133
+ live?: boolean;
134
+ /** Ask for GPS permission and upgrade the pin if granted. Default false. */
135
+ precise?: boolean;
136
+ /** Passed through to the Geolocation API. Defaults to true for `precise`. */
137
+ enableHighAccuracy?: boolean;
138
+ timeout?: number;
139
+ maximumAge?: number;
140
+ /**
141
+ * Where to put the pin for a non-GPS fix. "auto" (default) uses the country
142
+ * centroid for countries wider than 8°: one time zone covers all of India,
143
+ * so its published city would be confidently wrong, and the time-zone city
144
+ * everywhere else.
145
+ */
146
+ anchor?: "auto" | "country" | "timezone";
147
+ /** Draw the uncertainty radius around the pin. Default true. */
148
+ accuracyCircle?: boolean;
149
+ accuracyColor?: string;
150
+ /** Centre the view on the viewer once located. */
151
+ flyTo?: boolean;
152
+ flyToOptions?: FlyToOptions;
153
+ /** Fire a ping at the viewer's position. */
154
+ ping?: boolean;
155
+ onLocate?: (location: ViewerLocation) => void;
156
+ }
157
+
158
+ export interface PingSpec {
159
+ lat: number;
160
+ lon: number;
161
+ label?: string;
162
+ emoji?: string;
163
+ color?: string;
164
+ /** Number of expanding rings. Default 3. */
165
+ rings?: number;
166
+ /** Peak ring radius in px. Default 46. */
167
+ radius?: number;
168
+ /** Lifetime in ms. Default 2600. */
169
+ duration?: number;
170
+ /** Throw particles outward: `true` for 14, or a count. */
171
+ burst?: boolean | number;
172
+ burstColor?: string;
173
+ flyTo?: boolean;
174
+ flyToOptions?: FlyToOptions;
175
+ }
176
+
177
+ export interface Handle {
178
+ stop(): void;
179
+ }
180
+
181
+ export interface StoryStep extends Partial<GeoGlobeOptions> {
182
+ /** Scroll progress, 0-1. */
183
+ at: number;
184
+ center?: [lon: number, lat: number];
185
+ zoom?: number;
186
+ }
187
+
188
+ export interface HeatmapOptions {
189
+ /** Blob radius in px at full weight. Default 30. */
190
+ radius?: number;
191
+ /** Peak opacity, 0-1. Default 0.5. */
192
+ intensity?: number;
193
+ color?: string;
194
+ }
195
+
196
+ export interface SpikeOptions {
197
+ /** Tallest spike as a fraction of the globe radius. Default 0.28. */
198
+ height?: number;
199
+ /** Line width in px. Default 2.4. */
200
+ width?: number;
201
+ }
202
+
203
+ export interface LegendSpec {
204
+ title?: string;
205
+ /** Discrete swatches. */
206
+ items?: { color: string; label: string }[];
207
+ /** Continuous ramp; mirrors `colorScale` arguments. */
208
+ scale?: { domain?: number[]; range?: string[] };
209
+ position?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
210
+ width?: number;
211
+ height?: number;
212
+ }
213
+
214
+ export interface RecordingHandle {
215
+ promise: Promise<Blob>;
216
+ mimeType?: string;
217
+ stop(): Promise<Blob>;
218
+ }
219
+
220
+ /** Anything `drawImage` accepts, plus a URL or a live stream. */
221
+ export type MediaSource = string | CanvasImageSource | MediaStream;
222
+
223
+ export interface MediaSpec {
224
+ src: MediaSource;
225
+ /** How the media fills the country's box. Default "cover". */
226
+ fit?: "cover" | "contain" | "fill";
227
+ /** Force the source type when the URL has no useful extension. */
228
+ type?: "image" | "video";
229
+ opacity?: number;
230
+ /** Any canvas composite operation, e.g. "screen" or "multiply". */
231
+ blend?: GlobalCompositeOperation;
232
+ /** Extra zoom on top of the fit. Default 1. */
233
+ scale?: number;
234
+ /** Pixel nudge, `[x, y]`. */
235
+ offset?: [number, number];
236
+ loop?: boolean;
237
+ muted?: boolean;
238
+ crossOrigin?: string | null;
239
+ }
240
+
241
+ /** Type cut out of a country's outline, auto-sized to fit its width. */
242
+ export interface CountryTextSpec {
243
+ text: string;
244
+ color?: string;
245
+ background?: string;
246
+ font?: string;
247
+ weight?: number;
248
+ /** Fixed size in px; omit to auto-fit. */
249
+ size?: number;
250
+ /** Fraction of the shape's width the text should span. Default 0.86. */
251
+ fill?: number;
252
+ opacity?: number;
253
+ offset?: [number, number];
254
+ }
255
+
256
+ export interface Annotation {
257
+ lat: number;
258
+ lon: number;
259
+ text?: string;
260
+ /** Leader-line offset from the point. Defaults to 46, -46. */
261
+ dx?: number;
262
+ dy?: number;
263
+ color?: string;
264
+ size?: number;
265
+ }
266
+
267
+ export interface CounterSpec {
268
+ value: number;
269
+ label?: string;
270
+ /** Formats the rolling value. Defaults to a localised integer. */
271
+ format?: (value: number) => string;
272
+ size?: number;
273
+ color?: string;
274
+ padding?: number;
275
+ position?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
276
+ }
277
+
278
+ export type OverlayPosition =
279
+ | "top-left" | "top-center" | "top-right"
280
+ | "bottom-left" | "bottom-center" | "bottom-right";
281
+
282
+ export interface TitleSpec {
283
+ text: string;
284
+ subtitle?: string;
285
+ /** Defaults to 6.2% of the smaller canvas side. */
286
+ size?: number;
287
+ /** Defaults to 42% of `size`. */
288
+ subtitleSize?: number;
289
+ weight?: number | string;
290
+ font?: string;
291
+ color?: string;
292
+ subtitleColor?: string;
293
+ padding?: number;
294
+ position?: OverlayPosition;
295
+ }
296
+
297
+ export interface WatermarkSpec {
298
+ /** A logo URL or any drawable element. */
299
+ image?: string | CanvasImageSource;
300
+ /** Wordmark drawn under the logo, or on its own. */
301
+ text?: string;
302
+ /** Logo height in pixels. Defaults to 7% of the smaller canvas side. */
303
+ height?: number;
304
+ /** Wordmark size. Defaults to 3.2% of the smaller canvas side. */
305
+ size?: number;
306
+ weight?: number | string;
307
+ font?: string;
308
+ color?: string;
309
+ /** Defaults to 0.85. */
310
+ opacity?: number;
311
+ padding?: number;
312
+ /** Defaults to "bottom-right". */
313
+ position?: OverlayPosition;
314
+ }
315
+
316
+ export interface TimelineSpec {
317
+ /** Markers with a later `date` are hidden. */
318
+ at: string | number | Date;
319
+ }
320
+
321
+ export type ExportPresetName =
322
+ | "square" | "story" | "portrait" | "wide" | "linkedin" | "og" | "twitter" | "thumbnail";
323
+
324
+ /** `{ "Ahmedabad": [lon, lat] }`: plug in your own places. */
325
+ export type Gazetteer = Record<string, [number, number] | { lat: number; lon: number }>;
326
+
327
+ export interface CsvOptions {
328
+ gazetteer?: Gazetteer;
329
+ /** Copy every unrecognised column onto the marker. Default true. */
330
+ extra?: boolean;
331
+ }
332
+
333
+ export interface ExportOptions {
334
+ preset?: ExportPresetName;
335
+ width?: number;
336
+ height?: number;
337
+ /** Skip the ocean fill so the result has an alpha channel. */
338
+ transparent?: boolean;
339
+ type?: string;
340
+ quality?: number;
341
+ }
342
+
343
+ export interface FocusSpec {
344
+ /** ISO alpha-2 code, numeric id or country name. */
345
+ country: string;
346
+ /** Drop every other country instead of dimming it. */
347
+ isolate?: boolean;
348
+ /** Opacity for unfocused countries when not isolating. Default 0.16. */
349
+ dim?: number;
350
+ /** Outline width for the focused country. Default 1.6. */
351
+ outlineWidth?: number;
352
+ /** Fraction of the viewport to fill. Default 0.82. */
353
+ padding?: number;
354
+ }
355
+
356
+ export interface Orbit {
357
+ /** Tilt of the ring in degrees. Default varies per generated ring. */
358
+ inclination?: number;
359
+ /** Starting rotation in degrees. */
360
+ phase?: number;
361
+ /** Ring radius as a multiple of the globe radius. Default ~1.15. */
362
+ radius?: number;
363
+ /** Degrees per second; negative counter-rotates. */
364
+ speed?: number;
365
+ color?: string;
366
+ width?: number;
367
+ }
368
+
369
+ export interface RenderMarkerContext {
370
+ x: number;
371
+ y: number;
372
+ /** 0…1 foreshortening factor; always 1 in map mode. */
373
+ depth: number;
374
+ scale: number;
375
+ theme: Theme;
376
+ /** Largest `count` in the current set, for relative sizing. */
377
+ max: number;
378
+ globe: GeoGlobe;
379
+ }
380
+
381
+ export type TooltipKind = "marker" | "cluster" | "country";
382
+
383
+ export interface GeoGlobeOptions {
384
+ /**
385
+ * License key supplied for a GPLv3-compatible project or with a commercial
386
+ * order. Never sent over the network and never used to disable features.
387
+ */
388
+ licenseKey?: string | null;
389
+ /** "globe" (orthographic, spinnable) or "map" (flat). Default "globe". */
390
+ mode?: "globe" | "map";
391
+ /** Flat-map projection. Default "equirectangular". */
392
+ projection?: MapProjection;
393
+ /** Built-in theme name or a partial theme object. Default "atlas". */
394
+ theme?: ThemeName | Partial<Theme>;
395
+ /** Named bundle of theme + render style, applied under your own options. */
396
+ preset?: PresetName;
397
+ /** Theme name, a partial theme, "auto" for the OS colour scheme, or "css"
398
+ * to read `--geo-*` custom properties off the canvas. */
399
+ theme?: ThemeName | "auto" | "css" | Partial<Theme>;
400
+ /** How landmasses are drawn. Default "fill". */
401
+ landStyle?: LandStyle;
402
+ /** Dot grid spacing in degrees when `landStyle` is "dots". Default 2. */
403
+ dotSpacing?: number;
404
+ /** Dot radius in px when `landStyle` is "dots". Default 1.15. */
405
+ dotSize?: number;
406
+ /** Decorative great-circle rings: a count (0-6) or explicit ring specs. */
407
+ orbits?: number | Orbit[];
408
+ /** Fills used by `countryColors: "auto"`. */
409
+ countryPalette?: string[] | null;
410
+ /** Equirectangular image painted onto the sphere. URL, image or canvas. */
411
+ texture?: string | CanvasImageSource | null;
412
+ /** Pixel step for the texture pass; higher is faster. Default "auto". */
413
+ textureQuality?: "auto" | number;
414
+ /** Frame a single country, optionally dropping the rest of the world. */
415
+ focus?: string | FocusSpec | null;
416
+ /** Media painted inside each country's outline, keyed by ISO, id or name. */
417
+ countryMedia?: Record<string, MediaSource | MediaSpec | CountryTextSpec> | null;
418
+ /** Whole composition: preset plus the layers a given job needs. */
419
+ scene?: SceneName;
420
+ /** Leader-line callouts. */
421
+ annotations?: Annotation[] | null;
422
+ /** Rolling headline number drawn over the scene. */
423
+ counter?: CounterSpec | null;
424
+ /** Headline text painted onto the canvas, so exports come out finished. */
425
+ title?: TitleSpec | null;
426
+ /** Logo or wordmark painted onto the canvas, so exports come out branded. */
427
+ watermark?: WatermarkSpec | null;
428
+ /** Hides markers whose `date` has not arrived. */
429
+ timeline?: TimelineSpec | null;
430
+ /** Skip the ocean fill so exports keep an alpha channel. */
431
+ transparentBackground?: boolean;
432
+ /** Additive density blobs instead of, or under, markers. */
433
+ heatmap?: boolean | HeatmapOptions;
434
+ /** Bars standing off the surface, scaled by each marker's `count`. */
435
+ spikes?: boolean | SpikeOptions;
436
+ /** Text labels with collision avoidance. */
437
+ labels?: boolean | "markers" | "countries" | "both";
438
+ /** Draws a legend card in a corner. */
439
+ legend?: LegendSpec | null;
440
+ /** Pin the current viewer using their time zone: no prompt, no network. */
441
+ showViewer?: boolean | ShowViewerOptions;
442
+ /** Coast after a drag instead of stopping dead. Default true. */
443
+ momentum?: boolean;
444
+ markers?: Marker[];
445
+ /** Great-circle connections drawn above the surface. */
446
+ arcs?: Arc[];
447
+ /** Initial view centre. Default { lon: 10, lat: 20 }. */
448
+ center?: { lon: number; lat: number };
449
+ /** Initial zoom. Default 1. */
450
+ zoom?: number;
451
+ /** Default 1. */
452
+ minZoom?: number;
453
+ /** Default 8. */
454
+ maxZoom?: number;
455
+ /** Wheel and pinch zoom. Default true. */
456
+ zoomable?: boolean;
457
+ /** Spin when idle. Default true. */
458
+ autoRotate?: boolean;
459
+ /** Degrees per frame. Default 0.09. */
460
+ rotateSpeed?: number;
461
+ /** Drag, zoom and hover/click. Default true. */
462
+ interactive?: boolean;
463
+ /** Arrow keys, +/-, 0 and PageUp/PageDown. Default true. */
464
+ keyboard?: boolean;
465
+ graticule?: boolean;
466
+ /** Starfield outside the sphere. Default true. */
467
+ stars?: boolean;
468
+ /** Lit-from-upper-left shading. Default true. */
469
+ shade?: boolean;
470
+ /** Shade the night side using the real solar position. Default false. */
471
+ terminator?: boolean;
472
+ /** Clock for the terminator. null tracks the current time. */
473
+ time?: Date | number | null;
474
+ /** "auto" uses bubbles when a marker has an emoji or count > 1. Default "auto". */
475
+ markerStyle?: "auto" | "bubble" | "dot";
476
+ markerScale?: number;
477
+ /** Draw markers yourself. Return the hit radius in px. */
478
+ renderMarker?: (ctx: CanvasRenderingContext2D, marker: Marker | ClusterMarker, info: RenderMarkerContext) => number | void;
479
+ /** Merge nearby markers into count bubbles. Default false. */
480
+ cluster?: boolean;
481
+ /** Cluster grid size in px. Default 42. */
482
+ clusterRadius?: number;
483
+ /** Default arc height as a fraction of the globe radius. Default 0.28. */
484
+ arcLift?: number;
485
+ /** Multiplies every arc's travel speed. Default 1. */
486
+ arcSpeed?: number;
487
+ /** Fill colours keyed by ISO code, numeric id or country name. */
488
+ countryColors?: Record<string, string> | null;
489
+ /** Per-country fill callback; wins over `countryColors`. */
490
+ countryColor?: ((shape: CountryShape) => string | null | undefined) | null;
491
+ /** Maps a shape to the key used against `countryColors`. */
492
+ countryKey?: ((shape: CountryShape) => string | null | undefined) | null;
493
+ /** Globe radius as a fraction of the smaller canvas side. Default 0.4. */
494
+ radiusRatio?: number;
495
+ /** [north, south] latitude bounds for map mode. Default [83, -56]. */
496
+ latRange?: [number, number];
497
+ /** Replace the bundled country geometry. Accepts GeoJSON or the shape array. */
498
+ world?: unknown;
499
+ /** Frame cap. Default 30. */
500
+ fps?: number;
501
+ /** Built-in tooltip. `true` uses the default text, or pass a formatter. */
502
+ tooltip?: boolean | ((target: Marker | ClusterMarker | CountryShape, kind: TooltipKind) => string);
503
+ /** Honour `prefers-reduced-motion`. Default true. */
504
+ respectReducedMotion?: boolean;
505
+ /** Accessible name for the canvas. */
506
+ ariaLabel?: string;
507
+ onHover?: (marker: Marker | ClusterMarker | null, position: { x: number; y: number } | null) => void;
508
+ onClick?: (marker: Marker | ClusterMarker, position: { x: number; y: number }) => void;
509
+ onCountryHover?: (country: CountryShape | null, position: { x: number; y: number } | null) => void;
510
+ onCountryClick?: (country: CountryShape, position: { x: number; y: number }) => void;
511
+ onRender?: (instance: GeoGlobe) => void;
512
+ }
513
+
514
+ export interface FlyToOptions {
515
+ /** Jump instead of easing. */
516
+ instant?: boolean;
517
+ /** Also set the zoom level. */
518
+ zoom?: number;
519
+ }
520
+
521
+ export declare class GeoGlobe {
522
+ constructor(canvas: HTMLCanvasElement, options?: GeoGlobeOptions);
523
+ readonly canvas: HTMLCanvasElement;
524
+ readonly ctx: CanvasRenderingContext2D;
525
+ readonly theme: Theme;
526
+ readonly zoom: number;
527
+ /** Resolved country geometry currently in use. */
528
+ readonly world: CountryShape[];
529
+ lon: number;
530
+ lat: number;
531
+ markers: Marker[];
532
+ setMarkers(markers: Marker[]): this;
533
+ setArcs(arcs: Arc[]): this;
534
+ setOptions(patch: Partial<GeoGlobeOptions>): this;
535
+ setMode(mode: "globe" | "map"): this;
536
+ setTheme(theme: GeoGlobeOptions["theme"]): this;
537
+ setProjection(projection: MapProjection): this;
538
+ /** Applies a named look. Keys the preset omits return to their defaults. */
539
+ setPreset(name: PresetName): this;
540
+ setLandStyle(style: LandStyle): this;
541
+ /** Equirectangular image painted onto the sphere; null removes it. */
542
+ setTexture(source: string | CanvasImageSource | null): this;
543
+ /** Frames a country and, with `isolate`, drops the rest of the world away. */
544
+ focusOn(country: string | FocusSpec | null, opts?: Partial<FocusSpec> & FlyToOptions): this;
545
+ clearFocus(): this;
546
+ /** Media painted inside a country's outline; null clears it. */
547
+ setCountryMedia(country: string, source: MediaSource | MediaSpec | null): this;
548
+ /** Height / width ratio that frames a country without letterboxing. */
549
+ countryAspect(country: string): number | null;
550
+ /** Applies a whole composition. Keys the scene omits return to defaults. */
551
+ setScene(name: SceneName, overrides?: Partial<GeoGlobeOptions>): this;
552
+ /** Renders one frame at an arbitrary size. Null without a document. */
553
+ exportImage(opts?: ExportOptions): string | null;
554
+ /** Same as `exportImage`, resolved as a Blob. */
555
+ exportBlob(opts?: ExportOptions): Promise<Blob | null> | null;
556
+ /** Reveals markers whose `date` has arrived; null shows everything. */
557
+ setTimelineAt(at: string | number | Date | null): this;
558
+ /** Animates the timeline across a date range. */
559
+ playTimeline(opts?: { from?: string | number | Date; to?: string | number | Date; duration?: number; loop?: boolean; onTick?: (at: number) => void }): Handle;
560
+ stopTimeline(): this;
561
+ /** Fires a one-shot expanding ring at a coordinate. */
562
+ ping(spec: PingSpec): this;
563
+ ping(lat: number, rest: Omit<PingSpec, "lat">): this;
564
+ /** Replays a list of pings on a timer. */
565
+ pingFeed(items: PingSpec[], options?: { interval?: number; loop?: boolean; flyTo?: boolean; onPing?: (item: PingSpec) => void }): Handle;
566
+ clearPings(): this;
567
+ /** Flies between points on a timer. */
568
+ tour(points: (Coordinate)[], options?: { dwell?: number; zoom?: number; loop?: boolean; onStep?: (point: Coordinate, index: number) => void }): Handle;
569
+ stopTour(): this;
570
+ /** Drives the view from an element's scroll progress. */
571
+ story(element: Element, steps: StoryStep[], options?: { onStep?: (step: StoryStep, index: number) => void }): this;
572
+ stopStory(): this;
573
+ /** Records the canvas to a WebM Blob, entirely in the tab. */
574
+ record(options?: { duration?: number; fps?: number; bitrate?: number; type?: string; filename?: string }): RecordingHandle;
575
+ /** Where the viewer is, from their time zone. `precise` prompts for GPS. */
576
+ locateViewer(options?: { precise?: false }): ViewerLocation | null;
577
+ locateViewer(options: { precise: true }): Promise<ViewerLocation | null>;
578
+ /** Applies a resolved location as the viewer pin. */
579
+ setViewerLocation(location: ViewerLocation, spec?: ShowViewerOptions): this;
580
+ /** null tracks the current time. */
581
+ setTime(time: Date | number | null): this;
582
+ setZoom(zoom: number): this;
583
+ zoomBy(factor: number): this;
584
+ getCenter(): { lon: number; lat: number };
585
+ /** Eases the view to a coordinate; `{ instant: true }` jumps there. */
586
+ flyTo(lon: number, lat: number, opts?: FlyToOptions): this;
587
+ /** Frames a `[west, south, east, north]` bounding box. */
588
+ fitTo(bounds: [number, number, number, number], opts?: FlyToOptions & { padding?: number }): this;
589
+ /** Frames every marker, picking the shortest longitude arc that covers them. */
590
+ fitToMarkers(opts?: FlyToOptions & { padding?: number }): this;
591
+ /** Screen position of a coordinate, or null when it is behind the globe. */
592
+ project(lon: number, lat: number): { x: number; y: number; visible: boolean } | null;
593
+ /** Coordinate `[lon, lat]` under a canvas pixel, or null when it misses. */
594
+ unproject(x: number, y: number): [number, number] | null;
595
+ /** Country shape at a canvas pixel, or null. */
596
+ countryAt(x: number, y: number): CountryShape | null;
597
+ /** Marks the next frame as needing a redraw. */
598
+ invalidate(): this;
599
+ resize(): this;
600
+ render(): this;
601
+ snapshot(type?: string, quality?: number): string;
602
+ toBlob(type?: string, quality?: number): Promise<Blob | null>;
603
+ destroy(): this;
604
+ }
605
+
606
+ export declare function createGlobe(canvas: HTMLCanvasElement, options?: GeoGlobeOptions): GeoGlobe;
607
+ /** Brand-aligned alias for `GeoGlobe`. */
608
+ export { GeoGlobe as CanvasGlobe };
609
+ /** Brand-aligned alias for `createGlobe`. */
610
+ export { createGlobe as createCanvasGlobe };
611
+ export declare const DEFAULT_LICENSE_KEY: "0000-0000-000-0000";
612
+ export interface LicenseKeyStatus {
613
+ valid: boolean;
614
+ kind: "missing" | "placeholder" | "provided";
615
+ key: string;
616
+ }
617
+ /** Returns the configured license-key status. */
618
+ export declare function inspectLicenseKey(value: unknown): LicenseKeyStatus;
619
+ /** Returns whether a configured license key is available. */
620
+ export declare function hasLicenseKey(value: unknown): boolean;
621
+ export declare const themes: Record<ThemeName, Theme>;
622
+ /** Named bundles of theme + render style. */
623
+ export declare const presets: Record<PresetName, Partial<GeoGlobeOptions>>;
624
+ /** Whole compositions: preset plus the layers a given job needs. */
625
+ export declare const scenes: Record<SceneName, Partial<GeoGlobeOptions>>;
626
+ /** Distinct fills used by `countryColors: "auto"`. */
627
+ export declare const countryPalette: string[];
628
+ /** Canvas sizes for the places marketing assets get posted. */
629
+ export declare const exportPresets: Record<ExportPresetName, [number, number]>;
630
+ export declare function exportSize(spec: unknown, fallback: [number, number]): [number, number];
631
+
632
+ /** Parses CSV text into row objects with lowercased headers. */
633
+ export declare function parseCSV(text: string, options?: { delimiter?: string }): Record<string, string>[];
634
+ /** Converts rows to markers, resolving lat/lon, city or country columns. */
635
+ export declare function fromRows(rows: Record<string, string>[], options?: CsvOptions): Marker[] & { skipped: Record<string, string>[] };
636
+ /** `fromCSV("city,count\nAhmedabad,12")` → markers. */
637
+ export declare function fromCSV(text: string, options?: CsvOptions & { delimiter?: string }): Marker[] & { skipped: Record<string, string>[] };
638
+ /** Best-effort coordinate for a free-text place. */
639
+ export declare function geocode(name: string, options?: { gazetteer?: Gazetteer }): { lat: number; lon: number } | null;
640
+ /** Resolves a country code or name to a coordinate. */
641
+ export declare function countryPoint(name: string): { lat: number; lon: number; country: string | null } | null;
642
+ /** Coordinate for one of the time zone table's representative cities. */
643
+ export declare function placeLocation(name: string): { lat: number; lon: number; country: string; timeZone: string } | null;
644
+ /** Height / width ratio a flat map should use for a latitude range. */
645
+ export declare function mapAspect(latRange?: [number, number], projection?: MapProjection): number;
646
+ /** Builds a linear colour ramp for choropleths. */
647
+ export declare function colorScale(domain?: number[], range?: string[]): (value: number) => string | null;
648
+ /** Coordinate where the sun is directly overhead. */
649
+ export declare function subsolarPoint(when?: Date | number): { lon: number; lat: number };
650
+ /** Samples the shorter great-circle path between two coordinates. */
651
+ export declare function greatCircle(lon1: number, lat1: number, lon2: number, lat2: number, steps?: number): [number, number][];
652
+ /** Angular distance between two coordinates, in degrees. */
653
+ export declare function angularDistance(lon1: number, lat1: number, lon2: number, lat2: number): number;
654
+ /** Ray-casting hit test against a GeoJSON Polygon or MultiPolygon. */
655
+ export declare function pointInGeometry(geometry: unknown, lon: number, lat: number): boolean;
656
+ /** `[west, south, east, north]` bounds of a Polygon or MultiPolygon. */
657
+ export declare function geometryBounds(geometry: unknown): [number, number, number, number];
658
+ export declare const projections: Record<MapProjection, {
659
+ forward(lon: number, lat: number): [number, number];
660
+ inverse(x: number, y: number): [number, number];
661
+ }>;
662
+ export declare const world: CountryShape[];
663
+
664
+ /** Viewer location from the browser time zone. No prompt, no network call. */
665
+ export declare function locateViewer(): ViewerLocation | null;
666
+ /** Upgrades to GPS if the viewer allows it; falls back to the time zone. Never rejects. */
667
+ export declare function locateViewerPrecise(options?: { timeout?: number; maximumAge?: number; enableHighAccuracy?: boolean }): Promise<ViewerLocation | null>;
668
+ /** Published coordinate for an IANA zone name, resolving legacy aliases. */
669
+ export declare function timeZoneLocation(name: string): { lat: number; lon: number; country: string; timeZone: string } | null;
670
+ /** Representative coordinate for an ISO 3166-1 alpha-2 country code. */
671
+ export declare function countryLocation(code: string): { lat: number; lon: number; country: string; timeZone: string } | null;
672
+
673
+ /** True when this browser can encode a clip from a canvas. */
674
+ export declare function canRecord(): boolean;
675
+ export declare function supportedRecordingType(): string | null;
676
+ export declare function recordCanvas(canvas: HTMLCanvasElement, options?: { duration?: number; fps?: number; bitrate?: number; type?: string }): RecordingHandle;
677
+ export declare function downloadBlob(blob: Blob, filename: string): void;
678
+
679
+ /** Equirectangular image mapped onto the orthographic sphere. */
680
+ export declare class SphereTexture {
681
+ constructor(source: string | CanvasImageSource, options?: { maxWidth?: number; onLoad?: (texture: SphereTexture) => void });
682
+ readonly ready: boolean;
683
+ readonly error: Error | null;
684
+ }
685
+
686
+ /** A drawable media source: image, GIF, video, canvas or live stream. */
687
+ export declare class Media {
688
+ constructor(spec: MediaSource | MediaSpec, onReady?: (media: Media) => void);
689
+ readonly ready: boolean;
690
+ readonly error: Error | null;
691
+ readonly animated: boolean;
692
+ size(): [number, number] | null;
693
+ destroy(): void;
694
+ }
695
+
696
+ export default createGlobe;