Detect pointerUp outside object

My objective is very simple, but for some reason I am having trouble with it. I have an implementation where I click and drag on a mesh, and change its height according to the mouse position. At first I used the stardard pointer events onPointerDown, onPointerUp, and onPointerMove. The problem is that i want my object to respond to mouse moves and mouse ups outside the object as well (but NOT mouse down). For example, the user would click on the object and drag the mouse, even if the user drags the mouse outside the bounds of the object, the height will still be updated normally, and then when the user releases the mouse the updating stops.

I have managed to do something similar with useFrame in which I respond to mouse moving outside the object, but not the mouseup part – I still need to drag the mouse back into the object for it to detect the mouseup. I also tried to use onPointerMissed, but that only identifies clicks, and I only want mouseups (no downs).

Here is the code I have so far. I imagine there is a very simple way to achieve what i need but I haven’t solved it so far. Does anyone have a suggestion?


const onMouseDown = (event) => {
            event.stopPropagation()
            setIsDragging(true)
            controls.enabled = false
      }

const onMouseUp = (event) => {
      controls.enabled = true
      setIsDragging(false)
}

useFrame(({ pointer }) => {
                if (isDragging) {
                    if (controls) { controls.enabled = false }
                    const mouseY = (pointer.y);
                    setHeight(mouseY)
                }
        })

You mean something like this?

useEffect(() => {
  if (!isDragging) {
    return;
  }

  const onMouseMoveAnywhere = (event: MouseEvent) => {
    // NOTE Do something when mouse is moving, regardless if it's within the object or not
  };
  const onMouseUpAnywhere = (event: MouseEvent) => {
    // NOTE Do something when mouse is released, regardless if it's within the object or not
  };

  window.addEventListener('pointermove', onMouseMoveAnywhere);
  window.addEventListener('pointerup', onMouseUpAnywhere);

  return () => {
    window.removeEventListener('pointermove', onMouseMoveAnywhere);
    window.removeEventListener('pointerup', onMouseUpAnywhere);
  };
}, [isDragging]);

Unless I misunderstand, there’s no real need for a useFrame - you want to be reacting to pointer movement, not the rendering.

1 Like

Thank you! That makes perfect sense and works like a charm!!

1 Like