canvas-globe 1.1.1 → 1.3.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.
- package/CHANGELOG.md +44 -0
- package/README.md +113 -5
- package/THIRD_PARTY_NOTICES.md +1 -0
- package/codemeta.json +1 -1
- package/custom-elements.json +2 -2
- package/dist/canvas-globe.umd.js +331 -8
- package/package.json +34 -2
- package/src/charts.js +458 -0
- package/src/controls.js +187 -0
- package/src/data/places.js +5 -0
- package/src/fx/effects/ambient.js +355 -0
- package/src/fx/effects/data.js +438 -0
- package/src/fx/effects/entrances.js +111 -0
- package/src/fx/effects/interaction.js +850 -0
- package/src/fx/effects/scene.js +571 -0
- package/src/fx/effects/transitions.js +209 -0
- package/src/fx/index.js +52 -0
- package/src/fx/pointer.js +94 -0
- package/src/fx/runtime.js +161 -0
- package/src/geo-globe.js +261 -8
- package/src/geo.js +70 -0
- package/src/places.js +97 -0
- package/src/recipes.js +188 -0
- package/src/version.js +1 -1
- package/types/charts.d.ts +82 -0
- package/types/controls.d.ts +54 -0
- package/types/element.d.ts +3 -3
- package/types/fx-interaction.d.ts +16 -0
- package/types/fx.d.ts +313 -0
- package/types/index.d.ts +94 -7
- package/types/jsr-element.d.ts +3 -3
- package/types/places.d.ts +43 -0
- package/types/recipes.d.ts +54 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,50 @@ All notable changes to this package are documented here. The format follows
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.3.0] - 2026-09-19
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added an interactive screen-space hex-bin density layer for globe and map
|
|
14
|
+
modes, including weighted aggregation, colour ramps, source-marker hit
|
|
15
|
+
payloads, framework event types, and 5,000-marker performance coverage.
|
|
16
|
+
- Added an Angular SSR and hydration starter with prerendered HTML, a stable
|
|
17
|
+
canvas shell, client hydration, and project-creator support.
|
|
18
|
+
- Added a reproducible nine-library globe comparison harness for timing,
|
|
19
|
+
bundle size, package metadata, server-import, and accessibility-surface
|
|
20
|
+
measurements.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Prevented the Angular component from creating a CanvasGlobe instance during
|
|
25
|
+
server rendering.
|
|
26
|
+
- Corrected public TypeScript declarations for story-step overrides and theme
|
|
27
|
+
options.
|
|
28
|
+
|
|
29
|
+
## [1.2.0] - 2026-09-18
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- Added an opt-in effect system with 54 composable effects, three paint stages,
|
|
34
|
+
deterministic timeline controls, pointer state, path tracing, and land-point
|
|
35
|
+
sampling through `canvas-globe/fx`.
|
|
36
|
+
- Added nine chart layers in `canvas-globe/charts`, six reversible recipes in
|
|
37
|
+
`canvas-globe/recipes`, and four markup-independent DOM controls in
|
|
38
|
+
`canvas-globe/controls`.
|
|
39
|
+
- Added `canvas-globe/places`, an optional offline search module containing
|
|
40
|
+
6,772 populated places from Natural Earth.
|
|
41
|
+
- Added 26 effect-authoring helpers for easing, deterministic particles,
|
|
42
|
+
scratch buffers, spherical geometry, HUD elements, and pointer interaction.
|
|
43
|
+
- Added five effect and interaction demo pages plus export, type, package, and
|
|
44
|
+
documentation coverage for all new public entry points.
|
|
45
|
+
|
|
46
|
+
### Changed
|
|
47
|
+
|
|
48
|
+
- Made auto-rotation, arcs, orbits, and marker pulses follow the seekable clock
|
|
49
|
+
during frame rendering.
|
|
50
|
+
- Kept all add-on modules outside the core entry point, leaving the core bundle
|
|
51
|
+
at 125.0 KB gzipped.
|
|
52
|
+
|
|
9
53
|
## [1.1.1] - 2026-09-17
|
|
10
54
|
|
|
11
55
|
- Prevented the production licensing presentation from covering live globes on
|
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
|
|
36
36
|
[](https://stackblitz.com/github/Shree-hari/canvas-globe?startScript=start)
|
|
37
37
|
|
|
38
|
-
**Start with your stack:** [Vanilla JS](starters/vanilla-vite) | [React + Vite](starters/react-vite) | [Next.js](starters/nextjs-app-router) | [Vue](starters/vue-vite) | [SvelteKit](starters/sveltekit) | [Web Component](starters/web-component-vite)
|
|
38
|
+
**Start with your stack:** [Vanilla JS](starters/vanilla-vite) | [React + Vite](starters/react-vite) | [Next.js](starters/nextjs-app-router) | [Nuxt](starters/nuxt-ssr) | [Vue](starters/vue-vite) | [SvelteKit](starters/sveltekit) | [Angular SSR](starters/angular-ssr) | [Web Component](starters/web-component-vite)
|
|
39
39
|
|
|
40
40
|
**Install with shadcn:** `npx shadcn@latest add https://canvasglobe.swiftools.com/r/canvas-globe.json`
|
|
41
41
|
|
|
@@ -56,6 +56,10 @@ key, tile service, or runtime network request.
|
|
|
56
56
|
- **Viewer location:** estimate a region from the browser time zone without a permission prompt
|
|
57
57
|
- **Live pings:** display recent activity without requiring a CanvasGlobe backend
|
|
58
58
|
- **Recording:** export a WebM clip in the browser
|
|
59
|
+
- **Optional effects:** 54 seekable visual and interaction effects in `canvas-globe/fx`
|
|
60
|
+
- **Chart layers:** nine animated geographic chart treatments in `canvas-globe/charts`
|
|
61
|
+
- **Recipes and controls:** complete looks and DOM bindings without adding framework code
|
|
62
|
+
- **Place search:** an optional 6,772-place search table with no runtime API request
|
|
59
63
|
- **Presets:** ten included visual styles
|
|
60
64
|
- **Day and night:** calculate the solar terminator for a given time
|
|
61
65
|
- **Four projections:** orthographic, equirectangular, Mercator, and Natural Earth
|
|
@@ -135,19 +139,19 @@ your existing application rather than installing a second React copy.
|
|
|
135
139
|
For a plain `<script>` installation, use the versioned UMD build:
|
|
136
140
|
|
|
137
141
|
```html
|
|
138
|
-
<script src="https://cdn.jsdelivr.net/npm/canvas-globe@1.
|
|
142
|
+
<script src="https://cdn.jsdelivr.net/npm/canvas-globe@1.3.0/dist/canvas-globe.umd.js"></script>
|
|
139
143
|
```
|
|
140
144
|
|
|
141
145
|
The same npm release is also available from UNPKG:
|
|
142
146
|
|
|
143
147
|
```html
|
|
144
|
-
<script src="https://unpkg.com/canvas-globe@1.
|
|
148
|
+
<script src="https://unpkg.com/canvas-globe@1.3.0/dist/canvas-globe.umd.js"></script>
|
|
145
149
|
```
|
|
146
150
|
|
|
147
151
|
Modern browsers can import the package through an ESM CDN:
|
|
148
152
|
|
|
149
153
|
```js
|
|
150
|
-
import { createGlobe } from "https://esm.sh/canvas-globe@1.
|
|
154
|
+
import { createGlobe } from "https://esm.sh/canvas-globe@1.3.0";
|
|
151
155
|
```
|
|
152
156
|
|
|
153
157
|
Pin an exact version in production so a future release cannot change a deployed page unexpectedly.
|
|
@@ -167,7 +171,7 @@ import { createGlobe } from "canvas-globe";
|
|
|
167
171
|
Or drop the UMD build on a page with no build step at all:
|
|
168
172
|
|
|
169
173
|
```html
|
|
170
|
-
<script src="https://cdn.jsdelivr.net/npm/canvas-globe@1.
|
|
174
|
+
<script src="https://cdn.jsdelivr.net/npm/canvas-globe@1.3.0/dist/canvas-globe.umd.js"></script>
|
|
171
175
|
<canvas id="globe" style="width:520px;aspect-ratio:1"></canvas>
|
|
172
176
|
<script>
|
|
173
177
|
CanvasGlobe.createGlobe(document.getElementById("globe"), {
|
|
@@ -284,6 +288,74 @@ npx skills add https://github.com/Shree-hari/canvas-globe --skill canvas-globe
|
|
|
284
288
|
|
|
285
289
|
Or copy the maintained prompt from the [AI-assisted setup guide](https://canvasglobe.swiftools.com/getting-started/ai-assisted-setup). The skill and prompt select the correct framework entry point, include cleanup and accessibility, and require the user to purchase a production license before shipping.
|
|
286
290
|
|
|
291
|
+
## Effects, charts, recipes, controls, and place search
|
|
292
|
+
|
|
293
|
+
The animation and data-visualization modules are separate entry points. The
|
|
294
|
+
core globe remains about 125 KB gzipped, and applications only download the
|
|
295
|
+
modules they import.
|
|
296
|
+
|
|
297
|
+
| Import | Approximate gzip size | Includes |
|
|
298
|
+
| --- | ---: | --- |
|
|
299
|
+
| `canvas-globe/fx` | 25.4 KB | 54 visual, transition, data, camera, and interaction effects plus authoring helpers |
|
|
300
|
+
| `canvas-globe/charts` | 4.3 KB | Nine animated chart layers |
|
|
301
|
+
| `canvas-globe/recipes` | 2.0 KB | Six complete, reversible compositions |
|
|
302
|
+
| `canvas-globe/controls` | 1.8 KB | Search, timeline, threshold, and crossfilter bindings |
|
|
303
|
+
| `canvas-globe/places` | 93.6 KB | Search over 6,772 bundled places |
|
|
304
|
+
|
|
305
|
+
Effects are plain objects installed on a globe. They can be combined, removed,
|
|
306
|
+
and rendered at an exact timeline position:
|
|
307
|
+
|
|
308
|
+
```js
|
|
309
|
+
import { createGlobe } from "canvas-globe";
|
|
310
|
+
import { aurora, counterRoll, routeDashes } from "canvas-globe/fx";
|
|
311
|
+
import { tilegram } from "canvas-globe/charts";
|
|
312
|
+
|
|
313
|
+
const globe = createGlobe(canvas, { preset: "midnight", markers });
|
|
314
|
+
globe
|
|
315
|
+
.use(aurora())
|
|
316
|
+
.use(routeDashes({ routes }))
|
|
317
|
+
.use(counterRoll({ to: 21947, caption: "customers", position: "bottom-center" }));
|
|
318
|
+
|
|
319
|
+
globe.renderFrame(1200); // draw the frame at 1.2 seconds
|
|
320
|
+
globe.use(tilegram({ values: countryValues }));
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Use a recipe when you want a complete look rather than individual effects:
|
|
324
|
+
|
|
325
|
+
```js
|
|
326
|
+
import { applyRecipe, keynoteGlobe } from "canvas-globe/recipes";
|
|
327
|
+
|
|
328
|
+
const undo = applyRecipe(globe, keynoteGlobe({ countries: 68 }));
|
|
329
|
+
undo(); // restores the previous options and removes the recipe effects
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Controls bind elements you already own and return cleanup functions. They do
|
|
333
|
+
not inject markup or styles:
|
|
334
|
+
|
|
335
|
+
```js
|
|
336
|
+
import { searchAndFly } from "canvas-globe/controls";
|
|
337
|
+
import { placeSource } from "canvas-globe/places";
|
|
338
|
+
|
|
339
|
+
const unbind = searchAndFly(globe, document.querySelector("#place-search"), {
|
|
340
|
+
source: placeSource(),
|
|
341
|
+
});
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
`canvas-globe/places` is optional because its city table is almost as large as
|
|
345
|
+
the country geometry. Core already resolves countries and roughly 300 major
|
|
346
|
+
cities. Import the place module only when broader offline city search is worth
|
|
347
|
+
the extra payload.
|
|
348
|
+
|
|
349
|
+
`seek(ms)` and `renderFrame(ms)` pin the effect clock, auto-rotation, arcs,
|
|
350
|
+
orbits, and marker pulses. `windField` and part of
|
|
351
|
+
`glitch` accumulate the previous frame by design, so reproduce them by
|
|
352
|
+
exporting frames sequentially. Live media, newly fired pings, and a terminator
|
|
353
|
+
using the current time are external dynamic state and should be fixed or
|
|
354
|
+
disabled for frame-exact export.
|
|
355
|
+
|
|
356
|
+
Custom effects use the same public contract and authoring helpers as the
|
|
357
|
+
included effects. See `types/fx.d.ts` for every option and callback signature.
|
|
358
|
+
|
|
287
359
|
## Options
|
|
288
360
|
|
|
289
361
|
| Option | Default | Description |
|
|
@@ -309,6 +381,7 @@ Or copy the maintained prompt from the [AI-assisted setup guide](https://canvasg
|
|
|
309
381
|
| `timeline` | Not set | `{ at }`: hides markers whose `date` has not arrived |
|
|
310
382
|
| `transparentBackground` | `false` | Skip the ocean fill so exports keep an alpha channel |
|
|
311
383
|
| `heatmap` | `false` | Additive density blobs: `{ radius, intensity, color }` |
|
|
384
|
+
| `hexBins` | `false` | Interactive screen-space density cells; see [Hex bins](#hex-bins) |
|
|
312
385
|
| `spikes` | `false` | Bars off the surface, sized by `count`: `{ height, width }` |
|
|
313
386
|
| `labels` | `false` | `"markers"` \| `"countries"` \| `"both"`, with collision avoidance |
|
|
314
387
|
| `legend` | Not set | `{ title, items }` or `{ title, scale, position }` |
|
|
@@ -371,6 +444,41 @@ With `cluster: true`, dense areas collapse into a single bubble and your callbac
|
|
|
371
444
|
`{ cluster: true, count, markers, lat, lon }` instead. Clustering happens in screen space, so it
|
|
372
445
|
re-balances automatically as you zoom.
|
|
373
446
|
|
|
447
|
+
## Hex bins
|
|
448
|
+
|
|
449
|
+
Use hex bins when individual markers are too dense to read. CanvasGlobe aggregates the visible,
|
|
450
|
+
projected markers into a pointy-top hexagonal grid, so the density view updates naturally as the
|
|
451
|
+
globe rotates, the map pans, or the user zooms.
|
|
452
|
+
|
|
453
|
+
```js
|
|
454
|
+
const globe = createGlobe(canvas, {
|
|
455
|
+
markers: demandPoints,
|
|
456
|
+
hexBins: {
|
|
457
|
+
radius: 19,
|
|
458
|
+
value: "sum",
|
|
459
|
+
colorRange: ["#dbeafe", "#2563eb", "#172554"],
|
|
460
|
+
padding: 1.5,
|
|
461
|
+
showCount: true,
|
|
462
|
+
},
|
|
463
|
+
tooltip: (target, kind) => kind === "hex-bin"
|
|
464
|
+
? `${target.markerCount} locations, ${target.value} total requests`
|
|
465
|
+
: target.name,
|
|
466
|
+
onClick: (target) => {
|
|
467
|
+
if (target.hexBin) console.log(target.markers);
|
|
468
|
+
},
|
|
469
|
+
});
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
Each interactive bin returned to `tooltip`, `onHover`, and `onClick` contains
|
|
473
|
+
`{ hexBin: true, markerCount, count, value, markers, lat, lon }`. The default `value: "sum"` adds
|
|
474
|
+
each marker's `count`; use `value: "count"` to colour by the number of markers. Individual markers
|
|
475
|
+
are hidden by default while the layer is active. Set `hideMarkers: false` to keep them visible.
|
|
476
|
+
|
|
477
|
+
Available options are `radius`, `minValue`, `value`, `color`, `colorRange`, `opacity`, `stroke`,
|
|
478
|
+
`strokeWidth`, `padding`, `showCount`, `labelColor`, and `hideMarkers`. The same configuration works
|
|
479
|
+
in globe and flat-map modes. Since binning happens after projection, `radius` is measured in screen
|
|
480
|
+
pixels rather than geographic degrees.
|
|
481
|
+
|
|
374
482
|
### How accurate is marker placement?
|
|
375
483
|
|
|
376
484
|
The projection maths is exact: a marker's pixel position matches the closed-form projection to
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -5,6 +5,7 @@ CanvasGlobe includes geographic data derived from these sources:
|
|
|
5
5
|
| Files | Source | Terms |
|
|
6
6
|
| --- | --- | --- |
|
|
7
7
|
| `src/data/world.js` | [Natural Earth 1:110m](https://www.naturalearthdata.com/about/terms-of-use/) through [world-atlas](https://github.com/topojson/world-atlas) | Natural Earth states that its data is public domain |
|
|
8
|
+
| `src/data/places.js` | [Natural Earth 1:10m populated places](https://www.naturalearthdata.com/downloads/10m-cultural-vectors/10m-populated-places/) | Natural Earth states that its data is public domain |
|
|
8
9
|
| `src/data/india.js` | [Datameet india-composite](https://github.com/datameet/maps) | CC0 / public-domain dedication as stated by the source repository |
|
|
9
10
|
|
|
10
11
|
The CanvasGlobe Software License Agreement applies to CanvasGlobe's original software
|
package/codemeta.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"identifier": "canvas-globe",
|
|
6
6
|
"description": "CanvasGlobe helps developers add interactive 3D globes and flat world maps to JavaScript and React apps with Canvas 2D, without WebGL, map tiles, API keys, or runtime network calls.",
|
|
7
7
|
"url": "https://canvasglobe.swiftools.com/",
|
|
8
|
-
"version": "1.
|
|
8
|
+
"version": "1.3.0",
|
|
9
9
|
"codeRepository": "https://github.com/Shree-hari/canvas-globe",
|
|
10
10
|
"issueTracker": "https://github.com/Shree-hari/canvas-globe/issues",
|
|
11
11
|
"downloadUrl": "https://www.npmjs.com/package/canvas-globe",
|
package/custom-elements.json
CHANGED
|
@@ -112,8 +112,8 @@
|
|
|
112
112
|
{ "name": "lat-range", "description": "Serialized latitude range.", "type": { "text": "[number, number]" } }
|
|
113
113
|
],
|
|
114
114
|
"events": [
|
|
115
|
-
{ "name": "geo-hover", "description": "Fires when the hovered marker changes.", "type": { "text": "CustomEvent<{ marker: Marker | ClusterMarker | null; pos: { x: number; y: number } | null }>" } },
|
|
116
|
-
{ "name": "geo-click", "description": "Fires when a marker is clicked.", "type": { "text": "CustomEvent<{ marker: Marker | ClusterMarker; pos: { x: number; y: number } }>" } },
|
|
115
|
+
{ "name": "geo-hover", "description": "Fires when the hovered marker changes.", "type": { "text": "CustomEvent<{ marker: Marker | ClusterMarker | HexBinMarker | null; pos: { x: number; y: number } | null }>" } },
|
|
116
|
+
{ "name": "geo-click", "description": "Fires when a marker is clicked.", "type": { "text": "CustomEvent<{ marker: Marker | ClusterMarker | HexBinMarker; pos: { x: number; y: number } }>" } },
|
|
117
117
|
{ "name": "geo-country-hover", "description": "Fires when the hovered country changes.", "type": { "text": "CustomEvent<{ country: CountryShape | null; pos: { x: number; y: number } | null }>" } },
|
|
118
118
|
{ "name": "geo-country-click", "description": "Fires when a country is clicked.", "type": { "text": "CustomEvent<{ country: CountryShape; pos: { x: number; y: number } }>" } },
|
|
119
119
|
{ "name": "geo-render", "description": "Fires after CanvasGlobe renders a frame.", "type": { "text": "CustomEvent<{ globe: GeoGlobe }>" } }
|