react-three-fiber icon indicating copy to clipboard operation
react-three-fiber copied to clipboard

`onPointerOut` called after `onPointerUp` if `setPointerCapture` / `releasePointerCapture` used

Open alberto-taiuti-skydio opened this issue 2 years ago • 3 comments

I've noticed that if you use setPointerCapture/releasePointerCapture from within the onPointerDown and onPointerUp callbacks, respectively, then an onPointerOut event is also triggered after the onPointerUp, spuriously, when the user clicks and doesn't move the mouse at all on an object that has those events attached.

Removing the usage of setPointerCapture/releasePointerCapture removes the issue: onPointerOut isn't called after onPointerUp.

I've created a sandbox that reproduces the issue. The code in there is just setup as such:

      <mesh
        rotation={[0, 1, 2]}
        onClick={() => setState(Math.random() * 0xffffff)}
        onPointerDown={(e: any) => {
          e.stopPropagation()
          // Comment this out to see that the issue goes away
          e.target.setPointerCapture(e.pointerId)
        }}
        onPointerMove={() => {}}
        onPointerUp={(e: any) => {
          e.stopPropagation()
          // Comment this out to see that the issue goes away
          e.target.releasePointerCapture(e.pointerId)
          console.log('On pointer up')
        }}
        onPointerOver={(e: any) => {
          e.stopPropagation()
          console.log('On pointer over')
        }}
        onPointerOut={() => {
          console.log('On pointer out')
        }}>
        <boxBufferGeometry args={[1, 1, 1]} />
        <meshStandardMaterial color={state} />
      </mesh>

To repro, open the console and click on the object: you'll see the after a onPointerUp event, a onPointerOut is triggered too.

This doesn't match the behavior of HTML elements, as I have reproed in this other sandbox I created that shows the desired behavior.

I also noticed that in a similar example that was created with a much older version of r3f, this issue doesn't repro (which I found here).

Any ideas why this happens? Thanks.

alberto-taiuti-skydio avatar Oct 07 '22 04:10 alberto-taiuti-skydio

Looks like we're mostly calling onPointerOut when pointerleave is triggered. I'm not sure how that interacts with pointer lock, but I'm assuming it would mirror the behavior described here.

https://github.com/pmndrs/react-three-fiber/blob/68abd48dd2a2e25c4c49bc01a604e65794165c4e/packages/fiber/src/core/events.ts#L362-L413

Thanks for attaching a working example, I'll see how we handled this behavior in that version.

CodyJasonBennett avatar Oct 07 '22 05:10 CodyJasonBennett

Fix published in v8.8.11.

CodyJasonBennett avatar Oct 29 '22 11:10 CodyJasonBennett

I've updated @alberto-taiuti-skydio's original sandbox with the latest r3f version: https://codesandbox.io/s/setpointercapture-onpointerout-issue-forked-7fj987

This issue is fixed on Chrome but not Safari. When you mouse up on the cube you get different console output on each browser.

Chrome:

On pointer up

Safari:

On pointer up
On pointer out

Any ideas what's going on here @CodyJasonBennett? Thanks

charliefuller avatar Oct 20 '23 12:10 charliefuller