DEV Community

Cover image for Three.js com React Three Fiber: Criando Experiências 3D Impressionantes no React
Johan Henrique
Johan Henrique

Posted on

Three.js com React Three Fiber: Criando Experiências 3D Impressionantes no React

Quando comecei a trabalhar com gráficos 3D na web, minha primeira tentativa foi utilizar o Three.js puro. Apesar de ser uma biblioteca incrível, integrar Three.js diretamente com o ciclo de vida do React sempre foi complicado. Foi então que descobri o React Three Fiber e isso mudou completamente minha abordagem para desenvolvimento 3D no ecossistema React.

Neste post, vou compartilhar minha experiência e mostrar como você pode começar a criar experiências 3D impressionantes usando React Three Fiber em suas aplicações React.

O que é React Three Fiber?

React Three Fiber (R3F) é um renderizador React para Three.js, uma das bibliotecas mais populares para gráficos 3D na web. O R3F permite que você escreva código Three.js usando a sintaxe declarativa do React, o que torna o desenvolvimento 3D muito mais intuitivo para desenvolvedores React.

Em vez de lidar com instâncias, cenas e loops de renderização manualmente, o R3F cuida de tudo isso por você, permitindo que você se concentre no que realmente importa: criar experiências 3D incríveis.

Por que usar React Three Fiber?

Ao longo dos últimos projetos que desenvolvi na SparkWebStudios, percebi várias vantagens ao usar React Three Fiber:

  1. Sintaxe declarativa: Escrever código Three.js no estilo React
  2. Reconciliação automática: O R3F atualiza apenas o que mudou, sem re-renderizações desnecessárias
  3. Hooks especializados: Hooks como useFrame e useThree facilitam o acesso ao loop de renderização e ao estado do Three.js
  4. Ecossistema React: Aproveite todo o poder do ecossistema React junto com Three.js
  5. Abstração de complexidade: Menos código boilerplate comparado ao Three.js vanilla

Configurando o ambiente

Vamos começar configurando um projeto básico com React Three Fiber:

# Criar projeto React com Vite
npm create vite@latest my-r3f-app -- --template react-ts

# Instalar dependências
cd my-r3f-app
npm install three @react-three/fiber @react-three/drei

# Iniciar o servidor de desenvolvimento
npm run dev
Enter fullscreen mode Exit fullscreen mode

Seu primeiro componente 3D

Agora, vamos criar uma cena simples com uma caixa giratória:

import { useState, useRef } from 'react'
import { Canvas, useFrame } from '@react-three/fiber'
import { OrbitControls } from '@react-three/drei'
import * as THREE from 'three'

function Box(props: any) {
  // Referência para o mesh
  const meshRef = useRef<THREE.Mesh>(null!)

  // Estado para controlar hover e clique
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)

  // Hook para animação por frame
  useFrame((state, delta) => {
    meshRef.current.rotation.x += delta * 0.5
    meshRef.current.rotation.y += delta * 0.2
  })

  return (
    <mesh
      {...props}
      ref={meshRef}
      scale={active ? 1.5 : 1}
      onClick={() => setActive(!active)}
      onPointerOver={() => setHover(true)}
      onPointerOut={() => setHover(false)}>
      <boxGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color={hovered ? '#ff6b6b' : '#6246ea'} />
    </mesh>
  )
}

export default function App() {
  return (
    <div style={{ width: '100vw', height: '100vh' }}>
      <Canvas>
        <ambientLight intensity={0.5} />
        <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} />
        <Box position={[0, 0, 0]} />
        <OrbitControls />
      </Canvas>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Este código cria uma cena com uma caixa 3D que gira constantemente. Você pode interagir com ela clicando para aumentar seu tamanho e passando o mouse para mudar sua cor. Além disso, graças ao componente OrbitControls do pacote @react-three/drei, você pode orbitar, aplicar zoom e pan na cena.

Conceitos fundamentais

1. Canvas

O componente Canvas é o ponto de entrada para sua cena 3D. Ele configura o renderizador, a cena e a câmera por você:

<Canvas
  camera={{ position: [0, 0, 5], fov: 75 }}
  shadows
  dpr={[1, 2]}
>
  {/* Seus objetos 3D aqui */}
</Canvas>
Enter fullscreen mode Exit fullscreen mode

2. Primitivas e geometrias

React Three Fiber expõe todas as primitivas do Three.js como componentes React:

Three.js React Three Fiber
new THREE.Mesh() <mesh />
new THREE.BoxGeometry() <boxGeometry />
new THREE.MeshStandardMaterial() <meshStandardMaterial />

3. Hooks especializados

O R3F fornece hooks poderosos para interagir com o loop de renderização e o estado do Three.js:

  • useFrame: Executa código em cada frame de animação
  • useThree: Acessa o estado global do Three.js (cena, câmera, renderer)
  • useLoader: Carrega assets 3D (modelos, texturas) com suporte a Suspense

Criando uma cena mais complexa

Um dos projetos mais interessantes que desenvolvi foi uma visualização 3D interativa de dados. Vou compartilhar um exemplo simplificado:

import { Canvas } from '@react-three/fiber'
import { OrbitControls, Text } from '@react-three/drei'
import { useState } from 'react'

// Componente para representar barras de dados em 3D
function DataBar({ value, label, index, total }: { value: number, label: string, index: number, total: number }) {
  const [hovered, setHovered] = useState(false)

  // Calculando posição com base no índice
  const angle = (index / total) * Math.PI * 2
  const x = Math.cos(angle) * 3
  const z = Math.sin(angle) * 3

  return (
    <group position={[x, 0, z]}>
      <mesh
        position={[0, value / 2, 0]}
        onPointerOver={() => setHovered(true)}
        onPointerOut={() => setHovered(false)}>
        <boxGeometry args={[0.5, value, 0.5]} />
        <meshStandardMaterial color={hovered ? '#ff9e64' : '#63c5da'} />
      </mesh>
      <Text
        position={[0, -0.5, 0]}
        fontSize={0.3}
        color="#ffffff"
        anchorX="center"
        anchorY="middle">
        {label}
      </Text>
      <Text
        position={[0, value + 0.5, 0]}
        fontSize={0.3}
        color="#ffffff"
        anchorX="center"
        anchorY="middle">
        {value.toFixed(1)}
      </Text>
    </group>
  )
}

// Visualização de dados em 3D
function DataVisualization() {
  const data = [
    { label: 'Jan', value: 5.2 },
    { label: 'Fev', value: 4.3 },
    { label: 'Mar', value: 6.7 },
    { label: 'Abr', value: 8.1 },
    { label: 'Mai', value: 7.5 },
    { label: 'Jun', value: 9.2 }
  ]

  return (
    <Canvas camera={{ position: [0, 10, 10], fov: 50 }}>
      <ambientLight intensity={0.6} />
      <directionalLight position={[10, 10, 5]} intensity={1} />

      {data.map((item, index) => (
        <DataBar
          key={item.label}
          value={item.value}
          label={item.label}
          index={index}
          total={data.length}
        />
      ))}

      <mesh position={[0, 0, 0]} rotation={[-Math.PI / 2, 0, 0]}>
        <cylinderGeometry args={[3.5, 3.5, 0.1, 32]} />
        <meshStandardMaterial color="#2a2a2a" />
      </mesh>

      <OrbitControls enableDamping dampingFactor={0.1} />
    </Canvas>
  )
}

export default DataVisualization
Enter fullscreen mode Exit fullscreen mode

Este exemplo cria uma visualização de dados circular em 3D, onde cada barra representa um valor mensal. É interativo, permitindo que o usuário orbite ao redor e passe o mouse sobre cada barra para destacá-la.

Otimizações e performance

Ao trabalhar com Three.js e React Three Fiber, a performance é sempre uma preocupação. Aqui estão algumas dicas que aprendi e aplico nos meus projetos:

  1. Instancing para elementos repetitivos: Use <instancedMesh> em vez de múltiplos <mesh> para geometrias idênticas
  2. Gerenciamento de estado: Evite atualizações de estado desnecessárias que causam re-renderizações
  3. Memoização: Use useMemo e useCallback para evitar recálculos custosos
  4. LOD (Level of Detail): Reduza a complexidade de modelos distantes da câmera
  5. Carregamento assíncrono: Use Suspense e useLoader para carregar assets sem bloquear a UI

Integrando com o ecossistema React

Uma das maiores vantagens do React Three Fiber é a facilidade de integração com o restante do ecossistema React. Você pode usar bibliotecas como:

  • Zustand: Para gerenciamento de estado global
  • Framer Motion: Para animações na interface 2D
  • React Router: Para navegação entre diferentes cenas 3D

No meu portfólio pessoal johanhenrique.com, utilizo React Three Fiber para criar experiências 3D interativas que complementam a interface 2D tradicional, proporcionando uma experiência única aos visitantes.

Conclusão

Depois de trabalhar com Three.js e React Three Fiber em diversos projetos, posso afirmar que esta combinação oferece um equilíbrio perfeito entre o poder do Three.js e a facilidade de desenvolvimento do React. A curva de aprendizado inicial é compensada pela produtividade e flexibilidade que você ganha.

Se você está construindo aplicações web modernas e quer adicionar uma camada extra de interatividade e impacto visual, vale a pena investir tempo aprendendo React Three Fiber. Além de ser extremamente divertido trabalhar com gráficos 3D, você estará preparado para criar experiências web de próxima geração.

E você, já experimentou React Three Fiber em algum projeto? Compartilhe suas experiências ou dúvidas nos comentários!


Este post foi escrito por Johan Henrique, desenvolvedor fullstack e Head da SparkWebStudios. Visite meu portfólio para mais conteúdos sobre desenvolvimento web.

Top comments (0)