Una inmersión en React y Three.js usando react-three-fiber

Publicado: 2022-03-10
Resumen rápido ↬ react-three-fiber es un poderoso renderizador Three.js que ayuda a renderizar modelos 3D y animaciones para React y sus aplicaciones nativas. En este tutorial, aprenderá cómo configurar y construir modelos 3D en una aplicación React.

Hoy vamos a aprender cómo configurar y usar react-three-fiber para crear y mostrar animaciones y modelos 3D en aplicaciones React y React Native.

Este tutorial es para desarrolladores que desean obtener más información sobre animaciones de modelos 3D en la web usando React y para cualquier persona que haya tenido limitaciones con Three.js, como la incapacidad para crear lienzos, vincular eventos de usuario como eventos de click e iniciar un bucle de renderizado, react-three-fiber viene con estos métodos. Construiremos un modelo 3D para entender mejor cómo construir modelos 3D de Three.js usando react-three-fiber .

Primeros pasos con react-three-fiber

Three.js es una biblioteca que facilita la creación de gráficos 3D en el navegador, utiliza un lienzo + WebGL para mostrar los modelos y animaciones 3D, puede obtener más información aquí.

react-three-fiber es un renderizador React para Three.js en la web y react-native, es un impulso a la velocidad a la que crea modelos 3D y animaciones con Three.js, algunos ejemplos de sitios con modelos 3D y animaciones se puede encontrar aquí. react-three-fiber reduce el tiempo dedicado a las animaciones debido a sus componentes reutilizables, eventos de vinculación y bucle de procesamiento. Primero, echemos un vistazo a lo que es Three.js.

react-three-fiber nos permite construir componentes de código threeJS usando el estado de React, ganchos y accesorios, también viene con los siguientes elementos:

Elemento Descripción
mesh Una propiedad que ayuda a definir la forma de nuestros modelos.
hooks react-three-fiber define ganchos que nos ayudan a escribir funciones que ayudan a definir eventos de usuario como onClick y onPointOver
Bucle de renderizado y basado en componentes react-three-fiber se basa en componentes y se procesa de acuerdo con un cambio en el estado o la tienda
¡Más después del salto! Continúe leyendo a continuación ↓

Cómo usar react-three-fiber

Para usar react-three-fiber , comienza usando los siguientes comandos:

MNP

 npm i three react-three-fiber

HILO

 yarn add three react-three-fiber

Nota : Para que funcione react-three-fiber , deberá instalar three (Three.js) como lo hicimos anteriormente.

Construcción de un proyecto de animación y modelo de dados React 3D Ludo

Aquí vamos a construir un modelo de dados ludo en 3D usando react-three-fiber como el que tenemos en el video a continuación.

Usaremos create-react-app para inicializar nuestro proyecto, para hacer eso, ejecutemos el siguiente comando en nuestra terminal.

 create-react-app react-three-fiber-ludo-model

El comando anterior inicializa un proyecto React dentro de nuestra máquina local, luego cd al directorio e instalemos nuestros paquetes react-three-fiber y three .

 cd react-three-fiber-ludo-model npm i three react-three-fiber

Una vez que los paquetes estén instalados, iniciemos nuestro servidor de desarrollo usando el comando

 npm start

El comando anterior debería iniciar nuestro servidor de desarrollo de proyectos en nuestro navegador. A continuación, abramos nuestro proyecto en nuestro editor de texto de elección, dentro de nuestra carpeta src del proyecto, elimine los siguientes archivos: App.css , App.test.js , serviceWorker.js y setupTests.js . A continuación, eliminemos todo el código que hace referencia a los archivos eliminados en nuestro App.js

Para este proyecto, necesitaremos un componente Box para nuestros dados ludo y nuestro componente App proporcionado por React.

Construyendo el componente de la Box

El componente Box contendrá la forma de nuestros dados ludo, una imagen de un dado ludo y un estado para mantenerlo siempre en rotación. Primero, importemos todos los paquetes que necesitamos para nuestro componente Box a continuación.

 import React, { useRef, useState, useMemo } from "react"; import { Canvas, useFrame } from "react-three-fiber"; import * as THREE from "three"; import five from "./assets/five.png";

En el código anterior, estamos importando useRef , useState y useMemo . Usaremos el gancho useRef para acceder a la malla de los dados y el gancho useState para verificar el estado activo de los dados ludo. useMemo hook se usará para devolver el número en los dados. A continuación, estamos importando Canvas y useFrame desde react-three-fiber , el canvas se usa para dibujar los gráficos en el navegador, mientras que useFrame permite que los componentes se conecten al bucle de procesamiento, lo que hace posible que un componente se reproduzca el contenido de otro. Luego, importamos los three paquetes y luego importamos una imagen estática de un dado ludo.

Lo siguiente para nosotros es escribir lógica para nuestro componente Box . Primero, comenzaremos con la construcción de un componente funcional y agregaremos estado a nuestro componente, hagámoslo a continuación.

 const Box = (props) => { const mesh = useRef(); const [active, setActive] = useState(false); useFrame(() => { mesh.current.rotation.x = mesh.current.rotation.y += 0.01; }); const texture = useMemo(() => new THREE.TextureLoader().load(five), []); return ( <Box /> ); }

En el código anterior, estamos creando un componente Box con accesorios, luego creamos una referencia llamada mesh usando el gancho useRef , lo hicimos para que siempre podamos devolver la misma malla cada vez.

Una malla es un elemento visual en una escena, es un objeto 3D que forma un polígono triangular, generalmente se construye usando Geometría, que se usa para definir la forma del modelo y Material que define la apariencia del modelo, puede Obtenga más información sobre una malla aquí. También puede obtener más información sobre el gancho useRef aquí.

Después de inicializar una mesh , necesitamos inicializar un estado para nuestra aplicación usando el useState , aquí configuramos el estado activo y flotante de la aplicación en falso.

A continuación, usamos el gancho useFrame de react-three-fiber para rotar la malla (ludo dice), usando el siguiente código

 mesh.current.rotation.x = mesh.current.rotation.y += 0.01;

Aquí, rotamos la posición actual de la malla cada 0,01 segundos, esto se hace para darle una buena animación a la rotación.

 const texture = useMemo(() => new THREE.TextureLoader().load(five), []);

En el código anterior, estamos creando una constante llamada texture y pasando un gancho de reacción useMemo como una función para cargar una nueva tirada de dados, aquí useMemo para memorizar la imagen del dado y su número. Puede obtener información sobre el useMemo aquí.

A continuación, queremos representar el componente Box en el navegador y agregar nuestros eventos, lo hacemos a continuación.

 const Box = (props) => { return ( <mesh {...props} ref={mesh} scale={active ? [2, 2, 2] : [1.5, 1.5, 1.5]} onClick={(e) => setActive(!active)} > <boxBufferGeometry args={[1, 1, 1]} /> <meshBasicMaterial attach="material" transparent side={THREE.DoubleSide}> <primitive attach="map" object={texture} /> </meshBasicMaterial> </mesh> ); }

En el código anterior, devolvemos nuestro componente Box y lo envolvemos en la mesh . Pasamos todas las propiedades del componente Box usando el operador de extensión, y luego hicimos referencia a la malla usando el useRef . A continuación, usamos la propiedad de scale de Three.js para establecer el tamaño del cuadro de dados cuando está activo en 2 y 1,5 cuando no lo está. Por último, pero no menos importante, agregamos un evento onClick para establecer state en active si no está configurado de forma predeterminada.

 <boxBufferGeometry args={[1, 1, 1]} />

Para renderizar el cuadro de dados, renderizamos el componente boxBufferGeometry de Three.js, boxBufferGeometry nos ayuda a dibujar líneas y puntos como cuadros, usamos el argumento args para pasar constructores como el tamaño de la geometría del cuadro.

 <meshBasicMaterial attach="material" transparent side={THREE.DoubleSide}>

El meshBasicMaterial de Three.js se utiliza para dibujar geometrías de forma sencilla. Aquí pasamos el atributo de attach y THREE.DoubleSide accesorios DoubleSide al atributo side . THREE.DoubleSide define los lados o espacios que debe representar react-three-fiber .

 <primitive attach="map" object={texture} />

El componente primitive de Three.js se usa para dibujar gráficos en 3D. Adjuntamos la propiedad del mapa para mantener la forma original de los dados ludo. A continuación, renderizaremos nuestro componente Box en el archivo App.js y completaremos nuestro cuadro de dados 3d ludo. Su componente debe verse similar a la imagen de abajo.

Componente de caja para ludo 3D box

Caja de dados Ludo de renderizado 3D

En esta sección, vamos a renderizar nuestro componente Box en nuestro App.js y completaremos nuestro cuadro ludo 3d, para hacer eso primero, creemos un componente App y envolvámoslo con una etiqueta Canvas , esto es para renderizar nuestros modelos 3D, hagamos eso abajo.

 const App = () => { return ( <Canvas> </Canvas> ); } export default App;

A continuación, agreguemos una luz a las cajas, react-three-fiber nos proporciona tres componentes para iluminar nuestros modelos, son los siguientes

  • ambientLight
    Esto se usa para iluminar todos los objetos en una escena o modelo por igual, acepta accesorios como la intensidad de la luz, esto iluminará el cuerpo de los dados ludo.
  • spotLight
    Esta luz se emite desde una sola dirección, y aumenta a medida que aumenta el tamaño del objeto, esto iluminará las puntas de los dados ludo.
  • pointLight
    Este funciona de manera similar a la luz de un foco, se emite luz desde un solo punto hacia todas las direcciones, esto será necesario para el estado activo de nuestra aplicación.

Implementemos lo anterior en nuestra aplicación a continuación.

 const App = () => { return ( <Canvas> <ambientLight intensity={0.5} /> <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} /> <pointLight position={[-10, -10, -10]} /> </Canvas> ); } export default App;

En el código anterior, importamos el componente ambientLight de react-three-fiber y le agregamos una intensidad de 0.5, luego agregamos una posición y un ángulo a nuestro componente spotLight y pointLight . El paso final de nuestra aplicación es representar nuestro componente de caja y agregar una posición a las cajas de dados ludo, lo haríamos en el código a continuación.

 <Box position={[-1.2, 0, 0]} /> <Box position={[2.5, 0, 0]} />

Cuando haya terminado, sus dados ludo 3D deberían verse similares a la imagen a continuación:

caja de dados ludo modelo 3d

Una demostración de trabajo está disponible en CodeSandbox.

Conclusión

react-three-fiber ha facilitado la creación de animaciones y modelos 3D para aplicaciones React y React Native. Al construir nuestra caja de dados de Ludo 3D, aprendimos los conceptos básicos de Three.js junto con sus componentes y los beneficios de react-three-fiber , así como también cómo usarlo.

Puede llevar esto más lejos construyendo modelos 3D y animaciones en sus aplicaciones React y Native usando react-three-fiber por su cuenta. ¡Me encantaría ver qué cosas nuevas se te ocurren!

Puede leer más sobre Three.js y react-three-fiber en las referencias a continuación.

Recursos Relacionados

  • Documentación de Three.js
  • Fundamentos de Three.js
  • Repo de GitHub de React-Three-fiber de Poimandres
  • documentación de react-tres-fibras
  • Documentación oficial de React Hooks (useState, useMemo, etc.)