HTML

Starter pack

Hasta ahora, las experiencias 3D que hemos construido contenían solo un canvas elemento HTML donde se renderizaban nuestras escenas 3D de Three.js.

Hay dos maneras de hacer nuestras experiencias más interactivas:

  • Construir tu página HTML como lo haces habitualmente y añadir tu escena 3D como fondo en un canvas a pantalla completa. Luego intégrala bien conectándolas a través de eventos de ratón o desplazamiento de página. Veremos cómo lograr esto en la sección de scroll en la lección de animaciones.
  • Agregar elementos HTML como si fueran objetos 3D en nuestras escenas 3D. Esto es lo que veremos en esta lección.

Esas dos aproximaciones no son mutuamente exclusivas. Puedes combinarlas para crear experiencias inmersivas.

Showroom online de Ikea

Para esta lección, imaginemos que queremos crear un showroom online para Ikea. El paquete de inicio contiene varios modelos 3D de mobiliario de cocina (Todos provenientes de Quaternius en Poly Pizza, gracias 🙏).

3D Kitchen

Esto es lo que tenemos hasta ahora. Una cocina de estilo japonés.

Intentaremos añadir etiquetas en los muebles de la cocina para mostrar el nombre y precio de cada artículo.

Antes de hacerlo, permíteme explicar algunas partes del paquete de inicio.

Para hacer el código genérico, en vez de declarar cada artículo manualmente y reescribir la lógica de carga y posicionamiento, creé un array de items.

const sceneItems = [
  {
    model: "Japanese Door.glb",
    position: [0, -0.88, -1.2],
    scale: 1.8,
  },
  {
    model: "Counter Sink.glb",
    position: [1.3, 0, -2.8],
  },
  {
    model: "Chopping board.glb",
    position: [2.8, 1.9, -2.8],
    scale: 0.5,
  },
  {
    model: "Fridge.glb",
    position: [-2.1, 0, -3],
  },
  {
    model: "Table.glb",
    position: [-1, 0, 2],
    scale: [1, 1, 1],
  },
  {
    model: "Dango.glb",
    position: [-1.4, 1.64, 2],
    scale: 0.72,
    rotation: [0, Math.PI / 6, 0],
  },
];

Luego creé un componente genérico llamado Item que toma la ruta del modelo y otros props de transformación (position, rotation, scale...):

const Item = ({ model, position, rotation, ...props }) => {
  const gltf = useGLTF(`models/${model}`);

  return (
    <group position={position} rotation={rotation}>
      <primitive object={gltf.scene} {...props} />
    </group>
  );
};

El componente se encarga de cargar el modelo 3D y posicionarlo en la escena. Elegí un grupo como elemento raíz para poder agregar posteriormente elementos HTML como hijos.

Luego recorremos el array de items y renderizamos un componente Item para cada artículo:

export const Experience = () => {
  return (
    <>
      {sceneItems.map((item, index) => {
        return <Item key={index} {...item} />;
      })}
    </>
  );
};

Elementos HTML en 3D

Ahora que tenemos un componente genérico que puede renderizar cualquier modelo 3D y posicionarlo en la escena, podemos enfocarnos en nuestras etiquetas de muebles.

Vamos a añadir más información a nuestro array de items agregando las propiedades label y price:

const sceneItems = [
  {
    model: "Japanese Door.glb",
    position: [0, -0.88, -1.2],
    scale: 1.8,
    name: "Hemnes",
    price: 300,
  },
  {
    model: "Counter Sink.glb",
    position: [1.3, 0, -2.8],
    name: "Lillången",
    price: 450,
  },
  {
    model: "Chopping board.glb",
    position: [2.8, 1.9, -2.8],
    scale: 0.5,
    name: "Skogsta",
    price: 25,
  },
  {
    model: "Fridge.glb",
    position: [-2.1, 0, -3],
    name: "Lagan",
    price: 600,
  },
  {
    model: "Table.glb",
    position: [-1, 0, 2],
    scale: [1, 1, 1],
    name: "Lerhamn",
    price: 80,
  },
  {
    model: "Dango.glb",
    position: [-1.4, 1.64, 2],
    scale: 0.72,
    rotation: [0, Math.PI / 6, 0],
    name: "Dango",
    price: 4,
  },
];

No te ofendas por los nombres y precios, los generó GitHub Copilot...

Ahora podemos actualizar nuestro componente Item para obtener los props name y price y renderizarlos como elementos HTML:

End of lesson preview

To get access to the entire lesson, you need to purchase the course.