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.
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í
<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.
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.
// 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.