Spaces:
Running
Running
live location
Browse files- index.html +5 -1
- script.js +51 -7
- style.css +10 -2
index.html
CHANGED
|
@@ -108,8 +108,12 @@
|
|
| 108 |
<div class="text-sm text-purple-300">
|
| 109 |
<span id="dateDisplay"></span>
|
| 110 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
</div>
|
| 112 |
-
|
| 113 |
<button id="fullscreenBtn" class="control-button glass-effect px-4 py-2 rounded-lg flex items-center gap-2">
|
| 114 |
<i data-feather="maximize" class="w-4 h-4"></i>
|
| 115 |
<span class="hidden sm:inline">Fullscreen</span>
|
|
|
|
| 108 |
<div class="text-sm text-purple-300">
|
| 109 |
<span id="dateDisplay"></span>
|
| 110 |
</div>
|
| 111 |
+
<div class="text-sm text-green-400 flex items-center gap-2">
|
| 112 |
+
<i data-feather="map-pin" class="w-4 h-4"></i>
|
| 113 |
+
<span id="locationDisplay">Loading location...</span>
|
| 114 |
+
</div>
|
| 115 |
</div>
|
| 116 |
+
<div class="flex gap-4">
|
| 117 |
<button id="fullscreenBtn" class="control-button glass-effect px-4 py-2 rounded-lg flex items-center gap-2">
|
| 118 |
<i data-feather="maximize" class="w-4 h-4"></i>
|
| 119 |
<span class="hidden sm:inline">Fullscreen</span>
|
script.js
CHANGED
|
@@ -165,7 +165,6 @@ class SolarSystem {
|
|
| 165 |
|
| 166 |
this.init();
|
| 167 |
}
|
| 168 |
-
|
| 169 |
init() {
|
| 170 |
this.resize();
|
| 171 |
window.addEventListener('resize', () => this.resize());
|
|
@@ -173,10 +172,11 @@ class SolarSystem {
|
|
| 173 |
this.createStars();
|
| 174 |
this.animate();
|
| 175 |
this.updateDate();
|
|
|
|
| 176 |
setInterval(() => this.updateDate(), 1000);
|
|
|
|
| 177 |
}
|
| 178 |
-
|
| 179 |
-
resize() {
|
| 180 |
this.canvas.width = window.innerWidth;
|
| 181 |
this.canvas.height = window.innerHeight;
|
| 182 |
this.centerX = this.canvas.width / 2;
|
|
@@ -242,14 +242,18 @@ class SolarSystem {
|
|
| 242 |
document.exitFullscreen();
|
| 243 |
}
|
| 244 |
});
|
| 245 |
-
|
| 246 |
// Info button
|
| 247 |
document.getElementById('infoBtn').addEventListener('click', () => {
|
| 248 |
const planetInfo = document.getElementById('planetInfo');
|
| 249 |
planetInfo.classList.toggle('hidden');
|
| 250 |
});
|
| 251 |
|
| 252 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 253 |
document.getElementById('closeInfo').addEventListener('click', () => {
|
| 254 |
document.getElementById('planetInfo').classList.add('hidden');
|
| 255 |
});
|
|
@@ -284,7 +288,6 @@ class SolarSystem {
|
|
| 284 |
document.getElementById('planetDiameter').textContent = planet.info.diameter;
|
| 285 |
document.getElementById('planetMoons').textContent = planet.info.moons || 'None';
|
| 286 |
}
|
| 287 |
-
|
| 288 |
updateDate() {
|
| 289 |
const now = new Date();
|
| 290 |
document.getElementById('dateDisplay').textContent = now.toLocaleDateString('en-US', {
|
|
@@ -294,7 +297,48 @@ class SolarSystem {
|
|
| 294 |
day: 'numeric'
|
| 295 |
});
|
| 296 |
}
|
| 297 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 298 |
// Simplified sun for performance
|
| 299 |
this.ctx.fillStyle = '#FBBF24';
|
| 300 |
this.ctx.beginPath();
|
|
|
|
| 165 |
|
| 166 |
this.init();
|
| 167 |
}
|
|
|
|
| 168 |
init() {
|
| 169 |
this.resize();
|
| 170 |
window.addEventListener('resize', () => this.resize());
|
|
|
|
| 172 |
this.createStars();
|
| 173 |
this.animate();
|
| 174 |
this.updateDate();
|
| 175 |
+
this.updateLocation();
|
| 176 |
setInterval(() => this.updateDate(), 1000);
|
| 177 |
+
setInterval(() => this.updateLocation(), 30000); // Update location every 30 seconds
|
| 178 |
}
|
| 179 |
+
resize() {
|
|
|
|
| 180 |
this.canvas.width = window.innerWidth;
|
| 181 |
this.canvas.height = window.innerHeight;
|
| 182 |
this.centerX = this.canvas.width / 2;
|
|
|
|
| 242 |
document.exitFullscreen();
|
| 243 |
}
|
| 244 |
});
|
|
|
|
| 245 |
// Info button
|
| 246 |
document.getElementById('infoBtn').addEventListener('click', () => {
|
| 247 |
const planetInfo = document.getElementById('planetInfo');
|
| 248 |
planetInfo.classList.toggle('hidden');
|
| 249 |
});
|
| 250 |
|
| 251 |
+
// Location refresh on click
|
| 252 |
+
document.getElementById('locationDisplay').addEventListener('click', () => {
|
| 253 |
+
document.getElementById('locationDisplay').textContent = 'Updating...';
|
| 254 |
+
this.updateLocation();
|
| 255 |
+
});
|
| 256 |
+
// Close info panel
|
| 257 |
document.getElementById('closeInfo').addEventListener('click', () => {
|
| 258 |
document.getElementById('planetInfo').classList.add('hidden');
|
| 259 |
});
|
|
|
|
| 288 |
document.getElementById('planetDiameter').textContent = planet.info.diameter;
|
| 289 |
document.getElementById('planetMoons').textContent = planet.info.moons || 'None';
|
| 290 |
}
|
|
|
|
| 291 |
updateDate() {
|
| 292 |
const now = new Date();
|
| 293 |
document.getElementById('dateDisplay').textContent = now.toLocaleDateString('en-US', {
|
|
|
|
| 297 |
day: 'numeric'
|
| 298 |
});
|
| 299 |
}
|
| 300 |
+
|
| 301 |
+
async updateLocation() {
|
| 302 |
+
const locationDisplay = document.getElementById('locationDisplay');
|
| 303 |
+
|
| 304 |
+
if (!navigator.geolocation) {
|
| 305 |
+
locationDisplay.textContent = 'Location not supported';
|
| 306 |
+
return;
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
navigator.geolocation.getCurrentPosition(
|
| 310 |
+
async (position) => {
|
| 311 |
+
const { latitude, longitude } = position.coords;
|
| 312 |
+
|
| 313 |
+
try {
|
| 314 |
+
// Using Nominatim reverse geocoding API
|
| 315 |
+
const response = await fetch(
|
| 316 |
+
`https://nominatim.openstreetmap.org/reverse?format=json&lat=${latitude}&lon=${longitude}&zoom=10`,
|
| 317 |
+
{
|
| 318 |
+
headers: {
|
| 319 |
+
'User-Agent': 'CosmicExplorer/1.0'
|
| 320 |
+
}
|
| 321 |
+
}
|
| 322 |
+
);
|
| 323 |
+
|
| 324 |
+
if (!response.ok) throw new Error('Location fetch failed');
|
| 325 |
+
|
| 326 |
+
const data = await response.json();
|
| 327 |
+
const city = data.address?.city || data.address?.town || data.address?.village || 'Unknown';
|
| 328 |
+
const country = data.address?.country || '';
|
| 329 |
+
|
| 330 |
+
locationDisplay.textContent = country ? `${city}, ${country}` : city;
|
| 331 |
+
} catch (error) {
|
| 332 |
+
// Fallback to coordinates
|
| 333 |
+
locationDisplay.textContent = `${latitude.toFixed(2)}°, ${longitude.toFixed(2)}°`;
|
| 334 |
+
}
|
| 335 |
+
},
|
| 336 |
+
(error) => {
|
| 337 |
+
locationDisplay.textContent = 'Location denied';
|
| 338 |
+
}
|
| 339 |
+
);
|
| 340 |
+
}
|
| 341 |
+
drawSun() {
|
| 342 |
// Simplified sun for performance
|
| 343 |
this.ctx.fillStyle = '#FBBF24';
|
| 344 |
this.ctx.beginPath();
|
style.css
CHANGED
|
@@ -26,7 +26,15 @@
|
|
| 26 |
background: linear-gradient(135deg, #9333ea, #ec4899);
|
| 27 |
border-radius: 4px;
|
| 28 |
}
|
| 29 |
-
|
| 30 |
::-webkit-scrollbar-thumb:hover {
|
| 31 |
background: linear-gradient(135deg, #a855f7, #f472b6);
|
| 32 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
background: linear-gradient(135deg, #9333ea, #ec4899);
|
| 27 |
border-radius: 4px;
|
| 28 |
}
|
|
|
|
| 29 |
::-webkit-scrollbar-thumb:hover {
|
| 30 |
background: linear-gradient(135deg, #a855f7, #f472b6);
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
#locationDisplay {
|
| 34 |
+
cursor: pointer;
|
| 35 |
+
transition: opacity 0.3s ease;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
#locationDisplay:hover {
|
| 39 |
+
opacity: 0.8;
|
| 40 |
+
}
|