marker with size
This commit is contained in:
parent
8d6fe92481
commit
5d8360dd87
@ -18,6 +18,8 @@ $(document).ready(function () {
|
|||||||
let descriptionTextbox = null;
|
let descriptionTextbox = null;
|
||||||
let markerObjects = {};
|
let markerObjects = {};
|
||||||
let partsListData = [];
|
let partsListData = [];
|
||||||
|
// DIMENSIONE GLOBALE MARKER
|
||||||
|
let globalMarkerSize = 24;
|
||||||
|
|
||||||
// ===================
|
// ===================
|
||||||
// MODAL INITIALIZATION
|
// MODAL INITIALIZATION
|
||||||
@ -67,6 +69,9 @@ $(document).ready(function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
modal.show();
|
modal.show();
|
||||||
|
// Inizializza slider dimensione marker
|
||||||
|
$("#markerSizeSlider").val(globalMarkerSize);
|
||||||
|
$("#markerSizeValue").text(globalMarkerSize + "px");
|
||||||
|
|
||||||
// Debug: Verifica presenza elementi DOM
|
// Debug: Verifica presenza elementi DOM
|
||||||
console.log(
|
console.log(
|
||||||
@ -128,6 +133,7 @@ $(document).ready(function () {
|
|||||||
}
|
}
|
||||||
descriptionTextbox = null;
|
descriptionTextbox = null;
|
||||||
markerObjects = {};
|
markerObjects = {};
|
||||||
|
globalMarkerSize = 24;
|
||||||
$("#photoSelectorContainerAnnotations").empty().hide();
|
$("#photoSelectorContainerAnnotations").empty().hide();
|
||||||
$("#samplePhotoAnnotations").attr("src", "");
|
$("#samplePhotoAnnotations").attr("src", "");
|
||||||
$("#partsListAnnotations").empty();
|
$("#partsListAnnotations").empty();
|
||||||
@ -144,6 +150,16 @@ $(document).ready(function () {
|
|||||||
$(":focus").blur();
|
$(":focus").blur();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// SLIDER DIMENSIONE MARKER
|
||||||
|
$(document)
|
||||||
|
.off("input", "#markerSizeSlider")
|
||||||
|
.on("input", "#markerSizeSlider", function () {
|
||||||
|
globalMarkerSize = parseInt($(this).val());
|
||||||
|
$("#markerSizeValue").text(globalMarkerSize + "px");
|
||||||
|
updateMarkers();
|
||||||
|
markUnsaved();
|
||||||
|
});
|
||||||
|
|
||||||
// ===================
|
// ===================
|
||||||
// PHOTO LOADERS
|
// PHOTO LOADERS
|
||||||
// ===================
|
// ===================
|
||||||
@ -465,113 +481,80 @@ $(document).ready(function () {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// ===================
|
// ===================
|
||||||
// BACK TO PARTS MODAL
|
// TORNA AL MODALE PARTI (modal_partsTable.php)
|
||||||
// ===================
|
// ===================
|
||||||
$(document)
|
$(document)
|
||||||
.off("click.backToParts", "#backToPartsBtnAnnotations")
|
.off("click.backToParts", "#backToPartsBtnAnnotations")
|
||||||
.on("click.backToParts", "#backToPartsBtnAnnotations", function (e) {
|
.on("click.backToParts", "#backToPartsBtnAnnotations", function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
console.log(
|
|
||||||
"Evento click su #backToPartsBtnAnnotations, ID elemento:",
|
|
||||||
$(this).attr("id"),
|
|
||||||
);
|
|
||||||
if (!$("#backToPartsBtnAnnotations").length) {
|
|
||||||
console.error(
|
|
||||||
"Pulsante #backToPartsBtnAnnotations non trovato nel DOM.",
|
|
||||||
);
|
|
||||||
const errorMsg = $(
|
|
||||||
'<div class="alert alert-danger temp-alert" role="alert">Errore: Pulsante #backToPartsBtnAnnotations non trovato nel DOM.</div>',
|
|
||||||
);
|
|
||||||
$("#annotationsModal .modal-body").prepend(errorMsg);
|
|
||||||
setTimeout(function () {
|
|
||||||
errorMsg.fadeOut(500, function () {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
}, 5000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Controlla modifiche non salvate
|
|
||||||
if (
|
if (
|
||||||
unsavedChanges &&
|
unsavedChanges &&
|
||||||
!confirm(
|
!confirm(
|
||||||
"Hai modifiche non salvate. Vuoi davvero tornare al modale delle parti?",
|
"Hai modifiche non salvate. Vuoi davvero tornare al modale delle parti?",
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
console.log(
|
|
||||||
"Tornare al modale delle parti annullato a causa di modifiche non salvate.",
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chiudi annotationsModal
|
|
||||||
const annotationsModalElement =
|
|
||||||
document.getElementById("annotationsModal");
|
|
||||||
const annotationsModal = bootstrap.Modal.getInstance(
|
|
||||||
annotationsModalElement,
|
|
||||||
);
|
|
||||||
if (annotationsModal) {
|
|
||||||
annotationsModal.hide();
|
|
||||||
} else {
|
|
||||||
console.error(
|
|
||||||
"Impossibile trovare l'istanza del modale #annotationsModal.",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apri partsModal
|
|
||||||
const iddatadb = $("#annotationsModal").data("iddatadb");
|
const iddatadb = $("#annotationsModal").data("iddatadb");
|
||||||
const idquotations = $("#annotationsModal").data("idquotations");
|
const idquotations = $("#annotationsModal").data("idquotations");
|
||||||
const trfHeader = $("#trfHeaderAnnotations").text();
|
const trfHeader = $("#trfHeaderAnnotations").text();
|
||||||
console.log("Apertura partsModal con:", {
|
|
||||||
|
// CHIUDI MODALE ANNOTAZIONI IN MODO SICURO
|
||||||
|
const annotationsModalElement =
|
||||||
|
document.getElementById("annotationsModal");
|
||||||
|
if (annotationsModalElement) {
|
||||||
|
const modalInstance = bootstrap.Modal.getInstance(
|
||||||
|
annotationsModalElement,
|
||||||
|
);
|
||||||
|
if (modalInstance) {
|
||||||
|
modalInstance.hide();
|
||||||
|
} else {
|
||||||
|
$(annotationsModalElement).modal("hide"); // fallback jQuery
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("Torno a modal_partsTable.php con:", {
|
||||||
iddatadb,
|
iddatadb,
|
||||||
idquotations,
|
idquotations,
|
||||||
trfHeader,
|
trfHeader,
|
||||||
});
|
});
|
||||||
|
// CARICA E APRI MODALE PARTI
|
||||||
|
$.get(
|
||||||
|
"modal_partsTable.php",
|
||||||
|
{
|
||||||
|
iddatadb: iddatadb || "",
|
||||||
|
idquotations: idquotations || "",
|
||||||
|
trfHeader: trfHeader,
|
||||||
|
},
|
||||||
|
function (data) {
|
||||||
|
// Rimuovi vecchio modale (con ID corretto)
|
||||||
|
$("#partsTableModal").remove();
|
||||||
|
$(".modal-backdrop").remove();
|
||||||
|
|
||||||
const partsModalElement = document.getElementById("partsModal");
|
// Aggiungi nuovo modale
|
||||||
if (!partsModalElement) {
|
$("body").append(data);
|
||||||
console.error("Elemento #partsModal non trovato nel DOM.");
|
|
||||||
const errorMsg = $(
|
// Apri con Bootstrap 5
|
||||||
'<div class="alert alert-danger temp-alert" role="alert">Errore: Il modale delle parti non è presente nel DOM.</div>',
|
const partsModalElement =
|
||||||
|
document.getElementById("partsTableModal");
|
||||||
|
if (partsModalElement) {
|
||||||
|
const modal = new bootstrap.Modal(partsModalElement, {
|
||||||
|
backdrop: true,
|
||||||
|
keyboard: true,
|
||||||
|
focus: true,
|
||||||
|
});
|
||||||
|
modal.show();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
).fail(function (xhr) {
|
||||||
|
console.error("Errore caricamento modale parti:", xhr);
|
||||||
|
alert(
|
||||||
|
"Errore 404: modal_partsTable.php non trovato o errore server.",
|
||||||
);
|
);
|
||||||
$("#annotationsModal .modal-body").prepend(errorMsg);
|
});
|
||||||
setTimeout(function () {
|
|
||||||
errorMsg.fadeOut(500, function () {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
}, 5000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let partsModal = bootstrap.Modal.getInstance(partsModalElement);
|
|
||||||
if (!partsModal) {
|
|
||||||
partsModal = new bootstrap.Modal(partsModalElement, {
|
|
||||||
backdrop: true,
|
|
||||||
keyboard: true,
|
|
||||||
focus: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inizializza il modale delle parti
|
|
||||||
if (typeof window.initPartsModal === "function") {
|
|
||||||
window.initPartsModal(iddatadb, idquotations, trfHeader);
|
|
||||||
partsModal.show();
|
|
||||||
console.log("partsModal aperto con successo.");
|
|
||||||
} else {
|
|
||||||
console.error("Funzione initPartsModal non definita.");
|
|
||||||
const errorMsg = $(
|
|
||||||
'<div class="alert alert-danger temp-alert" role="alert">Errore: Funzione initPartsModal non trovata.</div>',
|
|
||||||
);
|
|
||||||
$("#annotationsModal .modal-body").prepend(errorMsg);
|
|
||||||
setTimeout(function () {
|
|
||||||
errorMsg.fadeOut(500, function () {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// ===================
|
// ===================
|
||||||
// PARTS LIST
|
// PARTS LIST
|
||||||
// ===================
|
// ===================
|
||||||
@ -892,8 +875,8 @@ $(document).ready(function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const radius = 12;
|
const radius = globalMarkerSize / 2;
|
||||||
const fontSize = 16;
|
const fontSize = Math.max(10, Math.round(globalMarkerSize * 0.65));
|
||||||
const markerColor =
|
const markerColor =
|
||||||
marker.color || partColors[marker.partNumber] || "#ff0000";
|
marker.color || partColors[marker.partNumber] || "#ff0000";
|
||||||
|
|
||||||
@ -1013,7 +996,7 @@ $(document).ready(function () {
|
|||||||
scaleY: 1,
|
scaleY: 1,
|
||||||
backgroundColor: "transparent",
|
backgroundColor: "transparent",
|
||||||
fontFamily: "Arial",
|
fontFamily: "Arial",
|
||||||
fontSize: 24,
|
fontSize: Math.max(16, Math.round(globalMarkerSize * 0.8)),
|
||||||
fill: "#000000",
|
fill: "#000000",
|
||||||
padding: 10,
|
padding: 10,
|
||||||
editable: false,
|
editable: false,
|
||||||
|
|||||||
@ -1,14 +1,23 @@
|
|||||||
<!-- Modal per la gestione delle annotazioni -->
|
<!-- Modal per la gestione delle annotazioni -->
|
||||||
<div class="modal fade" id="annotationsModal" tabindex="-1" aria-labelledby="annotationsModalLabel" aria-hidden="true">
|
<div class="modal fade" id="annotationsModal" tabindex="-1" aria-labelledby="annotationsModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-xl" style="max-width: 80% !important; width: 80% !important;">
|
<div class="modal-dialog modal-xl" style="max-width: 90% !important; width: 90% !important;">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title" id="annotationsModalLabel">Annotazioni per TRF: <span id="trfHeaderAnnotations"></span></h5>
|
<h5 class="modal-title" id="annotationsModalLabel">Annotazioni per TRF: <span id="trfHeaderAnnotations"></span></h5>
|
||||||
|
|
||||||
|
<!-- SLIDER PER DIMENSIONE MARKER -->
|
||||||
|
<div style="display: flex; align-items: center; gap: 10px; margin-left: 20px;">
|
||||||
|
<label for="markerSizeSlider" style="margin: 0; font-size: 0.9rem; white-space: nowrap;">Dimensione marker:</label>
|
||||||
|
<input type="range" id="markerSizeSlider" min="16" max="48" value="24" step="2" style="width: 120px;">
|
||||||
|
<span id="markerSizeValue" style="font-weight: bold; min-width: 30px;">24px</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<!-- COLONNA SINISTRA RIDOTTA -->
|
||||||
|
<div class="col-md-4">
|
||||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||||
<h6 style="margin: 0;">Elenco Parti</h6>
|
<h6 style="margin: 0;">Elenco Parti</h6>
|
||||||
<div style="display: flex; align-items: center;">
|
<div style="display: flex; align-items: center;">
|
||||||
@ -16,15 +25,17 @@
|
|||||||
<label for="showMixPartsAnnotations" style="font-size: 0.9rem;">Mix</label>
|
<label for="showMixPartsAnnotations" style="font-size: 0.9rem;">Mix</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul id="partsListAnnotations" class="list-group"></ul>
|
<ul id="partsListAnnotations" class="list-group" style="max-height: 500px; overflow-y: auto;"></ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
|
||||||
|
<!-- COLONNA DESTRA PIÙ GRANDE -->
|
||||||
|
<div class="col-md-8">
|
||||||
<h6>Foto del Campione</h6>
|
<h6>Foto del Campione</h6>
|
||||||
<div style="display: flex; align-items: center; margin-bottom: 10px;">
|
<div style="display: flex; align-items: center; margin-bottom: 10px;">
|
||||||
<button type="button" class="btn btn-primary btn-sm" id="downloadPhotoBtnAnnotations" style="padding: 0.1rem 0.5rem; font-size: 0.8rem; margin-right: 10px;"><i class="fas fa-download"></i></button>
|
<button type="button" class="btn btn-primary btn-sm" id="downloadPhotoBtnAnnotations" style="padding: 0.1rem 0.5rem; font-size: 0.8rem; margin-right: 10px;"><i class="fas fa-download"></i></button>
|
||||||
<div id="photoSelectorContainerAnnotations" style="display: none;"></div>
|
<div id="photoSelectorContainerAnnotations" style="display: none;"></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="position: relative; width: 100%; min-height: 400px;">
|
<div style="position: relative; width: 100%; min-height: 500px; border: 1px solid #ddd; border-radius: 4px; overflow: hidden;">
|
||||||
<img id="samplePhotoAnnotations" src="" alt="Foto del campione" style="max-width: 100%; max-height: 100%; object-fit: contain; position: absolute; top: 0; left: 0;">
|
<img id="samplePhotoAnnotations" src="" alt="Foto del campione" style="max-width: 100%; max-height: 100%; object-fit: contain; position: absolute; top: 0; left: 0;">
|
||||||
<canvas id="photoCanvasAnnotations" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></canvas>
|
<canvas id="photoCanvasAnnotations" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></canvas>
|
||||||
<canvas id="overlayCanvasAnnotations" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1000;"></canvas>
|
<canvas id="overlayCanvasAnnotations" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1000;"></canvas>
|
||||||
@ -216,4 +227,32 @@
|
|||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
z-index: 3000;
|
z-index: 3000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stile per lo slider */
|
||||||
|
#markerSizeSlider {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: #ddd;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#markerSizeSlider::-webkit-slider-thumb {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #007bff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#markerSizeSlider::-moz-range-thumb {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #007bff;
|
||||||
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -399,14 +399,18 @@ if (isset($_GET['edit_id'])) {
|
|||||||
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
|
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
|
||||||
<?php include('include/footer.php'); ?>
|
<?php include('include/footer.php'); ?>
|
||||||
</div>
|
</div>
|
||||||
<?php include('modal_parts.php'); ?>
|
<div id="partsModalContainer"></div>
|
||||||
<?php include('photos_functions.php'); ?>
|
<div id="annotationsModalContainer"></div>
|
||||||
|
<?php include 'photos_functions.php'; ?>
|
||||||
|
|
||||||
<?php include('jsinclude.php'); ?>
|
<?php include('jsinclude.php'); ?>
|
||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
|
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
|
||||||
<script src="photos.js"></script>
|
<script src="photos.js"></script>
|
||||||
<script src="parts.js"></script>
|
<script src="annotationsModal.js"></script>
|
||||||
|
<script src="partsTable.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
// Mostra messaggi di stato se presenti
|
// Mostra messaggi di stato se presenti
|
||||||
@ -423,6 +427,45 @@ if (isset($_GET['edit_id'])) {
|
|||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(document).on('click', '.parts-btn', function() {
|
||||||
|
const idquotations = $(this).data('idquotations');
|
||||||
|
$.ajax({
|
||||||
|
url: 'modal_partsTable.php',
|
||||||
|
method: 'GET',
|
||||||
|
data: {
|
||||||
|
idquotations: idquotations
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
$('#partsModalContainer').html(response);
|
||||||
|
const modalElement = document.getElementById('partsModal');
|
||||||
|
if (!modalElement) return;
|
||||||
|
$("#trfHeader").text(`Quotation #${idquotations}`);
|
||||||
|
$("#partsModal").data("idquotations", idquotations);
|
||||||
|
let modal = bootstrap.Modal.getInstance(modalElement) || new bootstrap.Modal(modalElement, {
|
||||||
|
backdrop: true
|
||||||
|
});
|
||||||
|
modal.show();
|
||||||
|
if (typeof window.loadParts === 'function') window.loadParts(null, idquotations);
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
alert('Errore nel caricamento del modale: ' + error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('hidden.bs.modal', '#partsModal', function() {
|
||||||
|
$('#partsModalContainer').empty();
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open').css('padding-right', '');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('hidden.bs.modal', '#annotationsModal', function() {
|
||||||
|
$('#annotationsModalContainer').empty();
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open').css('padding-right', '');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Inizializza DataTables se non siamo in modalità modifica
|
// Inizializza DataTables se non siamo in modalità modifica
|
||||||
if (!document.querySelector('#editForm')) {
|
if (!document.querySelector('#editForm')) {
|
||||||
$('#quotationsTable').DataTable({
|
$('#quotationsTable').DataTable({
|
||||||
@ -524,12 +567,7 @@ if (isset($_GET['edit_id'])) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Modale per le foto in quotations.php -->
|
<!-- Modale per le foto in quotations.php -->
|
||||||
<div class="modal" id="photosModal">
|
|
||||||
<div class="modal-content">
|
|
||||||
<span class="close-btn">×</span>
|
|
||||||
<div class="popup-content"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user