diff --git a/public/css/editorPiscina.css b/public/css/editorPiscina.css index 7830f3c..827c7a0 100644 --- a/public/css/editorPiscina.css +++ b/public/css/editorPiscina.css @@ -1,262 +1,168 @@ -/* ------------------- ESTILO GLOBAL ------------------- */ +/* === Variables === */ :root { --color-primary: #0d6efd; - --color-success: #198754; + --color-secondary: #6c757d; + --color-light: #f9fafb; + --color-border: #dee2e6; --radius-lg: 0.75rem; --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08); - --transition-fast: all 0.25s ease; --font-family: 'Inter', sans-serif; } -html { - overflow-y: scroll; - scroll-behavior: smooth; -} - +/* === Reset === */ body { font-family: var(--font-family); - font-size: clamp(1rem, 1vw + 0.2rem, 1.1rem); - line-height: 1.7; - background-color: #f9fafb; + font-size: 1rem; + background-color: var(--color-light); color: #212529; - margin: 0; - padding: 0; } -/* ------------------- NAVBAR ------------------- */ +/* === Navbar === */ .navbar { min-height: 72px; - padding-top: 1rem !important; - padding-bottom: 1rem !important; } - .navbar .nav-link { font-weight: 500; - font-size: 1rem; - transition: all 0.2s ease; } -.navbar .nav-link:hover { - opacity: 0.85; -} - -.navbar * { - box-sizing: border-box; -} - -/* ------------------- TARJETAS ------------------- */ +/* === Cards === */ .card { border: none; border-radius: var(--radius-lg); box-shadow: var(--shadow-md); - background-color: white; - overflow: visible; } -/* ------------------- FORMULARIOS ------------------- */ +/* === Forms === */ .form-control, .form-select { border-radius: var(--radius-lg); - border: 1px solid #ced4da; - transition: var(--transition-fast); - font-size: 1rem; + border: 1px solid var(--color-border); + transition: border-color 0.2s; } - .form-control:focus, .form-select:focus { border-color: var(--color-primary); box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.15); } -/* ------------------- BOTONES ------------------- */ +/* === Botones === */ button, .btn { border-radius: var(--radius-lg); - padding: 0.6rem 1.2rem; font-weight: 600; - font-size: 1rem; - transition: var(--transition-fast); - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); } - -.btn-primary, -.btn-success, -.btn-outline-primary, -.btn-outline-secondary { - border-width: 2px; -} - .btn-primary { background-color: var(--color-primary); border-color: var(--color-primary); - color: #fff; } .btn-primary:hover { background-color: #084298; - border-color: #084298; -} - -.btn-success { - background-color: var(--color-success); - border-color: var(--color-success); - color: white; -} -.btn-success:hover { - background-color: #145c32; - border-color: #145c32; -} - -.btn-outline-primary { - color: var(--color-primary); - border-color: var(--color-primary); - background-color: white; } +.btn-outline-secondary:hover, .btn-outline-primary:hover { - background-color: var(--color-primary); - color: white; + opacity: 0.9; } -.btn-outline-secondary { - color: #6c757d; - border-color: #6c757d; - background-color: white; -} -.btn-outline-secondary:hover { - background-color: #6c757d; - color: white; -} - -button:disabled, -.btn:disabled { - opacity: 0.65; - cursor: not-allowed; -} - -/* ------------------- PISCINA ------------------- */ +/* === Piscina === */ #piscinaContainer { background-color: #e6f7ff; border: 2px dashed #007bff; - padding: 1rem; border-radius: var(--radius-lg); - width: fit-content; - height: fit-content; - min-width: 300px; - min-height: 200px; + aspect-ratio: 2 / 1; + width: 100%; + height: auto; max-width: 100%; - box-sizing: border-box; + overflow: hidden; } #piscina { - display: block; - width: 100% !important; - height: 100% !important; + width: 100%; + height: 100%; background-image: linear-gradient(to right, rgba(0,0,0,0.05) 1px, transparent 1px), linear-gradient(to bottom, rgba(0,0,0,0.05) 1px, transparent 1px); background-size: 45px 45px; - background-position: top left; - overflow: hidden; + display: block; } -/* ------------------- TIMELINE ------------------- */ +/* === Timeline === */ .timeline-placeholder { - display: flex; - overflow-x: auto; - gap: 10px; - padding: 1rem; - border: 1px solid #ddd; - background: #ffffff; + border: 1px solid #ccc; border-radius: var(--radius-lg); - box-shadow: 0 1px 4px rgba(0,0,0,0.05); + padding: 1rem; + background-color: white; + box-shadow: var(--shadow-md); + overflow-x: auto; } - .timeline-placeholder .step { min-width: 100px; padding: 0.5rem; - border: 1px solid #ccc; background: white; - border-radius: 8px; - text-align: center; - cursor: pointer; + border: 1px solid #ccc; + border-radius: 0.5rem; font-size: 0.85rem; + cursor: pointer; transition: all 0.2s ease; - box-shadow: 1px 1px 3px rgba(0,0,0,0.05); } .timeline-placeholder .step:hover { background-color: #dbeafe; - font-weight: bold; - transform: scale(1.03); } .step.active { - background-color: #0d6efd !important; - color: white !important; + background-color: var(--color-primary); + color: white; font-weight: bold; } -/* ------------------- AUTOCOMPLETADO ------------------- */ +/* === Sugerencias figura === */ #sugerenciasFigura { - margin-top: 4px; - padding: 6px 0; - background-color: #fff; + background: #fff; border: 1px solid #ccc; border-radius: 6px; - box-shadow: 0 2px 8px rgba(0,0,0,0.06); - max-height: 160px; - overflow-y: auto; position: absolute; width: 100%; z-index: 10; + max-height: 160px; + overflow-y: auto; } #sugerenciasFigura button { - display: block; width: 100%; padding: 6px 12px; - font-size: 0.9rem; border: none; background: none; text-align: left; - color: #333; + font-size: 0.9rem; cursor: pointer; - transition: background 0.2s ease; } #sugerenciasFigura button:hover { background-color: #edf6ff; - color: #007bff; font-weight: 500; } -/* ------------------- VISTA PREVIA FIGURA ------------------- */ -#previewFigura img { - margin-top: 8px; - max-width: 100%; - border: 1px solid #ddd; - border-radius: 6px; - height: auto; -} -#previewFigura p { - font-size: 0.85rem; - color: #555; - margin-top: 4px; -} - -/* ------------------- MULTIMEDIA ------------------- */ +/* === Audio === */ #waveform { - width: 100%; - height: 100px; - margin-bottom: 10px; + height: 80px; + background: #f1f3f5; + border-radius: 6px; } #audioPlayer { display: none; } -/* ------------------- RESPONSIVO ------------------- */ +/* === Responsivo === */ @media (max-width: 768px) { - #piscina { - min-height: 280px; - } - .timeline-placeholder .step { min-width: 80px; - font-size: 0.75rem; + } + #piscinaContainer { + aspect-ratio: 1.5 / 1; } } + +/* === Ancho de página controlado === */ +main.container-xl { + max-width: 1440px; + margin-left: auto; + margin-right: auto; + padding-left: 2rem; + padding-right: 2rem; +} diff --git a/public/js/piscina.js b/public/js/piscina.js index c8309a3..34e1e9d 100644 --- a/public/js/piscina.js +++ b/public/js/piscina.js @@ -40,6 +40,8 @@ atletas.forEach(a => { select.addEventListener('change', () => { const datos = JSON.parse(select.value || '{}'); + select.dataset.id = datos.id; // << GUARDAS el ObjectId real + if (datos.idPers) { document.getElementById('idPersonalizado').value = datos.idPers; document.getElementById('idPersonalizado').disabled = true; @@ -48,6 +50,7 @@ select.addEventListener('change', () => { document.getElementById('idPersonalizado').disabled = false; } }); + let figurasFINA = []; try { const res = await fetch('/catalog/figurasFINA.json'); @@ -192,7 +195,7 @@ tipoPiscinaSelect.addEventListener('change', async () => { return; } - const idAtleta = select.value; + const idAtleta = select.dataset.id; const rol = document.getElementById('rolAtleta').value.trim().toLowerCase(); const idPersonalizado = document.getElementById('idPersonalizado').value.trim(); const figura = inputFigura?.value.trim(); @@ -235,114 +238,122 @@ tipoPiscinaSelect.addEventListener('change', async () => { function dibujarAtleta(atleta) { - const color = atleta.rol === 'volador' ? 'purple' : atleta.rol === 'pilar' ? 'blue' : 'red'; + const color = atleta.rol === 'volador' ? 'purple' : atleta.rol === 'pilar' ? 'blue' : 'red'; + const metros = convertirAMetros(atleta.x, atleta.y); - const metros = convertirAMetros(atleta.x, atleta.y); + const circle = new Konva.Circle({ + x: atleta.x, + y: atleta.y, + radius: 15, + fill: color, + stroke: 'white', + strokeWidth: 2, + draggable: !modoDireccion + }); - const circle = new Konva.Circle({ - x: atleta.x, - y: atleta.y, - radius: 15, - fill: color, - stroke: 'white', - strokeWidth: 2, - draggable: !modoDireccion - }); + const text = new Konva.Text({ + x: atleta.x, + y: atleta.y, + text: atleta.idPersonalizado, + fontSize: 12, + fill: 'white', + fontStyle: 'bold', + align: 'center' + }); + text.offsetX(text.width() / 2); + text.offsetY(text.height() / 2); - const text = new Konva.Text({ - x: atleta.x, - y: atleta.y, - text: atleta.idPersonalizado, - fontSize: 12, - fill: 'white', - fontStyle: 'bold', - align: 'center' - }); - text.offsetX(text.width() / 2); - text.offsetY(text.height() / 2); + const figuraText = new Konva.Text({ + x: atleta.x - 25, + y: atleta.y + 18, + text: atleta.figura || '', + fontSize: 10, + fill: '#333', + fontStyle: 'italic' + }); + figuraText.listening(false); + const coordText = new Konva.Text({ + x: atleta.x - 35, + y: atleta.y + 30, + text: `${metros.metrosX}m, ${metros.metrosY}m`, + fontSize: 9, + fill: '#666' + }); + coordText.listening(false); - const figuraText = new Konva.Text({ - x: atleta.x - 25, - y: atleta.y + 18, - text: atleta.figura || '', - fontSize: 10, - fill: '#333', - fontStyle: 'italic' - }); - figuraText.listening(false); - - const coordText = new Konva.Text({ - x: atleta.x - 35, - y: atleta.y + 30, - text: `${metros.metrosX}m, ${metros.metrosY}m`, - fontSize: 9, - fill: '#666' - }); - coordText.listening(false); - - circle.on('dblclick', () => { - const i = formacionActual.findIndex(a => a.idPersonalizado === atleta.idPersonalizado); - const html = ` -