document.addEventListener("DOMContentLoaded", function () { // Funzione per caricare il contenuto del popup async function loadPopupContent(iddatadb) { const popupContent = document.getElementById("popupContent"); if (!popupContent) { console.error("Elemento popupContent non trovato"); return; } try { console.log("Caricamento contenuto per iddatadb:", iddatadb); const response = await fetch( `photos_popup.php?iddatadb=${iddatadb}`, ); if (!response.ok) throw new Error("Errore nella risposta del server"); popupContent.innerHTML = await response.text(); attachPhotoEventListeners(iddatadb); } catch (error) { popupContent.innerHTML = `
Errore durante il caricamento: ${error.message}
`; console.error("Errore in loadPopupContent:", error); } } // Funzione per gestire la webcam function setupWebcam(iddatadb) { const openWebcamBtn = document.getElementById("openWebcamBtn"); const webcamArea = document.getElementById("webcamArea"); const webcamVideo = document.getElementById("webcamVideo"); const captureBtn = document.getElementById("captureBtn"); const closeWebcamBtn = document.getElementById("closeWebcamBtn"); const webcamSelect = document.getElementById("webcamSelect"); let stream = null; if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) { console.warn("La webcam non è supportata dal browser."); if (openWebcamBtn) openWebcamBtn.style.display = "none"; return; } if ( !openWebcamBtn || !webcamArea || !webcamVideo || !captureBtn || !closeWebcamBtn || !webcamSelect ) { console.error("Elementi webcam mancanti", { openWebcamBtn, webcamArea, webcamVideo, captureBtn, closeWebcamBtn, webcamSelect, }); return; } // Funzione per avviare la webcam con un deviceId specifico async function startWebcam(deviceId = null) { try { // Ferma il flusso video esistente, se presente if (stream) { stream.getTracks().forEach((track) => track.stop()); stream = null; webcamVideo.srcObject = null; } // Configura i vincoli per getUserMedia const constraints = { video: deviceId ? { deviceId: { exact: deviceId } } : true, }; // Avvia il flusso video stream = await navigator.mediaDevices.getUserMedia(constraints); webcamVideo.srcObject = stream; webcamArea.style.display = "block"; openWebcamBtn.style.display = "none"; dropArea.style.display = "none"; } catch (error) { console.error("Errore nell'accesso alla webcam:", error); alert("Errore nell'accesso alla webcam: " + error.message); webcamArea.style.display = "none"; openWebcamBtn.style.display = "block"; dropArea.style.display = "block"; } } // Funzione per popolare il dropdown delle webcam async function populateWebcamSelect() { try { // Richiedi i permessi per accedere ai dispositivi await navigator.mediaDevices.getUserMedia({ video: true }); const devices = await navigator.mediaDevices.enumerateDevices(); const videoDevices = devices.filter( (device) => device.kind === "videoinput", ); // Svuota il dropdown webcamSelect.innerHTML = ''; // Popola il dropdown con le webcam disponibili videoDevices.forEach((device) => { const option = document.createElement("option"); option.value = device.deviceId; option.text = device.label || `Webcam ${webcamSelect.options.length}`; webcamSelect.appendChild(option); }); // Mostra il dropdown solo se ci sono più webcam webcamSelect.style.display = videoDevices.length > 1 ? "block" : "none"; // Avvia la webcam predefinita se ce n'è almeno una if (videoDevices.length > 0) { await startWebcam(videoDevices[0].deviceId); } else { alert("Nessuna webcam rilevata."); webcamArea.style.display = "none"; openWebcamBtn.style.display = "block"; dropArea.style.display = "block"; } } catch (error) { console.error("Errore nel recupero dei dispositivi:", error); alert("Errore nel recupero dei dispositivi: " + error.message); webcamSelect.style.display = "none"; } } // Apri la webcam e popola il dropdown openWebcamBtn.addEventListener("click", async () => { await populateWebcamSelect(); }); // Gestisci il cambio della webcam selezionata webcamSelect.addEventListener("change", async (e) => { const deviceId = e.target.value; if (deviceId) { await startWebcam(deviceId); } }); // Chiudi la webcam closeWebcamBtn.addEventListener("click", () => { if (stream) { stream.getTracks().forEach((track) => track.stop()); stream = null; webcamVideo.srcObject = null; } webcamArea.style.display = "none"; openWebcamBtn.style.display = "block"; dropArea.style.display = "block"; }); // Cattura la foto captureBtn.addEventListener("click", () => { const canvas = document.createElement("canvas"); canvas.width = webcamVideo.videoWidth; canvas.height = webcamVideo.videoHeight; canvas .getContext("2d") .drawImage(webcamVideo, 0, 0, canvas.width, canvas.height); canvas.toBlob(async (blob) => { const file = new File( [blob], `webcam_photo_${Date.now()}.jpg`, { type: "image/jpeg" }, ); const loader = document.getElementById("loader"); if (loader) { console.log("Mostro loader per upload webcam"); loader.style.display = "flex"; } await handleFiles([file], iddatadb); if (stream) { stream.getTracks().forEach((track) => track.stop()); stream = null; webcamVideo.srcObject = null; } webcamArea.style.display = "none"; openWebcamBtn.style.display = "block"; dropArea.style.display = "block"; }, "image/jpeg"); }); } // Funzione per gestire il caricamento dei file async function handleFiles(files, iddatadb) { const loader = document.getElementById("loader"); if (!loader) { console.error("Elemento loader non trovato"); return; } if (!files || files.length === 0) { console.warn("Nessun file da caricare"); return; } for (const file of files) { if (!file.type.startsWith("image/")) { alert("Per favore, carica solo immagini!"); continue; } console.log("Inizio upload del file:", file.name); loader.style.display = "flex"; const formData = new FormData(); formData.append("photo", file); formData.append("iddatadb", iddatadb); try { const response = await fetch("upload_photo.php", { method: "POST", body: formData, }); const result = await response.json(); if (result.success) { console.log( "Upload completato con successo, ricarico popup", ); loadPopupContent(iddatadb); } else { alert("Errore durante il caricamento: " + result.message); } } catch (error) { alert("Errore durante il caricamento: " + error.message); } finally { console.log("Nascondo loader dopo upload"); loader.style.display = "none"; } } } // Funzione per attaccare gli event listener al contenuto del popup function attachPhotoEventListeners(iddatadb) { const dropArea = document.getElementById("dropArea"); const photoInput = document.getElementById("photoInput"); const photosModal = document.getElementById("photosModal"); if (!dropArea || !photoInput || !photosModal) { console.error("Elementi mancanti:", { dropArea, photoInput, photosModal, }); return; } console.log("Event listener associati per iddatadb:", iddatadb); // Gestione drag-and-drop const preventDefaults = (e) => { e.preventDefault(); e.stopPropagation(); }; ["dragenter", "dragover", "dragleave", "drop"].forEach((eventName) => { dropArea.addEventListener(eventName, preventDefaults, false); }); ["dragenter", "dragover"].forEach((eventName) => { dropArea.addEventListener( eventName, () => dropArea.classList.add("highlight"), false, ); }); ["dragleave", "drop"].forEach((eventName) => { dropArea.addEventListener( eventName, () => dropArea.classList.remove("highlight"), false, ); }); dropArea.addEventListener( "drop", (e) => { console.log("Evento drop attivato"); const files = e.dataTransfer.files; if (files.length > 0) { handleFiles(files, iddatadb); } }, false, ); dropArea.addEventListener( "click", () => { console.log("Click su dropArea, apro input file"); photoInput.click(); }, false, ); photoInput.addEventListener( "change", (e) => { console.log("Evento change su photoInput"); const files = e.target.files; if (files.length > 0) { handleFiles(files, iddatadb); } // Resetta l'input per consentire il caricamento dello stesso file e.target.value = ""; }, false, ); // Gestione rimozione foto document.querySelectorAll(".delete-photo-btn").forEach((button) => { button.addEventListener("click", async function () { const photoId = this.getAttribute("data-photo-id"); if (confirm("Sei sicuro di voler eliminare questa foto?")) { try { const response = await fetch("delete_photo.php", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", }, body: `photo_id=${photoId}`, }); const result = await response.json(); if (result.success) { console.log( "Foto eliminata con successo, ricarico popup", ); loadPopupContent(iddatadb); } else { alert( "Errore durante l'eliminazione: " + result.message, ); } } catch (error) { alert( "Errore durante l'eliminazione: " + error.message, ); } } }); }); // Gestione ingrandimento immagini document.querySelectorAll(".thumbnail").forEach((img) => { img.addEventListener("click", function () { console.log("Click su thumbnail, apro modale immagine"); const enlargedImage = document.getElementById("enlargedImage"); enlargedImage.src = this.src; document.getElementById("imageModal").style.display = "block"; }); }); // Gestione chiusura modale immagine const imageCloseBtn = document.querySelector(".image-modal-close"); if (imageCloseBtn) { imageCloseBtn.addEventListener("click", () => { console.log("Chiusura modale immagine"); document.getElementById("imageModal").style.display = "none"; }); } document .getElementById("imageModal") .addEventListener("click", function (event) { if (event.target === this) { console.log( "Chiusura modale immagine cliccando sullo sfondo", ); this.style.display = "none"; } }); // Inizializza la gestione della webcam setupWebcam(iddatadb); // Gestione bottone Crea Collage const createCollageBtn = document.getElementById("createCollageBtn"); if (createCollageBtn) { createCollageBtn.addEventListener("click", () => { console.log("Apertura modale collage"); document.getElementById("collageModal").style.display = "block"; initCollageCanvas(); }); } // Chiusura modale collage const closeCollageBtn = document.querySelector(".close-collage"); if (closeCollageBtn) { closeCollageBtn.addEventListener("click", () => { console.log("Chiusura modale collage"); document.getElementById("collageModal").style.display = "none"; if (isCropping) { console.log( "Chiusura modale durante ritaglio, esco dalla modalità ritaglio", ); exitCropMode(); } }); } // Inizializza canvas con Fabric.js let canvas; let cropRect = null; let isCropping = false; let croppedImage = null; // Memorizza l'immagine da ritagliare let isApplyingCrop = false; // Flag per prevenire duplicazioni function initCollageCanvas() { if (typeof fabric === "undefined") { console.error("Fabric.js non è caricato!"); alert( "Errore: Fabric.js non è disponibile. Controlla la connessione al CDN.", ); return; } canvas = new fabric.Canvas("collageCanvas", { backgroundColor: "#fff", selection: true, }); // Imposta stile globale per i controlli fabric.Object.prototype.set({ cornerColor: "black", cornerStrokeColor: "black", cornerSize: 12, borderColor: "black", transparentCorners: false, }); // Abilita ridimensionamento e trascinamento canvas.on("object:modified", () => { console.log("Oggetto modificato nel canvas"); canvas.renderAll(); }); // Gestisci selezione per abilitare/disabilitare pulsanti di ritaglio canvas.on("selection:created", () => { console.log("Evento selection:created triggerato"); updateCropButtons(); }); canvas.on("selection:updated", () => { console.log("Evento selection:updated triggerato"); updateCropButtons(); }); canvas.on("selection:cleared", () => { console.log("Evento selection:cleared triggerato"); if (!isCropping) { updateCropButtons(); } else { console.log( "Ignoro selection:cleared perché in modalità ritaglio", ); if (cropRect) { canvas.setActiveObject(cropRect); // Ripristina selezione del rettangolo canvas.renderAll(); } } }); // Forza un aggiornamento iniziale dei pulsanti updateCropButtons(); } // Aggiorna stato dei pulsanti di ritaglio function updateCropButtons() { const cropBtn = document.getElementById("cropImageBtn"); const applyCropBtn = document.getElementById("applyCropBtn"); const cancelCropBtn = document.getElementById("cancelCropBtn"); const activeObject = canvas.getActiveObject(); console.log( "updateCropButtons: activeObject =", activeObject ? activeObject.type : null, "isCropping =", isCropping, ); if (isCropping && cropRect) { console.log( "Modo ritaglio attivo, applyCropBtn e cancelCropBtn abilitati", ); cropBtn.disabled = true; applyCropBtn.disabled = false; if (cancelCropBtn) cancelCropBtn.disabled = false; } else if ( activeObject && activeObject.type === "image" && !isCropping ) { console.log("Abilitazione cropImageBtn"); cropBtn.disabled = false; applyCropBtn.disabled = true; if (cancelCropBtn) cancelCropBtn.disabled = true; } else { console.log( "Disabilitazione cropImageBtn, applyCropBtn e cancelCropBtn", ); cropBtn.disabled = true; applyCropBtn.disabled = true; if (cancelCropBtn) cancelCropBtn.disabled = true; } } // Entra in modalità ritaglio function enterCropMode() { const activeObject = canvas.getActiveObject(); if (!activeObject || activeObject.type !== "image") { console.warn("Nessuna immagine selezionata per il ritaglio"); alert("Seleziona un'immagine prima di attivare il ritaglio!"); return; } console.log( "Entrata in modalità ritaglio per immagine:", activeObject, ); isCropping = true; croppedImage = activeObject; // Memorizza l'immagine da ritagliare canvas.discardActiveObject(); // Deseleziona l'immagine // Crea un rettangolo di ritaglio cropRect = new fabric.Rect({ left: activeObject.left, top: activeObject.top, width: activeObject.width * activeObject.scaleX * 0.5, height: activeObject.height * activeObject.scaleY * 0.5, fill: "rgba(0, 0, 0, 0.3)", stroke: "red", strokeWidth: 2, hasBorders: true, hasControls: true, lockRotation: true, selectable: true, cornerColor: "black", cornerStrokeColor: "black", cornerSize: 12, borderColor: "black", transparentCorners: false, }); canvas.add(cropRect); canvas.setActiveObject(cropRect); canvas.renderAll(); document.getElementById("cropImageBtn").disabled = true; document.getElementById("applyCropBtn").disabled = false; const cancelCropBtn = document.getElementById("cancelCropBtn"); if (cancelCropBtn) cancelCropBtn.disabled = false; console.log("Rettangolo di ritaglio creato e applicato"); } // Esci dalla modalità ritaglio function exitCropMode() { if (cropRect) { console.log("Rimozione rettangolo di ritaglio"); canvas.remove(cropRect); cropRect = null; } isCropping = false; croppedImage = null; isApplyingCrop = false; canvas.discardActiveObject(); canvas.renderAll(); updateCropButtons(); console.log("Uscita dalla modalità ritaglio"); } // Applica il ritaglio function applyCrop() { if (isApplyingCrop) { console.log("applyCrop già in esecuzione, ignoro chiamata"); return; } console.log("applyCrop chiamato, stato:", { isCropping, cropRect: !!cropRect, croppedImage: !!croppedImage, }); if (!isCropping || !cropRect || !croppedImage) { console.warn("Condizioni per il ritaglio non soddisfatte", { isCropping, cropRect: !!cropRect, croppedImage: !!croppedImage, }); alert( "Nessun rettangolo di ritaglio attivo o immagine selezionata!", ); exitCropMode(); return; } isApplyingCrop = true; console.log("Applicazione ritaglio all'immagine:", croppedImage); const img = croppedImage; const cropX = (cropRect.left - img.left) / img.scaleX; const cropY = (cropRect.top - img.top) / img.scaleY; const cropWidth = cropRect.width / img.scaleX; const cropHeight = cropRect.height / img.scaleY; // Crea un'immagine ritagliata fabric.Image.fromURL( img.getSrc(), (newImg) => { newImg.set({ left: cropRect.left, top: cropRect.top, scaleX: img.scaleX, scaleY: img.scaleY, cropX: cropX, cropY: cropY, width: cropWidth, height: cropHeight, hasControls: true, hasBorders: true, cornerColor: "black", cornerStrokeColor: "black", cornerSize: 12, borderColor: "black", transparentCorners: false, }); canvas.remove(img); // Rimuovi l'immagine originale canvas.remove(cropRect); // Rimuovi il rettangolo di ritaglio canvas.add(newImg); // Aggiungi l'immagine ritagliata canvas.setActiveObject(newImg); exitCropMode(); canvas.renderAll(); console.log("Ritaglio applicato con successo"); }, { crossOrigin: "anonymous" }, ); } // Aggiungi foto selezionate al canvas const addToCanvasBtn = document.getElementById("addToCanvasBtn"); if (addToCanvasBtn) { addToCanvasBtn.addEventListener("click", () => { const checkboxes = document.querySelectorAll( ".photo-checkbox:checked", ); if (checkboxes.length === 0) { alert("Seleziona almeno una foto!"); return; } checkboxes.forEach((cb) => { const imgPath = cb.getAttribute("data-path"); fabric.Image.fromURL( imgPath, (img) => { img.set({ left: Math.random() * 600, // Posizione random iniziale top: Math.random() * 400, scaleX: 0.5, // Scala iniziale scaleY: 0.5, hasControls: true, // Abilita resize/rotate hasBorders: true, cornerColor: "black", cornerStrokeColor: "black", cornerSize: 12, borderColor: "black", transparentCorners: false, }); canvas.add(img); canvas.renderAll(); console.log( "Immagine aggiunta al canvas:", imgPath, ); }, { crossOrigin: "anonymous" }, ); }); // Deseleziona checkbox dopo aggiunta checkboxes.forEach((cb) => (cb.checked = false)); }); } // Salva collage const saveCollageBtn = document.getElementById("saveCollageBtn"); if (saveCollageBtn) { saveCollageBtn.addEventListener("click", async () => { if (canvas.getObjects().length === 0) { alert("Il canvas è vuoto! Aggiungi almeno una foto."); return; } const dataURL = canvas.toDataURL({ format: "jpeg", quality: 0.8, }); const blob = await (await fetch(dataURL)).blob(); const file = new File([blob], `collage_${Date.now()}.jpg`, { type: "image/jpeg", }); // Upload come nuova foto await handleFiles([file], iddatadb); // Chiudi modale e ricarica popup document.getElementById("collageModal").style.display = "none"; loadPopupContent(iddatadb); console.log("Collage salvato e modale chiuso"); }); } // Pulisci canvas const clearCanvasBtn = document.getElementById("clearCanvasBtn"); if (clearCanvasBtn) { clearCanvasBtn.addEventListener("click", () => { canvas.clear(); canvas.setBackgroundColor("#fff"); canvas.renderAll(); console.log("Canvas pulito"); }); } // Gestione livelli delle immagini const bringToFrontBtn = document.getElementById("bringToFrontBtn"); if (bringToFrontBtn) { bringToFrontBtn.addEventListener("click", () => { const activeObject = canvas.getActiveObject(); if (activeObject) { canvas.bringToFront(activeObject); canvas.renderAll(); console.log("Oggetto portato in primo piano"); } else { alert("Seleziona un'immagine sul canvas!"); } }); } const sendToBackBtn = document.getElementById("sendToBackBtn"); if (sendToBackBtn) { sendToBackBtn.addEventListener("click", () => { const activeObject = canvas.getActiveObject(); if (activeObject) { canvas.sendToBack(activeObject); canvas.renderAll(); console.log("Oggetto mandato in fondo"); } else { alert("Seleziona un'immagine sul canvas!"); } }); } const bringForwardBtn = document.getElementById("bringForwardBtn"); if (bringForwardBtn) { bringForwardBtn.addEventListener("click", () => { const activeObject = canvas.getActiveObject(); if (activeObject) { canvas.bringForward(activeObject); canvas.renderAll(); console.log("Oggetto spostato avanti di un livello"); } else { alert("Seleziona un'immagine sul canvas!"); } }); } const sendBackwardBtn = document.getElementById("sendBackwardBtn"); if (sendBackwardBtn) { sendBackwardBtn.addEventListener("click", () => { const activeObject = canvas.getActiveObject(); if (activeObject) { canvas.sendBackwards(activeObject); canvas.renderAll(); console.log("Oggetto spostato indietro di un livello"); } else { alert("Seleziona un'immagine sul canvas!"); } }); } // Gestione ritaglio immagini const cropImageBtn = document.getElementById("cropImageBtn"); if (cropImageBtn) { cropImageBtn.addEventListener("click", () => { console.log("Pulsante Ritaglia cliccato"); enterCropMode(); }); } const applyCropBtn = document.getElementById("applyCropBtn"); if (applyCropBtn) { applyCropBtn.addEventListener("click", () => { console.log("Pulsante Applica Ritaglio cliccato"); applyCrop(); }); } // Gestione pulsante Annulla Ritaglio const cancelCropBtn = document.getElementById("cancelCropBtn"); if (cancelCropBtn) { cancelCropBtn.addEventListener("click", () => { console.log("Pulsante Annulla Ritaglio cliccato"); exitCropMode(); }); } // Assicurati che il loader sia nascosto all'apertura del popup const loader = document.getElementById("loader"); if (loader) { console.log("Nascondo loader all'apertura del popup"); loader.style.display = "none"; } } // Gestione del pulsante Photos const photosButtons = document.querySelectorAll(".photos-btn"); const photosModal = document.getElementById("photosModal"); const closeBtn = document.querySelector(".close-btn"); if (photosButtons.length && photosModal && closeBtn) { photosButtons.forEach((button) => { button.addEventListener("click", function () { console.log( "Pulsante Photos cliccato per iddatadb:", this.getAttribute("data-iddatadb"), ); const iddatadb = this.getAttribute("data-iddatadb"); loadPopupContent(iddatadb); photosModal.style.display = "block"; document.querySelector(".overlay").style.display = "none"; }); }); closeBtn.addEventListener("click", function () { console.log("Chiusura modale photos"); photosModal.style.display = "none"; document.querySelector(".overlay").style.display = "none"; document.body.style.pointerEvents = "auto"; }); window.addEventListener("click", function (event) { if (event.target === photosModal) { console.log("Chiusura modale photos cliccando sullo sfondo"); photosModal.style.display = "none"; document.querySelector(".overlay").style.display = "none"; document.body.style.pointerEvents = "auto"; } }); } else { console.error("Elementi mancanti:", { photosButtons, photosModal, closeBtn, }); } });