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.
- package/CHANGELOG.md +137 -0
- package/COPYRIGHT +8 -0
- package/LICENSE +674 -0
- package/LICENSING.md +83 -0
- package/README.md +638 -0
- package/THIRD_PARTY_NOTICES.md +14 -0
- package/codemeta.json +34 -0
- package/dist/canvas-globe.umd.js +4338 -0
- package/dist/package.json +1 -0
- package/package.json +110 -0
- package/src/csv.js +151 -0
- package/src/data/timezones.js +5 -0
- package/src/data/world.js +6 -0
- package/src/element.js +144 -0
- package/src/export.js +19 -0
- package/src/geo-globe.js +2856 -0
- package/src/geo.js +286 -0
- package/src/index.js +19 -0
- package/src/license.js +36 -0
- package/src/media.js +160 -0
- package/src/presets.js +21 -0
- package/src/react.js +60 -0
- package/src/recorder.js +70 -0
- package/src/scenes.js +80 -0
- package/src/texture.js +129 -0
- package/src/themes.js +241 -0
- package/src/viewer.js +130 -0
- package/types/element.d.ts +41 -0
- package/types/index.d.ts +696 -0
- package/types/react.d.ts +15 -0
package/src/element.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<geo-globe>` custom element. Wraps GeoGlobe so it can be dropped into any
|
|
3
|
+
* framework or plain HTML without requiring the imperative API.
|
|
4
|
+
*/
|
|
5
|
+
import { GeoGlobe } from "./geo-globe.js";
|
|
6
|
+
|
|
7
|
+
const BOOLS = ["auto-rotate", "interactive", "keyboard", "graticule", "stars", "shade", "terminator", "cluster", "tooltip", "zoomable"];
|
|
8
|
+
const NUMBERS = ["zoom", "min-zoom", "max-zoom", "rotate-speed", "marker-scale", "radius-ratio", "fps", "cluster-radius", "arc-lift", "arc-speed", "lat", "lon", "orbits", "dot-spacing", "dot-size"];
|
|
9
|
+
const STRINGS = ["mode", "projection", "theme", "preset", "land-style", "marker-style", "aria-label", "license-key"];
|
|
10
|
+
const JSONS = ["markers", "arcs", "country-colors", "lat-range"];
|
|
11
|
+
|
|
12
|
+
const camel = (s) => s.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
13
|
+
|
|
14
|
+
const parseJSON = (value, fallback) => {
|
|
15
|
+
try {
|
|
16
|
+
const v = JSON.parse(value);
|
|
17
|
+
return v == null ? fallback : v;
|
|
18
|
+
} catch {
|
|
19
|
+
return fallback;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Built lazily: HTMLElement only exists in a document, so importing this
|
|
24
|
+
// module during SSR or in Node must not throw.
|
|
25
|
+
const createElementClass = () => class GeoGlobeElement extends HTMLElement {
|
|
26
|
+
static get observedAttributes() {
|
|
27
|
+
return [...BOOLS, ...NUMBERS, ...STRINGS, ...JSONS];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
constructor() {
|
|
31
|
+
super();
|
|
32
|
+
this._props = {};
|
|
33
|
+
const root = this.attachShadow({ mode: "open" });
|
|
34
|
+
root.innerHTML =
|
|
35
|
+
"<style>:host{display:block;position:relative}canvas{display:block;width:100%;height:100%}</style><canvas></canvas>";
|
|
36
|
+
this._canvas = root.querySelector("canvas");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
connectedCallback() {
|
|
40
|
+
if (this.globe) return;
|
|
41
|
+
this.globe = new GeoGlobe(this._canvas, {
|
|
42
|
+
...this._readAttributes(),
|
|
43
|
+
...this._props,
|
|
44
|
+
onHover: (marker, pos) => this._emit("geo-hover", { marker, pos }),
|
|
45
|
+
onClick: (marker, pos) => this._emit("geo-click", { marker, pos }),
|
|
46
|
+
onCountryHover: (country, pos) => this._emit("geo-country-hover", { country, pos }),
|
|
47
|
+
onCountryClick: (country, pos) => this._emit("geo-country-click", { country, pos }),
|
|
48
|
+
onRender: () => this._emit("geo-render", { globe: this.globe }),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
disconnectedCallback() {
|
|
53
|
+
this.globe?.destroy();
|
|
54
|
+
this.globe = null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
attributeChangedCallback(name) {
|
|
58
|
+
if (!this.globe) return;
|
|
59
|
+
if (name === "preset") this.globe.setPreset(this.getAttribute("preset"));
|
|
60
|
+
else this.globe.setOptions(this._readAttributes());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
_emit(type, detail) {
|
|
64
|
+
this.dispatchEvent(new CustomEvent(type, { detail, bubbles: true, composed: true }));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
_readAttributes() {
|
|
68
|
+
const out = {};
|
|
69
|
+
for (const name of STRINGS) if (this.hasAttribute(name)) out[camel(name)] = this.getAttribute(name);
|
|
70
|
+
for (const name of NUMBERS) {
|
|
71
|
+
if (!this.hasAttribute(name)) continue;
|
|
72
|
+
const n = Number(this.getAttribute(name));
|
|
73
|
+
if (Number.isFinite(n)) out[camel(name)] = n;
|
|
74
|
+
}
|
|
75
|
+
for (const name of BOOLS) {
|
|
76
|
+
if (!this.hasAttribute(name)) continue;
|
|
77
|
+
const v = this.getAttribute(name);
|
|
78
|
+
out[camel(name)] = v !== "false" && v !== "0";
|
|
79
|
+
}
|
|
80
|
+
for (const name of JSONS) {
|
|
81
|
+
if (!this.hasAttribute(name)) continue;
|
|
82
|
+
const v = parseJSON(this.getAttribute(name), null);
|
|
83
|
+
if (v !== null) out[camel(name)] = v;
|
|
84
|
+
}
|
|
85
|
+
if ("lat" in out || "lon" in out) {
|
|
86
|
+
out.center = { lon: out.lon ?? 10, lat: out.lat ?? 20 };
|
|
87
|
+
delete out.lat;
|
|
88
|
+
delete out.lon;
|
|
89
|
+
}
|
|
90
|
+
if (out.theme && out.theme.startsWith("{")) out.theme = parseJSON(out.theme, "atlas");
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Live marker array: assigning re-renders immediately. */
|
|
95
|
+
get markers() {
|
|
96
|
+
return this.globe ? this.globe.markers : this._props.markers || [];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
set markers(value) {
|
|
100
|
+
this._props.markers = value;
|
|
101
|
+
this.globe?.setMarkers(value);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
get arcs() {
|
|
105
|
+
return this.globe ? this.globe.o.arcs : this._props.arcs || [];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
set arcs(value) {
|
|
109
|
+
this._props.arcs = value;
|
|
110
|
+
this.globe?.setArcs(value);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Bulk option patch, for values that cannot travel through attributes. */
|
|
114
|
+
set options(value) {
|
|
115
|
+
Object.assign(this._props, value);
|
|
116
|
+
this.globe?.setOptions(value);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
flyTo(lon, lat, opts) {
|
|
120
|
+
this.globe?.flyTo(lon, lat, opts);
|
|
121
|
+
return this;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
fitTo(bounds, opts) {
|
|
125
|
+
this.globe?.fitTo(bounds, opts);
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
snapshot(type, quality) {
|
|
130
|
+
return this.globe?.snapshot(type, quality);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/** The element class, or null when there is no DOM. */
|
|
135
|
+
export const GeoGlobeElement = typeof HTMLElement === "undefined" ? null : createElementClass();
|
|
136
|
+
|
|
137
|
+
/** Registers `<geo-globe>` (safe to call more than once). */
|
|
138
|
+
export function defineGeoGlobe(tag = "geo-globe") {
|
|
139
|
+
if (typeof customElements === "undefined" || !GeoGlobeElement) return null;
|
|
140
|
+
if (!customElements.get(tag)) customElements.define(tag, GeoGlobeElement);
|
|
141
|
+
return customElements.get(tag);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
defineGeoGlobe();
|
package/src/export.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Canvas sizes for the places marketing assets actually get posted. */
|
|
2
|
+
export const exportPresets = {
|
|
3
|
+
square: [1080, 1080],
|
|
4
|
+
story: [1080, 1920],
|
|
5
|
+
portrait: [1080, 1350],
|
|
6
|
+
wide: [1920, 1080],
|
|
7
|
+
linkedin: [1200, 627],
|
|
8
|
+
og: [1200, 630],
|
|
9
|
+
twitter: [1600, 900],
|
|
10
|
+
thumbnail: [640, 640],
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** Resolves a preset name or explicit size to `[width, height]`. */
|
|
14
|
+
export function exportSize(spec, fallback) {
|
|
15
|
+
if (typeof spec === "string") return exportPresets[spec] || fallback;
|
|
16
|
+
if (Array.isArray(spec)) return spec;
|
|
17
|
+
if (spec && spec.width && spec.height) return [spec.width, spec.height];
|
|
18
|
+
return fallback;
|
|
19
|
+
}
|