my_gallery/js/mapGlobal.js
2026-02-21 23:50:21 +01:00

172 lines
5 KiB
JavaScript

// ===============================
// MAPPA GLOBALE (marker personalizzati + bottom sheet + cluster intelligenti)
// ===============================
document.getElementById("openMapBtn").addEventListener("click", openGlobalMap);
function openGlobalMap() {
const mapDiv = document.getElementById("globalMap");
const gallery = document.getElementById("gallery");
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);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19
}).addTo(globalMap);
// ===============================
// FUNZIONE: calcola luminosità miniatura
// ===============================
function getBrightness(photo) {
return new Promise(resolve => {
const img = new Image();
img.crossOrigin = "anonymous";
img.src = `https://prova.patachina.it/${photo.thub1}`;
img.onload = () => {
const canvas = document.createElement("canvas");
canvas.width = 20;
canvas.height = 20;
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, 20, 20);
const data = ctx.getImageData(0, 0, 20, 20).data;
let total = 0;
for (let i = 0; i < data.length; i += 4) {
total += (data[i] + data[i + 1] + data[i + 2]) / 3;
}
resolve(total / (20 * 20));
};
img.onerror = () => resolve(0);
});
}
// ===============================
// FUNZIONE: sceglie la foto migliore (recenti + luminosa)
// ===============================
async function chooseBestRepresentative(photos) {
// Ordina per data
photos.sort((a, b) => new Date(b.taken_at) - new Date(a.taken_at));
// Prendi le 3 più recenti
const candidates = photos.slice(0, 3);
// Calcola luminosità
const brightnessValues = await Promise.all(
candidates.map(p => getBrightness(p))
);
// Trova la più luminosa
let bestIndex = 0;
let bestValue = brightnessValues[0];
for (let i = 1; i < brightnessValues.length; i++) {
if (brightnessValues[i] > bestValue) {
bestValue = brightnessValues[i];
bestIndex = i;
}
}
return candidates[bestIndex];
}
// ===============================
// CLUSTER PERSONALIZZATI
// ===============================
globalMarkers = L.markerClusterGroup({
iconCreateFunction: function (cluster) {
const markers = cluster.getAllChildMarkers();
const photos = markers.map(m => m.photoData);
// Mostra SUBITO la più recente (velocissimo)
photos.sort((a, b) => new Date(b.taken_at) - new Date(a.taken_at));
const representative = photos[0];
// Aggiorna in background con la più luminosa
chooseBestRepresentative(photos).then(best => {
const icon = cluster._icon;
if (!icon) return;
const back = icon.querySelector(".cluster-back");
const front = icon.querySelector(".cluster-front");
if (back) back.src = `https://prova.patachina.it/${best.thub1}`;
if (front) front.src = `https://prova.patachina.it/${best.thub1}`;
});
return L.divIcon({
html: `
<div class="photo-cluster">
<img class="cluster-back" src="https://prova.patachina.it/${representative.thub1}">
<img class="cluster-front" src="https://prova.patachina.it/${representative.thub1}">
</div>
`,
className: "",
iconSize: [56, 56]
});
}
});
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;
const markerIcon = L.divIcon({
html: `
<div class="photo-marker">
<img src="https://prova.patachina.it/${photo.thub1}">
</div>
`,
className: "",
iconSize: [48, 48]
});
const marker = L.marker([photo.gps.lat, photo.gps.lng], {
icon: markerIcon
});
marker.photoData = photo;
marker.on("click", () => {
openBottomSheet([photo]);
});
globalMarkers.addLayer(marker);
});
}
// Fix dimensioni mappa
setTimeout(() => globalMap.invalidateSize(), 200);
}