Funciones trigonométricas en CSS

Calcular el seno, el coseno, la tangente y otros valores en CSS

Funciones trigonométricas

En CSS, es posible escribir expresiones matemáticas. En la base, se encuentra la función calc() para hacer cálculos, pero es probable que también hayas oído hablar de min(), max() y clamp().

Unir estas funciones están las funciones trigonométricas sin(), cos(), tan(), asin(), acos(), atan() y atan2(). Estas funciones se definen en el nivel 4 del módulo de unidades y valores de CSS y están disponibles en todos los navegadores.

Navegadores compatibles

  • 111
  • 111
  • 108
  • 15.4

Origen

sin(), cos() y tan()

Las tres funciones principales de trig son las siguientes:

  • cos(): Muestra el coseno de un ángulo, que es un valor entre -1 y 1.
  • sin(): Muestra el seno de un ángulo, que es un valor entre -1 y 1.
  • tan(): Muestra la tangente de un ángulo, que es un valor entre −∞ y +∞.

A diferencia de sus equivalentes de JavaScript, estas funciones aceptan ángulos y radianes como argumento.

En la siguiente demostración, estas funciones se usan para dibujar las líneas que conforman el triángulo que rodea el conjunto --angle:

  • La "hipotenusa" (línea amarilla) es una línea desde el centro del círculo hasta la posición del punto. Su longitud es igual al --radius del círculo.
  • La (línea roja) "adyacente" es una línea desde el centro del círculo a lo largo del eje X. Su longitud es igual al --radius multiplicado por el coseno de --angle.
  • El valor "opuesto" (línea azul) es una línea que proviene del centro del punto a lo largo del eje Y. Su longitud es igual al --radius multiplicado por el seno de --angle.
  • La función tan() de --angle se usa para dibujar la línea verde desde el punto hacia el eje X.

asin(), acos(), atan() y atan2()

Los equivalentes arco o inverso de sin(), cos() y tan() son asin(), acos() y atan(), respectivamente. Estas funciones realizan el cálculo en la dirección opuesta: toman un valor numérico como argumento y devuelven el ángulo correspondiente.

Por último, está atan2(), que acepta dos argumentos: A y B. La función muestra el ángulo entre el eje X positivo y el punto (B,A).

Ejemplos

Existen varios casos de uso para estas funciones. Lo que sigue es una pequeña selección.

Mover elementos en una ruta circular alrededor de un punto central

En la siguiente demostración, los puntos giran en torno a un punto central. En lugar de rotar cada punto alrededor de su propio centro y luego moverlo hacia afuera, cada punto se traslada en los ejes X e Y. Las distancias en los ejes X e Y se determinan teniendo en cuenta cos() y, respectivamente, la sin() de --angle.

:root {
  --radius: 20vmin;
}

.dot {
  --angle: 30deg;
  translate: /* Translation on X-axis */
             calc(cos(var(--angle)) * var(--radius))

             /* Translation on Y-axis */
             calc(sin(var(--angle)) * var(--radius) * -1)
  ;
}

Para distribuir los puntos de manera uniforme alrededor del punto central, a cada punto se le asigna un desplazamiento adicional en función de su índice nth-child. Por ejemplo, si hay tres puntos, hay una distancia de 120deg (= 360deg / 3) entre cada uno de ellos.

  • El primer elemento secundario de tres se desplaza en 0 x 120deg = 0deg.
  • El segundo elemento secundario de un total de tres se desplaza en 1 x 120deg = 120deg.
  • El tercer elemento secundario de un total de tres se desplaza en 2 x 120deg = 240deg.

Rota un elemento para que mire su origen

La función atan2() calcula el ángulo relativo de un punto a otro. La función acepta dos valores separados por comas como parámetros: la posición y y x del otro punto, en relación con el punto de origen que se encuentra en el origen 0,0.

Con el valor calculado, es posible rotar los elementos para que estén frente a frente usando las propiedades de transformación individuales.

En el siguiente ejemplo, los cuadros rotan de modo que queden orientados hacia la ubicación del mouse. La posición del mouse se sincroniza con una propiedad personalizada a través de JavaScript.

div.box {
  --my-x: 200;
  --my-y: 300;

  /* Position the box inside its parent */
  position: absolute;
  width: 50px;
  aspect-ratio: 1;
  translate: calc((var(--my-x) * 1px)) calc(var(--my-y) * 1px);

  /* Rotate so that the box faces the mouse position */
  /* For this, take the box its own position and size (25 = half the width) into account */
  rotate: atan2(
            calc((var(--mouse-x) - var(--my-x) - 25) * 1),
            calc((var(--mouse-y) - var(--my-y) - 25) * -1)
          );
}

Momento destacado de la comunidad

Como se demuestra en esta parte animada de Möbius de Ana Tudor, cos() y sin() se pueden usar para mucho más que solo traducciones. Aquí, su resultado se usa para manipular los componentes s y l de la función de color hsl().