From 62996eb76da05316b66e87335f3eb40bb04d0bd4 Mon Sep 17 00:00:00 2001 From: luisgulo Date: Sun, 1 Nov 2026 11:28:07 +0100 Subject: [PATCH] soporte acciones con dedos en tablet --- regla_portland_tablet.html | 75 +++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 42 deletions(-) diff --git a/regla_portland_tablet.html b/regla_portland_tablet.html index 5976250..284530c 100644 --- a/regla_portland_tablet.html +++ b/regla_portland_tablet.html @@ -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; - } @@ -170,20 +166,20 @@
-

1. Medir o Trazar un Rumbo Verdadero (Rv):

+

1. Medir o Trazar un Rumbo Verdadero (Rv)[cite: 3, 10, 11, 12]:

-

2. Corrección Total (Ct) y Rumbo de Aguja (Ra):

+

2. Corrección Total (Ct) y Rumbo de Aguja (Ra)[cite: 3, 10, 11, 12]:

-

3. Trazado de Rutas Múltiples (A ➞ B ➞ C ➞ ...):

+

3. Trazado de Rutas Múltiples (A ➞ B ➞ C ➞ ...)[cite: 10, 11, 12]:

@@ -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) => {