*Edit: I'm an idiot, I don't think my function has anything to do with it because it appears like double clicking without moving your mouse has this behavior somewhat consistently on its own, on the Three.js example as well.
I still don't know how to remove this functionality or even if this is some sort of feature.
When double-clicking the scene, I am calling a function that smoothly resets the camera position to its original position. However, after doing so, whenever trying to move with OrbitControls
causes the not-allowed
cursor to appear and the controls to rotate hardly at all before stopping. The only way to move the controls again is by single clicking the canvas and not dragging, this will reset the controls to a functional state.
When the resetPosition
function, which moves the camera back to the origin slightly every frame, is removed, the controls work *mostly as intended. I've looked through it and see no obvious cause.
*The same thing happens very inconsistently when double-clicking (usually by dragging the controls quickly on the second click) even without resetPosition
, resetPosition
just makes it occur consistently. This behavior can even be observed in this official Three.js example.
An image of that, StackOverflow won't let me post images
How do I stop this from happening? I've found plenty of Three.js examples that don't have this issue, but I have no clue what they do differently.
The relevant code is below:
this.controls = new OrbitControls(this.camera, this.element)
this.controls.target.set(CONTROLS_TARGET.x, CONTROLS_TARGET.y, CONTROLS_TARGET.z)
this.controls.userRotateSpeed = 3
this.controls.maxDistance = 200
this.controls.minDistance = 10
resetPosition() {
let azimuthalAngle = this.controls.getAzimuthalAngle(),
polarAngle = this.controls.getPolarAngle() - Math.PI / 2,
distance = this.controls.getDistance() - 30,
movement = this.controls.target.clone()
let lerpDelta = LERP_ALPHA ** (1 + this.deltaTime * 60)
if (Math.abs(azimuthalAngle) < 0.001) azimuthalAngle = 0
if (Math.abs(polarAngle) < 0.001) polarAngle = 0
if (Math.abs(distance) < 0.001 && Math.abs(distance) > -0.001) distance = 0
if (movement.distanceTo(CONTROLS_TARGET) < 0.05) movement = CONTROLS_TARGET
this.controls.minAzimuthAngle = lerpDelta * azimuthalAngle
this.controls.maxAzimuthAngle = this.controls.minAzimuthAngle
this.controls.minPolarAngle = Math.PI/2 + lerpDelta * polarAngle
this.controls.maxPolarAngle = this.controls.minPolarAngle
this.controls.minDistance = lerpDelta * distance + 30
this.controls.maxDistance = this.controls.minDistance
movement.lerp(CONTROLS_TARGET, 1.0 - lerpDelta)
this.controls.target.set(movement.x, movement.y, movement.z)
if(azimuthalAngle === 0
&& polarAngle === 0
&& distance === 0
&& movement.equals(CONTROLS_TARGET)
) this.finishReset()
}
finishReset() {
this.controls.minAzimuthAngle = -Infinity
this.controls.maxAzimuthAngle = Infinity
this.controls.minPolarAngle = 0
this.controls.maxPolarAngle = Math.PI
this.controls.minDistance = 10
this.controls.maxDistance = 200
this.doReset = false
}
animate() {
if (this.doReset) this.resetPosition()
this.controls.update()
this.render()
}
The issue you are encountering might be related to the way you are handling the
resetPosition()
function and the continuous updates to the OrbitControls during the animation loop. When you double-click the scene, you trigger theresetPosition()
function, which smoothly resets the camera position. During this resetting process, you are modifying the min/max azimuthal and polar angles, as well as the min/max distance of the OrbitControls. This is intended to prevent the camera from moving away during the reset.The problem arises when you modify these constraints continuously during the animation loop. The
resetPosition()
function is called on every frame whenthis.doReset
is true, and this can interfere with the smooth operation of the OrbitControls, leading to the undesired behavior you described.To fix this, you can try the following approach:
Make sure that the
resetPosition()
function is only called once when you double-click to reset the camera. Set a flag to indicate that the reset process should start and then clear the flag once the reset is complete.Remove the continuous updating of min/max azimuthal and polar angles, as well as min/max distance, inside the
resetPosition()
function. Instead, set these constraints only once during the initialization of the OrbitControls.Here's a modified version of your code:
By ensuring that the
resetPosition()
function is called only once during the double-click event and setting the constraints only once during initialization, the OrbitControls should work smoothly without getting stuck in the "not-allowed" cursor state.