Funzioni trigonometriche in CSS

Calcola il seno, il coseno, la tangente e altro ancora in CSS.

In CSS è possibile scrivere espressioni matematiche. Alla base c'è la funzione calc() per eseguire i calcoli, ma molto probabilmente avrai sentito parlare anche di min(), max() e clamp().

A queste funzioni si aggiungono le funzioni trigonometriche sin(), cos(), tan(), asin(), acos(), atan() e atan2(). Queste funzioni sono definite nel Modulo Valori e unità CSS di Livello 4 e sono disponibili in tutti i browser.

Supporto dei browser

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

Origine

sin(), cos() e tan()

Le tre funzioni trigonometriche principali sono:

  • cos(): restituisce il coseno di un angolo, ovvero un valore compreso tra -1 e 1.
  • sin(): restituisce il seno di un angolo, ovvero un valore compreso tra -1 e 1.
  • tan(): restituisce la tangente di un angolo, ovvero un valore compreso tra −∞ e +∞.

A differenza delle loro controparti JavaScript, queste funzioni accettano come argomento sia gli angoli che i radianti.

Nella seguente demo, queste funzioni vengono utilizzate per disegnare le linee che compongono il triangolo che circonda l'insieme --angle:

  • L'"ipotenusa" (linea gialla) è una linea che va dal centro del cerchio alla posizione del punto. La sua lunghezza è uguale al --radius del cerchio.
  • La linea "adiacente" (linea rossa) è una linea che parte dal centro del cerchio lungo l'asse X. La sua lunghezza è uguale al --radius moltiplicato per la cotangente del --angle.
  • Il valore "opposto" (linea blu) è una linea che parte dal centro del punto lungo l'asse Y. La sua lunghezza è uguale a --radius moltiplicato per il seno di --angle.
  • La funzione tan() di --angle viene utilizzata per tracciare la linea verde dal punto verso l'asse X.

asin(), acos(), atan() e atan2()

Le corrispondenze arco o inversa di sin(), cos() e tan() sono rispettivamente asin(), acos() e atan(). Queste funzioni eseguono il calcolo nella direzione opposta: prendono un valore numerico come argomento e restituiscono l'angolo corrispondente.

Infine, c'è atan2() che accetta due argomenti A e B. La funzione restituisce l'angolo tra l'asse X positivo e il punto (B,A).

Esempi

Esistono vari casi d'uso per queste funzioni. Di seguito è riportata una piccola selezione.

Spostare elementi su un percorso circolare attorno a un punto centrale

Nella seguente demo, i punti ruotano attorno a un punto centrale. Invece di ruotare ogni punto attorno al proprio centro e poi spostarlo verso l'esterno, ogni punto viene tradotto sugli assi X e Y. Le distanze sugli assi X e Y vengono determinate tenendo conto del cos() e, rispettivamente, del sin() del --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)
 
;
}

Per distribuire i punti in modo uniforme attorno al punto centrale, a ogni punto viene assegnato un offset aggiuntivo in base al relativo indice nth-child. Ad esempio, se ci sono tre punti, tra ciascun punto c'è una distanza di 120deg (= 360deg / 3).

  • Il primo elemento secondario di tre viene compensato per 0 x 120deg = 0deg.
  • Il secondo elemento secondario di tre viene spostato di 1 x 120deg = 120deg.
  • Il terzo elemento secondario su tre viene compensato per 2 x 120deg = 240deg.

Ruotare un elemento in modo che sia rivolto verso l'origine

La funzione atan2() calcola l'angolo relativo da un punto all'altro. La funzione accetta come parametri due valori separati da virgole: la posizione y e x dell'altro punto rispetto al punto di origine che si trova all'origine 0,0.

Con il valore calcolato è possibile ruotare gli elementi in modo che si fronteggino, utilizzando le proprietà di trasformazione individuali.

Nell'esempio seguente, le caselle sono ruotate in modo che siano rivolte verso la posizione del mouse. La posizione del mouse viene sincronizzata con una proprietà personalizzata tramite 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)
         
);
}

In evidenza nella community

Come dimostrato in questo nastro di Möbius animato di Ana Tudor, cos() e sin() possono essere utilizzati per qualcosa di più delle traduzioni. Qui il risultato viene utilizzato per manipolare i componenti s e l della funzione di colore hsl().