Skip to content

Animaciones básicas

Esta guía te ayudará a comenzar con animaciones básicas en TresJS.

Construiremos una escena simple con un cubo. Luego animaremos el cubo para que rote alrededor del eje Y y Z.

useRenderLoop

El composable useRenderLoop es el núcleo de las animaciones en TresJS. Te permite registrar una función de devolución de llamada que se ejecutará cada vez que el renderizador actualice la escena con la frecuencia de actualización del navegador.

Para obtener una explicación detallada de cómo funciona, consulta la documentación de useRenderLoop.

ts
const { onLoop } = useRenderLoop()

onLoop(({ delta, elapsed }) => {
  // Se ejecutará en cada fotograma ~ 60FPS (dependiendo de tu monitor)
})

Obteniendo la referencia al cubo

Para animar el cubo, necesitamos obtener una referencia a él. Podemos hacerlo pasando una Referencia de Plantilla utilizando la propiedad ref en el componente TresMesh. Esto nos devolverá la instancia de THREE.

Para mejorar el rendimiento, utilizaremos una Referencia Superficial para almacenar la referencia en lugar de una referencia regular. Puedes ver por qué aquí

vue
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'

const boxRef: ShallowRef<TresInstance | null> = shallowRef(null)
</script>

<template>
  <TresCanvas>
    <TresMesh
      ref="boxRef"
      :scale="1"
    >
      <TresBoxGeometry :args="[1, 1, 1]" />
      <TresMeshNormalMaterial />
    </TresMesh>
  </TresCanvas>
</template>

Animando el cubo

Ahora que tenemos una referencia al cubo, podemos animarlo. Utilizaremos la devolución de llamada onLoop para actualizar la rotación del cubo.

ts
onLoop(({ delta, elapsed }) => {
  if (boxRef.value) {
    boxRef.value.rotation.y += delta
    boxRef.value.rotation.z = elapsed * 0.2
  }
})

También puedes usar el delta del reloj interno de THREE o el elapsed para animar el cubo.

¿Pero por qué no usar la reactividad?

Es posible que te preguntes por qué no estamos usando la reactividad para animar el cubo. La respuesta es simple: rendimiento.

vue
// Esto es una mala idea ❌
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'

const boxRotation = reactive([0, 0, 0])

onLoop(({ delta, elapsed }) => {
  boxRotation[1] += delta
  boxRotation[2] = elapsed * 0.2
})
</script>

Podemos sentirnos tentados a usar la reactividad para animar el cubo. Pero sería una mala idea. La razón es que la reactividad de Vue se basa en Proxies y no está diseñada para ser utilizada en un bucle de renderizado que se actualiza 60 o más veces por segundo.

La página incrustada a continuación muestra la prueba de rendimiento de un proxy frente a un objeto regular. Como puedes ver, el proxy es 5 veces más lento que el objeto regular.

Puedes leer más sobre esto en la sección de Caveats.