feat(weather): add real-time animated cloud and precipitation radar layer, integrate early warning badges, refine showcase text, and remove floating CTA button

This commit is contained in:
Hamza-Ayed
2026-08-19 16:14:33 +03:00
parent 470d6d959d
commit 3d13d31101
5 changed files with 925 additions and 1023 deletions
+55 -1
View File
@@ -331,8 +331,62 @@ const MapComponent: React.FC<MapProps> = ({
}
};
fetchWeather();
// 2. Fetch RainViewer Animated Cloud & Rain Radar
let radarTimer: any = null;
const fetchRadar = async () => {
try {
const res = await fetch('https://api.rainviewer.com/public/weather-maps.json');
const data = await res.json();
const host = data.host || 'https://tilecache.rainviewer.com';
const frames = data.radar?.past || [];
if (frames.length > 0 && map.current && map.current.isStyleLoaded()) {
let currentIdx = frames.length - 1;
const getTileUrl = (i: number) => `${host}${frames[i].path}`;
if (!map.current.getSource('weather-radar-source')) {
map.current.addSource('weather-radar-source', {
type: 'raster',
tiles: [getTileUrl(currentIdx)],
tileSize: 256
});
map.current.addLayer({
id: 'weather-radar-layer',
type: 'raster',
source: 'weather-radar-source',
paint: {
'raster-opacity': 0.72,
'raster-fade-duration': 250
}
}, map.current.getLayer('weather-city-circles') ? 'weather-city-circles' : undefined);
} else {
map.current.setLayoutProperty('weather-radar-layer', 'visibility', 'visible');
}
// Animate through radar frames every 1200ms
if (frames.length > 1) {
radarTimer = setInterval(() => {
if (!map.current || !map.current.getSource('weather-radar-source')) return;
currentIdx = (currentIdx + 1) % frames.length;
const src = map.current.getSource('weather-radar-source') as any;
if (src && src.setTiles) {
src.setTiles([getTileUrl(currentIdx)]);
}
}, 1200);
}
}
} catch (err) {
console.warn('Radar fetch failed', err);
}
};
fetchRadar();
return () => {
if (radarTimer) clearInterval(radarTimer);
};
} else {
const weatherLayers = ['weather-city-circles', 'weather-city-icons', 'weather-wind-arrows', 'weather-wind-speed'];
const weatherLayers = ['weather-city-circles', 'weather-city-icons', 'weather-wind-arrows', 'weather-wind-speed', 'weather-radar-layer'];
weatherLayers.forEach(layerId => {
if (map.current && map.current.getLayer(layerId)) {
map.current.setLayoutProperty(layerId, 'visibility', 'none');