diff --git a/index.html b/index.html index b9a2766..f51306f 100644 --- a/index.html +++ b/index.html @@ -44,6 +44,12 @@
+ +
+
+ +
+ @@ -68,6 +74,10 @@ + + + + diff --git a/js/bottomSheet.js b/js/bottomSheet.js new file mode 100644 index 0000000..7e5359b --- /dev/null +++ b/js/bottomSheet.js @@ -0,0 +1,51 @@ +// =============================== +// BOTTOM SHEET (Google Photos Web) +// =============================== + +const bottomSheet = document.getElementById("bottomSheet"); +const sheetGallery = document.getElementById("sheetGallery"); + +// Apri il bottom sheet con una lista di foto +function openBottomSheet(photoList) { + sheetGallery.innerHTML = ""; + + photoList.forEach(photo => { + const div = document.createElement("div"); + div.className = "sheet-item"; + + div.innerHTML = ` + + `; + + div.addEventListener("click", () => { + openModal( + `https://prova.patachina.it/${photo.path}`, + photo.thub2 + ? `https://prova.patachina.it/${photo.thub2}` + : `https://prova.patachina.it/${photo.thub1}`, + photo + ); + }); + + sheetGallery.appendChild(div); + }); + + bottomSheet.classList.add("open"); +} + +// Chiudi il bottom sheet +function closeBottomSheet() { + bottomSheet.classList.remove("open"); +} + +// Chiudi cliccando fuori dal bottom sheet +document.addEventListener("click", (e) => { + if (!bottomSheet.classList.contains("open")) return; + + const clickedInside = bottomSheet.contains(e.target); + const clickedMarker = e.target.closest(".photo-marker, .photo-cluster"); + + if (!clickedInside && !clickedMarker) { + closeBottomSheet(); + } +}); diff --git a/js/mapGlobal.js b/js/mapGlobal.js index c8017f7..e233625 100644 --- a/js/mapGlobal.js +++ b/js/mapGlobal.js @@ -1,5 +1,5 @@ // =============================== -// MAPPA GLOBALE (marker personalizzati) +// MAPPA GLOBALE (marker personalizzati + bottom sheet) // =============================== document.getElementById("openMapBtn").addEventListener("click", openGlobalMap); @@ -10,15 +10,18 @@ function openGlobalMap() { const isOpen = mapDiv.classList.contains("open"); + // Toggle mappa if (isOpen) { mapDiv.classList.remove("open"); gallery.classList.remove("hidden"); + closeBottomSheet(); return; } mapDiv.classList.add("open"); gallery.classList.add("hidden"); + // Inizializza solo la prima volta if (!globalMap) { globalMap = L.map("globalMap").setView([42.5, 12.5], 6); @@ -26,11 +29,13 @@ function openGlobalMap() { maxZoom: 19 }).addTo(globalMap); + // =============================== // CLUSTER PERSONALIZZATI + // =============================== globalMarkers = L.markerClusterGroup({ iconCreateFunction: function (cluster) { const markers = cluster.getAllChildMarkers(); - const representative = markers[0].photoData; // la prima foto del gruppo + const representative = markers[0].photoData; return L.divIcon({ html: ` @@ -47,7 +52,19 @@ function openGlobalMap() { globalMap.addLayer(globalMarkers); + // =============================== + // CLICK SUI CLUSTER → BOTTOM SHEET + // =============================== + globalMarkers.on("clusterclick", function (a) { + const markers = a.layer.getAllChildMarkers(); + const photos = markers.map(m => m.photoData); + + openBottomSheet(photos); + }); + + // =============================== // MARKER SINGOLI PERSONALIZZATI + // =============================== photosData.forEach(photo => { if (!photo.gps || !photo.gps.lat || !photo.gps.lng) return; @@ -65,23 +82,18 @@ function openGlobalMap() { icon: markerIcon }); - // Salviamo i dati della foto nel marker (serve per il cluster) + // Salviamo i dati della foto nel marker marker.photoData = photo; + // CLICK SU MARKER → BOTTOM SHEET CON 1 FOTO marker.on("click", () => { - // QUI poi apriremo il pannello inferiore - openModal( - `https://prova.patachina.it/${photo.path}`, - photo.thub2 - ? `https://prova.patachina.it/${photo.thub2}` - : `https://prova.patachina.it/${photo.thub1}`, - photo - ); + openBottomSheet([photo]); }); globalMarkers.addLayer(marker); }); } + // Fix dimensioni mappa setTimeout(() => globalMap.invalidateSize(), 200); } diff --git a/style.css b/style.css index cdb229c..cad5927 100644 --- a/style.css +++ b/style.css @@ -271,3 +271,73 @@ header { object-fit: cover; box-shadow: 0 2px 6px rgba(0,0,0,0.35); } +/* =============================== + BOTTOM SHEET (Google Photos Web) + =============================== */ + +.bottom-sheet { + position: fixed; + bottom: 0; + left: 0; + width: 100%; + height: 140px; + background: rgba(255,255,255,0.95); + backdrop-filter: blur(6px); + border-top: 1px solid #ddd; + box-shadow: 0 -2px 10px rgba(0,0,0,0.15); + display: none; + flex-direction: column; + z-index: 9999; +} + +.bottom-sheet.open { + display: flex; +} + +.sheet-header { + height: 12px; + display: flex; + justify-content: center; + align-items: center; +} + +.sheet-header::before { + content: ""; + width: 40px; + height: 4px; + background: #bbb; + border-radius: 4px; +} + +.sheet-gallery { + display: flex; + flex-direction: row; + overflow-x: auto; + padding: 10px; + gap: 10px; +} + +.sheet-gallery::-webkit-scrollbar { + height: 6px; +} + +.sheet-gallery::-webkit-scrollbar-thumb { + background: #ccc; + border-radius: 3px; +} + +.sheet-item { + width: 90px; + height: 90px; + border-radius: 10px; + overflow: hidden; + flex-shrink: 0; + box-shadow: 0 2px 6px rgba(0,0,0,0.25); + background: #eee; +} + +.sheet-item img { + width: 100%; + height: 100%; + object-fit: cover; +}