0

I'm building a page with two overlapping components and i want to pass mouse events from the top component to the bottom one.

I'm using ReactJs and the code looks like this:

export default function App() {
  return (
    <>
    
    <SkyBox className='Streetview' onClick={()=>console.log("you clicked STREETVIEW!")}/>
    
    <Canvas className='Canvas' onClick={()=> console.log("you clicked THREEJS")}>
       <Camera position={[0, 0, -20]} />
     <ambientLight intensity={0.7} />
     
      <spotLight position={[10, 10, 10]} angle={0.90} penumbra={1} />
      <pointLight position={[-10, -10, -10]} />
      
      <Suspense fallback={null}>
        <Scene />
      </Suspense>
    
      </Canvas>

    </>
  );
} 

so I want to get the mouse events from the Canvas component and pass them to the streetview SkyBox one so the user could navigate the streetview panorama and therefore the events i'm interested in is the mouseClick , mouseMove and mouseOut.

Tawfik
  • 39
  • 4
  • Do you need to capture events in the overlaying component? If not... https://stackoverflow.com/questions/3680429/click-through-div-to-underlying-elements – isherwood Apr 16 '21 at 12:34

2 Answers2

1

You can pass events as props like so:

import { useState } from 'react'

const Wrapper = () => {
  const [event, setEvent] = useState(null)

  return (
    <div onClick={(e) => setEvent(e)}>
      Lorem Ipsum
      <Component event={event} />
    </div>
  )
}

const Component = (event) => {
  console.log(event) // → event: SyntheticBaseEvent
  return null
}

export default Wrapper
moritzsalla
  • 389
  • 1
  • 12
1

I'm not sure if you need the current state of the mouse-events but doesn't matter if state or the setters you can use context for this.

export const CanvasContext = createContext();

export default function App() {
 const [mouseClicked, setMouseClicked] = useState(...);
 const [mouseMoveState, setMouseMoveState] = useState(...);
 const [mouseOut, setMouseOut] = useState(...);

  return (
    <CanvasContext.Provider value={{
       mouseClicked,
       setMouseClicked,
       mouseMoveState,
       setMouseMoveState,
       mouseOut,
       setMouseOut
    }}>
      <SkyBox
        className="Streetview"
        onClick={() => console.log("you clicked STREETVIEW!")}
      />

      <Canvas
        className="Canvas"
        onClick={() => console.log("you clicked THREEJS")}
      >
        <Camera position={[0, 0, -20]} />
        <ambientLight intensity={0.7} />

        <spotLight position={[10, 10, 10]} angle={0.9} penumbra={1} />
        <pointLight position={[-10, -10, -10]} />

        <Suspense fallback={null}>
          <Scene />
        </Suspense>
      </Canvas>
    </CanvasContext.Provider>
  );
}

then use inside Canvas/SkyBox/... the state/setter you need like this.

export default function Canvas() {
 const {setMouseClicked, setMouseMoveState} = useContext(CanvasContext);

  return (
    <div>
      .....
    </div>
  );
}
inux
  • 17
  • 5