// Mappa Calabria — Leaflet.js + CartoDB Voyager tiles // Coordinate: x = 100 + (lon-15.6)*250 → lon = (x-100)/250 + 15.6 // y = 80 + (40.15-lat)*278 → lat = 40.15 - (y-80)/278 const KIND_DEFS = [ { key: "citta", label: "Città", color: "#1c1612" }, { key: "costa", label: "Costa", color: "#1a5c7a" }, { key: "parco", label: "Parchi", color: "#2d6a4f" }, { key: "archeologia", label: "Archeologia", color: "#9b5c1a" }, { key: "borgo", label: "Borghi", color: "#7a2e2e" }, { key: "spiaggia", label: "Spiagge", color: "#0077a8" }, { key: "alture", label: "Alture", color: "#4a6741" }, ]; function getKindColor(kind) { return (KIND_DEFS.find(k => k.key === kind) || {}).color || "#6b5f4e"; } function ptToLatLng(pt) { return [ 40.15 - (pt.y - 80) / 278, (pt.x - 100) / 250 + 15.6, ]; } function CalabriaMap() { const [activeKind, setActiveKind] = useState("ALL"); const [hoveredPt, setHoveredPt] = useState(null); const mobile = useMobile(); const mapDivRef = useRef(null); const mapRef = useRef(null); const markersRef = useRef({}); // ── Inizializza Leaflet una sola volta ── useEffect(() => { if (mapRef.current) return; const map = L.map(mapDivRef.current, { center: [38.85, 16.55], zoom: 8, scrollWheelZoom: false, zoomControl: false, attributionControl: true, }); L.control.zoom({ position: "bottomright" }).addTo(map); // CartoDB Voyager — palette calda, ottimo su desktop e mobile L.tileLayer( "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png", { attribution: '© OpenStreetMap © CARTO', subdomains: "abcd", maxZoom: 17, } ).addTo(map); // ── Marker per ogni luogo ── MAP_POINTS.forEach(pt => { const latlng = ptToLatLng(pt); const color = getKindColor(pt.kind); const isCitta = pt.kind === "citta"; const r = isCitta ? 9 : 7; const circle = L.circleMarker(latlng, { radius: r, fillColor: color, color: "#fff", weight: 2, opacity: 1, fillOpacity: 0.9, }).addTo(map); // Tooltip — permanente per le città, al hover per gli altri circle.bindTooltip(pt.name, { permanent: isCitta, direction: "right", offset: [10, 0], className: "cal-tip", opacity: 1, }); circle.on("mouseover", function () { setHoveredPt(pt); this.setRadius(isCitta ? 13 : 11); if (!isCitta) this.openTooltip(); }); circle.on("mouseout", function () { setHoveredPt(null); this.setRadius(r); if (!isCitta) this.closeTooltip(); }); markersRef.current[pt.id] = { circle, isCitta, r }; }); mapRef.current = map; }, []); // ── Aggiorna opacità marker al cambio filtro ── useEffect(() => { if (!mapRef.current) return; Object.entries(markersRef.current).forEach(([id, { circle }]) => { const pt = MAP_POINTS.find(p => p.id === id); const visible = activeKind === "ALL" || pt?.kind === activeKind; circle.setStyle({ fillOpacity: visible ? 0.9 : 0.06, opacity: visible ? 1 : 0.06, }); }); }, [activeKind]); const toggleKind = (key) => setActiveKind(prev => prev === key ? "ALL" : key); const visibleCount = activeKind === "ALL" ? MAP_POINTS.length : MAP_POINTS.filter(p => p.kind === activeKind).length; return ( {/* ── Pannello sinistro ── */} {hoveredPt ? ( <> {(KIND_DEFS.find(k => k.key === hoveredPt.kind) || {}).label || hoveredPt.kind} {hoveredPt.name} Provincia di {(PROVINCES.find(p => p.code === hoveredPt.province) || {}).name} Scopri {hoveredPt.name} > ) : ( <> Esplora {visibleCount} luoghi Passa sopra un punto della mappa. Filtra per tipologia o passa il cursore su un marker per scoprire il luogo. > )} {/* ── Filtri tipologia ── */} {KIND_DEFS.map(kind => { const isActive = activeKind === kind.key; return ( toggleKind(kind.key)} style={{ display: "flex", alignItems: "center", gap: 9, fontSize: 11, fontFamily: "var(--font-mono)", letterSpacing: "0.06em", textTransform: "uppercase", color: isActive ? "var(--ink)" : "var(--muted)", fontWeight: isActive ? 600 : 400, background: isActive ? "var(--paper-2)": "transparent", border: "none", textAlign: "left", padding: "8px 10px", cursor: "pointer", borderRadius: 2, transition: "color .2s, background .2s", }}> {kind.label} ); })} {/* ── Contenitore mappa Leaflet ── */} ); } window.CalabriaMap = CalabriaMap;
Filtra per tipologia o passa il cursore su un marker per scoprire il luogo.