Display a circle follow cursor on a plane

Hi, so I managed to make a circle follow my mouse when I’m on my planeGeometry, unfortunately I encounter bugs and I don’t understand.

Sometimes when I go to make it disappear when I move the camera, and then it reappears, sometimes it appears shifted from my mouse, I have to move my mouse so that it refocuses, and I do not understand why? maybe the performance is bad and I miss frames?

Because I noticed that my gpu was at 7/8 ms while there is nothing on the scene? Maybe I misunderstood the use of UseFrame() ?

there is my CodeSandbox: moving camera - CodeSandbox

If someone have some advice for this issues, or for my utilisation on Useframe() would be anwsome

you are making the circle invisible on drag, if you remove that you see it always, i don’t see any issues then.

btw, i would not setState the pointer movement.

       onPointerMove={(e) => {
          setpointerMove(e.point)
          e.stopPropagation()
        }}

it’s just wasteful to go through react like that. if you need it in multiple places, use a vector, this is how you’d do it in vanilla as well so why deviate?

const [pointer] = useState(() => new THREE.Vector3())

useFrame(() => {
  ...
  ringRef.current.position.copy(pointer)
})

... onPointerMove={(e) => pointer.copy(e.point)}

if you don’t need pointer in multiple places it’s even easier, just set it directly in the event

... onPointerMove={(e) => ringRef.current.position.copy(e.point)}

also

useFrame(() => {
  ..
  setHover(false);
})

you have to understand that useFrame is a loop. at worst you are setStating 120 times per second, which re-renders the entire component 120 times per second, running through all the hooks again, diffing the view, looking for changes. it is no wonder you experience a slowdown.

quickly read this: React Three Fiber Documentation (TLDR, don’t setstate in loops)

hover is a simple event, no need for any looping:

const [hovered, hover] = useState(false)

useEffect(() => {
  document.body.style.cursor = hovered ? "pointer" : "auto"
}, [hovered])

<mesh onPointerOver={() => hover(true)} onPointerOut={() => hover(false)}>

Hi, thanks for your answer! Maybe I wasn’t clear but I just want it to disappear when I drag and reappear just when I move the mouse on my plane without dragging.

I’m pretty new to three js and react too , I still have a lot to learn, I will try to change the code and see what it gives, thank you very much for you’re advices!

So I tried to modify, and indeed the way to do is better, but the concern is that for example for

const [hovered, hover] = useState(false)

useEffect(() => {
  document.body.style.cursor = hovered ? "pointer" : "auto"
}, [hovered])

<mesh onPointerOver={() => hover(true)} onPointerOut={() => hover(false)}>

What I was trying to do was when i move the camera I have the style of the mouse turns into drag, and that the circle disappears. But when im doing nothing i have the normal cursor.

a bit like that demo : https://showroom.littleworkshop.fr/

But also when I’m not on my plane, the circle disappears. That’s why in my head i had to use several events in a Useframe() to know at each frame if the different events trigger but maybe i’m wrong.

here’s an example of how i would do it: dof (forked) - CodeSandbox

this is just about the marker though.

Ok thanks, so you create a pointer in Vec3, and copy the position of the ring on this pointer.

But if i want to hide this pointer when i’m moving the camera , i have to do it why an event too?

marker.current.visible = false

most controls have start/stop events, so you know when the user is pulling the camera or not.

Yep, there is a currentAction props = 0 or 1 for the camera.

So i have done something like this with you’re CodeSandbox : moving camera - CodeSandbox

And i have used a Show variable to Show/hide the cursor + the plane when i move the camera , but i have used a Setstate in a UseFrame() , and as you said earlier i can’t do this. But i really dont know how to proceed with an UseEffect.

And i have noticed a bug after hiding the cursor , when he show again , he is placed in offset, and i don’t understand why. Maybe because i have used a useState inside the loop?

there is a video of the bug :

I noticed the same problem on your sandbox when I move the camera, if I stop moving the mouse, the circle does not fit the cursor.

vid :