Three.js React Three Fiber Bento
January 31, 2024
January 31, 2024
In this task, we create a simple tutorial that shows how to start a basic project using React Three Fiber and Vite with TypeScript. The goal of the project is to create a simple "bento" box, one part of which we can move interactively. Finished site here
POWERSHELLnpm create vite@latest
Choose the react + typescript + SWC
POWERSHELLnpm install three @types/three @react-three/fiber
Due to the project, the following installations are still necessary:
POWERSHELL@react-three/drei @react-three/csg
Imports
Canvas Components:
TYPESCRIPT//App.tsximport { Canvas } from "@react-three/fiber";import { Scene } from "./Scene";import { ACESFilmicToneMapping, sRGBEncoding } from "three";function App() {return (<Canvasdpr={[1, 2]}gl={{antialias: true,toneMapping: ACESFilmicToneMapping,outputEncoding: sRGBEncoding,}}camera={{fov: 10,near: 0.1,far: 200,position: [0, 9, 9],}}shadows><Scene /></Canvas>);}export default App;
We now add the 3D elements to the previously created canvas. First, we create a simple cube using new Three.BoxGeometry to test the environment.
TYPESCRIPT//Scene.tsximport { OrbitControls, PivotControls } from "@react-three/drei";import { Base, CSGGeometryRef, Geometry } from "@react-three/csg";import * as THREE from "three";import { useRef } from "react";const box = new THREE.BoxGeometry();function Scene() {const csg = useRef<CSGGeometryRef>(null);return (<><OrbitControls makeDefault /><directionalLightposition={[-2, 2, 3]}intensity={0.8}castShadowshadow-mapSize={[1024 * 2, 1024 * 2]}/><ambientLight intensity={0.2} /><mesh receiveShadow castShadow><Geometry ref={csg}><Base name="base" geometry={box} scale={[1.4, 0.2, 2]}></Base></Geometry><meshStandardMaterial color="#A1662F" envMapIntensity={0.05} /></mesh></>);}export { Scene };
If the environment is functioning properly, we will create our simple bento storage box.
Here, we first add a flat plane on which the shadows will appear.
TYPESCRIPT//Plane.tsxfunction Plane() {return (<meshrotation-x={-Math.PI / 2}position={[0, -0.1, 0]}scale={[10, 10, 10]}receiveShadow><planeGeometry /><shadowMaterial transparent opacity={0.4} /></mesh>);}export { Plane };
Add the plane to Scene.tsx
TYPESCRIPT//Scene.tsximport { Plane } from "./components/Plane";...<ambientLight intensity={0.2} /><Plane />...
We create the base for the cutouts, whose position and size we can modify with each call.
TYPESCRIPT//SubtractBox.tsximport { Geometry, Subtraction } from "@react-three/csg";import * as THREE from "three";const box = new THREE.BoxGeometry();type SubtractBoxProps = {position?: [number, number, number];scale?: [number, number, number];};const SubtractBox: React.FC<SubtractBoxProps> = (props) => (<Subtraction {...props}><Geometry><Subtraction geometry={box} /></Geometry></Subtraction>);export { SubtractBox };
We add our created cutout to Scene.tsx. To our cutout, we also add a controller that allows us to move it.
TYPESCRIPT//Scene.tsximport { SubtractBox } from "./components/SubtractBox";...<mesh receiveShadow castShadow><Geometry ref={csg}><Base name="base" geometry={box} scale={[1.4, 0.2, 2]}></Base><PivotControlsactiveAxes={[true, true, true]}scale={0.2}anchor={[0, 0, 0]}onDrag={() => {if (csg.current) {csg.current.update();}}}><SubtractBox position={[0, 0.2, 0]} scale={[1.2, 0.4, 1]} /></PivotControls></Geometry><meshStandardMaterial color="#A1662F" envMapIntensity={0.05} /></mesh>...
We can add multiple cutouts to the base object to create our bento box.
This is a fairly basic program, but a good starting point for React Three Fiber and understanding the 3D environment in Node.js.
The complete code can be found: https://github.com/balazsfaragodev/r3f-vite-ts-bento
Share this article
Start your day right with the daily newsletter that entertains and informs. Subscribe now for free!