Disabling rotation when dragging

I am having a bit of trouble stopping rotation from occurring when dragging things on the map. When dragging an object you of course stop rotation with scene.screenSpaceCameraController.enableRotate = false.

This mostly works, except if you quickly drag the object around and release the mouse button while the mouse is still moving. The globe will spin for some reason, and I am not sure how to combat this.

It doesn't make sense to me, because you are re-enabling rotation when the mouse is released, so why would the globe start spinning?

I tried disabling inertiaSpin on mouse down and re-enabling it on mouse up but that appears to make no difference.

In this example you can see the issue: http://analyticalgraphicsinc.github.io/cesium-google-earth-examples/examples/pinDrag.html

Thanks for your help.

2 Likes

Hi @Scott_Mills ,

I am also having this kind of issue. I just wanted to do panning without the rotation when quickly dragging the object. Are you able to fix this issue or do you have a workaround on how to prevent this?

Thanks,
Sarah

We really dont like it on touch devices

Hi, I know this is an old post, but I recently stumbled upon the very same issue while implementing draggable entities. The globe always kept spinning a little bit after dragging an object due to inertia, although I disabled the camera inputs with scene.screenSpaceCameraController.enableInputs = false upon the LEFT_DOWN mouse event and resetting it to true upon LEFT_UP. After some digging through the Cesium Source code and checking how the inertia gets applied etc., I found this interesting little function inside CameraEventAggregator and a workaround to stop the inertia spin from happening that seems to work for my dragging use case:

function cancelMouseDownAction(cancelKey, aggregator) {
  const releaseTime = aggregator._releaseTime;
  const isDown = aggregator._isDown;
  if (isDown[cancelKey]) {
    aggregator._buttonsDown = Math.max(aggregator._buttonsDown - 1, 0);
  }
  isDown[cancelKey] = false;
  releaseTime[cancelKey] = new Date();
}

In this function, the cancelKey parameter is the camera event key you want to cancel (LEFT_DRAG camera event is key ‘0’ (string)) and the aggregator parameter is the CameraEventAggregator instance that is a private member inside the ScreenSpaceCameraController (screen.screenSpaceCameraController._aggregator).
As far as I understand it, the CameraEventAggregator ‘collects’ ScreenSpaceEventType (input) events that happen between frames and aggregates them to internal CameraEventType (camera) events, e.g. ‘left mouse down’, ‘mouse move’. ‘mouse move’, ‘left mouse up’ events get converted to a single LEFT_DRAG camera event with a start and end position and timestamps when the buttons were pressed/released. Based on the time difference between the mouse button press/release the inertia gets calculated (I think). So what I did is I utilitzed the above function to cancel the LEFT_DRAG event as soon as I ‘picked’ my draggable entity in the LEFT_DOWN event. This seems to work perfectly without any downsides. I also re-created the ‘pinDrag’ Sandcastle that Scott_Mills mentioned with a boolean APPLY_DRAG_INERTIA_FIX to enable or disable the workaround. When the boolean is false and you drag/flick the pin around the globe will spin due to inertia after letting go of the pin. When the boolean is true, this behavior is prevented.

Please note that the cancelMouseDownAction should NOT immediately be called every time the LEFT_DOWN event is triggered, but rather when the LEFT_DOWN event is called and some condition is met (like a draggable entity was picked, like in the Sandcastle)

Hope that helps.

TL;DR
Check this ‘pinDrag’ Sandcastle and how the Cesium internal cancelMouseDownAction function is used within that Sandcastle.

1 Like