Controles de Cámara

Starter pack

Para posicionar y animar la cámara en una escena 3D, hemos descubierto algunas formas de hacerlo:

  • Establecer manualmente la posición y rotación de la cámara.
  • Usar diferentes tipos de controles, como OrbitControls.

Pero a veces, necesitamos más control sobre la cámara, y esto requiere mucho código y cálculos para hacerlo correctamente. Afortunadamente, existen librerías que nos pueden ayudar con eso.

La que vamos a usar se llama camera-controls. Es una pequeña librería que nos permite realizar una variedad de movimientos y animaciones de cámara muy fácilmente.

Por suerte, Drei tiene un envoltorio para esta librería, así que podemos usarla con unas pocas líneas de código.

Proyecto Inicial

Para descubrir las diferentes características de esta librería, vamos a crear un bonito deslizador 3D para mostrar el nuevo iPhone 15 Pro Max Black.

Por favor, contáctame cuando se lance el iPhone 16 para que pueda actualizar esta lección 🤭

El proyecto inicial contiene:

iPhone 15 Pro Max Black

Por ahora solo podemos ver el modelo del iPhone

Empecemos a jugar con los controles de cámara.

Controles

Para habilitar los controles de la cámara, necesitamos reemplazar los OrbitControls ya presentes en el proyecto inicial con el componente CameraControls de Drei.

También agregaremos una referencia al control para que podamos acceder a él más tarde y usar sus métodos.

Experience.jsx:

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

export const Experience = () => {
  const controls = useRef();
  return (
    <>
      <CameraControls ref={controls} />
      {/* ... */}
    </>
  );
};

Al hacer esto, no notaremos ninguna diferencia importante con los OrbitControls. Aún podemos rotar, desplazar y acercar la cámara.

La API también tiene muchos controles en común, como la distance, zoom, polarAngle, azimuthAngle, ...

Donde el componente CameraControls realmente destaca es cuando queremos animar la cámara.

No repasaremos todos los controles disponibles, pero veremos los más comunes. Puedes encontrar la lista completa en la documentación de camera-controls.

Dolly

El control dolly nos permite mover la cámara hacia adelante y hacia atrás.

Vamos a usar Leva para agregar botones que muevan la cámara hacia adelante y hacia atrás:

// ...
import { button, useControls } from "leva";

export const Experience = () => {
  // ...

  useControls("dolly", {
    in: button(() => {
      controls.current.dolly(1, true);
    }),
    out: button(() => {
      controls.current.dolly(-1, true);
    }),
  });
  // ...
};

El primer argumento del método dolly es la distancia que queremos mover la cámara. El segundo argumento es un boolean que indica si queremos animar el movimiento o no.

Nuestra cámara ahora puede moverse hacia adelante y hacia atrás

Si quisiéramos lograr el mismo resultado con OrbitControls, tendríamos que calcular la nueva posición de la cámara y el target. Luego tendríamos que animar tanto la cámara como el target a sus nuevas posiciones.

Truck

El control truck nos permite mover la cámara hacia arriba, abajo, izquierda y derecha sin cambiar la orientación de la cámara.

Como hicimos con el control dolly, agreguemos botones para experimentar el control truck:

// ...

export const Experience = () => {
  // ...
  useControls("truck", {
    up: button(() => {
      controls.current.truck(0, -0.5, true);
    }),
    left: button(() => {
      controls.current.truck(-0.5, 0, true);
    }),
    down: button(() => {
      controls.current.truck(0, 0.5, true);
    }),
    right: button(() => {
      controls.current.truck(0.5, 0, true);
    }),
  });
  // ...
};

Los primeros dos argumentos del método truck son las distancias horizontal y vertical que queremos mover la cámara. El tercer argumento es un booleano que indica si queremos animar el movimiento o no.

Puedes usar diferentes valores para las distancias horizontal y vertical para mover la cámara en diagonal.

Rotar

Camera Controls proporciona una forma de rotar programáticamente la cámara alrededor de su objetivo, similar al movimiento que hacemos cuando arrastramos el mouse con el OrbitControls.

Orbit rotation schema

Vamos a añadir botones para rotar la cámara alrededor de su objetivo:

// ...

export const Experience = () => {
  // ...
  useControls("rotate", {
    up: button(() => {
      controls.current.rotate(0, -0.5, true);
    }),
    down: button(() => {
      controls.current.rotate(0, 0.5, true);
    }),
    left: button(() => {
      controls.current.rotate(-0.5, 0, true);
    }),
    right: button(() => {
      controls.current.rotate(0.5, 0, true);
    }),
  });
  // ...
};

Los argumentos del método rotate son:

  • azimuthAngle: el ángulo horizontal en radianes.
  • polarAngle: el ángulo vertical en radianes.
  • enableTransition: un booleano que indica si queremos animar el movimiento o no.

Tiempo suave

Para controlar el tiempo de animación cuando usamos el argumento enableTransition, podemos usar la propiedad smoothTime.

End of lesson preview

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