Combine React-three-fiber and threeJS code

Hello,

I have a plain ThreeJS code and I would like to be able to combine it with code in React-three-fiber, React-three-Drei, and other React libraries. Is there any way to easily combine all this? Or would it be best if I translate the ThreeJS code to React-three-fiber? Knowing that the code is quite long and I’m not sure how to go about translating everything.

It’s definitely possible. There’s no way to know if it’s a good idea or not without seeing your code, however.

Yes, it’s not ideal, but sadly I don’t think I’m allowed to post my code.
Maybe if someone has links to project examples combining both, it could help?

function Vanilla(props) {
  const [scene] = useState(() => new THREE.Scene())
  useLayoutEffect(() => {
    const geometry = new THREE.BoxGeometry()
    const material = new THREE.MeshBasicMaterial()
    const mesh = new THREE.Mesh(geometry, material)
    scene.add(mesh)
    // ...
    return () => void scene.dispose()
  }, [])
  return <primitive object={scene} {...props} />
}

...
<Vanilla position={[1, 2, 3]} />

<primitive object={...} /> can mount any existing, foreign threejs object into the scene. But watch out for memory, you are now being responsible to clean up after yourself. useLayoutEffect is called before the component renders on screen, good place to handle imperative logic, and it has a clean-up phase (the return).

Generally it is best to do as much as you can declaratively. Try to break out parts and re-use them. You’ll soon figure that you’re reducing the original code and in the long run it will only help maintenance and sanity overall.

1 Like

let’s say I have an orbitcontrol from fiber and want to manipulate it with plain js code…

import { OrbitControls} from "@react-three/drei";

function MyComponent() {
	return (
		<Fragment>
			<OrbitControls target={[0, 0.35, 0]} maxPolarAngle={1.45} />
			<PerspectiveCamera makeDefault fov={50} position={[3, 2, 5]} />
               </Fragment>
}

const myCustomRaycasterFunction = (renderer, scene, camera, OrbitControls, box) => {
       //how to access to renderer, scene, camera or a early created box mesh?
}

function App() {
	return (
		<Suspense fallback={null}>
			<Canvas shadows>
				<MyComponent/>
			</Canvas>
		</Suspense>
	);
}

export default App;

what I programmed in plain js/three.js is a “lookAt()” function… where the MapControls looks at the clicked object and highlights this… I have no idea how to mount that code for three/fiber.

Fiber experts might give you even better options but you can generally use hooks to to run code alongside your components. useEffect by default runs every time the component rerenders. useFrame runs every frame (and is a native r3f hook).

These are react patterns and not r3f-specific patterns. Getting familiar with them early is going to pay back later on so I highly recommend spending some time with them!

Thank you.
But I still don’t know how to access a component of fiber which is inserted like to the jsx.

Ah, right! That’s another react hook called useRef. It’s quite similar to giving an element an ID in pure HTML. If you take a look at some of the examples from the fiber documentation you’ll see it in use.

1 Like

ok I know useRef() but I thought it just gives access to the DOM element but not to the OrbitControls JavaScript Object. So you say in this case using useRef() on fiber objects gives access to the actual js object? I have to test it.

Any updates on this thread?

1 Like

what’s your exact question? I may help you, since I “mastered” r3f by now :clown_face:

Could you maybe take a look at: Switching Between Multiple Views / Scenes on Scroll
and give your take on this question?

this site was made in fiber, you can always open react dev tools and inspect some contents of it to get an idea. from what i remember this is drei scrollcontrols and drei rendertexture. rendertexture allows you to render a real scene, animation interaction and all into a texture. there are multiple variants of this: hud, rendertexture, portals, …

i would start simple, disect the beginning of that video you made and compose it together. with drei tooling there will be very little code/math.

as others already wrote, there are multiple ways to achieve that. you can do it with the ScrollControls from drei - just watch this tutorial and you will get the result you wish.