swimmingArt/public/js/simulador.js

158 lines
4.6 KiB
JavaScript

document.addEventListener("DOMContentLoaded", async () => {
const rutinaId = new URLSearchParams(window.location.search).get("routineId");
const formationIndex = parseInt(new URLSearchParams(window.location.search).get("formationIndex"));
if (!rutinaId || isNaN(formationIndex)) {
return alert("No se proporcionó ID de rutina o índice de formación.");
}
const tituloRutina = document.getElementById("tituloRutina");
const tipoRutina = document.getElementById("tipoRutina");
const modalidadRutina = document.getElementById("modalidadRutina");
const audioPlayer = document.getElementById("audioPlayer");
const playBtn = document.getElementById("playPauseBtn");
const timeline = document.getElementById("lineaTiempo");
const rutina = await fetch(`/api/rutinas/${rutinaId}`).then(res => res.json());
const modalidad = rutina.modalidad;
tituloRutina.textContent = rutina.title || rutina.nombreCompetencia;
tipoRutina.textContent = rutina.tipoCompetencia;
modalidadRutina.textContent = modalidad;
if (rutina.musicUrl) {
audioPlayer.src = rutina.musicUrl;
playBtn.onclick = () => {
if (audioPlayer.paused) {
audioPlayer.play();
playBtn.textContent = "⏸ Pausar";
} else {
audioPlayer.pause();
playBtn.textContent = "▶ Reproducir";
}
};
} else {
playBtn.style.display = "none";
}
const piscinaWidth = rutina.piscina?.width || 850;
const piscinaHeight = rutina.piscina?.height || 400;
const escalaX = 25 / piscinaWidth;
const escalaY = 20 / piscinaHeight;
function convertirAMetros(pxX, pxY) {
return {
metrosX: (pxX * escalaX).toFixed(2),
metrosY: (pxY * escalaY).toFixed(2)
};
}
const stage = new Konva.Stage({
container: "piscina",
width: piscinaWidth,
height: piscinaHeight
});
const layer = new Konva.Layer();
stage.add(layer);
const divPiscina = document.getElementById("piscina");
divPiscina.style.width = `${piscinaWidth}px`;
divPiscina.style.height = `${piscinaHeight}px`;
divPiscina.style.background = "#d4f0ff"; // Azul claro
document.getElementById("piscinaContainer").style.width = `${piscinaWidth + 20}px`;
function dibujarCuadricula(layer, ancho, alto, tamano = 45) {
for (let x = 0; x <= ancho; x += tamano) {
layer.add(new Konva.Line({
points: [x, 0, x, alto],
stroke: '#cceeff',
strokeWidth: 1
}));
}
for (let y = 0; y <= alto; y += tamano) {
layer.add(new Konva.Line({
points: [0, y, ancho, y],
stroke: '#cceeff',
strokeWidth: 1
}));
}
}
dibujarCuadricula(layer, piscinaWidth, piscinaHeight);
function dibujarAtleta(atleta) {
const color = atleta.rol === 'volador' ? 'purple' : atleta.rol === 'pilar' ? 'blue' : 'red';
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
});
const text = new Konva.Text({
x: atleta.x - 10,
y: atleta.y - 7,
text: atleta.idPersonalizado,
fontSize: 14,
fontStyle: 'bold',
fill: 'white'
});
const figuraText = new Konva.Text({
x: atleta.x - 30,
y: atleta.y + 20,
text: atleta.figura || '',
fontSize: 11,
fill: '#333',
fontStyle: 'italic'
});
const coordText = new Konva.Text({
x: atleta.x - 38,
y: atleta.y + 34,
text: `${metros.metrosX}m, ${metros.metrosY}m`,
fontSize: 10,
fill: '#666'
});
layer.add(circle, text, figuraText, coordText);
if (atleta.direccion) {
const dir = new Konva.Line({
points: [atleta.direccion.x1, atleta.direccion.y1, atleta.direccion.x2, atleta.direccion.y2],
stroke: 'black',
strokeWidth: 2,
dash: [4, 4],
pointerLength: 10,
pointerWidth: 10
});
layer.add(dir);
}
layer.draw();
}
const formaciones = await fetch(`/api/rutinas/${rutinaId}/formations`).then(res => res.json());
const formacion = formaciones[formationIndex];
if (!formacion) {
alert("La formación solicitada no existe.");
return;
}
// Pintar solo esta formación
formacion.atletas.forEach(dibujarAtleta);
// Mostrar título visual
const block = document.createElement("button");
block.className = "btn btn-outline-primary btn-sm me-2 step";
block.textContent = `${formacion.nombreColoquial || `Formación ${formationIndex + 1}`} (${formacion.duracion || '?'}s)`;
block.dataset.index = formationIndex;
block.title = formacion.notasTacticas || '';
timeline.appendChild(block);
});