React Three Fiber
React Three Fiber (R3F) adalah React renderer untuk Three.js. Daripada menulis kode Three.js imperatif, kamu mendeklarasikan scene 3D menggunakan JSX — sama seperti menulis komponen React biasa.
Instalasi
npm install three @react-three/fiber @react-three/drei
@react-three/fiber— core renderer@react-three/drei— koleksi helper dan komponen siap pakai
Canvas Component — Entry Point
import { Canvas } from "@react-three/fiber";
function App() {
return (
<div style={{ width: "100vw", height: "100vh" }}>
<Canvas>
{/* Semua komponen 3D ditulis di sini */}
<mesh>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="orange" />
</mesh>
<ambientLight intensity={0.5} />
<directionalLight position={[5, 5, 5]} />
</Canvas>
</div>
);
}
Perhatikan: Di R3F, semua class Three.js ditulis dalam camelCase sebagai JSX element:
THREE.BoxGeometry→<boxGeometry />THREE.MeshStandardMaterial→<meshStandardMaterial />THREE.AmbientLight→<ambientLight />
Constructor arguments ditulis sebagai prop args={[...]}.
useFrame — Animation Hook
useFrame dipanggil setiap frame (60x per detik), sama seperti requestAnimationFrame:
import { useRef } from "react";
import { useFrame } from "@react-three/fiber";
function SpinningCube() {
const meshRef = useRef();
useFrame((state, delta) => {
meshRef.current.rotation.x += delta;
meshRef.current.rotation.y += delta * 0.5;
});
return (
<mesh ref={meshRef}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="#3498db" />
</mesh>
);
}
state berisi informasi scene (clock, camera, mouse, dll). delta adalah waktu sejak frame terakhir.
useThree — Akses Scene, Camera, dll
import { useThree } from "@react-three/fiber";
function CameraLogger() {
const { camera, scene, gl, size } = useThree();
console.log("Camera position:", camera.position);
console.log("Canvas size:", size.width, size.height);
return null; // komponen ini tidak render apa-apa
}
Drei Helpers — Komponen Siap Pakai
@react-three/drei menyediakan puluhan komponen berguna:
import {
OrbitControls,
Environment,
Text,
Float,
MeshWobbleMaterial,
RoundedBox,
Stars,
} from "@react-three/drei";
function Scene() {
return (
<>
{/* Kontrol kamera */}
<OrbitControls enableDamping />
{/* Environment lighting (HDRI) */}
<Environment preset="sunset" />
{/* Teks 3D */}
<Text
position={[0, 2, 0]}
fontSize={0.5}
color="white"
>
Hello R3F!
</Text>
{/* Objek yang melayang */}
<Float speed={2} rotationIntensity={1} floatIntensity={2}>
<mesh>
<torusKnotGeometry args={[0.5, 0.15, 100, 16]} />
<MeshWobbleMaterial color="#e74c3c" factor={0.5} speed={2} />
</mesh>
</Float>
{/* Background bintang */}
<Stars radius={100} depth={50} count={5000} />
{/* Box dengan sudut membulat */}
<RoundedBox args={[1, 1, 1]} radius={0.1}>
<meshStandardMaterial color="#2ecc71" />
</RoundedBox>
</>
);
}
Deklaratif vs Imperatif
Bandingkan Three.js murni vs R3F:
// Three.js imperatif
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: "red" });
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 1, 0);
scene.add(mesh);
// R3F deklaratif
<mesh position={[0, 1, 0]}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="red" />
</mesh>
R3F jauh lebih ringkas dan mengikuti mental model React — describe what you want, bukan how to do it.
Event Handling di R3F
R3F menangani Raycaster secara otomatis:
function InteractiveCube() {
const [hovered, setHovered] = useState(false);
const [clicked, setClicked] = useState(false);
return (
<mesh
onPointerOver={() => setHovered(true)}
onPointerOut={() => setHovered(false)}
onClick={() => setClicked(!clicked)}
scale={clicked ? 1.5 : 1}
>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? "hotpink" : "orange"} />
</mesh>
);
}
Tidak perlu Raycaster manual! R3F menyediakan event props yang familiar: onClick, onPointerOver, onPointerOut, onPointerMove, onPointerDown, onPointerUp.
Contoh Komponen Reusable
function FloatingShape({ geometry, color, position, speed = 1 }) {
const ref = useRef();
useFrame((state) => {
ref.current.position.y = position[1] + Math.sin(state.clock.elapsedTime * speed) * 0.5;
ref.current.rotation.y += 0.01;
});
return (
<mesh ref={ref} position={position}>
{geometry}
<meshStandardMaterial color={color} roughness={0.3} />
</mesh>
);
}
// Penggunaan
<FloatingShape
geometry={<sphereGeometry args={[0.5, 32, 32]} />}
color="#e74c3c"
position={[-2, 0, 0]}
speed={1.5}
/>
R3F membuat 3D di web terasa natural bagi developer React — compose, reuse, dan manage state dengan cara yang sudah familiar.