three.js icon indicating copy to clipboard operation
three.js copied to clipboard

OrbitControls doesn't detect pointerup when off the DOM element

Open MixMasterMitch opened this issue 1 year ago • 8 comments

Describe the bug The OrbitControls continue to manipulate the camera if a click+drag is released outside of the OrbitControls' DOM element.

To Reproduce Steps to reproduce the behavior:

  1. Go to any three.js scene using OrbitControls, such as https://threejs.org/examples/#webgl_animation_keyframes
  2. Click and drag starting in the scene and release the click with the cursor out of the scene.
  3. Return the cursor to the scene without clicking and observe that the camera is still being controlled by the cursor movements.

Expected behavior I would expect the camera to no longer be rotated by the cursor after releasing the click.

Platform:

  • Device: Desktop
  • OS: MacOS (likely impacts others too)
  • Browser: Chrome (likely impacts others too)
  • Three.js version: r143 (impacts other versions too)

MixMasterMitch avatar Aug 30 '22 19:08 MixMasterMitch

I have hacked around this with code like this:

window.addEventListener('pointerup', (event) => {
    const clone = new event.constructor(event.type, { pointerId: event.pointerId, bubbles: false });
    document.getElementsByTagName('canvas')[0].dispatchEvent(clone); 
})

MixMasterMitch avatar Aug 30 '22 19:08 MixMasterMitch

Strange, I can't reproduce this with Chrome on macOS. Is there something else I have to look for?

Mugen87 avatar Aug 31 '22 07:08 Mugen87

and if instead you listen to window you listen to document?

VanderSP avatar Aug 31 '22 12:08 VanderSP

Strange, I can't reproduce this with Chrome on macOS. Is there something else I have to look for?

I was able to reproduce on Chrome/MacOS with middle mouse button (dolly).

arodic avatar Sep 01 '22 09:09 arodic

I can reproduce with the middle mouse button, too. It would be interesting to know why left/right and middle mouse button behave differently.

It seems a simple fix is adding this to OrbitControls:

scope.domElement.addEventListener( 'pointerleave', onPointerUp );

@MixMasterMitch Can you please check if this would work for you?

Mugen87 avatar Oct 10 '22 14:10 Mugen87

Faking a mouse event in the canvas turned out to be a workaround for me.

document.addEventListener('pointerleave', () => {
  canvas.dispatchEvent(new MouseEvent('pointerup'))
})

Tinoooo avatar Nov 11 '22 16:11 Tinoooo

I'm seeing this behavior with Chrome on MacOS: Left-click drags to and releasing outside window fire a pointerup normally. However when releasing a right click drag outside of the page, no pointerup is being fired. Then subsequent left click drag and release outside of the canvas no longer fire pointerup. Also pointermove events outside of the canvas are no longer firing for either type of click.

This is not the behavior in Safari or Firefox however, so it might be just a Chrome bug

snosenzo avatar Mar 16 '23 15:03 snosenzo

I too can reproduce it with Chrome on MacOS.

wnr avatar Feb 14 '24 12:02 wnr