Cómo funciona la perspectiva CSS | Programar Plus

Como alguien a quien le encanta crear animaciones CSS, una de las herramientas más poderosas que uso es perspective. Mientras que la perspective La propiedad no es capaz de producir efectos 3D por sí misma (ya que las formas básicas no pueden tener profundidad), puede usar la transform propiedad para mover y rotar objetos en un espacio 3D (con los ejes X, Y y Z), luego use perspective para controlar la profundidad.

En este artículo, intentaré explicar el concepto de perspective, comenzando con lo básico, a medida que avanzamos hasta un cubo 3D completamente animado.

Los fundamentos de la perspectiva

Comenzaremos con un simple cuadrado verde y lo moveremos en los tres ejes.

Si bien mover el objeto en los ejes X e Y es bastante sencillo, si lo movemos en el eje Z, parecerá que el cuadrado permanece exactamente igual, y eso es porque cuando el objeto se mueve en el eje Z, el La animación lo acerca a nosotros y luego más lejos de nosotros, pero el tamaño (y la ubicación) del cuadrado sigue siendo el mismo. Ahí es donde el CSS perspective La propiedad entra en juego.

Mientras perspective no tiene influencia sobre el objeto cuando se mueve en los ejes X o Y, cuando el objeto se mueve en el eje Z, perspective hace que el cuadrado parezca más grande cuando se acerca a nosotros y más pequeño cuando se aleja. Sí, como en la vida “real”.

El mismo efecto ocurre cuando estamos rotando el objeto:

Girar el cuadrado en el eje Z parece la rotación regular que todos conocemos y amamos, pero cuando giramos el cuadrado en los ejes X o Y (sin usar la perspectiva), solo parece que el cuadrado se está haciendo más pequeño (o más estrecho). que rotar. Pero cuando agregamos perspective, podemos ver que cuando el cuadrado está girando, el lado más cercano del cuadrado parece más grande y el lado más alejado parece más pequeño, y la rotación se ve como se esperaba.

Tenga en cuenta que cuando la rotación del objeto en los ejes X o Y es de 90 ° (o 270 °, 450 °, 630 °, etc.), “desaparecerá” de la vista. Nuevamente, esto sucede porque no podemos agregar profundidad a un objeto, y en esta posición, el ancho (o alto) del cuadrado en realidad será 0.

El valor de la perspectiva

Necesitamos configurar el perspective propiedad con un valor. Este valor establece la distancia desde el plano del objeto, o en otras palabras, la fuerza de la perspectiva. Cuanto mayor sea el valor, más lejos estará del objeto; cuanto menor sea el valor, más perceptible será la perspectiva.

El origen de la perspectiva

El perspective-origin La propiedad determina la posición desde la que está “mirando” un objeto. Si el origen está centrado (que es el valor predeterminado) y el objeto se mueve hacia la derecha, parecerá que lo está mirando desde la izquierda (y viceversa).

Alternativamente, puede dejar el objeto centrado y mover el perspective-origin. Cuando el origen se establece a un lado, es como si estuvieras “mirando” el objeto desde ese lado. Cuanto mayor sea el valor, más lejos se verá.

La transformación

Mientras perspective y perspective-origin se establecen en el contenedor principal de un elemento y determinan la posición del punto de fuga (es decir, la distancia desde el plano del objeto desde la posición desde la que está “mirando” el objeto), la posición y la rotación del objeto se establecen utilizando el transform propiedad, que se declara en el propio objeto.

Si echas un vistazo al código del ejemplo anterior, donde moví el cuadrado de un lado a otro, verás que usé el translateX() función, lo cual tiene sentido ya que quería que se moviera a lo largo del eje X. Pero observe que está asignado a la propiedad transform. La función es un tipo de transformación que se aplica directamente al elemento que queremos transformar, pero que se comporta según las reglas de perspectiva asignadas al elemento padre.

Podemos “encadenar” múltiples funciones al transform propiedad. Pero al usar múltiples transformaciones, hay tres cosas muy importantes a considerar:

  1. Al rotar un objeto, su sistema de coordenadas se transforma junto con el objeto.
  2. Al traducir un objeto, se mueve en relación con su propio sistema de coordenadas (en lugar de las coordenadas de su padre).
  3. El orden en el que se escriben estos valores puede (y cambiará) el resultado final.

Para obtener el efecto que estaba buscando en la demostración anterior, primero necesitaba trasladar el cuadrado en el eje X. Solo entonces pude rotarlo. Si esto se hubiera hecho al revés (primero rotar, luego trasladar), entonces el resultado habría sido completamente diferente.

Para subrayar lo importante que es el orden de los valores para la transform propiedad, echemos un vistazo a un par de ejemplos rápidos. Primero, una transformación bidimensional (2D) simple de dos cuadrados que tienen los mismos valores de transformación, pero declarados en un orden diferente:

Es el mismo trato incluso si estamos rotando los cuadrados en el eje Y:

Cabe señalar que, si bien el orden de los valores es importante, podríamos simplemente cambiar los valores para obtener el resultado deseado en lugar de cambiar el orden de los valores. Por ejemplo…

transform: translateX(100px) rotateY(90deg);

… tendrá el mismo efecto que:

transform: rotateY(90deg) translate<strong>Z(100px);

Eso es porque en la primera línea movimos el objeto en el Eje X antes de rotarlo, pero en la segunda línea rotamos el objeto, cambiamos sus coordenadas, luego lo movimos en el Eje Z. Mismo resultado, diferentes valores.

Veamos algo más interesante.

Claro, los cuadrados son una buena manera de explicar el concepto general de perspectiva, pero realmente comenzamos a ver cómo funciona la perspectiva cuando nos dividimos en formas tridimensionales (3D).

Usemos todo lo que hemos cubierto hasta ahora para construir un cubo 3D.

El HTML

Crearemos un elemento .container que envuelve un elemento .cube que, a su vez, consta de seis elementos que representan los lados del cubo.

<div class="container">
  <div class="cube">
    <div class="side front"></div>
    <div class="side back"></div>
    <div class="side left"></div>
    <div class="side right"></div>
    <div class="side top"></div>
    <div class="side bottom"></div>
  </div>
</div>

El CSS general

Primero, agregaremos algo de perspectiva al padre .container elemento. Entonces nos aseguraremos de .cube El elemento tiene lados de 200px y respeta las transformaciones 3D. Estoy agregando algunos estilos de presentación aquí, pero las propiedades clave están resaltadas.

/* The parent container, with perspective */
.container {
  width: 400px;
  height: 400px;
  border: 2px solid white;
  border-radius: 4px;
  display: flex;
  justify-content: center;
  align-items: center;
  perspective: 800px;
  perspective-origin: top right;
}

/* The child element, with 3D tranforms preserved */
.cube {
  position: relative;
  width: 200px;
  height: 200px;
  transform-style: preserve-3d;
}

/* The sides of the cube, absolutely positioned */
.side {
  position: absolute;
  width: 100%;
  height: 100%;
  opacity: 0.9;
  border: 2px solid white;
}

/* Background colors for the cube's sides to help visualize the work */
.front { background-color: #d50000; }
.back { background-color: #aa00ff; }

.left { background-color: #304ffe; }
.right { background-color: #0091ea; }

.top { background-color: #00bfa5; }
.bottom { background-color: #64dd17; }

Transformando los lados

El anverso es el más sencillo. Lo avanzaremos 100px:

.front {
  background-color: #d50000;
  transform: translateZ(100px);
}

Podemos mover la parte posterior del cubo hacia atrás agregando translateZ(-100px). Otra forma de hacerlo es girando el lado 180 grados y luego moviéndolo hacia adelante:

.back {
  background-color: #aa00ff;
  transform: translateZ(-100px);


  /* or */
  /* transform: rotateY(180deg) translateZ(100px); */
}

Al igual que la parte posterior, hay un par de formas en las que podemos transformar los lados izquierdo y derecho:

.left {
  background-color: #304ffe;
  transform: rotateY(90deg) translateZ(100px);


  /* or */
  /* transform: translateX(100px) rotateY(90deg); */
}

.right {
  background-color: #0091ea;
  transform: rotateY(-90deg) translateZ(100px);


  /* or */
  /* transform: translateX(-100px) rotateY(90deg); */
}

La parte superior e inferior son un poco diferentes. En lugar de rotarlos en el eje Y, necesitamos rotarlos en el eje X. Nuevamente, se puede hacer de dos formas diferentes:

.top {
  background-color: #00Bfa5;
  transform: rotateX(90deg) translateZ(100px);


  /* or */
  /* transform: translateY(-100px) rotateX(90deg); */
}
 
.bottom {
  background-color: #64dd17;
  transform: rotateX(-90deg) translateZ(100px);


  /* or */
  /* transform: translateY(100px) rotateX(90deg); */
}

¡Esto nos da un cubo 3D!

Siéntete libre de jugar con las diferentes opciones para perspective y perspective-origin para ver cómo afectan al cubo.

Vamos a hablar de transform-style

Vamos a agregar una animación elegante a nuestro cubo, pero primero hablemos de la transform-style propiedad. Lo agregué anteriormente en el CSS general, pero realmente no expliqué qué es ni qué hace.

La propiedad de estilo de transformación tiene dos valores:

  • flat (defecto)
  • preserve-3d

Cuando establecemos la propiedad en preserve-3d, hace dos cosas importantes:

  1. Le dice a los lados del cubo (los elementos secundarios) que se coloquen en el mismo espacio 3D que el cubo. Si no está configurado en preserve-3d, el valor predeterminado se establece en flat , y los lados se aplanan en el plano del cubo. preserve-3d “Copia” la perspectiva del cubo a sus hijos (los lados) y nos permite rotar solo el cubo, por lo que no necesitamos animar cada lado por separado.
  2. Muestra los elementos secundarios según su posición en el espacio 3D, independientemente de su lugar en el DOM.

Hay tres cuadrados en este ejemplo: verde, rojo y azul. El cuadrado verde tiene un translateZ valor de 100px, lo que significa que está delante de los otros cuadrados. El cuadrado azul tiene una translateZ de -100px, lo que significa que está detrás de los otros cuadrados.

Pero en el DOM, el orden de los cuadrados es: verde, rojo, azul. Por tanto, cuando transform-style está configurado como plano (o no configurado en absoluto), el cuadrado azul aparecerá en la parte superior y el cuadrado verde estará en la parte posterior, porque ese es el orden del DOM. Pero si configuramos el transform-style a preserve-3d, se renderizará según su posición en el espacio 3D. Como resultado, el cuadrado verde estará al frente y el cuadrado azul estará detrás.

Animación

¡Ahora, animemos el cubo! Y para hacer las cosas más interesantes, agregaremos la animación a los tres ejes. Primero, agregaremos el animation propiedad a la .cube. Todavía no hará nada, ya que no hemos definido los fotogramas clave de la animación, pero estará listo para cuando lo hagamos.

animation: cubeRotate 10s linear infinite;

Ahora los fotogramas clave. Básicamente, vamos a rotar el cubo a lo largo de cada eje para que parezca estar rodando en el espacio.

@keyframes cubeRotate {
  from { transform: rotateY(0deg) rotateX(720deg) rotateZ(0deg); }
  to { transform: rotateY(360deg) rotateX(0deg) rotateZ(360deg); }
}

El perspective La propiedad es realmente lo que le da a la animación esa profundidad, como si estuviéramos viendo el cubo rodar hacia la izquierda y hacia la derecha, así como hacia adelante y hacia atrás.

Pero antes de ahora, el valor de la propiedad de perspectiva había sido constante, y también lo era el perspective-origin. Veamos cómo el cambio de estos valores afecta la apariencia del cubo.

Agregué tres controles deslizantes a este ejemplo para ayudar a ver cómo los diferentes valores afectan la perspectiva del cubo:

  • El control deslizante de la izquierda establece el valor de la perspective propiedad. Recuerde, este valor establece la distancia desde el plano del objeto, por lo que cuanto menor sea el valor, más notorio será el efecto de perspectiva.
  • Los otros dos controles deslizantes se refieren al perspective-origin propiedad. El control deslizante derecho establece el origen en el eje vertical, de arriba a abajo, y el control deslizante inferior establece el origen en el eje horizontal, de derecha a izquierda.

Tenga en cuenta que mientras se ejecuta la animación, estos cambios pueden ser menos notorios a medida que el cubo gira, pero puede desactivar fácilmente la animación haciendo clic en el botón “Ejecutar animación”.

Juegue con estos valores y descubra cómo afectan la apariencia del cubo. No hay un valor “correcto”, y estos valores varían de un proyecto a otro, ya que dependen de la animación, el tamaño del objeto y el efecto que desea lograr.

¿Qué es lo siguiente?

Ahora que domina los conceptos básicos de perspective propiedad en CSS, puede usar su imaginación y creatividad para crear objetos 3D en sus propios proyectos, agregando profundidad e interés a sus botones, menús, entradas y cualquier otra cosa que desee “dar vida”.

Mientras tanto, puede practicar y mejorar sus habilidades tratando de crear algunas estructuras complejas y animaciones basadas en perspectivas como esta, esta, esta o incluso esta.

¡Espero que hayas disfrutado leyendo este artículo y hayas aprendido algo nuevo en el proceso! No dudes en dejar un comentario para hacerme saber lo que piensas o escríbeme en Twitter si tiene alguna pregunta sobre la perspectiva o cualquier otro tema de este artículo.

(Visited 5 times, 1 visits today)