-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Camera stuck after limiting zoom #3984
Comments
Thanks @nikakhov! I can confirm that it does take a little bit of scrolling out to start zooming. |
Also reported here: https://groups.google.com/forum/?hl=en#!topic/cesium-dev/7KZ9feIh1zE |
The first thing to understand is how zoom works: It's not linear. You don't move a fixed number of meters per mouse travel, because movements sizes only make sense when they're near objects of similar sizes. So if you have Cesium zoomed into a compact car on the street, as you zoom out your zoom speed is about a meter per pixel of mouse travel, then when you see a whole city block the speed is several meters/pixel, then as the whole city comes into view it's hundreds of meters/pixel, then as nearby mountain ranges come into view it's kilometers/pixel, and then the limb of the Earth comes into view, and then the whole Earth is onscreen and you're moving hundreds or thousands of km/pixel, and then the Moon comes into view, and faster you go. So when you set But back to your case, you set a minimum zoom in space, but didn't put any object at that altitude of space. So, as you zoom into that altitude, the zoom slows down, and the motion of the Earth in the background becomes imperceptible. You can eventually zoom in to where the camera is only moving one meter per pixel, but with the Earth 2,000,000 meters away, you don't know that you're moving, there's no nearby object of the correct scale to show you that you're moving. Of course, as you zoom out, the zoom speed slowly ramps up, just as it does when you zoom out from the ground. But unlike the ground, you can't see the ramp-up speed in empty space, so you feel stuck! One possible fix here is that |
@emackey sounds like a good idea. If it is easy to test out, please go for it if you have the bandwidth. |
here's my current workaround: const minZoom = 250; // m
const maxZoom = 20000000;
// be notified of ALL camera change events
camera.percentageChanged = 0;
// make global camera event listener:
const listener = () => {
const camHeight = camera.positionCartographic.height;
let isOutsideZoomLimits = false;
let destHeight;
if (camHeight < minZoom) {
isOutsideZoomLimits = true;
destHeight = minZoom;
} else if (camHeight > maxZoom) {
isOutsideZoomLimits = true;
destHeight = maxZoom;
}
if (isOutsideZoomLimits) {
const dest = Cesium.Cartesian3.fromRadians(
camera.positionCartographic.longitude,
camera.positionCartographic.latitude,
destHeight
);
camera.position = dest;
// removeListener();
// camera.flyTo({
// destination: dest,
// duration: 0.2, // seconds
// complete: () => camera.changed.addEventListener(listener)
// });
}
};
const removeListener = camera.changed.addEventListener(listener); |
the workaround (above) is not optimal though, since the camera keeps on moving parallel to the surface, when the height limit hits. I tried to counteract that by using the previous lat/lng coordinates of the camera: let lastCamPos = camera.positionCartographic.clone();
const listener = () => {
const camHeight = camera.positionCartographic.height;
let isOutsideZoomLimits = false;
let destHeight;
if (camHeight < constants.minZoom) {
isOutsideZoomLimits = true;
destHeight = constants.minZoom;
} else if (camHeight > constants.maxZoom) {
isOutsideZoomLimits = true;
destHeight = constants.maxZoom;
}
if (isOutsideZoomLimits) {
const dest = Cesium.Cartesian3.fromRadians(
lastCamPos.longitude, // ← previous coordinates
lastCamPos.latitude,
destHeight
);
camera.position = dest;
}
lastCamPos = camera.positionCartographic.clone();
}; while that seems to work ok enough for the |
I found a much better solution: simply setting
|
m |
Please, expose |
I believe this has been fixed in #9932 |
To reproduce
var viewer = new Cesium.Viewer('cesiumContainer');
viewer.scene.screenSpaceCameraController.minimumZoomDistance=2000000;
The text was updated successfully, but these errors were encountered: