Canceling Camera Damping Effect on Click in a 3D Scene

Hello everyone,

I’m working on a project where I want the camera to have a damping effect when the user stops rotating it using the mouse. This effect is desired, but I would also like to provide users with an option to cancel the damping effect by clicking on the screen.

I’ve tried the following code to disable and re-enable the controls and damping onClick event:

this.control.enabled = false;
this.control.enableDamping = false;
this.control.update();
this.control.enableDamping = true;
this.control.enabled = true;

However, this approach doesn’t work as expected. When the user clicks to cancel the damping effect, the camera suddenly jumps to a different position, as if it’s completing the calculation and moving to the latest update.

Any suggestions on how to achieve the desired behavior would be greatly appreciated. Thanks!

Here is one ugly, truly ugly solution (so ugly, that looking at the source may cause brain damage). The solution works only for canceling rotation damping. Canceling panning and zooming requires a little bit more work.

https://codepen.io/boytchev/full/qBJxdxo

image

I think the best would be to modify OrbitControls.js by adding a function to clear sphericalDelta and a few other variables.

2 Likes

Hey Pavel, Thank you for your solution! It’s exactly what I wanted but the pain is that I am using react-three-drei so I don’t know how to change the source code o orbitControls… it’s a bit complicated :confused:

export default function Controls(): JSX.Element {
  const dispatch = useAppDispatch();
  const { camera } = useThree();
  const droneType = useAppSelector(selectDroneState);
  const position = useAppSelector(selectCameraPosition);

  const cameraPosition = useMemo(() => {
    return position;
  }, [position]);

  useEffect(() => {
    dispatch(setCamera(camera));
    camera.position.set(...cameraPosition);
  }, [cameraPosition]);

  const rotate = droneType === 'circle';
  const isFreeFly = droneType === 'fly';
  const enable = droneType === 'circle' || droneType === 'idle';

  if (isFreeFly) {
    return (
      <Player currentCameraPosition={[camera.position.x, camera.position.y, camera.position.z]} />
    );
  }

  return <OrbitControls makeDefault autoRotate={rotate} enabled={enable} />;
}

Sorry, I have no experience with React. I thought it was a JS-only question. Maybe somebody else might help.

Thank you a lot.

1 Like