Fix camera jumping when opening InfoPanel
All checks were successful
Build Docker Image / build (push) Successful in 4m17s
All checks were successful
Build Docker Image / build (push) Successful in 4m17s
Replace setTimeout/debounce with event-based approach: - Add isInfoLoading computed that tracks all info loading states - Pass infoLoading prop through CatalogPage to CatalogMap - Watch infoLoading transition from true->false to trigger fitBounds - Remove setTimeout hack in favor of proper loading state detection
This commit is contained in:
@@ -51,6 +51,7 @@ const props = withDefaults(defineProps<{
|
||||
entityType?: 'offer' | 'hub' | 'supplier'
|
||||
initialCenter?: [number, number]
|
||||
initialZoom?: number
|
||||
infoLoading?: boolean
|
||||
relatedPoints?: Array<{
|
||||
uuid: string
|
||||
name: string
|
||||
@@ -64,6 +65,7 @@ const props = withDefaults(defineProps<{
|
||||
initialCenter: () => [37.64, 55.76],
|
||||
initialZoom: 2,
|
||||
useServerClustering: false,
|
||||
infoLoading: false,
|
||||
items: () => [],
|
||||
clusteredPoints: () => [],
|
||||
relatedPoints: () => []
|
||||
@@ -693,11 +695,8 @@ watch(() => props.hoveredItem, () => {
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
// Debounced fitBounds to avoid camera jumping when points load incrementally
|
||||
let fitBoundsTimeout: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
// Update related points layer when relatedPoints changes + fit bounds (debounced)
|
||||
watch(() => props.relatedPoints, (points) => {
|
||||
// Update related points layer when relatedPoints changes
|
||||
watch(() => props.relatedPoints, () => {
|
||||
if (!mapRef.value || !mapInitialized.value) return
|
||||
|
||||
// Update the source data immediately
|
||||
@@ -705,26 +704,23 @@ watch(() => props.relatedPoints, (points) => {
|
||||
if (source) {
|
||||
source.setData(relatedPointsGeoJson.value)
|
||||
}
|
||||
|
||||
// Debounce fitBounds - wait for all points to load before zooming
|
||||
if (fitBoundsTimeout) {
|
||||
clearTimeout(fitBoundsTimeout)
|
||||
}
|
||||
|
||||
if (points && points.length > 0) {
|
||||
fitBoundsTimeout = setTimeout(() => {
|
||||
if (!mapRef.value) return
|
||||
const bounds = new LngLatBounds()
|
||||
points.forEach(p => {
|
||||
bounds.extend([p.longitude, p.latitude])
|
||||
})
|
||||
if (!bounds.isEmpty()) {
|
||||
mapRef.value.fitBounds(bounds, { padding: 80, maxZoom: 12 })
|
||||
}
|
||||
}, 300) // Wait 300ms for all points to load
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
// Fit bounds when info loading finishes (all related data loaded)
|
||||
watch(() => props.infoLoading, (loading, wasLoading) => {
|
||||
// Only fit bounds when loading changes from true to false (data finished loading)
|
||||
if (wasLoading && !loading && props.relatedPoints && props.relatedPoints.length > 0) {
|
||||
if (!mapRef.value) return
|
||||
const bounds = new LngLatBounds()
|
||||
props.relatedPoints.forEach(p => {
|
||||
bounds.extend([p.longitude, p.latitude])
|
||||
})
|
||||
if (!bounds.isEmpty()) {
|
||||
mapRef.value.fitBounds(bounds, { padding: 80, maxZoom: 12 })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Watch for pointColor or entityType changes - update colors and icons
|
||||
watch([() => props.pointColor, () => props.entityType], async ([newColor, newType]) => {
|
||||
if (!mapRef.value || !mapInitialized.value) return
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
:hovered-item-id="hoveredId"
|
||||
:hovered-item="hoveredItem"
|
||||
:related-points="relatedPoints"
|
||||
:info-loading="infoLoading"
|
||||
@select-item="onMapSelect"
|
||||
@bounds-change="onBoundsChange"
|
||||
/>
|
||||
@@ -250,6 +251,7 @@ const props = withDefaults(defineProps<{
|
||||
items?: MapItem[]
|
||||
showPanel?: boolean
|
||||
filterByBounds?: boolean
|
||||
infoLoading?: boolean
|
||||
relatedPoints?: Array<{
|
||||
uuid: string
|
||||
name: string
|
||||
@@ -266,6 +268,7 @@ const props = withDefaults(defineProps<{
|
||||
items: () => [],
|
||||
showPanel: false,
|
||||
filterByBounds: false,
|
||||
infoLoading: false,
|
||||
relatedPoints: () => []
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user