useHelper DirectionalLightHelper OnClickEvent

I am currently creating an editor using R3F (React Three Fiber). I am visualizing the light using the useHelper from the Drei library, but how can I capture the specified DirectionalLightHelper with an OnClick event? Is it practical to implement this with the mouse and raycasting?

Sample code:

import { DirectionalLightHelper } from "three";
import { useRef } from "react";

const myLight = () => {
  const ref = useRef();
  // I want to attach  onClickEvent in this lightHelper.
  useHelper(ref, DirectionalLightHelper);
  
  return (
  <>
    <directionalLight 
         ref={ref}
         position={[5, 5, 5]}
     />
  </>
  )
}

myEditorCapture:

I’m not sure if this is an elegant solution, but for now, I set up an invisible box and added onPointerDown and OnPointerMissed to handle it. If there’s a more precise and elegant way to incorporate it with useHelper, I would appreciate any feedback.

Code:

import { DirectionalLightHelper } from "three";
import { useRef } from "react";

const myLight = () => {
  const ref = useRef();
  const boxRef = useRef<Mesh>();
  useHelper(ref, DirectionalLightHelper);
  
  const onClick = (e, flag) => {
    console.log("onClick", flag);
  }

  useFrame((_, delta) > {
    if (boxRef.current && ref.current){
      boxRef.current.position.copy(ref.current.position.clone());
    }
  });
  
  return (
  <>
    <directionalLight 
         ref={ref}
         position={[5, 5, 5]}
     />
    <mesh 
      onClick={(e) => onClick(e, true)}
      onPointerMissed={(e) => onClick(e, false)}
      ref={boxRef}
    >
       <boxBufferGeometry />
        <meshStandardMaterial wireframe={true} visible={false} />
     </mesh>
  </>
  )
}
1 Like

this is fine, though you probably want it to be a <planeGeometry>, the position isn’t enough, you also need the orientation/rotation and scale. you can copy this over from the useHelper ref.

Mr. drcmda

I am always grateful for your help.

This was certainly incomplete. I decided to make it the same shape as Helper’s appearance.
Scale and Rotation were also synced and worked perfectly.

Thank you for your review!

I’ll leave the code as well.

import { DirectionalLightHelper } from "three";
import { useRef } from "react";

const myLight = () => {
  const ref = useRef();
  const catchRef = useRef<Mesh>();
  useHelper(ref, DirectionalLightHelper);
  
  const onClick = (e, flag) => {
    console.log("onClick", flag);
  }

  useFrame((_, delta) > {
    if (catchRef.current && ref.current){
      catchRef.current.position.copy(ref.current.position.clone());
      catchRef.current.rotation.copy(ref.current.rotation.clone());
      catchRef.current.scale.copy(ref.current.scale.clone());
    }
  });
  
  return (
  <>
    <directionalLight 
         ref={ref}
         position={[5, 5, 5]}
     />
    <mesh 
      onClick={(e) => onClick(e, true)}
      onPointerMissed={(e) => onClick(e, false)}
      ref={boxRef}
    >
       <planeBufferGeometry  />
        <meshStandardMaterial wireframe={true} visible={false} side={DoubleSide} />
     </mesh>
  </>
  )
}
1 Like