soporte acciones con dedos en tablet

This commit is contained in:
luisgulo committed 2026-11-01 11:28:07 +01:00
1 parent 900f8d3371
commit 62996eb76d
1 file changed
+33 -42
+33 -42
View File
@@ -18,10 +18,6 @@
.cursor-grab-custom { cursor: grab; }
.cursor-grab-custom:active { cursor: grabbing; }
.cursor-crosshair-custom { cursor: crosshair; }
/* Previene el scroll por defecto del navegador al tocar el Canvas */
#plotterCanvas {
touch-action: none;
}
</style>
</head>
<body class="bg-slate-950 text-slate-100 h-screen w-screen flex flex-col font-sans select-none overflow-hidden m-0 p-0">
@@ -170,20 +166,20 @@
</button>
</div>
<div class="space-y-2.5 leading-relaxed">
<p><strong>1. Medir o Trazar un Rumbo Verdadero (Rv):</strong></p>
<p><strong>1. Medir o Trazar un Rumbo Verdadero (Rv)[cite: 3, 10, 11, 12]:</strong></p>
<ul class="list-disc list-inside space-y-1 text-slate-400 pl-2">
<li>Coloca el borde recto de la regla uniendo tu origen y tu destino. Asegúrate de que la <strong>Gran Flecha Azul</strong> apunte en el sentido de la navegación.</li>
<li>Gira el disco central de la brújula (Rosa de los Vientos) hasta que las líneas de su cuadrícula interna queden perfectamente paralelas a los <strong>meridianos (líneas Norte-Sur)</strong> de la carta.</li>
<li>Lee directamente en el transportador el <strong>Rumbo Verdadero (Rv)</strong> indicado por la marca de lectura fija.</li>
<li>Coloca el borde recto de la regla uniendo tu origen y tu destino[cite: 3, 10, 11, 12]. Asegúrate de que la <strong>Gran Flecha Azul</strong> apunte en el sentido de la navegación[cite: 3, 10, 11, 12].</li>
<li>Gira el disco central de la brújula (Rosa de los Vientos) hasta que las líneas de su cuadrícula interna queden perfectamente paralelas a los <strong>meridianos (líneas Norte-Sur)</strong> de la carta[cite: 3, 10, 11, 12].</li>
<li>Lee directamente en el transportador el <strong>Rumbo Verdadero (Rv)</strong> indicado por la marca de lectura fija[cite: 3, 10, 11, 12].</li>
</ul>
<p><strong>2. Corrección Total (Ct) y Rumbo de Aguja (Ra):</strong></p>
<p><strong>2. Corrección Total (Ct) y Rumbo de Aguja (Ra)[cite: 3, 10, 11, 12]:</strong></p>
<ul class="list-disc list-inside space-y-1 text-slate-400 pl-2">
<li>Ajusta la corrección total Ct = (±dm) + (±Δ) en el deslizador lateral.</li>
<li>Obtén el Rumbo Magnético o de Aguja (Rm/Ra) aplicando la fórmula clásica de corrección.</li>
<li>Ajusta la corrección total Ct = (±dm) + (±Δ) en el deslizador lateral[cite: 3, 10, 11, 12].</li>
<li>Obtén el Rumbo Magnético o de Aguja (Rm/Ra) aplicando la fórmula clásica de corrección[cite: 3, 10, 11, 12].</li>
</ul>
<p><strong>3. Trazado de Rutas Múltiples (A ➞ B ➞ C ➞ ...):</strong></p>
<p><strong>3. Trazado de Rutas Múltiples (A ➞ B ➞ C ➞ ...)[cite: 10, 11, 12]:</strong></p>
<ul class="list-disc list-inside space-y-1 text-slate-400 pl-2">
<li>Haz clic en <strong>"Añadir Puntos Ruta"</strong> para marcar secuencialmente los waypoints en la carta. El primer tramo (A ➞ B) orientará la regla automáticamente; para los siguientes tramos (B ➞ C ➞ ...), el usuario debe orientar y mover la regla manualmente sobre la línea trazada.</li>
<li>Haz clic en <strong>"Añadir Puntos Ruta"</strong> para marcar secuencialmente los waypoints en la carta[cite: 10, 11, 12]. El primer tramo (A ➞ B) orientará la regla automáticamente; para los siguientes tramos (B ➞ C ➞ ...), el usuario debe orientar y mover la regla manualmente sobre la línea trazada[cite: 10, 11, 12].</li>
</ul>
</div>
<div class="pt-2 flex justify-end">
@@ -563,7 +559,6 @@
}
function updateReadouts() {
// Cálculo preciso unificado del Rumbo Verdadero (Rv) considerando la diferencia entre regla y brújula
let baseReferenceAngle = (360 - state.rulerAngle) % 360;
let rv = (state.rulerAngle + 90 - (state.diskAngle - baseReferenceAngle)) % 360;
if (rv < 0) rv += 360;
@@ -591,7 +586,7 @@
btn.className = "bg-rose-500 hover:bg-rose-400 text-slate-950 font-bold px-3.5 py-1 rounded-lg text-xs transition-all flex items-center gap-2 shadow-md";
document.getElementById('btn-ab-text').innerText = "Finalizar Puntos";
badge.classList.remove('hidden');
statusText.innerText = "Haz clic para añadir puntos en la carta (A -> B -> C...)";
statusText.innerText = "Haz clic en la carta para añadir puntos (A -> B -> C...)";
} else {
resetToMoveMode();
}
@@ -613,8 +608,8 @@
draw();
}
// Lógica compartida para inicio de interacción (Mouse / Touch)
function handlePointerStart(clientX, clientY) {
// --- GESTIÓN DE RATÓN Y TÁCTIL UNIFICADA ---
function handleInteractionStart(clientX, clientY) {
const rect = canvas.getBoundingClientRect();
const clickX = clientX - rect.left;
const clickY = clientY - rect.top;
@@ -644,33 +639,34 @@
}
draw();
return false;
return true;
}
const dist = Math.hypot(clickX - state.rulerX, clickY - state.rulerY);
if (dist < 250) {
// Radio de toque amplio para asegurar que coja la regla cómodamente en tablets (aprox 300px)
if (dist < 300) {
state.isDragging = true;
state.dragStartX = clickX - state.rulerX;
state.dragStartY = clickY - state.rulerY;
canvas.classList.remove('cursor-grab-custom');
canvas.classList.add('cursor-grabbing');
return true; // Se inició el arrastre
return true; // Capturado por la regla
}
return false;
return false; // Tocó fuera de la regla, permitir scroll del mapa
}
// Lógica compartida para movimiento (Mouse / Touch)
function handlePointerMove(clientX, clientY) {
function handleInteractionMove(clientX, clientY) {
if (state.isDragging && state.mode === 'MOVE') {
const rect = canvas.getBoundingClientRect();
state.rulerX = (clientX - rect.left) - state.dragStartX;
state.rulerY = (clientY - rect.top) - state.dragStartY;
draw();
return true;
}
return false;
}
// Lógica compartida para fin de interacción
function handlePointerEnd() {
function handleInteractionEnd() {
if (state.isDragging) {
state.isDragging = false;
canvas.classList.remove('cursor-grabbing');
@@ -678,45 +674,40 @@
}
}
// --- MANEJADORES EVENTOS MOUSE ---
// Eventos de Ratón
canvas.addEventListener('mousedown', (e) => {
handlePointerStart(e.clientX, e.clientY);
handleInteractionStart(e.clientX, e.clientY);
});
canvas.addEventListener('mousemove', (e) => {
handlePointerMove(e.clientX, e.clientY);
handleInteractionMove(e.clientX, e.clientY);
});
window.addEventListener('mouseup', () => {
handlePointerEnd();
handleInteractionEnd();
});
// --- MANEJADORES EVENTOS TOUCH (TABLETS / MÓVILES) ---
// Eventos Táctiles (Tablet / Móvil)
canvas.addEventListener('touchstart', (e) => {
if (e.touches.length === 1) {
const touch = e.touches[0];
const isDraggingRuler = handlePointerStart(touch.clientX, touch.clientY);
// Prevenir el scroll del mapa si se está tocando la regla o agregando puntos
if (isDraggingRuler || state.mode === 'ADD_POINTS') {
e.preventDefault();
const captured = handleInteractionStart(touch.clientX, touch.clientY);
if (captured || state.mode === 'ADD_POINTS') {
e.preventDefault(); // Evita scroll solo si estás moviendo la regla o añadiendo puntos
}
}
}, { passive: false });
canvas.addEventListener('touchmove', (e) => {
if (state.isDragging && e.touches.length === 1) {
e.preventDefault(); // Prevenir desplazamiento de pantalla mientras se arrastra la regla
const touch = e.touches[0];
handlePointerMove(touch.clientX, touch.clientY);
handleInteractionMove(touch.clientX, touch.clientY);
e.preventDefault(); // Bloquea el scroll de la página mientras arrastras la regla
}
}, { passive: false });
window.addEventListener('touchend', () => {
handlePointerEnd();
});
window.addEventListener('touchcancel', () => {
handlePointerEnd();
canvas.addEventListener('touchend', () => {
handleInteractionEnd();
});
document.getElementById('disk-angle-slider').addEventListener('input', (e) => {