修复馆内模型初始视图与点位返回复位
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
lyf
2026-07-15 18:20:18 +08:00
parent 1072b25c46
commit 6566d38cb0
11 changed files with 568 additions and 44 deletions

View File

@@ -1999,8 +1999,12 @@ const handleResize = () => {
const container = getContainerElement()
if (!container || !camera || !renderer) return
const width = Math.max(1, container.clientWidth)
const height = Math.max(1, container.clientHeight)
const width = container.clientWidth
const height = container.clientHeight
// Kept-alive uni-app pages briefly report a zero-sized canvas while a detail page is on top.
// Treat that as hidden state instead of a real aspect-ratio change, otherwise a return reset
// would rebuild the floor baseline against a synthetic 1:1 viewport.
if (width <= 1 || height <= 1) return
const nextAspect = width / height
if (Math.abs(camera.aspect - nextAspect) > 1e-6) clearFloorViewBaselines()
camera.aspect = nextAspect
@@ -3391,19 +3395,39 @@ const restoreCameraSnapshot = (snapshot: CameraSnapshot) => {
cameraSnapshotRestoreCount += 1
cancelCameraTween()
clearProgrammaticCameraTimer()
isProgrammaticCameraChange = false
camera.position.copy(snapshot.position)
camera.up.copy(snapshot.up)
camera.fov = snapshot.fov
camera.zoom = snapshot.zoom
camera.near = snapshot.near
camera.far = snapshot.far
camera.updateProjectionMatrix()
controls.target.copy(snapshot.target)
controls.update()
// OrbitControls 以 position/target 同步内部球坐标后,恢复快照四元数以保存精确观察方向。
camera.quaternion.copy(snapshot.quaternion)
camera.updateMatrixWorld()
isProgrammaticCameraChange = true
// OrbitControls clamps the camera during update(). Make the immutable snapshot part of the
// valid range before synchronizing controls, otherwise a large floor baseline is clipped by
// the previous view's maxDistance and each reset converges to a different camera distance.
const snapshotDistance = snapshot.position.distanceTo(snapshot.target)
if (Number.isFinite(snapshotDistance) && snapshotDistance > 0) {
controls.minDistance = Math.min(controls.minDistance, snapshotDistance)
controls.maxDistance = Math.max(controls.maxDistance, snapshotDistance)
}
// Consume any gesture delta left in OrbitControls without damping before applying the
// snapshot. Subsequent render frames must not continue a drag or wheel gesture after reset.
const dampingEnabled = controls.enableDamping
controls.enableDamping = false
try {
controls.update()
camera.position.copy(snapshot.position)
camera.up.copy(snapshot.up)
camera.fov = snapshot.fov
camera.zoom = snapshot.zoom
camera.near = snapshot.near
camera.far = snapshot.far
camera.updateProjectionMatrix()
controls.target.copy(snapshot.target)
controls.update()
// OrbitControls 以 position/target 同步内部球坐标后,恢复快照四元数以保存精确观察方向。
camera.quaternion.copy(snapshot.quaternion)
camera.updateMatrixWorld()
} finally {
controls.enableDamping = dampingEnabled
isProgrammaticCameraChange = false
}
}
const applyReferenceOverviewCameraState = () => {

View File

@@ -10,7 +10,7 @@
:asset-base-url="indoorAssetBaseUrl"
:model-source="effectiveIndoorModelSource"
:initial-floor-id="activeFloorId"
:initial-view="indoorView"
:initial-view="indoorInitialView"
:show-controls="false"
:show-poi="shouldShowIndoorPois"
:visible-poi-ids="visiblePoiIds"