Wawa Sensei logo

HTML

Starter pack

Até agora, as experiências 3D que construímos continham apenas um elemento HTML canvas onde nossas cenas 3D do Three.js eram renderizadas.

Existem duas maneiras de tornar nossas experiências mais interativas:

  • Construa sua página HTML como de costume e adicione sua cena 3D como um fundo em um canvas em tela cheia. Em seguida, integre bem conectando-os por meio de eventos de mouse ou rolagem de página. Veremos como conseguir isso na seção de rolagem na lição de animações.
  • Adicionar elementos HTML como se fossem objetos 3D em nossas cenas 3D. Isso é o que veremos nesta lição.

Essas duas abordagens não são mutuamente exclusivas. Você pode combiná-las para criar experiências imersivas.

Showroom online da Ikea

Para esta lição, vamos imaginar que queremos criar um showroom online para a Ikea. O pacote inicial contém vários modelos 3D de móveis de cozinha (Todos provenientes de Quaternius no Poly Pizza, obrigado 🙏).

3D Kitchen

Isto é o que temos até agora. Uma cozinha em estilo japonês.

Tentaremos adicionar etiquetas nos móveis da cozinha para mostrar o nome e o preço de cada item.

Antes de fazê-lo, deixe-me explicar algumas partes do pacote inicial.

Para tornar o código genérico, em vez de declarar cada item manualmente e reescrever a lógica de carregamento e posicionamento, criei um 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],
  },
];

Então, criei um componente genérico chamado Item que recebe o caminho do modelo e outros props de transformação (posição, rotação, escala...):

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

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

O componente se encarrega de carregar o modelo 3D e posicioná-lo na cena. Escolhi um grupo como elemento raiz para poder adicionar elementos HTML como filhos posteriormente.

Em seguida, percorremos o array de items e renderizamos um componente Item para cada item:

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

Elementos HTML em 3D

Agora que temos um componente genérico que pode renderizar qualquer modelo 3D e posicioná-lo na cena, podemos focar em nossos rótulos de móveis.

Vamos adicionar mais informações ao nosso array de itens adicionando as propriedades label e 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,
  },
];

Não se ofenda pelo nome e preços, eles foram gerados pelo GitHub Copilot...

Agora podemos atualizar nosso componente Item para obter as props name e price e renderizá-las como elementos HTML:

End of lesson preview

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