// ===== ANOTADOR YOLO - JAVASCRIPT PRINCIPAL ===== // Variables globales let currentClass = 0; let annotations = []; let annotationCounter = 0; let isSelecting = false; let startX, startY; let currentBox = null; let originalImageData = null; // Configuración de clases const classes = { 0: {"name": "objeto 1", "color": "#ff0000"}, 1: {"name": "objeto 2", "color": "#00ff00"}, 2: {"name": "objeto 3", "color": "#0000ff"}, 3: {"name": "objeto 4", "color": "#ffff00"}, 4: {"name": "objeto 5", "color": "#ff00ff"}, 5: {"name": "objeto 6", "color": "#00ffff"} }; // ===== INICIALIZACIÓN ===== document.addEventListener('DOMContentLoaded', function() { // initializeModal(); // Modal de ayuda no implementado aún initializeClassButtons(); refreshSessions(); // Event listeners principales document.getElementById('imageForm').addEventListener('submit', handleImageUpload); document.getElementById('refreshSessions')?.addEventListener('click', refreshSessions); // Sliders de posición const xSlider = document.getElementById('xPos'); const ySlider = document.getElementById('yPos'); const xValue = document.getElementById('xValue'); const yValue = document.getElementById('yValue'); if (xSlider && xValue) { xSlider.addEventListener('input', function() { xValue.textContent = this.value; }); } if (ySlider && yValue) { ySlider.addEventListener('input', function() { yValue.textContent = this.value; }); } }); // ===== MANEJO DE CLASES ===== function initializeClassButtons() { const container = document.getElementById('classButtons'); if (!container) return; container.innerHTML = Object.entries(classes).map(([id, cls]) => ` `).join(''); // Event listeners para botones de clase container.querySelectorAll('.class-btn').forEach(btn => { btn.addEventListener('click', function() { currentClass = parseInt(this.dataset.class); // Actualizar botones activos container.querySelectorAll('.class-btn').forEach(b => b.classList.remove('active')); this.classList.add('active'); }); }); // Seleccionar primera clase por defecto container.querySelector('.class-btn')?.classList.add('active'); } // ===== MANEJO DE IMÁGENES ===== async function handleImageUpload(event) { event.preventDefault(); const formData = new FormData(event.target); try { const response = await fetch('/generate', { method: 'POST', body: formData }); const result = await response.json(); if (result.image) { displayImage(result.image); clearAnnotations(); } } catch (error) { alert('Error al procesar imagen: ' + error.message); } } function displayImage(base64Image) { const canvas = document.getElementById('imageCanvas'); const ctx = canvas.getContext('2d'); const img = new Image(); img.onload = function() { canvas.width = img.width; canvas.height = img.height; ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0); // Guardar imagen original para exportación originalImageData = base64Image; // Mostrar controles de anotación document.getElementById('annotationControls').style.display = 'block'; canvas.style.display = 'block'; // Configurar eventos de canvas setupCanvasEvents(); }; img.src = base64Image; } // ===== EVENTOS DE CANVAS PARA ANOTACIONES ===== function setupCanvasEvents() { const canvas = document.getElementById('imageCanvas'); // Limpiar eventos previos canvas.removeEventListener('mousedown', handleMouseDown); canvas.removeEventListener('mousemove', handleMouseMove); canvas.removeEventListener('mouseup', handleMouseUp); canvas.addEventListener('mousedown', handleMouseDown); canvas.addEventListener('mousemove', handleMouseMove); canvas.addEventListener('mouseup', handleMouseUp); } function handleMouseDown(e) { if (currentClass === undefined) return; const rect = e.target.getBoundingClientRect(); startX = e.clientX - rect.left; startY = e.clientY - rect.top; isSelecting = true; // Crear caja de selección visual currentBox = document.createElement('div'); currentBox.style.position = 'absolute'; currentBox.style.border = '2px solid ' + classes[currentClass].color; currentBox.style.backgroundColor = classes[currentClass].color + '20'; currentBox.style.pointerEvents = 'none'; currentBox.style.fontSize = '12px'; currentBox.style.color = classes[currentClass].color; currentBox.style.padding = '2px'; currentBox.style.zIndex = '1000'; } function handleMouseMove(e) { if (!isSelecting || !currentBox) return; const rect = e.target.getBoundingClientRect(); const currentX = e.clientX - rect.left; const currentY = e.clientY - rect.top; const left = Math.min(startX, currentX); const top = Math.min(startY, currentY); const width = Math.abs(currentX - startX); const height = Math.abs(currentY - startY); const classColor = classes[currentClass].color; currentBox.style.borderColor = classColor; currentBox.style.backgroundColor = classColor + '20'; currentBox.style.left = (rect.left + left) + 'px'; currentBox.style.top = (rect.top + top + window.scrollY) + 'px'; currentBox.style.width = width + 'px'; currentBox.style.height = height + 'px'; currentBox.textContent = classes[currentClass].name; document.body.appendChild(currentBox); } function handleMouseUp(e) { if (!isSelecting || !currentBox) return; const rect = e.target.getBoundingClientRect(); const endX = e.clientX - rect.left; const endY = e.clientY - rect.top; const left = Math.min(startX, endX); const top = Math.min(startY, endY); const width = Math.abs(endX - startX); const height = Math.abs(endY - startY); if (width > 5 && height > 5) { addAnnotation(left, top, width, height, currentClass); } if (currentBox) { currentBox.remove(); currentBox = null; } isSelecting = false; } // ===== GESTIÓN DE ANOTACIONES ===== function addAnnotation(x, y, width, height, classId) { const annotation = { id: annotationCounter++, x: Math.round(x), y: Math.round(y), width: Math.round(width), height: Math.round(height), class_id: classId, class_name: classes[classId].name }; annotations.push(annotation); updateAnnotationsList(); redrawCanvas(); } function removeAnnotation(id) { annotations = annotations.filter(ann => ann.id !== id); updateAnnotationsList(); redrawCanvas(); } function updateAnnotationsList() { const container = document.getElementById('annotationsList'); if (!container) return; if (annotations.length === 0) { container.innerHTML = '
Sin anotaciones aún
'; return; } container.innerHTML = annotations.map(ann => `No hay sesiones disponibles
'; return; } sessionsList.innerHTML = sessions.map(session => `