I have a very simple R3F code:
<Canvas>
<pointLight position={[5, 5, 5]} />
<ambientLight intensity={0.5}/>
<mesh>
<boxGeometry attach="geometry" />
<meshMatcapMaterial attach="material" color="lightblue" />
</mesh>
<OrbitControls />
</Canvas>
I just want to get the instance of renderer
to use it somewhere else lets say useFrame
.
I’ve tried using
const {gl} = useThree();
What you tried is correct. See R3F / hooks. If you’re getting any particular errors it would be important to share those errors, and/or the complete code so we can see anything else that might be wrong.
Note that useThree() can only be used by components inside the canvas, not by the root app component.
what @donmccurdy said is correct, canvas represents a service provider, three only exists within that, and you can of course also have more than one canvas. a useThree outside of canvas would be pointless as it has no relation to a canvas.
if you need the state outside you can do this
const [fiber, set] = useState()
return (
<Canvas onCreated={set}>
...
but i would suggest you don’t, leaking internals, reaching implementation details up is usually a bad omen. im guessing you want that state to drive something from above, like setting camera position or whatever, but that’s in almost all cases the wrong approach.
better state contains serializable primitives, like a position. you can change that from anywhere and within the canvas you can listen to that and then change the camera.
I want to use the renderer to export my model into a pdf using jspdf
, I’m doing like this:
const GetRenderer = () =>{
const {gl} = useThree()
const imgData = gl.domElement.toDataURL("image/jpeg", 1.0);
const pdf = new jsPDF();
pdf.addImage(imgData, 'JPEG', 0, 0,0,0);
pdf.save("download.pdf");
return null;
}
const App = ()=>{
//checking if the function is exporting model into pdf or not
return(
<>
<button className="text-lg" onClick={GetRenderer}>Test export</button>
<Canvas ref={canvasRef}
shadows
camera={{
position: [5, 5, 5],
fov: 15,
aspect: window.innerWidth / window.innerHeight,
}}
dpr={[1, 2]}
>
<ambientLight intensity={1} />
<Stats />
<GetRenderer />
<OrbitControls target={[0, -1.5, 0]}/>
<MyModel/>
</Canvas>
</>);
};
onClick runs in the context of react-dom, useThree isn’t available outside of the canvas. just copy the code above and you have gl available to you.