
Overview
Qué es y qué hice
Climapi es un globo terráqueo interactivo en pixel art que muestra el clima del planeta en tiempo real. Se puede buscar una ciudad o hacer clic en cualquier punto para abrir su clima, mover una línea de tiempo de −12 h a +24 h y superponer satélite, tormentas y eventos reales.
Lo diseñé y desarrollé de principio a fin: la interfaz y el sistema visual en pixel art, la integración con APIs públicas, el diseño adaptable a móvil y la publicación en un hosting propio.
- Globo 3D (MapLibre GL JS, proyección globe) con búsqueda de ciudades y clima al hacer clic.
- Ocho datos en el mapa: temperatura, precipitación, viento, nubosidad, humedad, presión, nieve e índice UV.
- Satélite real de la NASA (VIIRS, GOES y Himawari) y tormentas y huracanes del NHC/NOAA.
- «¿Es normal?»: la temperatura prevista frente a los mismos días de los últimos 10 años.
- Postal PNG compartible y enlaces que guardan toda la vista en la URL.
The Challenge
Problema
Los datos abiertos del clima existen, pero están repartidos en servicios distintos, con formatos y ritmos de actualización diferentes: pronóstico, satélite, tormentas, eventos naturales e histórico. Verlos juntos, sobre el mismo mapa y en el mismo momento, normalmente exige saltar entre varias herramientas.
El reto era unirlos en una sola vista explorable, entendible de un vistazo, sin cuentas ni claves de API, sin paso de compilación y que además funcionara bien en escritorio, tablet y móvil.
Approach
Cómo lo abordé
Tomé cinco decisiones de partida que guiaron el resto del proyecto:
- Sitio estático sin compilación: HTML, CSS y JavaScript clásico, publicable en cualquier hosting.
- Solo fuentes abiertas y sin claves: Open-Meteo, NASA GIBS, NASA EONET y NHC/NOAA.
- Un módulo por responsabilidad: capas del mapa, funciones con datos propios, interfaz y efectos.
- Una identidad visual propia: pixel art en iconos, tipografías (Silkscreen y VT323), mapa de color cuantizado y hasta la postal para compartir.
- Adaptable desde el inicio: escritorio, tablet, móvil vertical y móvil horizontal, con un «modo ligero» para equipos modestos.
UX / Architecture
Flujos + estructura
La pantalla se organiza en cuatro zonas: buscador arriba a la izquierda, dock de capas a la izquierda, panel de clima a la derecha y línea de tiempo abajo. Los flujos principales son:
- Consultar un lugar: buscar o hacer clic en el globo abre el panel con temperatura, sensación térmica, humedad, viento, presión, precipitación, pronóstico de cinco días y la anomalía «¿es normal?».
- Elegir qué ver: desde el dock se cambia el dato del mapa (ocho opciones) y se activan capas extra como nubes, viento, luces de ciudades, fronteras y satélite.
- Viajar en el tiempo: la línea de tiempo (−12 h a +24 h) mueve a la vez los datos, la iluminación día/noche, las nubes, el viento, las tormentas y el satélite.
- Explorar: una lista de eventos reales (incendios, ciclones, volcanes) y los récords del día; «Sorpréndeme» vuela hasta uno.
- Compartir: el estado completo viaja en la URL, o se genera una postal PNG.

Design
UI + sistema visual
El lenguaje visual es pixel art sobre fondo espacial oscuro: iconos de la Pixel Icon Library, tipografías Silkscreen y VT323, bloques con borde pixelado y un mapa de color cuantizado que refuerza el efecto. Los colores del mapa siguen rampas por variable (temperatura, viento, humedad…) con su leyenda siempre visible.
La misma estética se lleva a la postal compartible: el globo se pixela y se acompaña de la ficha del lugar, la anomalía y el pronóstico. En pantallas pequeñas el dock pasa a una fila horizontal y el panel de clima a una hoja inferior plegable.



Development
Stack + arquitectura técnica
Climapi es un sitio estático sin paso de compilación: scripts clásicos que se comunican mediante globales (window.*) y se cargan en un orden explícito desde index.html. El código se reparte en 18 módulos (unas 2 200 líneas de JavaScript) agrupados por responsabilidad: core (arranque, estado y compartir), layers (clima, nubes, día/noche, satélite, fronteras), features (tormentas, explorar, anomalía, postal), ui y effects.
La capa de clima descarga una rejilla global de Open-Meteo (un punto cada 15°), la interpola bilinealmente y la dibuja en un canvas con efecto pixel que MapLibre reproyecta sobre el globo; las partículas de viento se animan sobre ese mismo campo. El satélite viene de NASA GIBS (mosaico VIIRS de base y GOES/Himawari casi en vivo), las tormentas del servicio MapServer del NHC y los eventos de NASA EONET. La anomalía compara el pronóstico con las mismas fechas de los últimos 10 años (reanálisis ERA5 vía Open-Meteo Archive).
Open-Meteo
Pronóstico, rejilla global e histórico ERA5
NASA GIBS
Satélite VIIRS, GOES y Himawari
NASA EONET
Incendios, volcanes y ciclones
NHC / NOAA
Trayectoria e intensidad de tormentas
Módulos de JavaScript
Scripts clásicos que se comunican por window.*
- layers · clima, nubes, día/noche, satélite
- features · tormentas, explorar, anomalía, postal
- ui · dock, línea de tiempo, móvil
Globo MapLibre
Mapa de color con efecto pixel sobre la proyección globe
Panel de clima
Pronóstico de cinco días y «¿es normal?»
Línea de tiempo
De −12 h a +24 h: mueve todas las capas a la vez
Estado en la URL
#c=…&z=… guarda la vista en un enlace; la postal PNG la lleva a una imagen
- JavaScript
- HTML
- CSS
- MapLibre GL
- Open-Meteo
- NASA GIBS
- NASA EONET
- NHC / NOAA


Challenges
Problemas → soluciones
Los obstáculos más interesantes vinieron de las restricciones que me puse: sin compilación, sin claves y con APIs gratuitas.
Problema
Sin módulos ni compilación, los scripts comparten estado mediante globales y el orden de carga importa.
Solución
Cada archivo se envuelve en una función autoinvocada para no ensuciar el ámbito global, y el orden queda fijado en index.html: los datos de ciudades antes de las capas que los usan, los iconos antes de quien los dibuja y core/app.js al final.
Problema
Las APIs gratuitas tienen límites: Open-Meteo admite unas 600 llamadas por minuto y cada carga consume cerca de 400, así que recargar varias veces seguidas devuelve error 429.
Solución
La rejilla global se guarda una hora en localStorage, y la anomalía hace una sola petición corta por año de referencia (unos 11 días) en lugar de pedir el histórico completo.
Problema
Para generar la postal hacía falta capturar el globo, que es un lienzo WebGL.
Solución
Creé el mapa con preserveDrawingBuffer y compuse la postal en un canvas aparte: el globo se pixela a 192×192 y se amplía ×3. Los marcadores HTML (remolinos de tormenta, eventos) no están en el lienzo, así que no aparecen en la postal; sí las capas, las trayectorias y el satélite.
Problema
Tantas capas animadas (viento, nubes, estrellas, satélite) pesan demasiado en móviles y equipos modestos.
Solución
Un «modo ligero» se activa en pantallas táctiles o equipos modestos: menos partículas de viento, nubes y estrellas más ligeras, mapa de color de menor resolución y densidad de píxeles limitada a 2×. Se puede forzar con ?lite=1 o ?lite=0 para probarlo.
Problema
La línea de tiempo llega a +24 h, pero no existen imágenes de satélite del futuro.
Solución
El satélite pide la imagen de la hora elegida hasta 12 h atrás y, para el futuro, muestra la última disponible mientras el resto de capas sí avanzan.
Problema
Lighthouse puntuaba el rendimiento móvil en torno a 27 y reportaba un tiempo de bloqueo de decenas de segundos.
Solución
Antes de «optimizar» averigüé por qué: sin GPU, MapLibre se renderiza por software con la CPU frenada 4×. Dejé de perseguir esa puntuación y medí lo que sí es comparable entre versiones —FCP, accesibilidad y SEO—, con medianas de tres corridas alternadas. Corregí lo que de verdad era un problema (scripts que bloqueaban el pintado, una redirección, contraste y metaetiquetas) y documenté lo que no mejoró.
Results
Resultado técnico / métricas
Climapi está publicado y funcionando en labs.paginee.com/Climapi, como sitio estático servido por HTTPS desde un hosting Apache.
- 8datos meteorológicos en el mapa
- 36 hde línea de tiempo (−12 h a +24 h)
- 18módulos de JavaScript sin compilar
- 10 añosde histórico para «¿es normal?»
- 92 → 96accesibilidad en Lighthouse
- 90 → 100SEO en Lighthouse
Los enlaces del botón de compartir (#c=…&z=…) funcionan directamente sobre la dirección pública y reproducen la misma vista. El proyecto se empaqueta con un script en un zip listo para subir a cPanel y, como las rutas son relativas, sirve igual en la raíz de un dominio que en una subcarpeta.
Medición con Lighthouse
Medí la versión publicada y la versión con las optimizaciones del repositorio (pendientes de desplegar) con Lighthouse 13.5 en Edge sin interfaz, con la simulación de red y CPU de móvil y de escritorio. Cada cifra es la mediana de 3 corridas, alternando las versiones para que la carga del equipo no favorezca a ninguna.
- Accesibilidad: 92 → 96. El texto atenuado de la leyenda y de la línea de tiempo cumple ahora el contraste AA (de 4,49:1 a más de 5:1).
- SEO: 90 → 100, con descripción, URL canónica y metaetiquetas Open Graph.
- Primer contenido visible (FCP): de 1,3 s a 0,8 s en escritorio y de 4,3 s a 2,4 s en móvil. Lo logra cargar los 19 scripts con
defer(ya no bloquean el primer pintado), fijar la versión exacta de MapLibre (evita una redirección de unpkg), cargar las tipografías con<link>en vez de@importy abrir las conexiones externas por adelantado. - Puntuación de rendimiento: sin cambio (≈ 55 en escritorio y ≈ 28 en móvil).
- LCP: no mejoró; en escritorio pasó de 1,6 s a 2,2 s.
Lo que estas cifras no dicen
La puntuación de rendimiento de un globo WebGL es muy baja en este laboratorio por una razón técnica: Lighthouse corre sin GPU, MapLibre se renderiza por software y la CPU se frena 4×, lo que dispara el tiempo de bloqueo a decenas de segundos. Esos valores no representan cómo se siente en un equipo real, así que no los uso como conclusión. Además, el elemento que Lighthouse toma como LCP es el texto de atribución de MapLibre, que solo aparece cuando el mapa termina de iniciarse: al diferir los scripts la interfaz se pinta antes, pero el mapa tarda unas décimas más en estar listo.
El código propio transfiere unos 66 KB comprimidos y MapLibre otros 276 KB; el resto de los cerca de 2,4 MB son sobre todo imágenes, teselas y datos de las APIs.
Reflection
Qué aprendí
Diseñar alrededor de los límites de las APIs desde el principio, y no al final, condicionó decisiones clave: la resolución de la rejilla, la caché de una hora y la forma de calcular la anomalía. Un sitio sin compilación resulta muy portable, pero el orden de los scripts y las globales pasan a formar parte de la arquitectura y exigen disciplina.
Medir antes de optimizar cambió mi plan: la puntuación que parecía el problema era un artefacto del laboratorio, y un cambio que mejoraba el primer pintado (defer) empeoraba una métrica distinta (LCP). Aprendí a comprobar cada cambio por separado y a reportar también lo que no funcionó.
Si continuara el proyecto, añadiría un service worker para que funcione sin conexión (hoy es instalable en la pantalla de inicio, pero no tiene modo offline), cambiaría las teselas públicas de OpenStreetMap por un proveedor propio si crece el tráfico y llevaría los marcadores HTML también a la postal.
Live Project
Ver proyecto