added level to collahge
This commit is contained in:
File diff suppressed because one or more lines are too long
+108
-234
@@ -7,7 +7,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
console.log("Caricamento contenuto per iddatadb:", iddatadb);
|
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`photos_popup.php?iddatadb=${iddatadb}`,
|
`photos_popup.php?iddatadb=${iddatadb}`,
|
||||||
);
|
);
|
||||||
@@ -56,22 +55,18 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Funzione per avviare la webcam con un deviceId specifico
|
|
||||||
async function startWebcam(deviceId = null) {
|
async function startWebcam(deviceId = null) {
|
||||||
try {
|
try {
|
||||||
// Ferma il flusso video esistente, se presente
|
|
||||||
if (stream) {
|
if (stream) {
|
||||||
stream.getTracks().forEach((track) => track.stop());
|
stream.getTracks().forEach((track) => track.stop());
|
||||||
stream = null;
|
stream = null;
|
||||||
webcamVideo.srcObject = null;
|
webcamVideo.srcObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configura i vincoli per getUserMedia
|
|
||||||
const constraints = {
|
const constraints = {
|
||||||
video: deviceId ? { deviceId: { exact: deviceId } } : true,
|
video: deviceId ? { deviceId: { exact: deviceId } } : true,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Avvia il flusso video
|
|
||||||
stream = await navigator.mediaDevices.getUserMedia(constraints);
|
stream = await navigator.mediaDevices.getUserMedia(constraints);
|
||||||
webcamVideo.srcObject = stream;
|
webcamVideo.srcObject = stream;
|
||||||
webcamArea.style.display = "block";
|
webcamArea.style.display = "block";
|
||||||
@@ -86,21 +81,17 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Funzione per popolare il dropdown delle webcam
|
|
||||||
async function populateWebcamSelect() {
|
async function populateWebcamSelect() {
|
||||||
try {
|
try {
|
||||||
// Richiedi i permessi per accedere ai dispositivi
|
|
||||||
await navigator.mediaDevices.getUserMedia({ video: true });
|
await navigator.mediaDevices.getUserMedia({ video: true });
|
||||||
const devices = await navigator.mediaDevices.enumerateDevices();
|
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||||
const videoDevices = devices.filter(
|
const videoDevices = devices.filter(
|
||||||
(device) => device.kind === "videoinput",
|
(device) => device.kind === "videoinput",
|
||||||
);
|
);
|
||||||
|
|
||||||
// Svuota il dropdown
|
|
||||||
webcamSelect.innerHTML =
|
webcamSelect.innerHTML =
|
||||||
'<option value="">Select a webcam</option>';
|
'<option value="">Select a webcam</option>';
|
||||||
|
|
||||||
// Popola il dropdown con le webcam disponibili
|
|
||||||
videoDevices.forEach((device) => {
|
videoDevices.forEach((device) => {
|
||||||
const option = document.createElement("option");
|
const option = document.createElement("option");
|
||||||
option.value = device.deviceId;
|
option.value = device.deviceId;
|
||||||
@@ -109,11 +100,9 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
webcamSelect.appendChild(option);
|
webcamSelect.appendChild(option);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mostra il dropdown solo se ci sono più webcam
|
|
||||||
webcamSelect.style.display =
|
webcamSelect.style.display =
|
||||||
videoDevices.length > 1 ? "block" : "none";
|
videoDevices.length > 1 ? "block" : "none";
|
||||||
|
|
||||||
// Avvia la webcam predefinita se ce n'è almeno una
|
|
||||||
if (videoDevices.length > 0) {
|
if (videoDevices.length > 0) {
|
||||||
await startWebcam(videoDevices[0].deviceId);
|
await startWebcam(videoDevices[0].deviceId);
|
||||||
} else {
|
} else {
|
||||||
@@ -129,12 +118,10 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apri la webcam e popola il dropdown
|
|
||||||
openWebcamBtn.addEventListener("click", async () => {
|
openWebcamBtn.addEventListener("click", async () => {
|
||||||
await populateWebcamSelect();
|
await populateWebcamSelect();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Gestisci il cambio della webcam selezionata
|
|
||||||
webcamSelect.addEventListener("change", async (e) => {
|
webcamSelect.addEventListener("change", async (e) => {
|
||||||
const deviceId = e.target.value;
|
const deviceId = e.target.value;
|
||||||
if (deviceId) {
|
if (deviceId) {
|
||||||
@@ -142,7 +129,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Chiudi la webcam
|
|
||||||
closeWebcamBtn.addEventListener("click", () => {
|
closeWebcamBtn.addEventListener("click", () => {
|
||||||
if (stream) {
|
if (stream) {
|
||||||
stream.getTracks().forEach((track) => track.stop());
|
stream.getTracks().forEach((track) => track.stop());
|
||||||
@@ -154,7 +140,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
dropArea.style.display = "block";
|
dropArea.style.display = "block";
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cattura la foto
|
|
||||||
captureBtn.addEventListener("click", () => {
|
captureBtn.addEventListener("click", () => {
|
||||||
const canvas = document.createElement("canvas");
|
const canvas = document.createElement("canvas");
|
||||||
canvas.width = webcamVideo.videoWidth;
|
canvas.width = webcamVideo.videoWidth;
|
||||||
@@ -171,7 +156,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
);
|
);
|
||||||
const loader = document.getElementById("loader");
|
const loader = document.getElementById("loader");
|
||||||
if (loader) {
|
if (loader) {
|
||||||
console.log("Mostro loader per upload webcam");
|
|
||||||
loader.style.display = "flex";
|
loader.style.display = "flex";
|
||||||
}
|
}
|
||||||
await handleFiles([file], iddatadb);
|
await handleFiles([file], iddatadb);
|
||||||
@@ -187,7 +171,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Funzione per gestire il caricamento dei file
|
|
||||||
async function handleFiles(files, iddatadb) {
|
async function handleFiles(files, iddatadb) {
|
||||||
const loader = document.getElementById("loader");
|
const loader = document.getElementById("loader");
|
||||||
if (!loader) {
|
if (!loader) {
|
||||||
@@ -206,7 +189,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Inizio upload del file:", file.name);
|
|
||||||
loader.style.display = "flex";
|
loader.style.display = "flex";
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
@@ -219,9 +201,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
});
|
});
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
console.log(
|
|
||||||
"Upload completato con successo, ricarico popup",
|
|
||||||
);
|
|
||||||
loadPopupContent(iddatadb);
|
loadPopupContent(iddatadb);
|
||||||
} else {
|
} else {
|
||||||
alert("Errore durante il caricamento: " + result.message);
|
alert("Errore durante il caricamento: " + result.message);
|
||||||
@@ -229,13 +208,11 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert("Errore durante il caricamento: " + error.message);
|
alert("Errore durante il caricamento: " + error.message);
|
||||||
} finally {
|
} finally {
|
||||||
console.log("Nascondo loader dopo upload");
|
|
||||||
loader.style.display = "none";
|
loader.style.display = "none";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Funzione per attaccare gli event listener al contenuto del popup
|
|
||||||
function attachPhotoEventListeners(iddatadb) {
|
function attachPhotoEventListeners(iddatadb) {
|
||||||
const dropArea = document.getElementById("dropArea");
|
const dropArea = document.getElementById("dropArea");
|
||||||
const photoInput = document.getElementById("photoInput");
|
const photoInput = document.getElementById("photoInput");
|
||||||
@@ -250,9 +227,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Event listener associati per iddatadb:", iddatadb);
|
|
||||||
|
|
||||||
// Gestione drag-and-drop
|
|
||||||
const preventDefaults = (e) => {
|
const preventDefaults = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -281,7 +255,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
dropArea.addEventListener(
|
dropArea.addEventListener(
|
||||||
"drop",
|
"drop",
|
||||||
(e) => {
|
(e) => {
|
||||||
console.log("Evento drop attivato");
|
|
||||||
const files = e.dataTransfer.files;
|
const files = e.dataTransfer.files;
|
||||||
if (files.length > 0) {
|
if (files.length > 0) {
|
||||||
handleFiles(files, iddatadb);
|
handleFiles(files, iddatadb);
|
||||||
@@ -293,7 +266,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
dropArea.addEventListener(
|
dropArea.addEventListener(
|
||||||
"click",
|
"click",
|
||||||
() => {
|
() => {
|
||||||
console.log("Click su dropArea, apro input file");
|
|
||||||
photoInput.click();
|
photoInput.click();
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
@@ -302,18 +274,15 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
photoInput.addEventListener(
|
photoInput.addEventListener(
|
||||||
"change",
|
"change",
|
||||||
(e) => {
|
(e) => {
|
||||||
console.log("Evento change su photoInput");
|
|
||||||
const files = e.target.files;
|
const files = e.target.files;
|
||||||
if (files.length > 0) {
|
if (files.length > 0) {
|
||||||
handleFiles(files, iddatadb);
|
handleFiles(files, iddatadb);
|
||||||
}
|
}
|
||||||
// Resetta l'input per consentire il caricamento dello stesso file
|
|
||||||
e.target.value = "";
|
e.target.value = "";
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Gestione rimozione foto
|
|
||||||
document.querySelectorAll(".delete-photo-btn").forEach((button) => {
|
document.querySelectorAll(".delete-photo-btn").forEach((button) => {
|
||||||
button.addEventListener("click", async function () {
|
button.addEventListener("click", async function () {
|
||||||
const photoId = this.getAttribute("data-photo-id");
|
const photoId = this.getAttribute("data-photo-id");
|
||||||
@@ -329,9 +298,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
});
|
});
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
console.log(
|
|
||||||
"Foto eliminata con successo, ricarico popup",
|
|
||||||
);
|
|
||||||
loadPopupContent(iddatadb);
|
loadPopupContent(iddatadb);
|
||||||
} else {
|
} else {
|
||||||
alert(
|
alert(
|
||||||
@@ -348,21 +314,17 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Gestione ingrandimento immagini
|
|
||||||
document.querySelectorAll(".thumbnail").forEach((img) => {
|
document.querySelectorAll(".thumbnail").forEach((img) => {
|
||||||
img.addEventListener("click", function () {
|
img.addEventListener("click", function () {
|
||||||
console.log("Click su thumbnail, apro modale immagine");
|
|
||||||
const enlargedImage = document.getElementById("enlargedImage");
|
const enlargedImage = document.getElementById("enlargedImage");
|
||||||
enlargedImage.src = this.src;
|
enlargedImage.src = this.src;
|
||||||
document.getElementById("imageModal").style.display = "block";
|
document.getElementById("imageModal").style.display = "block";
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Gestione chiusura modale immagine
|
|
||||||
const imageCloseBtn = document.querySelector(".image-modal-close");
|
const imageCloseBtn = document.querySelector(".image-modal-close");
|
||||||
if (imageCloseBtn) {
|
if (imageCloseBtn) {
|
||||||
imageCloseBtn.addEventListener("click", () => {
|
imageCloseBtn.addEventListener("click", () => {
|
||||||
console.log("Chiusura modale immagine");
|
|
||||||
document.getElementById("imageModal").style.display = "none";
|
document.getElementById("imageModal").style.display = "none";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -370,57 +332,42 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
.getElementById("imageModal")
|
.getElementById("imageModal")
|
||||||
.addEventListener("click", function (event) {
|
.addEventListener("click", function (event) {
|
||||||
if (event.target === this) {
|
if (event.target === this) {
|
||||||
console.log(
|
|
||||||
"Chiusura modale immagine cliccando sullo sfondo",
|
|
||||||
);
|
|
||||||
this.style.display = "none";
|
this.style.display = "none";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Inizializza la gestione della webcam
|
|
||||||
setupWebcam(iddatadb);
|
setupWebcam(iddatadb);
|
||||||
|
|
||||||
// Gestione bottone Crea Collage
|
|
||||||
const createCollageBtn = document.getElementById("createCollageBtn");
|
const createCollageBtn = document.getElementById("createCollageBtn");
|
||||||
if (createCollageBtn) {
|
if (createCollageBtn) {
|
||||||
createCollageBtn.addEventListener("click", () => {
|
createCollageBtn.addEventListener("click", () => {
|
||||||
console.log("Apertura modale collage");
|
|
||||||
document.getElementById("collageModal").style.display = "block";
|
document.getElementById("collageModal").style.display = "block";
|
||||||
initCollageCanvas();
|
initCollageCanvas();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chiusura modale collage
|
|
||||||
const closeCollageBtn = document.querySelector(".close-collage");
|
const closeCollageBtn = document.querySelector(".close-collage");
|
||||||
if (closeCollageBtn) {
|
if (closeCollageBtn) {
|
||||||
closeCollageBtn.addEventListener("click", () => {
|
closeCollageBtn.addEventListener("click", () => {
|
||||||
console.log("Chiusura modale collage");
|
|
||||||
document.getElementById("collageModal").style.display = "none";
|
document.getElementById("collageModal").style.display = "none";
|
||||||
if (isCropping) {
|
if (isCropping) {
|
||||||
console.log(
|
|
||||||
"Chiusura modale durante ritaglio, esco dalla modalità ritaglio",
|
|
||||||
);
|
|
||||||
exitCropMode();
|
exitCropMode();
|
||||||
}
|
}
|
||||||
if (isRemovingBackground) {
|
if (isRemovingBackground) {
|
||||||
console.log(
|
|
||||||
"Chiusura modale durante rimozione sfondo, esco dalla modalità",
|
|
||||||
);
|
|
||||||
exitBackgroundRemovalMode();
|
exitBackgroundRemovalMode();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inizializza canvas con Fabric.js
|
|
||||||
let canvas;
|
let canvas;
|
||||||
let cropRect = null;
|
let cropRect = null;
|
||||||
let isCropping = false;
|
let isCropping = false;
|
||||||
let croppedImage = null; // Memorizza l'immagine da ritagliare
|
let croppedImage = null;
|
||||||
let isApplyingCrop = false; // Flag per prevenire duplicazioni
|
let isApplyingCrop = false;
|
||||||
let isRemovingBackground = false; // Flag per modalità rimozione sfondo
|
let isRemovingBackground = false;
|
||||||
let backgroundRemovalImage = null; // Immagine in modalità rimozione sfondo
|
let backgroundRemovalImage = null;
|
||||||
let history = []; // Pila per salvare gli stati del canvas
|
let history = [];
|
||||||
const maxHistory = 20; // Limite massimo di stati nella pila
|
const maxHistory = 20;
|
||||||
|
|
||||||
function initCollageCanvas() {
|
function initCollageCanvas() {
|
||||||
if (typeof fabric === "undefined") {
|
if (typeof fabric === "undefined") {
|
||||||
@@ -434,7 +381,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
backgroundColor: "#fff",
|
backgroundColor: "#fff",
|
||||||
selection: true,
|
selection: true,
|
||||||
});
|
});
|
||||||
// Imposta stile globale per i controlli
|
|
||||||
fabric.Object.prototype.set({
|
fabric.Object.prototype.set({
|
||||||
cornerColor: "black",
|
cornerColor: "black",
|
||||||
cornerStrokeColor: "black",
|
cornerStrokeColor: "black",
|
||||||
@@ -442,63 +388,103 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
borderColor: "black",
|
borderColor: "black",
|
||||||
transparentCorners: false,
|
transparentCorners: false,
|
||||||
});
|
});
|
||||||
// Abilita ridimensionamento e trascinamento
|
|
||||||
canvas.on("object:modified", () => {
|
canvas.on("object:modified", () => {
|
||||||
console.log("Oggetto modificato nel canvas");
|
|
||||||
saveCanvasState();
|
saveCanvasState();
|
||||||
|
updateLayersPanel();
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
});
|
});
|
||||||
// Gestisci selezione per abilitare/disabilitare pulsanti
|
canvas.on("object:added", () => {
|
||||||
|
updateLayersPanel();
|
||||||
|
});
|
||||||
|
canvas.on("object:removed", () => {
|
||||||
|
updateLayersPanel();
|
||||||
|
});
|
||||||
canvas.on("selection:created", () => {
|
canvas.on("selection:created", () => {
|
||||||
console.log("Evento selection:created triggerato");
|
|
||||||
updateButtons();
|
updateButtons();
|
||||||
});
|
});
|
||||||
canvas.on("selection:updated", () => {
|
canvas.on("selection:updated", () => {
|
||||||
console.log("Evento selection:updated triggerato");
|
|
||||||
updateButtons();
|
updateButtons();
|
||||||
});
|
});
|
||||||
canvas.on("selection:cleared", () => {
|
canvas.on("selection:cleared", () => {
|
||||||
console.log("Evento selection:cleared triggerato");
|
|
||||||
if (!isCropping && !isRemovingBackground) {
|
if (!isCropping && !isRemovingBackground) {
|
||||||
updateButtons();
|
updateButtons();
|
||||||
} else if (isCropping && cropRect) {
|
} else if (isCropping && cropRect) {
|
||||||
console.log(
|
canvas.setActiveObject(cropRect);
|
||||||
"Ignoro selection:cleared perché in modalità ritaglio",
|
|
||||||
);
|
|
||||||
canvas.setActiveObject(cropRect); // Ripristina selezione del rettangolo
|
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
} else if (isRemovingBackground) {
|
} else if (isRemovingBackground) {
|
||||||
console.log(
|
canvas.setActiveObject(backgroundRemovalImage);
|
||||||
"Ignoro selection:cleared perché in modalità rimozione sfondo",
|
|
||||||
);
|
|
||||||
canvas.setActiveObject(backgroundRemovalImage); // Ripristina selezione dell'immagine
|
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Gestisci click sul canvas per la rimozione dello sfondo
|
|
||||||
canvas.on("mouse:down", (event) => {
|
canvas.on("mouse:down", (event) => {
|
||||||
if (isRemovingBackground && backgroundRemovalImage) {
|
if (isRemovingBackground && backgroundRemovalImage) {
|
||||||
console.log(
|
|
||||||
"Click sul canvas in modalità rimozione sfondo",
|
|
||||||
);
|
|
||||||
handleBackgroundColorSelection(event);
|
handleBackgroundColorSelection(event);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Salva lo stato iniziale del canvas
|
|
||||||
saveCanvasState();
|
saveCanvasState();
|
||||||
// Forza un aggiornamento iniziale dei pulsanti
|
updateLayersPanel();
|
||||||
updateButtons();
|
updateButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Salva lo stato del canvas nella pila
|
function updateLayersPanel() {
|
||||||
function saveCanvasState() {
|
const layersList = document.getElementById("layersList");
|
||||||
if (isCropping || isRemovingBackground) {
|
if (!layersList) {
|
||||||
console.log(
|
console.error("Elemento layersList non trovato");
|
||||||
"Non salvo lo stato perché in modalità ritaglio o rimozione sfondo",
|
return;
|
||||||
);
|
}
|
||||||
|
layersList.innerHTML = "";
|
||||||
|
|
||||||
|
const images = canvas.getObjects("image");
|
||||||
|
images.forEach((img, index) => {
|
||||||
|
let thumbSrc;
|
||||||
|
try {
|
||||||
|
const thumbCanvas = document.createElement("canvas");
|
||||||
|
thumbCanvas.width = 50;
|
||||||
|
thumbCanvas.height = 50;
|
||||||
|
const thumbFabric = new fabric.Canvas(thumbCanvas);
|
||||||
|
|
||||||
|
const clonedImg = fabric.util.object.clone(img);
|
||||||
|
const scaleFactor = Math.min(
|
||||||
|
50 / img.width,
|
||||||
|
50 / img.height,
|
||||||
|
);
|
||||||
|
clonedImg.scaleX = scaleFactor;
|
||||||
|
clonedImg.scaleY = scaleFactor;
|
||||||
|
clonedImg.left = (50 - img.width * scaleFactor) / 2;
|
||||||
|
clonedImg.top = (50 - img.height * scaleFactor) / 2;
|
||||||
|
clonedImg.setCoords();
|
||||||
|
thumbFabric.add(clonedImg);
|
||||||
|
thumbFabric.renderAll();
|
||||||
|
|
||||||
|
thumbSrc = thumbCanvas.toDataURL("image/png");
|
||||||
|
thumbFabric.dispose();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(
|
||||||
|
"Errore nella generazione della thumbnail per immagine",
|
||||||
|
index + 1,
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
thumbSrc = img.getSrc(); // Fallback all'URL originale
|
||||||
|
}
|
||||||
|
|
||||||
|
const layerItem = document.createElement("li");
|
||||||
|
const thumbImg = document.createElement("img");
|
||||||
|
thumbImg.src = thumbSrc;
|
||||||
|
thumbImg.title = `Layer ${index + 1}`;
|
||||||
|
thumbImg.addEventListener("click", () => {
|
||||||
|
canvas.setActiveObject(img);
|
||||||
|
canvas.renderAll();
|
||||||
|
});
|
||||||
|
|
||||||
|
layerItem.appendChild(thumbImg);
|
||||||
|
layersList.appendChild(layerItem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveCanvasState() {
|
||||||
|
if (isCropping || isRemovingBackground) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("Salvataggio stato del canvas");
|
|
||||||
const state = JSON.stringify(
|
const state = JSON.stringify(
|
||||||
canvas.toJSON([
|
canvas.toJSON([
|
||||||
"cornerColor",
|
"cornerColor",
|
||||||
@@ -510,26 +496,22 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
);
|
);
|
||||||
history.push(state);
|
history.push(state);
|
||||||
if (history.length > maxHistory) {
|
if (history.length > maxHistory) {
|
||||||
history.shift(); // Rimuovi lo stato più vecchio se superato il limite
|
history.shift();
|
||||||
}
|
}
|
||||||
console.log("Stato salvato, lunghezza pila:", history.length);
|
|
||||||
updateButtons();
|
updateButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ripristina l'ultimo stato del canvas
|
|
||||||
function undo() {
|
function undo() {
|
||||||
if (history.length <= 1) {
|
if (history.length <= 1) {
|
||||||
console.log("Nessuno stato da annullare");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("Annullamento ultima azione");
|
history.pop();
|
||||||
history.pop(); // Rimuovi lo stato corrente
|
|
||||||
const previousState = history[history.length - 1];
|
const previousState = history[history.length - 1];
|
||||||
if (previousState) {
|
if (previousState) {
|
||||||
canvas.clear();
|
canvas.clear();
|
||||||
canvas.loadFromJSON(previousState, () => {
|
canvas.loadFromJSON(previousState, () => {
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
console.log("Stato ripristinato");
|
updateLayersPanel();
|
||||||
updateButtons();
|
updateButtons();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -537,11 +519,11 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
canvas.clear();
|
canvas.clear();
|
||||||
canvas.setBackgroundColor("#fff");
|
canvas.setBackgroundColor("#fff");
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
|
updateLayersPanel();
|
||||||
updateButtons();
|
updateButtons();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aggiorna stato dei pulsanti
|
|
||||||
function updateButtons() {
|
function updateButtons() {
|
||||||
const cropBtn = document.getElementById("cropImageBtn");
|
const cropBtn = document.getElementById("cropImageBtn");
|
||||||
const applyCropBtn = document.getElementById("applyCropBtn");
|
const applyCropBtn = document.getElementById("applyCropBtn");
|
||||||
@@ -555,20 +537,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
"backgroundRemovalInstruction",
|
"backgroundRemovalInstruction",
|
||||||
);
|
);
|
||||||
const activeObject = canvas.getActiveObject();
|
const activeObject = canvas.getActiveObject();
|
||||||
console.log(
|
|
||||||
"updateButtons: activeObject =",
|
|
||||||
activeObject ? activeObject.type : null,
|
|
||||||
"isCropping =",
|
|
||||||
isCropping,
|
|
||||||
"isRemovingBackground =",
|
|
||||||
isRemovingBackground,
|
|
||||||
"history.length =",
|
|
||||||
history.length,
|
|
||||||
);
|
|
||||||
if (isCropping && cropRect) {
|
if (isCropping && cropRect) {
|
||||||
console.log(
|
|
||||||
"Modo ritaglio attivo, applyCropBtn e cancelCropBtn abilitati",
|
|
||||||
);
|
|
||||||
cropBtn.disabled = true;
|
cropBtn.disabled = true;
|
||||||
applyCropBtn.disabled = false;
|
applyCropBtn.disabled = false;
|
||||||
cancelCropBtn.disabled = false;
|
cancelCropBtn.disabled = false;
|
||||||
@@ -577,9 +546,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
undoBtn.disabled = true;
|
undoBtn.disabled = true;
|
||||||
instruction.style.display = "none";
|
instruction.style.display = "none";
|
||||||
} else if (isRemovingBackground && backgroundRemovalImage) {
|
} else if (isRemovingBackground && backgroundRemovalImage) {
|
||||||
console.log(
|
|
||||||
"Modo rimozione sfondo attivo, removeBackgroundBtn disabilitato",
|
|
||||||
);
|
|
||||||
cropBtn.disabled = true;
|
cropBtn.disabled = true;
|
||||||
applyCropBtn.disabled = true;
|
applyCropBtn.disabled = true;
|
||||||
cancelCropBtn.disabled = true;
|
cancelCropBtn.disabled = true;
|
||||||
@@ -593,9 +559,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
!isCropping &&
|
!isCropping &&
|
||||||
!isRemovingBackground
|
!isRemovingBackground
|
||||||
) {
|
) {
|
||||||
console.log(
|
|
||||||
"Abilitazione cropImageBtn, removeBackgroundBtn e removeImageBtn",
|
|
||||||
);
|
|
||||||
cropBtn.disabled = false;
|
cropBtn.disabled = false;
|
||||||
applyCropBtn.disabled = true;
|
applyCropBtn.disabled = true;
|
||||||
cancelCropBtn.disabled = true;
|
cancelCropBtn.disabled = true;
|
||||||
@@ -604,7 +567,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
undoBtn.disabled = history.length <= 1;
|
undoBtn.disabled = history.length <= 1;
|
||||||
instruction.style.display = "none";
|
instruction.style.display = "none";
|
||||||
} else {
|
} else {
|
||||||
console.log("Disabilitazione tutti i pulsanti");
|
|
||||||
cropBtn.disabled = true;
|
cropBtn.disabled = true;
|
||||||
applyCropBtn.disabled = true;
|
applyCropBtn.disabled = true;
|
||||||
cancelCropBtn.disabled = true;
|
cancelCropBtn.disabled = true;
|
||||||
@@ -615,7 +577,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entra in modalità ritaglio
|
|
||||||
function enterCropMode() {
|
function enterCropMode() {
|
||||||
const activeObject = canvas.getActiveObject();
|
const activeObject = canvas.getActiveObject();
|
||||||
if (!activeObject || activeObject.type !== "image") {
|
if (!activeObject || activeObject.type !== "image") {
|
||||||
@@ -623,14 +584,9 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
alert("Seleziona un'immagine prima di attivare il ritaglio!");
|
alert("Seleziona un'immagine prima di attivare il ritaglio!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log(
|
|
||||||
"Entrata in modalità ritaglio per immagine:",
|
|
||||||
activeObject,
|
|
||||||
);
|
|
||||||
isCropping = true;
|
isCropping = true;
|
||||||
croppedImage = activeObject; // Memorizza l'immagine da ritagliare
|
croppedImage = activeObject;
|
||||||
canvas.discardActiveObject(); // Deseleziona l'immagine
|
canvas.discardActiveObject();
|
||||||
// Crea un rettangolo di ritaglio
|
|
||||||
cropRect = new fabric.Rect({
|
cropRect = new fabric.Rect({
|
||||||
left: activeObject.left,
|
left: activeObject.left,
|
||||||
top: activeObject.top,
|
top: activeObject.top,
|
||||||
@@ -653,13 +609,10 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
canvas.setActiveObject(cropRect);
|
canvas.setActiveObject(cropRect);
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
updateButtons();
|
updateButtons();
|
||||||
console.log("Rettangolo di ritaglio creato e applicato");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Esci dalla modalità ritaglio
|
|
||||||
function exitCropMode() {
|
function exitCropMode() {
|
||||||
if (cropRect) {
|
if (cropRect) {
|
||||||
console.log("Rimozione rettangolo di ritaglio");
|
|
||||||
canvas.remove(cropRect);
|
canvas.remove(cropRect);
|
||||||
cropRect = null;
|
cropRect = null;
|
||||||
}
|
}
|
||||||
@@ -669,20 +622,12 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
canvas.discardActiveObject();
|
canvas.discardActiveObject();
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
updateButtons();
|
updateButtons();
|
||||||
console.log("Uscita dalla modalità ritaglio");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Applica il ritaglio
|
|
||||||
function applyCrop() {
|
function applyCrop() {
|
||||||
if (isApplyingCrop) {
|
if (isApplyingCrop) {
|
||||||
console.log("applyCrop già in esecuzione, ignoro chiamata");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("applyCrop chiamato, stato:", {
|
|
||||||
isCropping,
|
|
||||||
cropRect: !!cropRect,
|
|
||||||
croppedImage: !!croppedImage,
|
|
||||||
});
|
|
||||||
if (!isCropping || !cropRect || !croppedImage) {
|
if (!isCropping || !cropRect || !croppedImage) {
|
||||||
console.warn("Condizioni per il ritaglio non soddisfatte", {
|
console.warn("Condizioni per il ritaglio non soddisfatte", {
|
||||||
isCropping,
|
isCropping,
|
||||||
@@ -696,20 +641,12 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
isApplyingCrop = true;
|
isApplyingCrop = true;
|
||||||
console.log("Applicazione ritaglio all'immagine:", croppedImage);
|
|
||||||
const img = croppedImage;
|
const img = croppedImage;
|
||||||
const cropX = (cropRect.left - img.left) / img.scaleX;
|
const cropX = (cropRect.left - img.left) / img.scaleX;
|
||||||
const cropY = (cropRect.top - img.top) / img.scaleY;
|
const cropY = (cropRect.top - img.top) / img.scaleY;
|
||||||
const cropWidth = (cropRect.width * cropRect.scaleX) / img.scaleX;
|
const cropWidth = (cropRect.width * cropRect.scaleX) / img.scaleX;
|
||||||
const cropHeight = (cropRect.height * cropRect.scaleY) / img.scaleY;
|
const cropHeight = (cropRect.height * cropRect.scaleY) / img.scaleY;
|
||||||
console.log("Parametri di ritaglio:", {
|
|
||||||
cropX,
|
|
||||||
cropY,
|
|
||||||
cropWidth,
|
|
||||||
cropHeight,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Crea un'immagine ritagliata
|
|
||||||
fabric.Image.fromURL(
|
fabric.Image.fromURL(
|
||||||
img.getSrc(),
|
img.getSrc(),
|
||||||
(newImg) => {
|
(newImg) => {
|
||||||
@@ -730,20 +667,19 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
borderColor: "black",
|
borderColor: "black",
|
||||||
transparentCorners: false,
|
transparentCorners: false,
|
||||||
});
|
});
|
||||||
canvas.remove(img); // Rimuovi l'immagine originale
|
canvas.remove(img);
|
||||||
canvas.remove(cropRect); // Rimuovi il rettangolo di ritaglio
|
canvas.remove(cropRect);
|
||||||
canvas.add(newImg); // Aggiungi l'immagine ritagliata
|
canvas.add(newImg);
|
||||||
canvas.setActiveObject(newImg);
|
canvas.setActiveObject(newImg);
|
||||||
exitCropMode();
|
exitCropMode();
|
||||||
saveCanvasState(); // Salva lo stato dopo il ritaglio
|
saveCanvasState();
|
||||||
|
updateLayersPanel();
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
console.log("Ritaglio applicato con successo");
|
|
||||||
},
|
},
|
||||||
{ crossOrigin: "anonymous" },
|
{ crossOrigin: "anonymous" },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entra in modalità rimozione sfondo
|
|
||||||
function enterBackgroundRemovalMode() {
|
function enterBackgroundRemovalMode() {
|
||||||
const activeObject = canvas.getActiveObject();
|
const activeObject = canvas.getActiveObject();
|
||||||
if (!activeObject || activeObject.type !== "image") {
|
if (!activeObject || activeObject.type !== "image") {
|
||||||
@@ -755,29 +691,19 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log(
|
|
||||||
"Entrata in modalità rimozione sfondo per immagine:",
|
|
||||||
activeObject,
|
|
||||||
);
|
|
||||||
isRemovingBackground = true;
|
isRemovingBackground = true;
|
||||||
backgroundRemovalImage = activeObject;
|
backgroundRemovalImage = activeObject;
|
||||||
updateButtons();
|
updateButtons();
|
||||||
console.log(
|
|
||||||
"Modalità rimozione sfondo attivata, clicca sull'immagine per selezionare il colore",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Esci dalla modalità rimozione sfondo
|
|
||||||
function exitBackgroundRemovalMode() {
|
function exitBackgroundRemovalMode() {
|
||||||
isRemovingBackground = false;
|
isRemovingBackground = false;
|
||||||
backgroundRemovalImage = null;
|
backgroundRemovalImage = null;
|
||||||
canvas.discardActiveObject();
|
canvas.discardActiveObject();
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
updateButtons();
|
updateButtons();
|
||||||
console.log("Uscita dalla modalità rimozione sfondo");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gestisci la selezione del colore dello sfondo
|
|
||||||
function handleBackgroundColorSelection(event) {
|
function handleBackgroundColorSelection(event) {
|
||||||
if (!isRemovingBackground || !backgroundRemovalImage) {
|
if (!isRemovingBackground || !backgroundRemovalImage) {
|
||||||
console.warn(
|
console.warn(
|
||||||
@@ -788,14 +714,12 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
const pointer = canvas.getPointer(event.e);
|
const pointer = canvas.getPointer(event.e);
|
||||||
const img = backgroundRemovalImage;
|
const img = backgroundRemovalImage;
|
||||||
|
|
||||||
// Crea una canvas temporanea per ottenere i dati dei pixel
|
|
||||||
const tempCanvas = document.createElement("canvas");
|
const tempCanvas = document.createElement("canvas");
|
||||||
tempCanvas.width = img.width;
|
tempCanvas.width = img.width;
|
||||||
tempCanvas.height = img.height;
|
tempCanvas.height = img.height;
|
||||||
const ctx = tempCanvas.getContext("2d");
|
const ctx = tempCanvas.getContext("2d");
|
||||||
ctx.drawImage(img.getElement(), 0, 0, img.width, img.height);
|
ctx.drawImage(img.getElement(), 0, 0, img.width, img.height);
|
||||||
|
|
||||||
// Calcola la posizione relativa del click rispetto all'immagine
|
|
||||||
const imgLeft = img.left;
|
const imgLeft = img.left;
|
||||||
const imgTop = img.top;
|
const imgTop = img.top;
|
||||||
const scaleX = img.scaleX;
|
const scaleX = img.scaleX;
|
||||||
@@ -803,22 +727,17 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
const x = (pointer.x - imgLeft) / scaleX;
|
const x = (pointer.x - imgLeft) / scaleX;
|
||||||
const y = (pointer.y - imgTop) / scaleY;
|
const y = (pointer.y - imgTop) / scaleY;
|
||||||
|
|
||||||
// Ottieni il colore del pixel cliccato
|
|
||||||
const pixelData = ctx.getImageData(x, y, 1, 1).data;
|
const pixelData = ctx.getImageData(x, y, 1, 1).data;
|
||||||
const targetColor = {
|
const targetColor = {
|
||||||
r: pixelData[0],
|
r: pixelData[0],
|
||||||
g: pixelData[1],
|
g: pixelData[1],
|
||||||
b: pixelData[2],
|
b: pixelData[2],
|
||||||
};
|
};
|
||||||
console.log("Colore dello sfondo selezionato:", targetColor);
|
|
||||||
|
|
||||||
// Rimuovi il colore dello sfondo
|
|
||||||
removeBackground(img, targetColor);
|
removeBackground(img, targetColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rimuovi il colore dello sfondo
|
|
||||||
function removeBackground(img, targetColor) {
|
function removeBackground(img, targetColor) {
|
||||||
console.log("Inizio rimozione sfondo con colore:", targetColor);
|
|
||||||
const tempCanvas = document.createElement("canvas");
|
const tempCanvas = document.createElement("canvas");
|
||||||
tempCanvas.width = img.width;
|
tempCanvas.width = img.width;
|
||||||
tempCanvas.height = img.height;
|
tempCanvas.height = img.height;
|
||||||
@@ -832,27 +751,24 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
tempCanvas.height,
|
tempCanvas.height,
|
||||||
);
|
);
|
||||||
const data = imageData.data;
|
const data = imageData.data;
|
||||||
const tolerance = 50; // Tolleranza per colori simili
|
const tolerance = 50;
|
||||||
|
|
||||||
// Scansiona i pixel e rendi trasparenti quelli che corrispondono al colore target
|
|
||||||
for (let i = 0; i < data.length; i += 4) {
|
for (let i = 0; i < data.length; i += 4) {
|
||||||
const r = data[i];
|
const r = data[i];
|
||||||
const g = data[i + 1];
|
const g = data[i + 1];
|
||||||
const b = data[i + 2];
|
const b = data[i + 2];
|
||||||
// Verifica se il colore è simile al targetColor
|
|
||||||
if (
|
if (
|
||||||
Math.abs(r - targetColor.r) <= tolerance &&
|
Math.abs(r - targetColor.r) <= tolerance &&
|
||||||
Math.abs(g - targetColor.g) <= tolerance &&
|
Math.abs(g - targetColor.g) <= tolerance &&
|
||||||
Math.abs(b - targetColor.b) <= tolerance
|
Math.abs(b - targetColor.b) <= tolerance
|
||||||
) {
|
) {
|
||||||
data[i + 3] = 0; // Imposta l'alpha a 0 (trasparente)
|
data[i + 3] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.putImageData(imageData, 0, 0);
|
ctx.putImageData(imageData, 0, 0);
|
||||||
const newImageUrl = tempCanvas.toDataURL("image/png");
|
const newImageUrl = tempCanvas.toDataURL("image/png");
|
||||||
|
|
||||||
// Crea una nuova immagine con lo sfondo rimosso
|
|
||||||
fabric.Image.fromURL(
|
fabric.Image.fromURL(
|
||||||
newImageUrl,
|
newImageUrl,
|
||||||
(newImg) => {
|
(newImg) => {
|
||||||
@@ -869,19 +785,18 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
borderColor: "black",
|
borderColor: "black",
|
||||||
transparentCorners: false,
|
transparentCorners: false,
|
||||||
});
|
});
|
||||||
canvas.remove(img); // Rimuovi l'immagine originale
|
canvas.remove(img);
|
||||||
canvas.add(newImg); // Aggiungi l'immagine con sfondo rimosso
|
canvas.add(newImg);
|
||||||
canvas.setActiveObject(newImg);
|
canvas.setActiveObject(newImg);
|
||||||
exitBackgroundRemovalMode();
|
exitBackgroundRemovalMode();
|
||||||
saveCanvasState(); // Salva lo stato dopo la rimozione dello sfondo
|
saveCanvasState();
|
||||||
|
updateLayersPanel();
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
console.log("Sfondo rimosso con successo");
|
|
||||||
},
|
},
|
||||||
{ crossOrigin: "anonymous" },
|
{ crossOrigin: "anonymous" },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rimuovi l'immagine selezionata
|
|
||||||
function removeImage() {
|
function removeImage() {
|
||||||
const activeObject = canvas.getActiveObject();
|
const activeObject = canvas.getActiveObject();
|
||||||
if (!activeObject || activeObject.type !== "image") {
|
if (!activeObject || activeObject.type !== "image") {
|
||||||
@@ -889,15 +804,13 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
alert("Seleziona un'immagine da rimuovere!");
|
alert("Seleziona un'immagine da rimuovere!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("Rimozione immagine selezionata:", activeObject);
|
|
||||||
canvas.remove(activeObject);
|
canvas.remove(activeObject);
|
||||||
canvas.discardActiveObject();
|
canvas.discardActiveObject();
|
||||||
saveCanvasState(); // Salva lo stato dopo la rimozione
|
saveCanvasState();
|
||||||
|
updateLayersPanel();
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
console.log("Immagine rimossa con successo");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aggiungi foto selezionate al canvas
|
|
||||||
const addToCanvasBtn = document.getElementById("addToCanvasBtn");
|
const addToCanvasBtn = document.getElementById("addToCanvasBtn");
|
||||||
if (addToCanvasBtn) {
|
if (addToCanvasBtn) {
|
||||||
addToCanvasBtn.addEventListener("click", () => {
|
addToCanvasBtn.addEventListener("click", () => {
|
||||||
@@ -914,11 +827,11 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
imgPath,
|
imgPath,
|
||||||
(img) => {
|
(img) => {
|
||||||
img.set({
|
img.set({
|
||||||
left: Math.random() * 600, // Posizione random iniziale
|
left: Math.random() * 600,
|
||||||
top: Math.random() * 400,
|
top: Math.random() * 400,
|
||||||
scaleX: 0.5, // Scala iniziale
|
scaleX: 0.5,
|
||||||
scaleY: 0.5,
|
scaleY: 0.5,
|
||||||
hasControls: true, // Abilita resize/rotate
|
hasControls: true,
|
||||||
hasBorders: true,
|
hasBorders: true,
|
||||||
cornerColor: "black",
|
cornerColor: "black",
|
||||||
cornerStrokeColor: "black",
|
cornerStrokeColor: "black",
|
||||||
@@ -928,25 +841,22 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
});
|
});
|
||||||
canvas.add(img);
|
canvas.add(img);
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
console.log(
|
|
||||||
"Immagine aggiunta al canvas:",
|
|
||||||
imgPath,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
{ crossOrigin: "anonymous" },
|
{ crossOrigin: "anonymous" },
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// Deseleziona checkbox dopo aggiunta
|
|
||||||
checkboxes.forEach((cb) => (cb.checked = false));
|
checkboxes.forEach((cb) => (cb.checked = false));
|
||||||
saveCanvasState(); // Salva lo stato dopo l'aggiunta
|
saveCanvasState();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Salva collage
|
|
||||||
const saveCollageBtn = document.getElementById("saveCollageBtn");
|
const saveCollageBtn = document.getElementById("saveCollageBtn");
|
||||||
if (saveCollageBtn) {
|
if (saveCollageBtn) {
|
||||||
saveCollageBtn.addEventListener("click", async () => {
|
saveCollageBtn.addEventListener("click", async () => {
|
||||||
if (canvas.getObjects().length === 0) {
|
if (
|
||||||
|
canvas.getObjects().length === 0 &&
|
||||||
|
!canvas.backgroundImage
|
||||||
|
) {
|
||||||
alert("Il canvas è vuoto! Aggiungi almeno una foto.");
|
alert("Il canvas è vuoto! Aggiungi almeno una foto.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -959,29 +869,12 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
type: "image/jpeg",
|
type: "image/jpeg",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Upload come nuova foto
|
|
||||||
await handleFiles([file], iddatadb);
|
await handleFiles([file], iddatadb);
|
||||||
// Chiudi modale e ricarica popup
|
|
||||||
document.getElementById("collageModal").style.display = "none";
|
document.getElementById("collageModal").style.display = "none";
|
||||||
loadPopupContent(iddatadb);
|
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");
|
|
||||||
history = []; // Resetta la pila di stati
|
|
||||||
saveCanvasState(); // Salva lo stato vuoto
|
|
||||||
canvas.renderAll();
|
|
||||||
console.log("Canvas pulito");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gestione livelli delle immagini
|
|
||||||
const bringToFrontBtn = document.getElementById("bringToFrontBtn");
|
const bringToFrontBtn = document.getElementById("bringToFrontBtn");
|
||||||
if (bringToFrontBtn) {
|
if (bringToFrontBtn) {
|
||||||
bringToFrontBtn.addEventListener("click", () => {
|
bringToFrontBtn.addEventListener("click", () => {
|
||||||
@@ -989,8 +882,8 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
if (activeObject) {
|
if (activeObject) {
|
||||||
canvas.bringToFront(activeObject);
|
canvas.bringToFront(activeObject);
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
saveCanvasState(); // Salva lo stato dopo il cambio di livello
|
saveCanvasState();
|
||||||
console.log("Oggetto portato in primo piano");
|
updateLayersPanel();
|
||||||
} else {
|
} else {
|
||||||
alert("Seleziona un'immagine sul canvas!");
|
alert("Seleziona un'immagine sul canvas!");
|
||||||
}
|
}
|
||||||
@@ -1004,8 +897,8 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
if (activeObject) {
|
if (activeObject) {
|
||||||
canvas.sendToBack(activeObject);
|
canvas.sendToBack(activeObject);
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
saveCanvasState(); // Salva lo stato dopo il cambio di livello
|
saveCanvasState();
|
||||||
console.log("Oggetto mandato in fondo");
|
updateLayersPanel();
|
||||||
} else {
|
} else {
|
||||||
alert("Seleziona un'immagine sul canvas!");
|
alert("Seleziona un'immagine sul canvas!");
|
||||||
}
|
}
|
||||||
@@ -1019,8 +912,8 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
if (activeObject) {
|
if (activeObject) {
|
||||||
canvas.bringForward(activeObject);
|
canvas.bringForward(activeObject);
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
saveCanvasState(); // Salva lo stato dopo il cambio di livello
|
saveCanvasState();
|
||||||
console.log("Oggetto spostato avanti di un livello");
|
updateLayersPanel();
|
||||||
} else {
|
} else {
|
||||||
alert("Seleziona un'immagine sul canvas!");
|
alert("Seleziona un'immagine sul canvas!");
|
||||||
}
|
}
|
||||||
@@ -1034,19 +927,17 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
if (activeObject) {
|
if (activeObject) {
|
||||||
canvas.sendBackwards(activeObject);
|
canvas.sendBackwards(activeObject);
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
saveCanvasState(); // Salva lo stato dopo il cambio di livello
|
saveCanvasState();
|
||||||
console.log("Oggetto spostato indietro di un livello");
|
updateLayersPanel();
|
||||||
} else {
|
} else {
|
||||||
alert("Seleziona un'immagine sul canvas!");
|
alert("Seleziona un'immagine sul canvas!");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gestione ritaglio immagini
|
|
||||||
const cropImageBtn = document.getElementById("cropImageBtn");
|
const cropImageBtn = document.getElementById("cropImageBtn");
|
||||||
if (cropImageBtn) {
|
if (cropImageBtn) {
|
||||||
cropImageBtn.addEventListener("click", () => {
|
cropImageBtn.addEventListener("click", () => {
|
||||||
console.log("Pulsante Ritaglia cliccato");
|
|
||||||
enterCropMode();
|
enterCropMode();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1054,7 +945,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
const applyCropBtn = document.getElementById("applyCropBtn");
|
const applyCropBtn = document.getElementById("applyCropBtn");
|
||||||
if (applyCropBtn) {
|
if (applyCropBtn) {
|
||||||
applyCropBtn.addEventListener("click", () => {
|
applyCropBtn.addEventListener("click", () => {
|
||||||
console.log("Pulsante Applica Ritaglio cliccato");
|
|
||||||
applyCrop();
|
applyCrop();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1062,49 +952,39 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
const cancelCropBtn = document.getElementById("cancelCropBtn");
|
const cancelCropBtn = document.getElementById("cancelCropBtn");
|
||||||
if (cancelCropBtn) {
|
if (cancelCropBtn) {
|
||||||
cancelCropBtn.addEventListener("click", () => {
|
cancelCropBtn.addEventListener("click", () => {
|
||||||
console.log("Pulsante Annulla Ritaglio cliccato");
|
|
||||||
exitCropMode();
|
exitCropMode();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gestione rimozione sfondo
|
|
||||||
const removeBackgroundBtn = document.getElementById(
|
const removeBackgroundBtn = document.getElementById(
|
||||||
"removeBackgroundBtn",
|
"removeBackgroundBtn",
|
||||||
);
|
);
|
||||||
if (removeBackgroundBtn) {
|
if (removeBackgroundBtn) {
|
||||||
removeBackgroundBtn.addEventListener("click", () => {
|
removeBackgroundBtn.addEventListener("click", () => {
|
||||||
console.log("Pulsante Rimuovi Sfondo cliccato");
|
|
||||||
enterBackgroundRemovalMode();
|
enterBackgroundRemovalMode();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gestione rimozione immagine
|
|
||||||
const removeImageBtn = document.getElementById("removeImageBtn");
|
const removeImageBtn = document.getElementById("removeImageBtn");
|
||||||
if (removeImageBtn) {
|
if (removeImageBtn) {
|
||||||
removeImageBtn.addEventListener("click", () => {
|
removeImageBtn.addEventListener("click", () => {
|
||||||
console.log("Pulsante Rimuovi Immagine cliccato");
|
|
||||||
removeImage();
|
removeImage();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gestione undo
|
|
||||||
const undoBtn = document.getElementById("undoBtn");
|
const undoBtn = document.getElementById("undoBtn");
|
||||||
if (undoBtn) {
|
if (undoBtn) {
|
||||||
undoBtn.addEventListener("click", () => {
|
undoBtn.addEventListener("click", () => {
|
||||||
console.log("Pulsante Annulla cliccato");
|
|
||||||
undo();
|
undo();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assicurati che il loader sia nascosto all'apertura del popup
|
|
||||||
const loader = document.getElementById("loader");
|
const loader = document.getElementById("loader");
|
||||||
if (loader) {
|
if (loader) {
|
||||||
console.log("Nascondo loader all'apertura del popup");
|
|
||||||
loader.style.display = "none";
|
loader.style.display = "none";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gestione del pulsante Photos
|
|
||||||
const photosButtons = document.querySelectorAll(".photos-btn");
|
const photosButtons = document.querySelectorAll(".photos-btn");
|
||||||
const photosModal = document.getElementById("photosModal");
|
const photosModal = document.getElementById("photosModal");
|
||||||
const closeBtn = document.querySelector(".close-btn");
|
const closeBtn = document.querySelector(".close-btn");
|
||||||
@@ -1112,10 +992,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
if (photosButtons.length && photosModal && closeBtn) {
|
if (photosButtons.length && photosModal && closeBtn) {
|
||||||
photosButtons.forEach((button) => {
|
photosButtons.forEach((button) => {
|
||||||
button.addEventListener("click", function () {
|
button.addEventListener("click", function () {
|
||||||
console.log(
|
|
||||||
"Pulsante Photos cliccato per iddatadb:",
|
|
||||||
this.getAttribute("data-iddatadb"),
|
|
||||||
);
|
|
||||||
const iddatadb = this.getAttribute("data-iddatadb");
|
const iddatadb = this.getAttribute("data-iddatadb");
|
||||||
loadPopupContent(iddatadb);
|
loadPopupContent(iddatadb);
|
||||||
photosModal.style.display = "block";
|
photosModal.style.display = "block";
|
||||||
@@ -1124,7 +1000,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
closeBtn.addEventListener("click", function () {
|
closeBtn.addEventListener("click", function () {
|
||||||
console.log("Chiusura modale photos");
|
|
||||||
photosModal.style.display = "none";
|
photosModal.style.display = "none";
|
||||||
document.querySelector(".overlay").style.display = "none";
|
document.querySelector(".overlay").style.display = "none";
|
||||||
document.body.style.pointerEvents = "auto";
|
document.body.style.pointerEvents = "auto";
|
||||||
@@ -1132,7 +1007,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
|
|
||||||
window.addEventListener("click", function (event) {
|
window.addEventListener("click", function (event) {
|
||||||
if (event.target === photosModal) {
|
if (event.target === photosModal) {
|
||||||
console.log("Chiusura modale photos cliccando sullo sfondo");
|
|
||||||
photosModal.style.display = "none";
|
photosModal.style.display = "none";
|
||||||
document.querySelector(".overlay").style.display = "none";
|
document.querySelector(".overlay").style.display = "none";
|
||||||
document.body.style.pointerEvents = "auto";
|
document.body.style.pointerEvents = "auto";
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ use Endroid\QrCode\Writer\PngWriter;
|
|||||||
try {
|
try {
|
||||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../../');
|
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../../');
|
||||||
$dotenv->load();
|
$dotenv->load();
|
||||||
error_log("File .env caricato correttamente da " . __DIR__ . '/../../.env');
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
error_log("Errore nel caricamento del file .env: " . $e->getMessage());
|
error_log("Errore nel caricamento del file .env: " . $e->getMessage());
|
||||||
echo json_encode(['error' => 'Errore nel caricamento del file di configurazione']);
|
echo json_encode(['error' => 'Errore nel caricamento del file di configurazione']);
|
||||||
@@ -176,7 +175,7 @@ $result->saveToFile($qrCodeFile);
|
|||||||
<!-- Modale per collage -->
|
<!-- Modale per collage -->
|
||||||
<div id="collageModal" class="modal" style="display: none; position: fixed; z-index: 1002; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.8);">
|
<div id="collageModal" class="modal" style="display: none; position: fixed; z-index: 1002; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.8);">
|
||||||
<div class="modal-content" style="background: white; margin: 5% auto; padding: 20px; width: 80%; max-width: 1200px; position: relative;">
|
<div class="modal-content" style="background: white; margin: 5% auto; padding: 20px; width: 80%; max-width: 1200px; position: relative;">
|
||||||
<span class="close-collage" style="position: absolute; top: 10px; right: 20px; font-size: 30px; cursor: pointer;">×</span>
|
<span class="close-collage" style="position: absolute; top: 10px; right: 20px; font-size: 30px; font-weight: bold; color: #333; cursor: pointer; z-index: 1003; background: #fff; padding: 5px 10px; border-radius: 50%;">×</span>
|
||||||
<h3>Crea Collage</h3>
|
<h3>Crea Collage</h3>
|
||||||
|
|
||||||
<!-- Lista foto selezionabili -->
|
<!-- Lista foto selezionabili -->
|
||||||
@@ -195,10 +194,15 @@ $result->saveToFile($qrCodeFile);
|
|||||||
<!-- Canvas per editing -->
|
<!-- Canvas per editing -->
|
||||||
<canvas id="collageCanvas" width="800" height="600" style="border: 1px solid #ccc; margin-top: 20px;"></canvas>
|
<canvas id="collageCanvas" width="800" height="600" style="border: 1px solid #ccc; margin-top: 20px;"></canvas>
|
||||||
|
|
||||||
|
<!-- Pannello dei livelli -->
|
||||||
|
<div id="layersPanel" style="width: 120px; max-height: 600px; overflow-y: auto; background: #f8f9fa; padding: 10px; position: absolute; right: 0; top: 60px;">
|
||||||
|
<h4 style="margin: 0 0 10px 0; font-size: 16px;">Livelli</h4>
|
||||||
|
<ul id="layersList" style="list-style: none; padding: 0;"></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Bottoni azioni -->
|
<!-- Bottoni azioni -->
|
||||||
<div style="margin-top: 20px; display: flex; flex-wrap: wrap; gap: 5px;">
|
<div style="margin-top: 20px; display: flex; flex-wrap: wrap; gap: 5px;">
|
||||||
<button id="saveCollageBtn" title="Salva il collage"><i class="fas fa-save"></i></button>
|
<button id="saveCollageBtn" title="Salva il collage"><i class="fas fa-save"></i></button>
|
||||||
<!-- <button id="clearCanvasBtn" title="Pulisci il canvas"><i class="fas fa-trash"></i></button> -->
|
|
||||||
<button id="bringToFrontBtn" title="Porta in primo piano"><i class="fas fa-arrow-up"></i></button>
|
<button id="bringToFrontBtn" title="Porta in primo piano"><i class="fas fa-arrow-up"></i></button>
|
||||||
<button id="sendToBackBtn" title="Manda in fondo"><i class="fas fa-arrow-down"></i></button>
|
<button id="sendToBackBtn" title="Manda in fondo"><i class="fas fa-arrow-down"></i></button>
|
||||||
<button id="bringForwardBtn" title="Sposta avanti di un livello"><i class="fas fa-arrow-circle-up"></i></button>
|
<button id="bringForwardBtn" title="Sposta avanti di un livello"><i class="fas fa-arrow-circle-up"></i></button>
|
||||||
@@ -311,11 +315,6 @@ $result->saveToFile($qrCodeFile);
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
#clearCanvasBtn {
|
|
||||||
background: #dc3545;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bringToFrontBtn,
|
#bringToFrontBtn,
|
||||||
#sendToBackBtn,
|
#sendToBackBtn,
|
||||||
#bringForwardBtn,
|
#bringForwardBtn,
|
||||||
@@ -323,7 +322,6 @@ $result->saveToFile($qrCodeFile);
|
|||||||
background: #007bff;
|
background: #007bff;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
/* Pulsanti solo icona più piccoli */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#cropImageBtn,
|
#cropImageBtn,
|
||||||
@@ -344,4 +342,25 @@ $result->saveToFile($qrCodeFile);
|
|||||||
#collageModal button i {
|
#collageModal button i {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stile per il pannello dei livelli */
|
||||||
|
#layersPanel {
|
||||||
|
z-index: 1002;
|
||||||
|
}
|
||||||
|
|
||||||
|
#layersPanel li {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#layersPanel img {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border: 2px solid #ccc;
|
||||||
|
cursor: pointer;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
#layersPanel img:hover {
|
||||||
|
border-color: #007bff;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user