Spaces:
Running
Running
Update index.html
Browse files- index.html +32 -40
index.html
CHANGED
|
@@ -54,15 +54,13 @@
|
|
| 54 |
|
| 55 |
<noscript style="color:#fff; position:fixed; left:12px; bottom:48px;">Enable JavaScript.</noscript>
|
| 56 |
|
| 57 |
-
<!--
|
| 58 |
-
<!-- three.js must be loaded globally for globe.gl UMD -->
|
| 59 |
<script src="https://unpkg.com/[email protected]/build/three.min.js" defer></script>
|
| 60 |
<script src="https://unpkg.com/globe.gl" defer></script>
|
| 61 |
|
| 62 |
<script>
|
| 63 |
(function(){
|
| 64 |
const showErr = (msg) => { const el = document.getElementById('err'); el.textContent = msg; el.style.display = 'block'; };
|
| 65 |
-
function safe(fn){ try { return fn(); } catch(e){ showErr((e && e.message) ? e.message : String(e)); throw e; } }
|
| 66 |
|
| 67 |
const toRad = (deg) => deg * Math.PI / 180;
|
| 68 |
const R_EARTH = 6371008.8; // meters
|
|
@@ -110,36 +108,37 @@
|
|
| 110 |
const normLng = (lng) => ((lng + 180) % 360 + 360) % 360 - 180;
|
| 111 |
const parseParamCoord = (s) => { if (!s) return null; const [a,b] = s.split(','); const lat=Number(a), lng=Number(b); return (Number.isFinite(lat)&&Number.isFinite(lng))?{lat:clampLat(lat),lng:normLng(lng)}:null; };
|
| 112 |
|
| 113 |
-
// State
|
| 114 |
-
const url = new URL(location.href);
|
| 115 |
-
let pointA = parseParamCoord(url.searchParams.get('a')) ?? { lat: 48.8566, lng: 2.3522 };
|
| 116 |
-
let pointB = parseParamCoord(url.searchParams.get('b')) ?? { lat: 40.7128, lng: -74.0060 };
|
| 117 |
-
let active = 'A';
|
| 118 |
-
let unit = url.searchParams.get('unit') || 'km';
|
| 119 |
-
|
| 120 |
-
// UI wiring
|
| 121 |
-
const dotA = document.getElementById('dotA');
|
| 122 |
-
const dotB = document.getElementById('dotB');
|
| 123 |
-
const setA = document.getElementById('setA');
|
| 124 |
-
const setB = document.getElementById('setB');
|
| 125 |
-
const coordsEl = document.getElementById('coords');
|
| 126 |
-
const distEl = document.getElementById('distance');
|
| 127 |
-
const swapBtn = document.getElementById('swapBtn');
|
| 128 |
-
const randBtn = document.getElementById('randBtn');
|
| 129 |
-
const copyBtn = document.getElementById('copyBtn');
|
| 130 |
-
document.querySelectorAll('[data-unit]').forEach(btn => btn.addEventListener('click', () => { unit = btn.dataset.unit; document.querySelectorAll('[data-unit]').forEach(b=>b.classList.toggle('active', b===btn)); updateScene(); }));
|
| 131 |
-
setA.onclick = () => { active='A'; setA.classList.add('active'); setB.classList.remove('active'); dotA.style.background='#60a5fa'; dotB.style.background='#334155'; };
|
| 132 |
-
setB.onclick = () => { active='B'; setB.classList.add('active'); setA.classList.remove('active'); dotB.style.background='#a78bfa'; dotA.style.background='#334155'; };
|
| 133 |
-
swapBtn.onclick = () => { const t = pointA; pointA = pointB; pointB = t; updateScene(); };
|
| 134 |
-
randBtn.onclick = () => { const rnd = () => ({ lat: Math.random()*180-90, lng: Math.random()*360-180 }); pointA=rnd(); pointB=rnd(); updateScene(); };
|
| 135 |
-
copyBtn.onclick = async () => { try { await navigator.clipboard.writeText(location.href); } catch(e){} };
|
| 136 |
-
|
| 137 |
function boot() {
|
| 138 |
if (!window.THREE) { showErr('three.js failed to load.'); return; }
|
| 139 |
-
if (!window.Globe || typeof window.Globe !== 'function') { showErr('globe.gl failed to load.
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
.backgroundColor('rgba(5,7,12,1)')
|
| 144 |
.showAtmosphere(true)
|
| 145 |
.globeImageUrl('https://unpkg.com/three-globe/example/img/earth-blue-marble.jpg')
|
|
@@ -153,11 +152,7 @@
|
|
| 153 |
.arcStroke(() => 0.6)
|
| 154 |
.arcDashLength(() => 0.6)
|
| 155 |
.arcDashGap(() => 0.2)
|
| 156 |
-
.arcDashAnimateTime(() => 2000)
|
| 157 |
-
);
|
| 158 |
-
|
| 159 |
-
const container = document.getElementById('globe-container');
|
| 160 |
-
container.appendChild(globe());
|
| 161 |
|
| 162 |
// Interaction: drag markers or click to set active point
|
| 163 |
const canvas = globe.renderer().domElement;
|
|
@@ -210,14 +205,11 @@
|
|
| 210 |
if (!light) updateURL();
|
| 211 |
}
|
| 212 |
|
| 213 |
-
// Initialize unit buttons and first render
|
| 214 |
document.querySelectorAll('[data-unit]').forEach(b => b.classList.toggle('active', b.dataset.unit===unit));
|
| 215 |
updateScene();
|
| 216 |
}
|
| 217 |
|
| 218 |
-
window.addEventListener('load',
|
| 219 |
-
try { boot(); } catch(e){ showErr((e && e.message) ? e.message : String(e)); }
|
| 220 |
-
});
|
| 221 |
})();
|
| 222 |
</script>
|
| 223 |
</body>
|
|
|
|
| 54 |
|
| 55 |
<noscript style="color:#fff; position:fixed; left:12px; bottom:48px;">Enable JavaScript.</noscript>
|
| 56 |
|
| 57 |
+
<!-- Required scripts (UMD) -->
|
|
|
|
| 58 |
<script src="https://unpkg.com/[email protected]/build/three.min.js" defer></script>
|
| 59 |
<script src="https://unpkg.com/globe.gl" defer></script>
|
| 60 |
|
| 61 |
<script>
|
| 62 |
(function(){
|
| 63 |
const showErr = (msg) => { const el = document.getElementById('err'); el.textContent = msg; el.style.display = 'block'; };
|
|
|
|
| 64 |
|
| 65 |
const toRad = (deg) => deg * Math.PI / 180;
|
| 66 |
const R_EARTH = 6371008.8; // meters
|
|
|
|
| 108 |
const normLng = (lng) => ((lng + 180) % 360 + 360) % 360 - 180;
|
| 109 |
const parseParamCoord = (s) => { if (!s) return null; const [a,b] = s.split(','); const lat=Number(a), lng=Number(b); return (Number.isFinite(lat)&&Number.isFinite(lng))?{lat:clampLat(lat),lng:normLng(lng)}:null; };
|
| 110 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
function boot() {
|
| 112 |
if (!window.THREE) { showErr('three.js failed to load.'); return; }
|
| 113 |
+
if (!window.Globe || typeof window.Globe !== 'function') { showErr('globe.gl failed to load.'); return; }
|
| 114 |
+
|
| 115 |
+
// State
|
| 116 |
+
const url = new URL(location.href);
|
| 117 |
+
let pointA = parseParamCoord(url.searchParams.get('a')) ?? { lat: 48.8566, lng: 2.3522 };
|
| 118 |
+
let pointB = parseParamCoord(url.searchParams.get('b')) ?? { lat: 40.7128, lng: -74.0060 };
|
| 119 |
+
let active = 'A';
|
| 120 |
+
let unit = url.searchParams.get('unit') || 'km';
|
| 121 |
+
|
| 122 |
+
// UI wiring
|
| 123 |
+
const dotA = document.getElementById('dotA');
|
| 124 |
+
const dotB = document.getElementById('dotB');
|
| 125 |
+
const setA = document.getElementById('setA');
|
| 126 |
+
const setB = document.getElementById('setB');
|
| 127 |
+
const coordsEl = document.getElementById('coords');
|
| 128 |
+
const distEl = document.getElementById('distance');
|
| 129 |
+
const swapBtn = document.getElementById('swapBtn');
|
| 130 |
+
const randBtn = document.getElementById('randBtn');
|
| 131 |
+
const copyBtn = document.getElementById('copyBtn');
|
| 132 |
+
document.querySelectorAll('[data-unit]').forEach(btn => btn.addEventListener('click', () => { unit = btn.dataset.unit; document.querySelectorAll('[data-unit]').forEach(b=>b.classList.toggle('active', b===btn)); updateScene(); }));
|
| 133 |
+
setA.onclick = () => { active='A'; setA.classList.add('active'); setB.classList.remove('active'); dotA.style.background='#60a5fa'; dotB.style.background='#334155'; };
|
| 134 |
+
setB.onclick = () => { active='B'; setB.classList.add('active'); setA.classList.remove('active'); dotB.style.background='#a78bfa'; dotA.style.background='#334155'; };
|
| 135 |
+
swapBtn.onclick = () => { const t = pointA; pointA = pointB; pointB = t; updateScene(); };
|
| 136 |
+
randBtn.onclick = () => { const rnd = () => ({ lat: Math.random()*180-90, lng: Math.random()*360-180 }); pointA=rnd(); pointB=rnd(); updateScene(); };
|
| 137 |
+
copyBtn.onclick = async () => { try { await navigator.clipboard.writeText(location.href); } catch(e){} };
|
| 138 |
+
|
| 139 |
+
// Globe mount: UMD signature is Globe()(container)
|
| 140 |
+
const container = document.getElementById('globe-container');
|
| 141 |
+
const globe = window.Globe()(container)
|
| 142 |
.backgroundColor('rgba(5,7,12,1)')
|
| 143 |
.showAtmosphere(true)
|
| 144 |
.globeImageUrl('https://unpkg.com/three-globe/example/img/earth-blue-marble.jpg')
|
|
|
|
| 152 |
.arcStroke(() => 0.6)
|
| 153 |
.arcDashLength(() => 0.6)
|
| 154 |
.arcDashGap(() => 0.2)
|
| 155 |
+
.arcDashAnimateTime(() => 2000);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
|
| 157 |
// Interaction: drag markers or click to set active point
|
| 158 |
const canvas = globe.renderer().domElement;
|
|
|
|
| 205 |
if (!light) updateURL();
|
| 206 |
}
|
| 207 |
|
|
|
|
| 208 |
document.querySelectorAll('[data-unit]').forEach(b => b.classList.toggle('active', b.dataset.unit===unit));
|
| 209 |
updateScene();
|
| 210 |
}
|
| 211 |
|
| 212 |
+
window.addEventListener('load', boot);
|
|
|
|
|
|
|
| 213 |
})();
|
| 214 |
</script>
|
| 215 |
</body>
|