Make spotlight follow mouse in three fiber

I have 3 components, App, SpecialCamera, Mouselight.

In the Mouselight I calculate the mouse position in relation to the Camera and want to position the Spotlight where the mouse is.


function MouseLight({camRef}){
	
	const [globalCoords, setGlobalCoords] = useState({x: 0, y: 0});

	useEffect(() => {
	  // 👇️ get global mouse coordinates
	  const handleWindowMouseMove = event => {
		setGlobalCoords({
		  x: event.screenX,
		  y: event.screenY,
		});
	  };
	  window.addEventListener('mousemove', handleWindowMouseMove);
  
	  return () => {
		window.removeEventListener('mousemove', handleWindowMouseMove);
	  };
	}, []);

	const ref = useRef();
	useFrame(x=>{
		ref.current.position.z +=0.01;
	})

	const [pos, setPos] = useState();
	useEffect(() => {
		console.log(camRef, ref)
		var vector = new Vector3(globalCoords.x, globalCoords.y, 0.5);
		vector.unproject( camRef.current );
		var dir = vector.sub( camRef.current.position ).normalize();
		var distance = - camRef.current.position.z / dir.z;
		var pos = camRef.current.position.clone().add( dir.multiplyScalar( distance ) );
                setPos(pos);
	}, [globalCoords])
	
	return (
	<spotLight ref={ref}
		color={[1, 0, 0]}
		intensity={5}
		angle={0.6}
		penumbra={0.5}
		position={pos}
		castShadow
		shadow-bias={-0.001}
	/>)
}
function VerySpecialCamera({camRef}){
	return <PerspectiveCamera ref={camRef} makeDefault fov={50} position={[3, 2, 5]} />
}

function App() {
	return (
		<Suspense fallback={null}>
			<Canvas shadows>
				<VerySpecialCamera camRef={camRef}></VerySpecialCamera>
                                <Ground/>
                                <MouseLight/>
			</Canvas>
		</Suspense>
	);
}

Is this the right way to do such a thing? Currently the position of the light is somehow affected, but it is not really following the mouse over the surface ground.

it seems unnecessarily complex, you don’t have to add event listeners, this is all done for you. all you need to do is set the light target: Volumetric spotlight - CodeSandbox

react fiber is really like three.js on cocaine… crazy.

hmm ok I mean its really nice, but it is not exactly what I want… what you show me are spotlights fixed on top and just their angle (cone?) is moving to the spot where the mouse is. I wanted to move the whole light…

and also in your example the light is invisible when looking at it from the top.

but really crazy…

You will need to move the spotlights target along with the light, the target defaults to 0,0,0. three.js docs

wouldnt that be even easier? you just move spotlight.current.position.

useFrame(state => {
  light.current.position.set(state.pointer.x, state.pointer.y, ......

state.pointer is the normalized (-1 — 0 — 1) vector of the pointer, so in three units.