Radar: switch to RainViewer (IEM blocks heavy tile use), cleaner Map tab
Publish Container / publish (push) Successful in 2m40s
Publish Container / publish (push) Successful in 2m40s
- /api/radar/times serves RainViewer frames (cached 2 min), IEM NEXRAD only as fallback; sources honour maxNativeZoom so tiles overzoom instead of going blank - Map tab opens with radar + location dot only; wind/AQI/alerts/temp/sun/lightning are opt-in, readout chips follow their toggles - Bolder location dot - Satellite (GIBS) layer: new storage key, never persisted by storm taps, radar always draws above it Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
13985344ed
commit
2efc945192
3 files changed
+62
-33
No files matched your search
@@ -342,3 +342,9 @@ body.map-fs #tab-unified-map { padding: 0; }
|
||||
.sticky-head { background: color-mix(in srgb, var(--paper) 96%, transparent) !important; }
|
||||
.hero-hilo { background: rgba(0, 0, 0, 0.24) !important; }
|
||||
.topbar, .bottom-nav { -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
|
||||
|
||||
/* readout chips follow their layer toggle (author display rules would otherwise beat [hidden]) */
|
||||
#tab-unified-map .map-overlay-readouts[hidden], #tab-unified-map .map-readout-chip[hidden] { display: none !important; }
|
||||
|
||||
/* Location dot: the one thing on the map by default, so make it unmistakable (static halo, no animation) */
|
||||
.map-location-dot { width: 20px; height: 20px; background: #2563eb; border: 3px solid #fff; border-radius: 50%; box-shadow: 0 0 0 7px rgba(37, 99, 235, 0.28), 0 2px 8px rgba(0, 0, 0, 0.55); }
|
||||
+26
-8
@@ -176,6 +176,8 @@ async function flyToHurricane(storm) {
|
||||
if (sat && !sat.checked) {
|
||||
sat.checked = true;
|
||||
sat.dispatchEvent(new Event('change'));
|
||||
// a storm tap is a one-off look, not a change to the user's saved map layers
|
||||
try { localStorage.removeItem(STORAGE_KEYS.showSatelliteLayer); } catch {}
|
||||
}
|
||||
|
||||
await new Promise(r => setTimeout(r, 450));
|
||||
@@ -358,6 +360,8 @@ async function renderCloudOverlay(map) {
|
||||
}
|
||||
});
|
||||
if (on) map.__cloudStamp = stamp;
|
||||
// Radar frames must always draw above the clouds (they may have been added after this layer), or rain disappears
|
||||
map.getStyle().layers.filter(l => l.id.startsWith('rv-radar-')).forEach(l => map.moveLayer(l.id));
|
||||
} catch { /* style swapped mid-update; next refresh retries */ }
|
||||
}
|
||||
|
||||
@@ -490,7 +494,7 @@ const STORAGE_KEYS = {
|
||||
showLightning: 'weather.showLightning',
|
||||
showWind: 'weather.showWind',
|
||||
showRadarLayer: 'weather.map.radar',
|
||||
showSatelliteLayer: 'weather.map.satellite',
|
||||
showSatelliteLayer: 'weather.map.goesIR', // new key: the old 'satellite' toggle never drew anything, ignore its stale value
|
||||
showLightningLayer: 'weather.map.lightning',
|
||||
showWindLayer: 'weather.map.wind',
|
||||
showAqiLayer: 'weather.map.aqi',
|
||||
@@ -537,12 +541,12 @@ const state = {
|
||||
unifiedMapLayers: {
|
||||
radar: localStorage.getItem(STORAGE_KEYS.showRadarLayer) !== 'false',
|
||||
satellite: localStorage.getItem(STORAGE_KEYS.showSatelliteLayer) === 'true',
|
||||
lightning: localStorage.getItem(STORAGE_KEYS.showLightningLayer) !== 'false',
|
||||
wind: localStorage.getItem(STORAGE_KEYS.showWindLayer) !== 'false',
|
||||
aqi: localStorage.getItem(STORAGE_KEYS.showAqiLayer) !== 'false',
|
||||
alerts: localStorage.getItem(STORAGE_KEYS.showAlertsLayer) !== 'false',
|
||||
temp: localStorage.getItem(STORAGE_KEYS.showTempMarker) !== 'false',
|
||||
sunMoon: localStorage.getItem(STORAGE_KEYS.showSunMoonMarkers) !== 'false',
|
||||
lightning: localStorage.getItem(STORAGE_KEYS.showLightningLayer) === 'true',
|
||||
wind: localStorage.getItem(STORAGE_KEYS.showWindLayer) === 'true',
|
||||
aqi: localStorage.getItem(STORAGE_KEYS.showAqiLayer) === 'true',
|
||||
alerts: localStorage.getItem(STORAGE_KEYS.showAlertsLayer) === 'true',
|
||||
temp: localStorage.getItem(STORAGE_KEYS.showTempMarker) === 'true',
|
||||
sunMoon: localStorage.getItem(STORAGE_KEYS.showSunMoonMarkers) === 'true',
|
||||
hurricane: localStorage.getItem(STORAGE_KEYS.showHurricaneLayer) === 'true',
|
||||
wildfire: localStorage.getItem(STORAGE_KEYS.showWildfireLayer) === 'true',
|
||||
spc: localStorage.getItem(STORAGE_KEYS.showSpcLayer) === 'true',
|
||||
@@ -1048,7 +1052,7 @@ function createRadar(mapEl, timelineEl, playBtn, tsEl, layerBtn) {
|
||||
function addFrameLayer(frame, forMode) {
|
||||
const id = `rv-${forMode}-${frame.time}`;
|
||||
if (!map.getSource(id)) {
|
||||
map.addSource(id, { type: 'raster', tiles: [frameTileUrl(frame, forMode)], tileSize: 256 });
|
||||
map.addSource(id, { type: 'raster', tiles: [frameTileUrl(frame, forMode)], tileSize: 256, ...(frame.maxNativeZoom ? { maxzoom: frame.maxNativeZoom } : {}) });
|
||||
map.addLayer({
|
||||
id, type: 'raster', source: id,
|
||||
paint: {
|
||||
@@ -2611,11 +2615,25 @@ document.querySelectorAll('#tab-unified-map input[type="checkbox"][data-layer]')
|
||||
}
|
||||
|
||||
if (layerName === 'satellite') renderCloudOverlay(mapsOverview.map);
|
||||
syncReadoutChips();
|
||||
|
||||
if (state.currentCity) refreshMapsOverview();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// The top-left readout chips only show for layers the user switched on
|
||||
function syncReadoutChips() {
|
||||
const L = state.unifiedMapLayers;
|
||||
[['overlay-temp', L.temp], ['overlay-aqi', L.aqi], ['overlay-sunmoon', L.sunMoon]].forEach(([id, on]) => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.hidden = !on;
|
||||
});
|
||||
const box = document.getElementById('map-overlay-readouts');
|
||||
if (box) box.hidden = !(L.temp || L.aqi || L.sunMoon);
|
||||
}
|
||||
syncReadoutChips();
|
||||
|
||||
const baseMapSelect = document.getElementById('base-map-select');
|
||||
if (baseMapSelect) {
|
||||
baseMapSelect.value = state.unifiedMapBaseLayer;
|
||||
|
||||
Reference in new issue
Block a user