diff --git a/vehicle-data-platform/apps/web/src/v2/map/FleetMap.test.tsx b/vehicle-data-platform/apps/web/src/v2/map/FleetMap.test.tsx index a67c5147..79282790 100644 --- a/vehicle-data-platform/apps/web/src/v2/map/FleetMap.test.tsx +++ b/vehicle-data-platform/apps/web/src/v2/map/FleetMap.test.tsx @@ -25,6 +25,14 @@ const markerOptions: Record[] = []; const mapOptions: Record[] = []; const labelLayerOptions: Record[] = []; +function useFastAnimationFrames(stepMs = 2_500) { + let timestamp = 0; + return vi.spyOn(window, 'requestAnimationFrame').mockImplementation((callback) => { + timestamp += stepMs; + return window.setTimeout(() => callback(timestamp), 0); + }); +} + class TestMap { constructor(_container: HTMLDivElement, options: Record) { mapOptions.push(options); @@ -274,6 +282,7 @@ test('cancels an in-flight point animation when the map unmounts', async () => { }); test('skips unchanged refresh redraws and smoothly moves points without replacing their labels', async () => { + useFastAnimationFrames(); window.__LINGNIU_APP_CONFIG__ = { amapWebJsKey: 'amap-web-key' }; window.AMapLoader = { load: vi.fn(async () => amapMock()) }; const view = render( undefined} />); @@ -362,6 +371,7 @@ test('converts AMap GCJ-02 bounds back to WGS-84 before requesting monitor data' }); test('renders one selected plate and smoothly follows it until the map is dragged', async () => { + useFastAnimationFrames(); window.__LINGNIU_APP_CONFIG__ = { amapWebJsKey: 'amap-web-key' }; window.AMapLoader = { load: vi.fn(async () => amapMock()) }; @@ -419,7 +429,7 @@ test('renders one selected plate and smoothly follows it until the map is dragge /> ); await waitFor(() => expect(markerSetPosition).toHaveBeenLastCalledWith(wgs84ToGcj02(113.27, 23.14)), { timeout: 1_800 }); - expect(panTo).toHaveBeenLastCalledWith(wgs84ToGcj02(113.27, 23.14), 1_000); + expect(panTo).toHaveBeenLastCalledWith(wgs84ToGcj02(113.27, 23.14), 5_000); expect(setZoomAndCenter).toHaveBeenCalledTimes(1); const follow = screen.getByRole('button', { name: '跟随车辆' }); @@ -444,7 +454,7 @@ test('renders one selected plate and smoothly follows it until the map is dragge expect(panTo).toHaveBeenCalledTimes(panCountAfterDrag); fireEvent.click(follow); await waitFor(() => expect(follow).toHaveAttribute('aria-pressed', 'true')); - expect(panTo).toHaveBeenLastCalledWith(wgs84ToGcj02(113.29, 23.16), 1_000); + expect(panTo).toHaveBeenLastCalledWith(wgs84ToGcj02(113.29, 23.16), 650); getZoom.mockReturnValue(20); view.rerender( @@ -455,7 +465,7 @@ test('renders one selected plate and smoothly follows it until the map is dragge onSelect={() => undefined} /> ); - await waitFor(() => expect(panTo).toHaveBeenLastCalledWith(wgs84ToGcj02(113.28, 23.15), 1_000)); + await waitFor(() => expect(panTo).toHaveBeenLastCalledWith(wgs84ToGcj02(113.28, 23.15), 650)); expect(setZoomAndCenter).toHaveBeenCalledTimes(1); expect(markerOptions[markerOptions.length - 1]?.content).toContain('is-idle'); diff --git a/vehicle-data-platform/apps/web/src/v2/map/FleetMap.tsx b/vehicle-data-platform/apps/web/src/v2/map/FleetMap.tsx index 8238222b..5f91283a 100644 --- a/vehicle-data-platform/apps/web/src/v2/map/FleetMap.tsx +++ b/vehicle-data-platform/apps/web/src/v2/map/FleetMap.tsx @@ -19,8 +19,9 @@ import type { MonitorViewport } from '../hooks/useMonitorData'; const COLORS = ['#12a46f', '#9aa6b7', '#1677ff', '#f59e0b', '#ef4444']; const CLUSTER_VISUAL_CACHE_LIMIT = 256; -const POINT_MOVE_DURATION_MS = 1_000; -const POINT_MOVE_FRAME_MS = 32; +const POINT_MOVE_DURATION_MS = 5_000; +const POINT_MOVE_FRAME_MS = 50; +const MAP_INTERACTION_PAN_DURATION_MS = 650; const clusterVisualCache = new Map(); function dotDataUrl(color: string) { @@ -595,7 +596,7 @@ export function FleetMap({ vehicles, selectedVin, onSelect, monitorMap, onSelect setFollowSelected(true); const currentZoom = mapRef.current.getZoom?.() ?? 15; if (currentZoom < 15) mapRef.current.setZoomAndCenter?.(15, mapPosition); - else mapRef.current.panTo?.(mapPosition, POINT_MOVE_DURATION_MS); + else mapRef.current.panTo?.(mapPosition, MAP_INTERACTION_PAN_DURATION_MS); centeredVinRef.current = selectedVin; } else if (selectionPositionRef.current && selectionPositionRef.current !== positionKey && followSelectedRef.current) { mapRef.current.panTo?.(mapPosition, POINT_MOVE_DURATION_MS); @@ -624,7 +625,7 @@ export function FleetMap({ vehicles, selectedVin, onSelect, monitorMap, onSelect followSelectedRef.current = next; setFollowSelected(next); if (next && selectedTarget && mapRef.current) { - mapRef.current.panTo?.(wgs84ToGcj02(selectedTarget.longitude, selectedTarget.latitude), POINT_MOVE_DURATION_MS); + mapRef.current.panTo?.(wgs84ToGcj02(selectedTarget.longitude, selectedTarget.latitude), MAP_INTERACTION_PAN_DURATION_MS); } };