Spaces:
Running
Running
Update index.html
Browse files- index.html +26 -15
index.html
CHANGED
|
@@ -154,21 +154,32 @@
|
|
| 154 |
.arcDashAnimateTime(() => 2000);
|
| 155 |
|
| 156 |
// Borders
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
|
| 173 |
// Orbit controls tuning (zoom/rotate)
|
| 174 |
const ctrl = globe.controls();
|
|
|
|
| 154 |
.arcDashAnimateTime(() => 2000);
|
| 155 |
|
| 156 |
// Borders
|
| 157 |
+
fetch('./geocountries.json', { cache: 'no-cache' })
|
| 158 |
+
.then(r => { if (!r.ok) throw new Error(`HTTP ${r.status}`); return r.json(); })
|
| 159 |
+
.then(({ features }) => {
|
| 160 |
+
const paths = [];
|
| 161 |
+
const pushRing = (ring) => {
|
| 162 |
+
// light decimation for speed
|
| 163 |
+
const step = ring.length > 200 ? 2 : 1;
|
| 164 |
+
const thinned = ring.filter((_, i) => i % step === 0);
|
| 165 |
+
paths.push(thinned.map(([lng, lat]) => [lat, normLng(lng)]));
|
| 166 |
+
};
|
| 167 |
+
for (const f of features) {
|
| 168 |
+
const g = f.geometry; if (!g) continue;
|
| 169 |
+
if (g.type === 'Polygon') g.coordinates.forEach(pushRing);
|
| 170 |
+
else if (g.type === 'MultiPolygon') g.coordinates.forEach(poly => poly.forEach(pushRing));
|
| 171 |
+
}
|
| 172 |
+
globe
|
| 173 |
+
.polygonsData([]) // remove polygon meshes
|
| 174 |
+
.pathsData(paths) // draw borders as lines
|
| 175 |
+
.pathColor(() => '#ffffff') // solid white
|
| 176 |
+
.pathStroke(0.12) // thickness in angular degrees
|
| 177 |
+
.pathPointAlt(() => 0.002) // lift slightly off the surface
|
| 178 |
+
.pathResolution(3); // keep interpolation modest for perf
|
| 179 |
+
})
|
| 180 |
+
.catch(err => showErr(`Failed to load borders: ${err.message}`));
|
| 181 |
+
|
| 182 |
+
|
| 183 |
|
| 184 |
// Orbit controls tuning (zoom/rotate)
|
| 185 |
const ctrl = globe.controls();
|