canvas-globe 0.1.2 → 0.1.3

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
@@ -6,6 +6,14 @@ All notable changes to this package are documented here. The format follows
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.1.3] - 2026-09-14
10
+
11
+ - Added JSR package configuration and tokenless GitHub publishing workflow.
12
+ - Added a Custom Elements Manifest for `<geo-globe>` so catalogs, IDEs, and
13
+ documentation tools can discover its attributes, properties, methods, and events.
14
+ - Added installation guidance for npm, pnpm, Yarn, Bun, Deno, jsDelivr, UNPKG,
15
+ and browser ESM CDNs.
16
+
9
17
  ## [0.1.2] - 2026-09-14
10
18
 
11
19
  - Added npm, CI, license, TypeScript, and zero-dependency badges to the README.
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # CanvasGlobe
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/canvas-globe.svg)](https://www.npmjs.com/package/canvas-globe)
4
+ [![JSR](https://jsr.io/badges/@swiftools/canvas-globe)](https://jsr.io/@swiftools/canvas-globe)
4
5
  [![npm downloads](https://img.shields.io/npm/dm/canvas-globe.svg)](https://www.npmjs.com/package/canvas-globe)
5
6
  [![CI](https://github.com/Shree-hari/canvas-globe/actions/workflows/ci.yml/badge.svg)](https://github.com/Shree-hari/canvas-globe/actions/workflows/ci.yml)
6
7
  [![GPL-3.0-only](https://img.shields.io/npm/l/canvas-globe.svg)](LICENSE)
@@ -16,6 +17,9 @@
16
17
  [Showcase](https://canvasglobe.swiftools.com/showcase) ·
17
18
  [Commercial pricing](https://canvasglobe.swiftools.com/pricing)
18
19
 
20
+ [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz_small.svg)](https://stackblitz.com/github/Shree-hari/canvas-globe?startScript=start)
21
+ [![Open in CodeSandbox](https://img.shields.io/badge/Open_in-CodeSandbox-151515?logo=codesandbox)](https://codesandbox.io/p/github/Shree-hari/canvas-globe)
22
+
19
23
  `canvas-globe` is a zero-dependency JavaScript library for an interactive
20
24
  **3D globe** and **flat world map** on Canvas 2D. It works with
21
25
  vanilla JavaScript, React, or a Web Component and requires no WebGL, map API
@@ -80,14 +84,73 @@ console warning in browser builds.
80
84
 
81
85
  ## Install
82
86
 
87
+ Choose the package manager already used by your project:
88
+
83
89
  ```bash
90
+ # npm
84
91
  npm install canvas-globe
92
+
93
+ # pnpm
94
+ pnpm add canvas-globe
95
+
96
+ # Yarn
97
+ yarn add canvas-globe
98
+
99
+ # Bun
100
+ bun add canvas-globe
101
+
102
+ # Deno and JSR-aware projects
103
+ deno add jsr:@swiftools/canvas-globe
104
+ npx jsr add @swiftools/canvas-globe
105
+ ```
106
+
107
+ You can also import the JSR release directly in Deno:
108
+
109
+ ```js
110
+ import { createGlobe } from "jsr:@swiftools/canvas-globe@0.1.3";
111
+ ```
112
+
113
+ The React entry point remains on npm so React's peer dependency is resolved by
114
+ your existing application rather than installing a second React copy.
115
+
116
+ ### Browser CDN
117
+
118
+ For a plain `<script>` installation, use the versioned UMD build:
119
+
120
+ ```html
121
+ <script src="https://cdn.jsdelivr.net/npm/canvas-globe@0.1.3/dist/canvas-globe.umd.js"></script>
122
+ ```
123
+
124
+ The same npm release is also available from UNPKG:
125
+
126
+ ```html
127
+ <script src="https://unpkg.com/canvas-globe@0.1.3/dist/canvas-globe.umd.js"></script>
128
+ ```
129
+
130
+ Modern browsers can import the package through an ESM CDN:
131
+
132
+ ```js
133
+ import { createGlobe } from "https://esm.sh/canvas-globe@0.1.3";
134
+ ```
135
+
136
+ Pin an exact version in production so a future release cannot change a deployed page unexpectedly.
137
+
138
+ ### Quick start
139
+
140
+ ```bash
141
+ npm install canvas-globe
142
+ ```
143
+
144
+ Then import the library:
145
+
146
+ ```js
147
+ import { createGlobe } from "canvas-globe";
85
148
  ```
86
149
 
87
- Or drop it on a page with no build step at all:
150
+ Or drop the UMD build on a page with no build step at all:
88
151
 
89
152
  ```html
90
- <script src="https://cdn.jsdelivr.net/npm/canvas-globe/dist/canvas-globe.umd.js"></script>
153
+ <script src="https://cdn.jsdelivr.net/npm/canvas-globe@0.1.3/dist/canvas-globe.umd.js"></script>
91
154
  <canvas id="globe" style="width:520px;aspect-ratio:1"></canvas>
92
155
  <script>
93
156
  CanvasGlobe.createGlobe(document.getElementById("globe"), {
package/codemeta.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "identifier": "canvas-globe",
6
6
  "description": "Zero-dependency JavaScript and React library for interactive 3D globes and flat world maps rendered with Canvas 2D, with no WebGL or API-key requirement.",
7
7
  "url": "https://canvasglobe.swiftools.com/",
8
- "version": "0.1.2",
8
+ "version": "0.1.3",
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",
@@ -0,0 +1,142 @@
1
+ {
2
+ "schemaVersion": "2.1.0",
3
+ "readme": "README.md",
4
+ "modules": [
5
+ {
6
+ "kind": "javascript-module",
7
+ "path": "src/element.js",
8
+ "declarations": [
9
+ {
10
+ "kind": "class",
11
+ "name": "GeoGlobeElement",
12
+ "description": "Framework-independent interactive globe and flat world map rendered with Canvas 2D.",
13
+ "customElement": true,
14
+ "tagName": "geo-globe",
15
+ "superclass": {
16
+ "name": "HTMLElement",
17
+ "package": "global:"
18
+ },
19
+ "members": [
20
+ {
21
+ "kind": "field",
22
+ "name": "globe",
23
+ "description": "Underlying GeoGlobe instance after the element is connected.",
24
+ "type": { "text": "GeoGlobe | null" }
25
+ },
26
+ {
27
+ "kind": "field",
28
+ "name": "markers",
29
+ "description": "Marker data displayed on the globe.",
30
+ "type": { "text": "Marker[]" }
31
+ },
32
+ {
33
+ "kind": "field",
34
+ "name": "arcs",
35
+ "description": "Great-circle route data displayed on the globe.",
36
+ "type": { "text": "Arc[]" }
37
+ },
38
+ {
39
+ "kind": "field",
40
+ "name": "options",
41
+ "description": "Applies options that cannot be represented as HTML attributes. Accepts Partial<GeoGlobeOptions>."
42
+ },
43
+ {
44
+ "kind": "method",
45
+ "name": "flyTo",
46
+ "description": "Animates the view to a longitude and latitude.",
47
+ "parameters": [
48
+ { "name": "lon", "type": { "text": "number" } },
49
+ { "name": "lat", "type": { "text": "number" } },
50
+ { "name": "opts", "type": { "text": "FlyToOptions" }, "optional": true }
51
+ ],
52
+ "return": { "type": { "text": "this" } }
53
+ },
54
+ {
55
+ "kind": "method",
56
+ "name": "fitTo",
57
+ "description": "Fits the view to geographic bounds.",
58
+ "parameters": [
59
+ { "name": "bounds", "type": { "text": "[number, number, number, number]" } },
60
+ { "name": "opts", "type": { "text": "FlyToOptions & { padding?: number }" }, "optional": true }
61
+ ],
62
+ "return": { "type": { "text": "this" } }
63
+ },
64
+ {
65
+ "kind": "method",
66
+ "name": "snapshot",
67
+ "description": "Returns a data URL snapshot of the current canvas.",
68
+ "parameters": [
69
+ { "name": "type", "type": { "text": "string" }, "optional": true },
70
+ { "name": "quality", "type": { "text": "number" }, "optional": true }
71
+ ],
72
+ "return": { "type": { "text": "string | undefined" } }
73
+ }
74
+ ],
75
+ "attributes": [
76
+ { "name": "mode", "description": "Rendering mode.", "type": { "text": "'globe' | 'map'" }, "default": "globe" },
77
+ { "name": "projection", "description": "Flat-map projection.", "type": { "text": "'equirectangular' | 'mercator' | 'naturalEarth'" }, "default": "equirectangular" },
78
+ { "name": "theme", "description": "Built-in theme name or serialized theme object.", "type": { "text": "string" }, "default": "atlas" },
79
+ { "name": "preset", "description": "Built-in visual preset.", "type": { "text": "string" } },
80
+ { "name": "land-style", "description": "Land rendering style.", "type": { "text": "'fill' | 'dots' | 'outline' | 'glow' | 'none'" }, "default": "fill" },
81
+ { "name": "marker-style", "description": "Marker rendering style.", "type": { "text": "string" } },
82
+ { "name": "aria-label", "description": "Accessible label for the canvas.", "type": { "text": "string" } },
83
+ { "name": "license-key", "description": "CanvasGlobe license key.", "type": { "text": "string" } },
84
+ { "name": "auto-rotate", "description": "Enables automatic rotation.", "type": { "text": "boolean" } },
85
+ { "name": "interactive", "description": "Enables pointer interaction.", "type": { "text": "boolean" }, "default": "true" },
86
+ { "name": "keyboard", "description": "Enables keyboard controls.", "type": { "text": "boolean" }, "default": "true" },
87
+ { "name": "graticule", "description": "Shows latitude and longitude grid lines.", "type": { "text": "boolean" } },
88
+ { "name": "stars", "description": "Shows the star background.", "type": { "text": "boolean" } },
89
+ { "name": "shade", "description": "Enables sphere shading.", "type": { "text": "boolean" } },
90
+ { "name": "terminator", "description": "Shows the day and night terminator.", "type": { "text": "boolean" } },
91
+ { "name": "cluster", "description": "Clusters nearby markers.", "type": { "text": "boolean" } },
92
+ { "name": "tooltip", "description": "Enables the built-in tooltip.", "type": { "text": "boolean" } },
93
+ { "name": "zoomable", "description": "Enables wheel and pinch zoom.", "type": { "text": "boolean" }, "default": "true" },
94
+ { "name": "zoom", "description": "Initial zoom level.", "type": { "text": "number" } },
95
+ { "name": "min-zoom", "description": "Minimum zoom level.", "type": { "text": "number" } },
96
+ { "name": "max-zoom", "description": "Maximum zoom level.", "type": { "text": "number" } },
97
+ { "name": "rotate-speed", "description": "Automatic rotation speed.", "type": { "text": "number" } },
98
+ { "name": "marker-scale", "description": "Global marker scale.", "type": { "text": "number" } },
99
+ { "name": "radius-ratio", "description": "Globe radius relative to its canvas.", "type": { "text": "number" } },
100
+ { "name": "fps", "description": "Maximum animation frame rate.", "type": { "text": "number" } },
101
+ { "name": "cluster-radius", "description": "Marker clustering radius in pixels.", "type": { "text": "number" } },
102
+ { "name": "arc-lift", "description": "Default arc lift above the sphere.", "type": { "text": "number" } },
103
+ { "name": "arc-speed", "description": "Default animated arc speed.", "type": { "text": "number" } },
104
+ { "name": "lat", "description": "Initial centre latitude.", "type": { "text": "number" } },
105
+ { "name": "lon", "description": "Initial centre longitude.", "type": { "text": "number" } },
106
+ { "name": "orbits", "description": "Number of decorative orbit rings.", "type": { "text": "number" } },
107
+ { "name": "dot-spacing", "description": "Dot land-style spacing in degrees.", "type": { "text": "number" } },
108
+ { "name": "dot-size", "description": "Dot land-style radius in pixels.", "type": { "text": "number" } },
109
+ { "name": "markers", "description": "Serialized marker array.", "type": { "text": "Marker[]" } },
110
+ { "name": "arcs", "description": "Serialized route array.", "type": { "text": "Arc[]" } },
111
+ { "name": "country-colors", "description": "Serialized country colour mapping.", "type": { "text": "Record<string, string>" } },
112
+ { "name": "lat-range", "description": "Serialized latitude range.", "type": { "text": "[number, number]" } }
113
+ ],
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 } }>" } },
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
+ { "name": "geo-country-click", "description": "Fires when a country is clicked.", "type": { "text": "CustomEvent<{ country: CountryShape; pos: { x: number; y: number } }>" } },
119
+ { "name": "geo-render", "description": "Fires after CanvasGlobe renders a frame.", "type": { "text": "CustomEvent<{ globe: GeoGlobe }>" } }
120
+ ]
121
+ }
122
+ ],
123
+ "exports": [
124
+ {
125
+ "kind": "js",
126
+ "name": "GeoGlobeElement",
127
+ "declaration": { "name": "GeoGlobeElement", "module": "src/element.js" }
128
+ },
129
+ {
130
+ "kind": "js",
131
+ "name": "defineGeoGlobe",
132
+ "declaration": { "name": "defineGeoGlobe", "module": "src/element.js" }
133
+ },
134
+ {
135
+ "kind": "custom-element-definition",
136
+ "name": "geo-globe",
137
+ "declaration": { "name": "GeoGlobeElement", "module": "src/element.js" }
138
+ }
139
+ ]
140
+ }
141
+ ]
142
+ }
@@ -4250,7 +4250,7 @@ const createElementClass = () => class GeoGlobeElement extends HTMLElement {
4250
4250
  onClick: (marker, pos) => this._emit("geo-click", { marker, pos }),
4251
4251
  onCountryHover: (country, pos) => this._emit("geo-country-hover", { country, pos }),
4252
4252
  onCountryClick: (country, pos) => this._emit("geo-country-click", { country, pos }),
4253
- onRender: () => this._emit("geo-render", { globe: this.globe }),
4253
+ onRender: (globe) => this._emit("geo-render", { globe }),
4254
4254
  });
4255
4255
  }
4256
4256
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canvas-globe",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Zero-dependency JavaScript and React library for interactive 3D globes and flat world maps rendered with Canvas 2D. No WebGL or API key.",
5
5
  "license": "GPL-3.0-only",
6
6
  "author": {
@@ -42,6 +42,7 @@
42
42
  "main": "./src/index.js",
43
43
  "module": "./src/index.js",
44
44
  "types": "./types/index.d.ts",
45
+ "customElements": "./custom-elements.json",
45
46
  "unpkg": "./dist/canvas-globe.umd.js",
46
47
  "jsdelivr": "./dist/canvas-globe.umd.js",
47
48
  "exports": {
@@ -60,7 +61,11 @@
60
61
  "import": "./src/react.js",
61
62
  "default": "./src/react.js"
62
63
  },
63
- "./data/world": "./src/data/world.js",
64
+ "./data/world": {
65
+ "types": "./types/data/world.d.ts",
66
+ "import": "./src/data/world.js",
67
+ "default": "./src/data/world.js"
68
+ },
64
69
  "./package.json": "./package.json"
65
70
  },
66
71
  "files": [
@@ -73,7 +78,8 @@
73
78
  "LICENSE",
74
79
  "LICENSING.md",
75
80
  "THIRD_PARTY_NOTICES.md",
76
- "codemeta.json"
81
+ "codemeta.json",
82
+ "custom-elements.json"
77
83
  ],
78
84
  "sideEffects": [
79
85
  "./src/element.js"
@@ -82,6 +88,7 @@
82
88
  "access": "public"
83
89
  },
84
90
  "scripts": {
91
+ "start": "node scripts/serve.mjs",
85
92
  "build": "node scripts/build.mjs",
86
93
  "data": "node scripts/generate-data.mjs && node scripts/generate-timezones.mjs",
87
94
  "example": "node scripts/serve.mjs",
package/src/element.js CHANGED
@@ -1,3 +1,5 @@
1
+ /* @ts-self-types="../types/element.d.ts" */
2
+
1
3
  /**
2
4
  * `<geo-globe>` custom element. Wraps GeoGlobe so it can be dropped into any
3
5
  * framework or plain HTML without requiring the imperative API.
@@ -45,7 +47,7 @@ const createElementClass = () => class GeoGlobeElement extends HTMLElement {
45
47
  onClick: (marker, pos) => this._emit("geo-click", { marker, pos }),
46
48
  onCountryHover: (country, pos) => this._emit("geo-country-hover", { country, pos }),
47
49
  onCountryClick: (country, pos) => this._emit("geo-country-click", { country, pos }),
48
- onRender: () => this._emit("geo-render", { globe: this.globe }),
50
+ onRender: (globe) => this._emit("geo-render", { globe }),
49
51
  });
50
52
  }
51
53
 
package/src/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ /* @ts-self-types="../types/index.d.ts" */
2
+
1
3
  export {
2
4
  GeoGlobe,
3
5
  GeoGlobe as CanvasGlobe,
package/src/react.js CHANGED
@@ -1,3 +1,5 @@
1
+ /* @ts-self-types="../types/react.d.ts" */
2
+
1
3
  /**
2
4
  * React binding. `import { Globe } from "canvas-globe/react"`.
3
5
  * React is a peer dependency and is only required by this entry point.
@@ -0,0 +1,5 @@
1
+ import type { CountryShape } from "../index.js";
2
+
3
+ export declare const world: CountryShape[];
4
+
5
+ export default world;
@@ -0,0 +1,29 @@
1
+ import type { Arc, CountryShape, GeoGlobe, GeoGlobeOptions, Marker, ClusterMarker, FlyToOptions } from "./index.js";
2
+
3
+ export interface GeoGlobeEventMap {
4
+ "geo-hover": CustomEvent<{ marker: Marker | ClusterMarker | null; pos: { x: number; y: number } | null }>;
5
+ "geo-click": CustomEvent<{ marker: Marker | ClusterMarker; pos: { x: number; y: number } }>;
6
+ "geo-country-hover": CustomEvent<{ country: CountryShape | null; pos: { x: number; y: number } | null }>;
7
+ "geo-country-click": CustomEvent<{ country: CountryShape; pos: { x: number; y: number } }>;
8
+ "geo-render": CustomEvent<{ globe: GeoGlobe }>;
9
+ }
10
+
11
+ declare class GeoGlobeElementInstance extends HTMLElement {
12
+ globe: GeoGlobe | null;
13
+ markers: Marker[];
14
+ arcs: Arc[];
15
+ set options(value: Partial<GeoGlobeOptions>);
16
+ flyTo(lon: number, lat: number, opts?: FlyToOptions): this;
17
+ fitTo(bounds: [number, number, number, number], opts?: FlyToOptions & { padding?: number }): this;
18
+ snapshot(type?: string, quality?: number): string | undefined;
19
+ addEventListener<K extends keyof GeoGlobeEventMap>(
20
+ type: K,
21
+ listener: (this: GeoGlobeElementInstance, ev: GeoGlobeEventMap[K]) => unknown,
22
+ options?: boolean | AddEventListenerOptions
23
+ ): void;
24
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
25
+ }
26
+
27
+ export type GeoGlobeElement = GeoGlobeElementInstance;
28
+ export declare const GeoGlobeElement: (new () => GeoGlobeElementInstance) | null;
29
+ export declare function defineGeoGlobe(tag?: string): (new () => GeoGlobeElementInstance) | null;