38 lines
1.1 KiB
TypeScript
38 lines
1.1 KiB
TypeScript
import { useEffect } from 'react'
|
|
import { useCesiumViewer } from './cesiumContext'
|
|
import { useMapStore } from '../store/mapStore'
|
|
import { rectangleToBbox } from './geoUtils'
|
|
|
|
/**
|
|
* Attaches a scene.preUpdate listener that writes camera height and
|
|
* the current view bbox to mapStore on every frame.
|
|
*
|
|
* Throttled so the store update fires at most once per 200 ms to avoid
|
|
* triggering expensive API queries on every rendered frame.
|
|
*/
|
|
export function useCesiumCamera() {
|
|
const viewer = useCesiumViewer()
|
|
const setCameraState = useMapStore((s) => s.setCameraState)
|
|
|
|
useEffect(() => {
|
|
let lastFired = 0
|
|
const THROTTLE_MS = 200
|
|
|
|
const removeListener = viewer.scene.preUpdate.addEventListener(() => {
|
|
const now = Date.now()
|
|
if (now - lastFired < THROTTLE_MS) return
|
|
lastFired = now
|
|
|
|
const height = viewer.camera.positionCartographic.height
|
|
const rect = viewer.camera.computeViewRectangle()
|
|
if (rect) {
|
|
setCameraState(height, rectangleToBbox(rect))
|
|
}
|
|
})
|
|
|
|
return () => {
|
|
removeListener()
|
|
}
|
|
}, [viewer, setCameraState])
|
|
}
|