Funciones trigonométricas en CSS

Calcula el seno, el coseno, la tangente y mucho más en CSS.

Funciones trigonométricas

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

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

Navegadores compatibles

  • Chrome: 111
  • Edge: 111
  • Firefox: 108.
  • Safari: 15.4.

Origen

sin(), cos() y tan()

Las tres funciones trig principales 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 su argumento.

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

  • La “hipotenusa” (línea amarilla) es una línea que va desde el centro del círculo hasta la posición del punto. Su longitud es igual a la --radius del círculo.
  • La iniciativa "adyacente" (línea roja) es una línea desde el centro del círculo a lo largo del eje X. Su longitud es igual a --radius multiplicado por el coseno de --angle.
  • Lo "opuesto" (línea azul) Es una línea que va desde el centro del punto a lo largo del eje Y. Su longitud es igual al --radius multiplicado por el seno del --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 arc o inverso de sin(), cos() y tan() son asin(), acos() y atan(), respectivamente. Estas funciones hacen el cálculo en la dirección opuesta: toman un valor numérico como argumento y muestran 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 de una ruta circular alrededor de un punto central

En la siguiente demostración, los puntos giran alrededor de un punto central. En lugar de rotar cada punto alrededor de su propio centro y luego moverlo hacia afuera, cada punto se traduce en los ejes X e Y. Para determinar las distancias en los ejes X e Y, se tienen en cuenta cos() y, respectivamente, 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 en todo el punto central, a cada punto se le asigna un desplazamiento adicional basado en su índice nth-child. Por ejemplo, si hay tres puntos, hay una distancia de 120deg (= 360deg / 3) entre cada punto.

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

Rota un elemento para que se oriente a 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 sus 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, mediante las Propiedades de transformación individuales.

En el siguiente ejemplo, los cuadros se rotan de modo que queden orientados a 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)
          );
}

Lo destacado de la comunidad

Como se demuestra en esta tira de Möbius animada 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().