Skip to content

Text3D

TextGeometry es una de las formas en las que podemos agregar texto en 3D a nuestra escena.

Sin embargo, no forma parte del núcleo de ThreeJS. Por lo tanto, para usarlo, tendrías que importarlo desde el módulo three/addons/controls/TextGeometry.

Esto crea un problema porque TresJS crea automáticamente un catálogo del núcleo de Three para que puedas usarlos como componentes.

Afortunadamente, TresJS proporciona una forma de ampliar el catálogo de componentes. Puedes hacerlo utilizando el método extend de la biblioteca principal.

Para obtener más información sobre cómo ampliar tu catálogo de TresJS, consulta la sección de extending.

Usando TextGeometry

Para usar TextGeometry, debes importarlo desde el módulo three/addons/geometries/TextGeometry.

js
import { TextGeometry } from 'three/addons/geometries/TextGeometry'

Luego, debes ampliar el catálogo de componentes utilizando el método extend.

js
import { extend } from '@tresjs/core'
import { TextGeometry } from 'three/addons/geometries/TextGeometry'

extend({ TextGeometry })

TextGeometry necesita solo un argumento requerido, la fuente. Puedes ver un ejemplo a continuación.

js
const fontPath = 'https://raw.githubusercontent.com/Tresjs/assets/main/fonts/FiraCodeRegular.json'

const loader = new FontLoader()

const font = await new Promise((resolve, reject) => {
  try {
    loader.load(fontPath, (font) => {
      resolve(font)
    })
  }
  catch (error) {
    reject(console.error('cientos', error))
  }
})

Ahora puedes usar el componente TresTextGeometry dentro de un TresMesh en tu escena.

vue
<template>
  <TresCanvas
    shadows
    alpha
  >
    <TresMesh>
      <TresTextGeometry
        :args="['TresJS', { font, ...fontOptions }]"
        center
      />
    </TresMesh>
  </TresCanvas>
</template>

luego, como en el ejemplo, puedes pasar un objeto con las configuraciones deseadas.

ts
const fontOptions = {
  size: 0.5,
  height: 0.2,
  curveSegments: 5,
  bevelEnabled: true,
  bevelThickness: 0.05,
  bevelSize: 0.02,
  bevelOffset: 0,
  bevelSegments: 4,
}

También podemos pasar una matcapTexture para agregar detalles finales, utilizando TresMeshNormalMaterial dentro de TresMesh.

ts
const matcapTexture = await useTexture(['https://raw.githubusercontent.com/Tresjs/assets/main/textures/matcaps/7.png'])
html
<TresMesh>
  <TresTextGeometry :args="['TresJS', { font, ...fontOptions }]" center />
  <TresMeshNormalMaterial :matcap="matcapTexture" />
</TresMesh>

Entonces, el código final sería algo como esto:

vue
<script setup lang="ts">
import { extend } from '@tresjs/core'
import { TextGeometry } from 'three/addons/geometries/TextGeometry'
import { FontLoader } from 'three/addons/loaders/FontLoader'
import { useTexture } from '/@/composables'

extend({ TextGeometry })

const fontPath = 'https://raw.githubusercontent.com/Tresjs/assets/main/fonts/FiraCodeRegular.json'

const fontOptions = {
  size: 0.5,
  height: 0.2,
  curveSegments: 5,
  bevelEnabled: true,
  bevelThickness: 0.05,
  bevelSize: 0.02,
  bevelOffset: 0,
  bevelSegments: 4,
}

const loader = new FontLoader()

const font = await new Promise((resolve, reject) => {
  try {
    loader.load(fontPath, (font) => {
      resolve(font)
    })
  }
  catch (error) {
    reject(console.error('cientos', error))
  }
})

const matcapTexture = await useTexture(['https://raw.githubusercontent.com/Tresjs/assets/main/textures/matcaps/7.png'])
</script>

<template>
  <TresCanvas
    shadows
    alpha
  >
    <TresMesh>
      <TresTextGeometry
        :args="['TresJS', { font, ...fontOptions }]"
        center
      />
      <TresMeshNormalMaterial :matcap="matcapTexture" />
    </TresMesh>
  </TresCanvas>
</template>

Sé que parece mucho trabajo, pero tengo buenas noticias, hay una forma mucho más sencilla.

TextGeometry de cientos

El paquete cientos proporciona un componente llamado <Text3D /> que es un envoltorio de TextGeometry del módulo three-stdlib.

¿Lo mejor? No necesitas extender el catálogo, solo pasa el argumento de la fuente. Simplemente funciona. 💯 (si no se proporciona un texto, el texto será TresJS)

vue
<template>
  <TresCanvas
    shadows
    alpha
  >
    <Text3D :font="fontPath" />
  </TresCanvas>
</template>

Podemos pasar las opciones como props

html
<Text3D :font="fontPath" :text="my 3d text" :size="0.8" />

en caso de que no se proporcionen las opciones, los valores predeterminados son:

{
  size: 0.5,
  height: 0.2,
  curveSegments: 5,
  bevelEnabled: true,
  bevelThickness: 0.05,
  bevelSize: 0.02,
  bevelOffset: 0,
  bevelSegments: 4,
}

De forma predeterminada, el texto en ThreeJS comienza en la posición inicial de la malla, por lo que si es [0,0,0], el texto comenzará allí, pero podemos centrarlo simplemente pasando la bandera "center".

vue
<Text3D :font="fontPath" :text="my 3d text" center />