Animaciones

Starter pack

Las animaciones son clave para dar vida a tu escena 3D. Pueden ser activadas por interacciones del usuario, basadas en scroll o en tiempo, y aplicadas a objetos 3D, luces y cámaras.

Dominar las animaciones es una habilidad clave para crear experiencias inmersivas. Cuantas más técnicas conozcas, más podrás expresar tu creatividad.

Nota: Las animaciones de modelos 3D se cubren en el capítulo de modelos.

Lerp

Lerp es una función matemática que interpola entre dos valores. Es útil para animar un valor desde un punto a otro.

const value = THREE.MathUtils.lerp(start, end, t);

El primer parámetro es el valor inicial, el segundo parámetro es el valor final y el tercer parámetro es el factor de interpolación entre 0 y 1.

Cuanto más cercano esté el factor de interpolación a 0, más lenta será la animación. Cuanto más cercano esté el factor de interpolación a 1, más rápido alcanzará la animación el valor final o de destino.

Experimentemos esto en el componente AnimatedBox del paquete de inicio.

El componente tiene un array boxPositions que contiene las posiciones de la caja en diferentes momentos. Vamos a añadir un hook useFrame para actualizar la posición de la caja en función del tiempo:

import { RoundedBox } from "@react-three/drei";
import { useRef } from "react";

export const AnimatedBox = ({ boxPositions, ...props }) => {
  const box = useRef();

  useFrame(({ clock }) => {
    const seconds = parseInt(clock.getElapsedTime());
    const targetPosition = boxPositions[seconds % boxPositions.length];

    box.current.position.x = targetPosition.x;
    box.current.position.y = targetPosition.y;
    box.current.position.z = targetPosition.z;
  });
  // ...
};

Aquí nuestra caja no está animada. Se teletransporta de una posición a otra. Usemos la función lerp para animarla:

import * as THREE from "three";
// ...

export const AnimatedBox = ({ boxPositions, ...props }) => {
  const box = useRef();

  useFrame(({ clock }) => {
    const seconds = parseInt(clock.getElapsedTime());
    const targetPosition = boxPositions[seconds % boxPositions.length];
    box.current.position.x = THREE.MathUtils.lerp(
      box.current.position.x,
      targetPosition.x,
      0.05
    );
    box.current.position.y = THREE.MathUtils.lerp(
      box.current.position.y,
      targetPosition.y,
      0.05
    );
    box.current.position.z = THREE.MathUtils.lerp(
      box.current.position.z,
      targetPosition.z,
      0.05
    );
  });
  // ...
};

La caja ahora está animada. Se mueve suavemente de una posición a otra.

La clase Vector3 tiene un método lerp que puede ser usado en lugar de la función THREE.MathUtils.lerp:

// box.current.position.x = THREE.MathUtils.lerp(
//   box.current.position.x,
//   targetPosition.x,
//   0.05
// );
// box.current.position.y = THREE.MathUtils.lerp(
//   box.current.position.y,
//   targetPosition.y,
//   0.05
// );
// box.current.position.z = THREE.MathUtils.lerp(
//   box.current.position.z,
//   targetPosition.z,
//   0.05
// );
box.current.position.lerp(targetPosition, 0.05);

¡Esas son muchas líneas de código ahorradas para el mismo resultado!

No dudes en jugar con el tiempo y hacer lerp en otras propiedades como el rotation o el scale para probar diferentes efectos.

Float

Float es un componente contenedor de la librería Drei para simplemente dar la impresión de que un objeto está flotando.

Contiene las siguientes propiedades:

  • speed: Velocidad de la animación, por defecto 1
  • rotationIntensity: Intensidad de la rotación en XYZ, por defecto 1
  • floatIntensity: Intensidad de la flotación hacia arriba/abajo, funciona como un multiplicador con floatingRange, por defecto 1
  • floatingRange: Rango de valores en el eje y en los que el objeto flotará, por defecto [-0.1,0.1]

Hagamos que nuestro Duck flote en Experience.jsx:

Three.js logoReact logo

React Three Fiber: The Ultimate Guide to 3D Web Development

✨ You have reached the end of the preview ✨

Go to the next level with Three.js and React Three Fiber!

Get full access to this lesson and the complete course when you enroll:

  • 🔓 Full lesson videos with no limits
  • 💻 Access to the final source code
  • 🎓 Course progress tracking & completion
  • 💬 Invite to our private Discord community
Unlock the Full Course – Just $85

One-time payment. Lifetime updates included.