mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
fix(street-level): own the framing flight and the nearest-photo lookup
From the IC8 review of #768, each with tests that fail before: - P1: closing a photo, switching the layer off or destroying it stops the 1.6 s framing flight toward that photo. The flight is claimed with a token before flyToBoundingSphere and released by its complete/cancel callbacks, so cancelFraming() calls camera.cancelFlight() only while the flight is still Street Level's: a newer navigation flight (a search result, a scene) is never cancelled. Turning FOLLOW on also stops it, so the tween cannot overwrite the follow view. - P2: an older nearest-photo lookup can no longer replace a newer choice. The core owns one AbortController per lookup, aborted by a newer lookup, a direct open or cone click, closing the viewer, disable and destroy; the signal reaches source.nearestImages through the provider, and an aborted lookup never surfaces as an error. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
c2f1b54d00
commit
09fc10756c
8 files changed
+371
-27
No files matched your search
@@ -70,11 +70,26 @@ export function createCameraFollow({ state, parts }) {
|
||||
requestRender();
|
||||
}
|
||||
|
||||
/**
|
||||
* The framing flight this module started, while it is still the camera's
|
||||
* current flight. Cesium cancels it (calling `cancel`) when any other
|
||||
* flight starts, so a stale token never cancels someone else's flight.
|
||||
* @type {object|null}
|
||||
*/
|
||||
let framing = null;
|
||||
|
||||
/** Frame the current image from a short distance behind it. */
|
||||
function lookAtPosition() {
|
||||
const { position, bearing, altitude } = state.street;
|
||||
if (!position || !state.viewer) return;
|
||||
const ground = groundHeightAt(position.lon, position.lat, altitude);
|
||||
// Owned before the call: starting it cancels the previous flight (ours
|
||||
// included) synchronously, and a zero-length one completes at once.
|
||||
const flight = {};
|
||||
framing = flight;
|
||||
const release = () => {
|
||||
if (framing === flight) framing = null;
|
||||
};
|
||||
state.viewer.camera.flyToBoundingSphere(
|
||||
new Cesium.BoundingSphere(
|
||||
Cesium.Cartesian3.fromDegrees(position.lon, position.lat, ground + 2),
|
||||
@@ -87,15 +102,32 @@ export function createCameraFollow({ state, parts }) {
|
||||
140,
|
||||
),
|
||||
duration: 1.6,
|
||||
complete: release,
|
||||
cancel: release,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the framing flight if it is still in the air (the image closed or
|
||||
* the layer went off). A flight another feature started since is left be.
|
||||
*/
|
||||
function cancelFraming() {
|
||||
if (!framing) return;
|
||||
// Give up ownership first: cancelFlight delivers `cancel` synchronously.
|
||||
framing = null;
|
||||
state.viewer?.camera?.cancelFlight?.();
|
||||
}
|
||||
|
||||
function setFollow(enabled) {
|
||||
state.street.follow = enabled === true && state.street.followAvailable;
|
||||
if (state.street.follow) followCamera();
|
||||
// The framing tween would keep overwriting the follow view until it lands.
|
||||
if (state.street.follow) {
|
||||
cancelFraming();
|
||||
followCamera();
|
||||
}
|
||||
state.notify?.();
|
||||
}
|
||||
|
||||
return { followCamera, lookAtPosition, setFollow };
|
||||
return { followCamera, lookAtPosition, cancelFraming, setFollow };
|
||||
}
|
||||
Reference in new issue
Block a user