soporte acciones con dedos en tablet
This commit is contained in:
1 parent
900f8d3371
commit
62996eb76d
1 file changed
+33
-42
+33
-42
@@ -18,10 +18,6 @@
|
|||||||
.cursor-grab-custom { cursor: grab; }
|
.cursor-grab-custom { cursor: grab; }
|
||||||
.cursor-grab-custom:active { cursor: grabbing; }
|
.cursor-grab-custom:active { cursor: grabbing; }
|
||||||
.cursor-crosshair-custom { cursor: crosshair; }
|
.cursor-crosshair-custom { cursor: crosshair; }
|
||||||
/* Previene el scroll por defecto del navegador al tocar el Canvas */
|
|
||||||
#plotterCanvas {
|
|
||||||
touch-action: none;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</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">
|
<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>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-2.5 leading-relaxed">
|
<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">
|
<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>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.</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.</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>
|
</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">
|
<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>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.</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>
|
</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">
|
<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>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="pt-2 flex justify-end">
|
<div class="pt-2 flex justify-end">
|
||||||
@@ -563,7 +559,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateReadouts() {
|
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 baseReferenceAngle = (360 - state.rulerAngle) % 360;
|
||||||
let rv = (state.rulerAngle + 90 - (state.diskAngle - baseReferenceAngle)) % 360;
|
let rv = (state.rulerAngle + 90 - (state.diskAngle - baseReferenceAngle)) % 360;
|
||||||
if (rv < 0) rv += 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";
|
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";
|
document.getElementById('btn-ab-text').innerText = "Finalizar Puntos";
|
||||||
badge.classList.remove('hidden');
|
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 {
|
} else {
|
||||||
resetToMoveMode();
|
resetToMoveMode();
|
||||||
}
|
}
|
||||||
@@ -613,8 +608,8 @@
|
|||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lógica compartida para inicio de interacción (Mouse / Touch)
|
// --- GESTIÓN DE RATÓN Y TÁCTIL UNIFICADA ---
|
||||||
function handlePointerStart(clientX, clientY) {
|
function handleInteractionStart(clientX, clientY) {
|
||||||
const rect = canvas.getBoundingClientRect();
|
const rect = canvas.getBoundingClientRect();
|
||||||
const clickX = clientX - rect.left;
|
const clickX = clientX - rect.left;
|
||||||
const clickY = clientY - rect.top;
|
const clickY = clientY - rect.top;
|
||||||
@@ -644,33 +639,34 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
draw();
|
draw();
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dist = Math.hypot(clickX - state.rulerX, clickY - state.rulerY);
|
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.isDragging = true;
|
||||||
state.dragStartX = clickX - state.rulerX;
|
state.dragStartX = clickX - state.rulerX;
|
||||||
state.dragStartY = clickY - state.rulerY;
|
state.dragStartY = clickY - state.rulerY;
|
||||||
canvas.classList.remove('cursor-grab-custom');
|
canvas.classList.remove('cursor-grab-custom');
|
||||||
canvas.classList.add('cursor-grabbing');
|
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 handleInteractionMove(clientX, clientY) {
|
||||||
function handlePointerMove(clientX, clientY) {
|
|
||||||
if (state.isDragging && state.mode === 'MOVE') {
|
if (state.isDragging && state.mode === 'MOVE') {
|
||||||
const rect = canvas.getBoundingClientRect();
|
const rect = canvas.getBoundingClientRect();
|
||||||
state.rulerX = (clientX - rect.left) - state.dragStartX;
|
state.rulerX = (clientX - rect.left) - state.dragStartX;
|
||||||
state.rulerY = (clientY - rect.top) - state.dragStartY;
|
state.rulerY = (clientY - rect.top) - state.dragStartY;
|
||||||
draw();
|
draw();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lógica compartida para fin de interacción
|
function handleInteractionEnd() {
|
||||||
function handlePointerEnd() {
|
|
||||||
if (state.isDragging) {
|
if (state.isDragging) {
|
||||||
state.isDragging = false;
|
state.isDragging = false;
|
||||||
canvas.classList.remove('cursor-grabbing');
|
canvas.classList.remove('cursor-grabbing');
|
||||||
@@ -678,45 +674,40 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- MANEJADORES EVENTOS MOUSE ---
|
// Eventos de Ratón
|
||||||
canvas.addEventListener('mousedown', (e) => {
|
canvas.addEventListener('mousedown', (e) => {
|
||||||
handlePointerStart(e.clientX, e.clientY);
|
handleInteractionStart(e.clientX, e.clientY);
|
||||||
});
|
});
|
||||||
|
|
||||||
canvas.addEventListener('mousemove', (e) => {
|
canvas.addEventListener('mousemove', (e) => {
|
||||||
handlePointerMove(e.clientX, e.clientY);
|
handleInteractionMove(e.clientX, e.clientY);
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('mouseup', () => {
|
window.addEventListener('mouseup', () => {
|
||||||
handlePointerEnd();
|
handleInteractionEnd();
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- MANEJADORES EVENTOS TOUCH (TABLETS / MÓVILES) ---
|
// Eventos Táctiles (Tablet / Móvil)
|
||||||
canvas.addEventListener('touchstart', (e) => {
|
canvas.addEventListener('touchstart', (e) => {
|
||||||
if (e.touches.length === 1) {
|
if (e.touches.length === 1) {
|
||||||
const touch = e.touches[0];
|
const touch = e.touches[0];
|
||||||
const isDraggingRuler = handlePointerStart(touch.clientX, touch.clientY);
|
const captured = handleInteractionStart(touch.clientX, touch.clientY);
|
||||||
// Prevenir el scroll del mapa si se está tocando la regla o agregando puntos
|
if (captured || state.mode === 'ADD_POINTS') {
|
||||||
if (isDraggingRuler || state.mode === 'ADD_POINTS') {
|
e.preventDefault(); // Evita scroll solo si estás moviendo la regla o añadiendo puntos
|
||||||
e.preventDefault();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, { passive: false });
|
}, { passive: false });
|
||||||
|
|
||||||
canvas.addEventListener('touchmove', (e) => {
|
canvas.addEventListener('touchmove', (e) => {
|
||||||
if (state.isDragging && e.touches.length === 1) {
|
if (state.isDragging && e.touches.length === 1) {
|
||||||
e.preventDefault(); // Prevenir desplazamiento de pantalla mientras se arrastra la regla
|
|
||||||
const touch = e.touches[0];
|
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 });
|
}, { passive: false });
|
||||||
|
|
||||||
window.addEventListener('touchend', () => {
|
canvas.addEventListener('touchend', () => {
|
||||||
handlePointerEnd();
|
handleInteractionEnd();
|
||||||
});
|
|
||||||
|
|
||||||
window.addEventListener('touchcancel', () => {
|
|
||||||
handlePointerEnd();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('disk-angle-slider').addEventListener('input', (e) => {
|
document.getElementById('disk-angle-slider').addEventListener('input', (e) => {
|
||||||
|
|||||||
Reference in new issue
Block a user