172 lines
5 KiB
JavaScript
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);
|
|
}
|