canvas-globe 0.1.0 → 0.1.2

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 CHANGED
@@ -1,137 +1,150 @@
1
- # Changelog
2
-
3
- All notable changes to this package are documented here. The format follows
4
- [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to
5
- [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
-
7
- ## [Unreleased]
8
-
9
- ## [0.1.0] - 2026-09-14
10
-
11
- - Renamed the public product and package to CanvasGlobe / `canvas-globe`,
12
- with matching repository, documentation, CDN, UMD, structured-data, and
13
- social-preview identities. Added `CanvasGlobe` and `createCanvasGlobe` aliases.
14
- - Added high-intent JavaScript, React, and competitor-comparison pages,
15
- SoftwareSourceCode JSON-LD, CodeMeta, crawler directives, and spec-shaped
16
- `llms.txt` / `llms-full.txt` indexes.
17
- - Prepared dual GPLv3/commercial licensing, including offline license-key
18
- classification, pricing/licensing documentation, legal-review drafts, and
19
- third-party notices.
20
- - Added Vue, Svelte, Angular, Astro, and dedicated Next.js integration guides.
21
- - Added release-candidate validation, npm provenance workflow, commercial
22
- funnel pages, robots metadata, and an LLM-oriented documentation index.
23
-
24
- ### Added
25
-
26
- - **Toolkit for building on top.** `fromCSV()` / `fromRows()` turn spreadsheet data into markers,
27
- resolving lat/lon columns, ~300 bundled city names, or country codes and names, with a
28
- `gazetteer` escape hatch and a `skipped` report. `exportImage()` / `exportBlob()` render one frame
29
- at any size off-screen using `square`, `story`, `linkedin`, `og`, or another preset. The
30
- `transparent` option preserves an alpha channel. `scenes` bundle a preset with the layers a job needs.
31
- - **Overlays.** `counter` rolls a headline number, `title` paints a headline and subheadline onto
32
- the canvas, and `watermark` bakes a logo or wordmark into every frame. `exportImage()` returns a
33
- finished, branded asset rather than raw art. `annotations` draw leader-line callouts,
34
- `timeline` reveals markers as their `date` arrives and `playTimeline()` animates the range.
35
- Markers accept `image` for logo and avatar crops, arcs accept `icon` for a travelling glyph,
36
- pings accept `burst`, and country media accepts `{ text }` to cut type out of an outline.
37
- - **Country canvas.** `focus` frames a single country and can drop or dim the rest of the world, and
38
- `countryMedia` paints an image, GIF, video, canvas or live `MediaStream` clipped to a country's
39
- outline. Added `focusOn()`, `clearFocus()`, `setCountryMedia()` and `countryAspect()`.
40
- - **Viewer location.** `showViewer` pins whoever is looking at the page, resolved from their IANA
41
- time zone: no permission prompt, no network call, no API key, and it always resolves. Legacy zone
42
- aliases are handled. `locateViewer({ precise: true })` offers a GPS upgrade and falls back to the
43
- estimate if declined. Exposed standalone as `locateViewer`, `locateViewerPrecise`,
44
- `timeZoneLocation` and `countryLocation`.
45
- - **Live pings.** `ping()` fires a one-shot expanding ring with an optional label; `pingFeed()`
46
- replays a list on a timer for social-proof activity feeds.
47
- - **Momentum.** Drags now coast to a stop, and `flyTo` uses a damped spring instead of a linear ease.
48
- - **Tour and scrollytelling.** `tour()` auto-flies between points; `story()` drives the view from an
49
- element's scroll progress, interpolating centre and zoom and applying per-step options.
50
- - **Recording.** `record()` encodes a WebM clip from the canvas via `MediaRecorder`, entirely in the
51
- tab. `GeoGlobe.canRecord` reports support.
52
- - **Textured earth.** `texture` maps an equirectangular image onto the sphere with limb shading,
53
- rendered at reduced resolution and upscaled to stay inside the frame budget.
54
- - **New layers.** `heatmap` (additive density blobs), `spikes` (bars sized by `count`, with markers
55
- riding the tip), `labels` with collision avoidance, and a `legend` card.
56
- - **`fitToMarkers()`**, which picks the shortest longitude arc covering the set.
57
- - **Theming hooks.** `theme: "auto"` follows the OS colour scheme; `theme: "css"` reads `--geo-*`
58
- custom properties off the canvas. `landStyle: "none"` skips land painting entirely.
59
- - **Render styles and presets.** `landStyle` draws land as a solid fill, a halftone dot matrix,
60
- line-art outlines or a neon glow; `orbits` adds decorative great-circle rings that pass behind the
61
- globe correctly; `countryColors: "auto"` gives every country a distinct fill via greedy graph
62
- colouring. Ten `presets` bundle a theme with a style: `hologram`, `neon`, `blueprint`, `aurora`,
63
- `noir`, `political`, `constellation` and the original three: applied with `preset` or
64
- `setPreset()`. Six new themes ship alongside them.
65
- - **Zoom and pan.** Wheel, pinch and keyboard zoom in both modes, with map panning that keeps the
66
- point under the cursor fixed. New `zoom`, `minZoom`, `maxZoom`, `zoomable` options and
67
- `setZoom`, `zoomBy`, `fitTo`, `getCenter` methods. `flyTo` accepts `{ zoom }`.
68
- - **Great-circle arcs.** `arcs` option and `setArcs()`, with a travelling head, configurable lift
69
- above the surface, horizon clipping on the globe and antimeridian splitting on the map.
70
- - **Choropleth.** `countryColors`, `countryColor` and `countryKey` colour countries by ISO alpha-2
71
- code, numeric id or name. New `onCountryHover` / `onCountryClick` with hover highlighting, plus
72
- `countryAt()` and a `colorScale()` helper.
73
- - **Marker clustering.** `cluster` and `clusterRadius` merge dense areas into count bubbles using a
74
- screen-space grid, so density re-balances with zoom.
75
- - **Day/night terminator.** `terminator` and `time` shade the night side from the real solar
76
- position, exact in both projections. `subsolarPoint()` is exported.
77
- - **More projections.** `projection` adds `mercator` and `naturalEarth` alongside
78
- `equirectangular`, with inverse projections for hit testing. `mapAspect()` takes a projection.
79
- - **Accessibility.** `role="img"`, `aria-label`, a polite live region, full keyboard control
80
- (arrows, `+`/`-`, `0`, `PageUp`/`PageDown`, `Enter`) and `prefers-reduced-motion` support via
81
- `respectReducedMotion`.
82
- - **Built-in tooltip.** `tooltip: true` or a formatter; output is always rendered as text.
83
- - **Framework bindings.** `canvas-globe/element` registers a `<geo-globe>` custom element;
84
- `canvas-globe/react` exports a `<Globe>` component with React as an optional peer.
85
- - **Custom marker rendering** via `renderMarker`, and `unproject()`, `invalidate()`, `toBlob()`,
86
- `setTime()`, `setProjection()`.
87
- - Test suite (`node --test`, no framework to install), a CI workflow, `tsconfig.json` for
88
- typechecking the declarations, and a gzipped size budget in the build.
89
-
90
- ### Changed
91
-
92
- - Supplemental CC0 geometry is reconciled into `world.js` during data generation instead of being
93
- applied as a runtime overlay. Country shapes work uniformly across choropleths, labels, media,
94
- hit testing, and automatic colouring. Obsolete country-specific options and exports were removed.
95
- Pass your own `world` GeoJSON when you need different geographic data.
96
- - The bundled data now carries ISO alpha-2 codes for 172 of 177 countries. The previous build
97
- shipped none, so `countryColors` keyed by ISO silently fell through to name matching.
98
- - `setOptions({ preset })` and `setOptions({ scene })` now expand into every option the preset or
99
- scene owns, rather than only recording the name. `setPreset` and `setScene` delegate to it, and
100
- options passed alongside still win.
101
- - Supplemental boundary data is decimated at 0.06° and rounded to two decimals so its detail is
102
- proportionate to the 1:110m dataset while reducing the compressed bundle size.
103
- - The render loop now idles when nothing is animating, so static charts cost nothing after the
104
- first paint.
105
- - Map mode is interactive: dragging pans and the cursor reflects it.
106
- - Map mode uses a uniform fit scale and letterboxes instead of stretching when the canvas aspect
107
- does not match `mapAspect()`.
108
- - Source split into `themes.js`, `geo.js` (pure, DOM-free math) and `geo-globe.js`; the UMD build
109
- inlines them in dependency order and reports gzipped size.
110
- - `generate-data.mjs` embeds ISO alpha-2 codes from natural-earth-vector.
111
-
112
- ### Fixed
113
-
114
- - Overlapping source geometry could create duplicate outlines in stroked land styles. Overlaps are
115
- now resolved during data generation so country shapes do not overlap and the renderer needs no
116
- country-specific branch.
117
- - `focusOn()` raised `maxZoom` to frame a country and never lowered it, so the ceiling leaked into
118
- every later view. `clearFocus()` now restores it, and an explicit `maxZoom` takes precedence.
119
- - A `focus` target that could not be resolved dimmed or hid every country instead of doing nothing.
120
- - Countries could only be looked up by ISO code; numeric ids and names now resolve too.
121
- - Video media threw during SSR instead of degrading to no media.
122
- - `locateViewerPrecise()` passed `enableHighAccuracy: false`, which asked the browser *not* to use
123
- GPS. It now requests the high-accuracy provider and reports the device's `accuracyMeters`.
124
- - The viewer pin claimed more precision than a time zone can give. Wide single-zone countries now
125
- anchor on the country centroid rather than the zone's published city: for India that moves the
126
- pin from Kolkata to central India, and a dashed uncertainty circle is drawn at the real radius.
127
- - The documented `india` option was ignored: the bundled geometry was always used.
128
- - Map mode had no grab cursor and no way to pan.
129
- - Map mode could not be panned across the antimeridian; the view clamped at the edge of the world and
130
- a marker at 179°W projected a whole world away from one at 179°E. Longitudes are now wrapped around
131
- the view centre and horizontal panning is free once the world is wider than the viewport.
132
- - Map graticule lines were drawn as straight segments, which was wrong for curved projections, and
133
- parallels ignored `latRange`.
134
- - The map terminator's polar closing edge tripped the antimeridian break and drew a diagonal band
135
- across the map.
136
- - Marker hit testing now walks front-to-back so overlapping markers resolve to the topmost one.
137
- - `destroy()` removes the tooltip, live region and reduced-motion listener.
1
+ # Changelog
2
+
3
+ All notable changes to this package are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.2] - 2026-09-14
10
+
11
+ - Added npm, CI, license, TypeScript, and zero-dependency badges to the README.
12
+ - Added guided bug, feature, documentation, and showcase issue forms.
13
+ - Added support and community conduct documents plus release-note categories.
14
+
15
+ ## [0.1.1] - 2026-09-14
16
+
17
+ - Added real product renders to the npm and GitHub README, including a clickable
18
+ hero linked to the interactive playground and a visual feature gallery.
19
+ - Moved live playground, examples, documentation, React, and pricing links to
20
+ the top of the README so evaluators can reach working demos immediately.
21
+
22
+ ## [0.1.0] - 2026-09-14
23
+
24
+ - Renamed the public product and package to CanvasGlobe / `canvas-globe`,
25
+ with matching repository, documentation, CDN, UMD, structured-data, and
26
+ social-preview identities. Added `CanvasGlobe` and `createCanvasGlobe` aliases.
27
+ - Added high-intent JavaScript, React, and competitor-comparison pages,
28
+ SoftwareSourceCode JSON-LD, CodeMeta, crawler directives, and spec-shaped
29
+ `llms.txt` / `llms-full.txt` indexes.
30
+ - Prepared dual GPLv3/commercial licensing, including offline license-key
31
+ classification, pricing/licensing documentation, legal-review drafts, and
32
+ third-party notices.
33
+ - Added Vue, Svelte, Angular, Astro, and dedicated Next.js integration guides.
34
+ - Added release-candidate validation, npm provenance workflow, commercial
35
+ funnel pages, robots metadata, and an LLM-oriented documentation index.
36
+
37
+ ### Added
38
+
39
+ - **Toolkit for building on top.** `fromCSV()` / `fromRows()` turn spreadsheet data into markers,
40
+ resolving lat/lon columns, ~300 bundled city names, or country codes and names, with a
41
+ `gazetteer` escape hatch and a `skipped` report. `exportImage()` / `exportBlob()` render one frame
42
+ at any size off-screen using `square`, `story`, `linkedin`, `og`, or another preset. The
43
+ `transparent` option preserves an alpha channel. `scenes` bundle a preset with the layers a job needs.
44
+ - **Overlays.** `counter` rolls a headline number, `title` paints a headline and subheadline onto
45
+ the canvas, and `watermark` bakes a logo or wordmark into every frame. `exportImage()` returns a
46
+ finished, branded asset rather than raw art. `annotations` draw leader-line callouts,
47
+ `timeline` reveals markers as their `date` arrives and `playTimeline()` animates the range.
48
+ Markers accept `image` for logo and avatar crops, arcs accept `icon` for a travelling glyph,
49
+ pings accept `burst`, and country media accepts `{ text }` to cut type out of an outline.
50
+ - **Country canvas.** `focus` frames a single country and can drop or dim the rest of the world, and
51
+ `countryMedia` paints an image, GIF, video, canvas or live `MediaStream` clipped to a country's
52
+ outline. Added `focusOn()`, `clearFocus()`, `setCountryMedia()` and `countryAspect()`.
53
+ - **Viewer location.** `showViewer` pins whoever is looking at the page, resolved from their IANA
54
+ time zone: no permission prompt, no network call, no API key, and it always resolves. Legacy zone
55
+ aliases are handled. `locateViewer({ precise: true })` offers a GPS upgrade and falls back to the
56
+ estimate if declined. Exposed standalone as `locateViewer`, `locateViewerPrecise`,
57
+ `timeZoneLocation` and `countryLocation`.
58
+ - **Live pings.** `ping()` fires a one-shot expanding ring with an optional label; `pingFeed()`
59
+ replays a list on a timer for social-proof activity feeds.
60
+ - **Momentum.** Drags now coast to a stop, and `flyTo` uses a damped spring instead of a linear ease.
61
+ - **Tour and scrollytelling.** `tour()` auto-flies between points; `story()` drives the view from an
62
+ element's scroll progress, interpolating centre and zoom and applying per-step options.
63
+ - **Recording.** `record()` encodes a WebM clip from the canvas via `MediaRecorder`, entirely in the
64
+ tab. `GeoGlobe.canRecord` reports support.
65
+ - **Textured earth.** `texture` maps an equirectangular image onto the sphere with limb shading,
66
+ rendered at reduced resolution and upscaled to stay inside the frame budget.
67
+ - **New layers.** `heatmap` (additive density blobs), `spikes` (bars sized by `count`, with markers
68
+ riding the tip), `labels` with collision avoidance, and a `legend` card.
69
+ - **`fitToMarkers()`**, which picks the shortest longitude arc covering the set.
70
+ - **Theming hooks.** `theme: "auto"` follows the OS colour scheme; `theme: "css"` reads `--geo-*`
71
+ custom properties off the canvas. `landStyle: "none"` skips land painting entirely.
72
+ - **Render styles and presets.** `landStyle` draws land as a solid fill, a halftone dot matrix,
73
+ line-art outlines or a neon glow; `orbits` adds decorative great-circle rings that pass behind the
74
+ globe correctly; `countryColors: "auto"` gives every country a distinct fill via greedy graph
75
+ colouring. Ten `presets` bundle a theme with a style: `hologram`, `neon`, `blueprint`, `aurora`,
76
+ `noir`, `political`, `constellation` and the original three: applied with `preset` or
77
+ `setPreset()`. Six new themes ship alongside them.
78
+ - **Zoom and pan.** Wheel, pinch and keyboard zoom in both modes, with map panning that keeps the
79
+ point under the cursor fixed. New `zoom`, `minZoom`, `maxZoom`, `zoomable` options and
80
+ `setZoom`, `zoomBy`, `fitTo`, `getCenter` methods. `flyTo` accepts `{ zoom }`.
81
+ - **Great-circle arcs.** `arcs` option and `setArcs()`, with a travelling head, configurable lift
82
+ above the surface, horizon clipping on the globe and antimeridian splitting on the map.
83
+ - **Choropleth.** `countryColors`, `countryColor` and `countryKey` colour countries by ISO alpha-2
84
+ code, numeric id or name. New `onCountryHover` / `onCountryClick` with hover highlighting, plus
85
+ `countryAt()` and a `colorScale()` helper.
86
+ - **Marker clustering.** `cluster` and `clusterRadius` merge dense areas into count bubbles using a
87
+ screen-space grid, so density re-balances with zoom.
88
+ - **Day/night terminator.** `terminator` and `time` shade the night side from the real solar
89
+ position, exact in both projections. `subsolarPoint()` is exported.
90
+ - **More projections.** `projection` adds `mercator` and `naturalEarth` alongside
91
+ `equirectangular`, with inverse projections for hit testing. `mapAspect()` takes a projection.
92
+ - **Accessibility.** `role="img"`, `aria-label`, a polite live region, full keyboard control
93
+ (arrows, `+`/`-`, `0`, `PageUp`/`PageDown`, `Enter`) and `prefers-reduced-motion` support via
94
+ `respectReducedMotion`.
95
+ - **Built-in tooltip.** `tooltip: true` or a formatter; output is always rendered as text.
96
+ - **Framework bindings.** `canvas-globe/element` registers a `<geo-globe>` custom element;
97
+ `canvas-globe/react` exports a `<Globe>` component with React as an optional peer.
98
+ - **Custom marker rendering** via `renderMarker`, and `unproject()`, `invalidate()`, `toBlob()`,
99
+ `setTime()`, `setProjection()`.
100
+ - Test suite (`node --test`, no framework to install), a CI workflow, `tsconfig.json` for
101
+ typechecking the declarations, and a gzipped size budget in the build.
102
+
103
+ ### Changed
104
+
105
+ - Supplemental CC0 geometry is reconciled into `world.js` during data generation instead of being
106
+ applied as a runtime overlay. Country shapes work uniformly across choropleths, labels, media,
107
+ hit testing, and automatic colouring. Obsolete country-specific options and exports were removed.
108
+ Pass your own `world` GeoJSON when you need different geographic data.
109
+ - The bundled data now carries ISO alpha-2 codes for 172 of 177 countries. The previous build
110
+ shipped none, so `countryColors` keyed by ISO silently fell through to name matching.
111
+ - `setOptions({ preset })` and `setOptions({ scene })` now expand into every option the preset or
112
+ scene owns, rather than only recording the name. `setPreset` and `setScene` delegate to it, and
113
+ options passed alongside still win.
114
+ - Supplemental boundary data is decimated at 0.06° and rounded to two decimals so its detail is
115
+ proportionate to the 1:110m dataset while reducing the compressed bundle size.
116
+ - The render loop now idles when nothing is animating, so static charts cost nothing after the
117
+ first paint.
118
+ - Map mode is interactive: dragging pans and the cursor reflects it.
119
+ - Map mode uses a uniform fit scale and letterboxes instead of stretching when the canvas aspect
120
+ does not match `mapAspect()`.
121
+ - Source split into `themes.js`, `geo.js` (pure, DOM-free math) and `geo-globe.js`; the UMD build
122
+ inlines them in dependency order and reports gzipped size.
123
+ - `generate-data.mjs` embeds ISO alpha-2 codes from natural-earth-vector.
124
+
125
+ ### Fixed
126
+
127
+ - Overlapping source geometry could create duplicate outlines in stroked land styles. Overlaps are
128
+ now resolved during data generation so country shapes do not overlap and the renderer needs no
129
+ country-specific branch.
130
+ - `focusOn()` raised `maxZoom` to frame a country and never lowered it, so the ceiling leaked into
131
+ every later view. `clearFocus()` now restores it, and an explicit `maxZoom` takes precedence.
132
+ - A `focus` target that could not be resolved dimmed or hid every country instead of doing nothing.
133
+ - Countries could only be looked up by ISO code; numeric ids and names now resolve too.
134
+ - Video media threw during SSR instead of degrading to no media.
135
+ - `locateViewerPrecise()` passed `enableHighAccuracy: false`, which asked the browser *not* to use
136
+ GPS. It now requests the high-accuracy provider and reports the device's `accuracyMeters`.
137
+ - The viewer pin claimed more precision than a time zone can give. Wide single-zone countries now
138
+ anchor on the country centroid rather than the zone's published city: for India that moves the
139
+ pin from Kolkata to central India, and a dashed uncertainty circle is drawn at the real radius.
140
+ - The documented `india` option was ignored: the bundled geometry was always used.
141
+ - Map mode had no grab cursor and no way to pan.
142
+ - Map mode could not be panned across the antimeridian; the view clamped at the edge of the world and
143
+ a marker at 179°W projected a whole world away from one at 179°E. Longitudes are now wrapped around
144
+ the view centre and horizontal panning is free once the world is wider than the viewport.
145
+ - Map graticule lines were drawn as straight segments, which was wrong for curved projections, and
146
+ parallels ignored `latRange`.
147
+ - The map terminator's polar closing edge tripped the antimeridian break and drew a diagonal band
148
+ across the map.
149
+ - Marker hit testing now walks front-to-back so overlapping markers resolve to the topmost one.
150
+ - `destroy()` removes the tooltip, live region and reduced-motion listener.