| | |
| | | const ACTIVE_TRIP_VIEWPORT_SYNC_INTERVAL_MS = 600; |
| | | const ACTIVE_TRIP_VIEWPORT_SYNC_ANIMATION_MS = 300; |
| | | const ACTIVE_TRIP_VIEWPORT_SAFE_X_MARGIN_RATIO = 0.08; |
| | | const USER_GESTURE_HOLD_MS = 8000; |
| | | const USER_GESTURE_CAUSED_BY = new Set(["gesture", "drag", "scale"]); |
| | | |
| | | const buildSiteViewportPoint = (site: any) => { |
| | | if (!site?.latitude || !site?.longitude) { |
| | |
| | | : mapBottomPadding; |
| | | return computeAdaptiveBottomPadding(points, basePadding); |
| | | }, [mapBottomPadding]); |
| | | |
| | | /** |
| | | * 用户手势拖拽/缩放地图后,暂停一段时间的自动视口同步,避免地图被立刻抢回。 |
| | | */ |
| | | const handleRegionChange = useCallback((event: any) => { |
| | | const causedBy = String(event?.causedBy || event?.detail?.causedBy || "").toLowerCase(); |
| | | if (!USER_GESTURE_CAUSED_BY.has(causedBy)) { |
| | | return; |
| | | } |
| | | holdDynamicScale(USER_GESTURE_HOLD_MS); |
| | | }, [holdDynamicScale]); |
| | | |
| | | const updateMapViewportPadding = useCallback(() => { |
| | | Taro.nextTick(() => { |
| | |
| | | }); |
| | | }, [computeBottomPadding, holdDynamicScale, mapBottomPadding]); |
| | | |
| | | /** |
| | | * 接驾中/行程中复位地图时,优先把整条线路完整放回屏幕,而不是只把中心点拉回车辆位置。 |
| | | */ |
| | | const resetActiveTripViewportToRoute = useCallback(() => { |
| | | const { pickupSite, dropoffSite } = resolveViewportSites(); |
| | | const { points } = buildViewportPayload("route", pickupSite, dropoffSite); |
| | | if (points.length === 0) { |
| | | return; |
| | | } |
| | | lastActiveTripViewportSyncAtRef.current = Date.now(); |
| | | updateViewportByPayload("route", points); |
| | | }, [ |
| | | deps.endSite, |
| | | deps.routePoints, |
| | | deps.startSite, |
| | | deps.tripStatus, |
| | | updateViewportByPayload |
| | | ]); |
| | | |
| | | const syncActiveTripViewportToVehicle = useCallback(() => { |
| | | if (![TripStatus.VehicleApproaching, TripStatus.InService].includes(deps.tripStatus)) { |
| | | return; |
| | |
| | | if (!hasLatitudeDelta && !hasLongitudeDelta) { |
| | | return; |
| | | } |
| | | lastActiveTripViewportSyncAtRef.current = Date.now(); |
| | | const mapCtx = Taro.createMapContext("map"); |
| | | mapCtx.moveToLocation({ |
| | | latitude: desiredCenterLatitude, |
| | | longitude: desiredCenterLongitude |
| | | }); |
| | | if (activeTripViewportSyncTimerRef.current) { |
| | | clearTimeout(activeTripViewportSyncTimerRef.current); |
| | | } |
| | | activeTripViewportSyncTimerRef.current = setTimeout(() => { |
| | | if (typeof deps.setLatitude === "function") { |
| | | deps.setLatitude(desiredCenterLatitude); |
| | | } |
| | | if (typeof deps.setLongitude === "function") { |
| | | deps.setLongitude(desiredCenterLongitude); |
| | | } |
| | | activeTripViewportSyncTimerRef.current = null; |
| | | }, ACTIVE_TRIP_VIEWPORT_SYNC_ANIMATION_MS); |
| | | resetActiveTripViewportToRoute(); |
| | | }) |
| | | .finally(() => { |
| | | activeTripViewportSyncingRef.current = false; |
| | |
| | | ensureMapRect, |
| | | getDynamicScaleHoldUntil, |
| | | getMapCenterLocation, |
| | | getMapRegion |
| | | getMapRegion, |
| | | resetActiveTripViewportToRoute |
| | | ]); |
| | | |
| | | useEffect(() => { |
| | |
| | | mapBottomPadding, |
| | | updateMapViewportPadding, |
| | | resolveSafeTopInset, |
| | | computeBottomPadding |
| | | computeBottomPadding, |
| | | handleRegionChange |
| | | }; |
| | | } |