diff --git a/frontend/src/composables/useFlujoPrincipal.ts b/frontend/src/composables/useFlujoPrincipal.ts index b75b1c5..482ef26 100644 --- a/frontend/src/composables/useFlujoPrincipal.ts +++ b/frontend/src/composables/useFlujoPrincipal.ts @@ -28,7 +28,8 @@ export const useFlujoPrincipal = () => { const procesarSeleccionDeRuta = async ( _ruta: { id: string }, paradas: BusStop[], - map: google.maps.Map | undefined + map: google.maps.Map | undefined, + skipGuidedZoom = false ) => { if (!map) return @@ -67,7 +68,15 @@ export const useFlujoPrincipal = () => { // ── PASO 3: Dibujar ruta completa (fondo, gris tenue) ─ await trazarRuta(paradasFormateadas, map, true); - // ── PASO 4: Calcular parada más cercana ─────────────── + // ── PASO 4: Calcular parada más cercana (Omitir si skipGuidedZoom) ─────────────── + if (skipGuidedZoom) { + // Si omitimos el zoom guiado, solo hacemos un zoom general a la ruta + const bounds = new google.maps.LatLngBounds() + paradasFormateadas.forEach(p => bounds.extend(new google.maps.LatLng(p.latitud, p.longitud))) + map.fitBounds(bounds, { top: 100, bottom: 100, left: 60, right: 60 }) + return; + } + await encontrarParadaCercana(ubicacion, paradas, map) const paradaCercanaFound = paradaCercana.value diff --git a/frontend/src/views/MapView.vue b/frontend/src/views/MapView.vue index f26c51f..c829763 100644 --- a/frontend/src/views/MapView.vue +++ b/frontend/src/views/MapView.vue @@ -270,8 +270,9 @@ watch( if (routeId) { // Route stops are automatically loaded when route is selected - // Update map markers for the selected route - await updateMapMarkers(); + // Si el ID cambió pero no estamos en el flujo de búsqueda (selectRouteAndClose), + // forzamos el skipZoom para evitar la animación de "encontrando parada". + await updateMapMarkers(true); } else { // Clear markers when no route is selected lastProcessedRouteId.value = null; @@ -301,7 +302,7 @@ watch( newStops.some((stop, idx) => stop.id !== oldStops[idx]?.id)) { console.log('Route stops changed - updating markers') - await updateMapMarkers(); + await updateMapMarkers(true); } } } @@ -314,7 +315,7 @@ function clearMapMarkers() { limpiarTodoCentralizado() } -async function updateMapMarkers() { +async function updateMapMarkers(skipZoom = false) { if (!isLoaded.value || !map.value || isUpdatingMarkers.value) return; isUpdatingMarkers.value = true; @@ -330,7 +331,8 @@ async function updateMapMarkers() { const selectedRouteObj = routeStore.allRoutes.find(r => r.id === currentRequestRouteId) || { id: currentRequestRouteId, short_name: currentRequestRouteId }; // Llamar al procesador de flujo principal, lo cual limpia el mapa y centra. - await procesarSeleccionDeRuta(selectedRouteObj, stops as BusStop[], map.value); + // Usamos skipZoom para evitar la animación intrusiva de búsqueda cuando no es desde el buscador + await procesarSeleccionDeRuta(selectedRouteObj, stops as BusStop[], map.value, skipZoom); // ⛔ ABORTAR SI EL USUARIO LIMPIÓ EL MAPA MIENTRAS DIBUJÁBAMOS if (routeStore.selectedRouteId !== currentRequestRouteId) { @@ -930,7 +932,7 @@ async function highlightOptimalStopForRoute() { position: absolute; bottom: 80px; /* Separado del borde inferior/menú */ left: 50%; - transform: translateX(-50%); + transform: translateX(-50%) translateY(0); width: 92%; max-width: 400px; background: rgba(255, 255, 255, 0.85); @@ -943,6 +945,7 @@ async function highlightOptimalStopForRoute() { box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15); color: #000; overflow: hidden; + transition: transform 0.6s cubic-bezier(0.32, 0.72, 0, 1), opacity 0.5s ease; } @media (prefers-color-scheme: dark) { @@ -1696,7 +1699,7 @@ html.light-theme .uber-search-trigger-compact { } .sheet-slide-enter-from, .sheet-slide-leave-to { - transform: translateY(100%) scale(0.98); + transform: translateX(-50%) translateY(110%) scale(0.95); opacity: 0; }