Hàm lượng giác trong CSS

Tính sin, cos, tang và nhiều hàm khác trong CSS.

Trong CSS, bạn có thể viết biểu thức toán học. Ở cơ sở là hàm calc() để thực hiện các phép tính, nhưng rất có thể bạn cũng đã nghe nói về min(), max()clamp().

Kết hợp các hàm này là các hàm lượng giác sin(), cos(), tan(), asin(), acos(), atan()atan2(). Các hàm này được xác định trong Mô-đun giá trị và đơn vị CSS cấp 4 và có sẵn trong tất cả trình duyệt.

Hỗ trợ trình duyệt

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

Nguồn

sin(), cos()tan()

Ba hàm lượng giác cốt lõi là:

  • cos(): Trả về cosin của một góc, là một giá trị nằm trong khoảng từ -1 đến 1.
  • sin(): Trả về sin của một góc, giá trị này nằm trong khoảng từ -1 đến 1.
  • tan(): Trả về giá trị tang của một góc, là một giá trị nằm trong khoảng từ −∞ đến +∞.

Không giống như các hàm tương đương trong JavaScript, các hàm này chấp nhận cả góc và radian làm đối số.

Trong bản minh hoạ sau, các hàm này được dùng để vẽ các đường tạo nên hình tam giác bao quanh tập hợp --angle:

  • "Đường gạch chéo" (đường màu vàng) là một đường kẻ từ tâm vòng tròn đến vị trí của dấu chấm. Độ dài của nó bằng --radius của vòng tròn.
  • "Giá trị" (đường màu đỏ) là một đường thẳng tính từ tâm của vòng tròn dọc theo trục X. Độ dài của nó bằng --radius nhân với cosin của --angle.
  • "Đối diện" (đường màu xanh dương) là một đường từ tâm của dấu chấm dọc theo trục Y. Chiều dài của nó bằng --radius nhân với sin của --angle.
  • Hàm tan() của --angle được dùng để vẽ đường màu xanh lục từ dấu chấm đến trục X.

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

Các đối tượng vòng cung hoặc ngược tương ứng với sin(), cos()tan() lần lượt là asin(), acos()atan(). Các hàm này thực hiện phép tính theo hướng ngược lại: lấy một giá trị số làm đối số và trả về góc tương ứng cho giá trị đó.

Cuối cùng, có atan2() chấp nhận hai đối số AB. Hàm này trả về góc giữa trục X dương và điểm (B,A).

Ví dụ

Có nhiều trường hợp sử dụng cho các hàm này. Sau đây là một số lựa chọn nhỏ.

Di chuyển các mục trên một đường tròn xung quanh một điểm trung tâm

Trong bản minh hoạ sau, các dấu chấm xoay quanh một điểm trung tâm. Thay vì xoay từng dấu chấm xung quanh tâm của dấu chấm đó rồi di chuyển ra ngoài, mỗi dấu chấm được dịch trên trục X và Y. Khoảng cách trên trục X và Y được xác định bằng cách tính đến cos()sin() của --angle tương ứng.

: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)
  ;
}

Để phân phối các dấu chấm đều xung quanh điểm trung tâm, mỗi dấu chấm được thêm một độ dời dựa trên chỉ mục nth-child của dấu chấm đó. Ví dụ: nếu có 3 dấu chấm thì khoảng cách giữa các dấu chấm là 120deg (= 360deg / 3).

  • Phần tử con đầu tiên trong số 3 phần tử con được bù bằng 0 x 120deg = 0deg.
  • Phần tử con thứ hai trong số ba phần tử con được bù bằng 1 x 120deg = 120deg.
  • Phần tử con thứ ba trong số ba phần tử con được bù bằng 2 x 120deg = 240deg.

Xoay một phần tử để hướng về nguồn gốc của phần tử đó

Hàm atan2() tính toán góc tương đối từ một điểm đến điểm khác. Hàm này chấp nhận hai giá trị được phân tách bằng dấu phẩy làm tham số: vị trí yx của điểm kia, so với điểm gốc nằm ở gốc 0,0.

Với giá trị đã tính, bạn có thể xoay các phần tử để chúng đối diện nhau bằng cách sử dụng Thuộc tính biến đổi riêng lẻ.

Trong ví dụ sau, các hộp được xoay để hướng về vị trí của chuột. Vị trí con trỏ được đồng bộ hoá với một thuộc tính tuỳ chỉnh thông qua 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)
          );
}

Nội dung nổi bật của cộng đồng

Như minh hoạ trong Dải Möbius động của Ana Tudor, cos()sin() không chỉ dùng để dịch. Ở đây, kết quả của chúng được dùng để thao tác với các thành phần sl của hàm màu hsl().