Tạo các đường cong ảnh động phức tạp trong CSS bằng hàm gia tốc tuyến tính()

Ra mắt linear(), một hàm gia tốc trong CSS. Hàm này nội suy tuyến tính giữa các điểm, cho phép bạn tạo lại hiệu ứng độ nảy và hiệu ứng lò xo.

Đơn giản trong CSS

Khi tạo ảnh động hoặc chuyển đổi các phần tử trong CSS, bạn có thể kiểm soát tốc độ thay đổi giá trị đối với hàm easing bằng cách sử dụng thuộc tính animation-timing-functiontransition-timing-function.

Có một số từ khóa có sẵn làm giá trị đặt trước trong CSS, cụ thể là linear, ease, ease-in, ease-outease-in-out. Để tạo đường cong gia tốc của riêng bạn, hãy sử dụng hàm cubic-bezier() hoặc thực hiện phương pháp theo bước bằng cách sử dụng hàm gia tốc steps().

Khi được sử dụng một cách thích hợp, tốc độ sẽ tạo cảm giác trọng lượng cho phần tử ảnh động vì phần tử này dường như thu thập động lượng.

Bạn không thể tạo các đường cong phức tạp như hiệu ứng độ nảy hoặc hiệu ứng lò xo trong CSS, nhưng nhờ có linear(), giờ đây bạn có thể ước tính chúng chính xác đến mức đáng kinh ngạc.

Giới thiệu về linear()

Hỗ trợ trình duyệt

  • 113
  • 113
  • 112
  • 17,2

Một cách mới để xác định tốc độ trong CSS là sử dụng linear(). Hàm này chấp nhận một số điểm dừng, được phân tách bằng dấu phẩy. Mỗi điểm dừng là một số duy nhất trong khoảng từ 0 đến 1. Ở giữa mỗi điểm dừng, nội suy được thực hiện theo cách tuyến tính, giải thích tên hàm.

animation-timing-function: linear(0, 0.25, 1);

Theo mặc định, các điểm dừng này được trải đều một cách đồng đều. Trong đoạn mã trước, điều đó có nghĩa là giá trị đầu ra của 0.25 sẽ được dùng ở mốc 50%.

Một cách trực quan, biểu đồ của linear(0, 0.25, 1) có dạng như sau:

Biểu đồ trực quan hoá tuyến tính(0, 0,25, 1).

Nếu không muốn chia đều các điểm dừng, bạn có thể tuỳ ý vượt qua thời lượng điểm dừng. Khi truyền một giá trị dưới dạng độ dài điểm dừng, bạn xác định điểm bắt đầu của giá trị đó:

animation-timing-function: linear(0, 0.25 75%, 1);

Ở đây, giá trị đầu ra của 0.25 sẽ không được dùng ở dấu 50% mà ở 75%.

Biểu đồ trực quan của tuyến tính(0; 0, 25 75%, 1).

Khi chỉ định hai giá trị làm độ dài điểm dừng, bạn phải xác định cả điểm bắt đầu và điểm kết thúc:

animation-timing-function: linear(0, 0.25 25% 75%, 1);

Giá trị đầu ra 0,25 sẽ được sử dụng từ 25% đến 75% trong thời gian.

Biểu đồ trực quan của tuyến tính(0, 0,25 25% 75%, 1).

Tạo đường cong phức tạp bằng hàm tuyến tính()

Mặc dù các ví dụ ở trên là các gia tốc rất đơn giản, bạn có thể sử dụng linear() để tạo lại các hàm gia tốc phức tạp theo cách rất đơn giản, đồng thời sẽ mất độ chính xác.

Hãy xem đường cong tốc độ thoát này, một loại gia tốc không thể được biểu thị trực tiếp trong CSS, được xác định bằng JavaScript:

function easing(pos) {
  const t = 7.5625;
  const e = 2.75;
  return pos < 1 / e
    ? t * pos * pos
    : pos < 2 / e
    ? t * (pos -= 1.5 / e) * pos + 0.75
    : pos < 2.5 / e
    ? t * (pos -= 2.25 / e) * pos + 0.9375
    : t * (pos -= 2.625 / e) * pos + 0.984375;
}

Mặc dù mã có thể không cho bạn biết nhiều, nhưng có thể có hình ảnh trực quan. Đây là kết quả, được minh hoạ dưới dạng đường cong màu xanh dương:

Một đường cong nảy mượt được vẽ bằng màu xanh dương.

Có thể đơn giản hoá đường cong bằng cách thêm một số điểm dừng vào đó. Ở đây, mỗi chấm màu xanh lục biểu thị một điểm dừng:

Một đường cong nảy nhẵn màu xanh dương, với các chấm màu xanh lục nằm ở trên cùng.

Khi truyền vào linear(), kết quả là một đường cong trông giống như đường cong ban đầu nhưng có chút thô hơn ở các cạnh.

Một đường cong được đơn giản hoá màu xanh lục nằm trên đường cong trơn ban đầu có màu xanh dương.

So sánh hộp ảnh động màu xanh lục với hộp màu xanh dương, bạn có thể thấy hộp này không mượt mà bằng.

Tuy nhiên, nếu bạn thêm đủ số điểm dừng, bạn có thể ước chừng đường cong ban đầu khá chính xác. Sau đây là phiên bản đã cập nhật:

Một đường cong được cập nhật, với số điểm dừng gấp đôi.

Chỉ cần tăng gấp đôi số điểm dừng là bạn đã có được kết quả suôn sẻ.

Mã dùng để tạo ảnh động có dạng như sau:

animation-timing-function: linear(
  /* Start to 1st bounce */
  0, 0.004, 0.016, 0.035, 0.063 9.1%, 0.141, 0.25, 0.391, 0.563, 0.765, 1,
  /* 1st to 2nd bounce */
  0.891, 0.813 45.5%, 0.785, 0.766, 0.754, 0.75, 0.754, 0.766, 0.785, 0.813 63.6%, 0.891, 1 72.7%,
  /* 2nd to 3rd bounce */
  0.973, 0.953, 0.941, 0.938, 0.941, 0.953, 0.973, 1,
  /* 3rd bounce to end */
  0.988, 0.984, 0.988, 1
);

Một công cụ trợ giúp

Việc tạo danh sách điểm dừng này theo cách thủ công sẽ rất rườm rà. Rất may là JakeAdam đã tạo một công cụ giúp bạn chuyển đổi đường cong gia tốc sang đường cong tương ứng linear().

Ảnh chụp màn hình công cụ tạo easing tuyến tính.
Ảnh chụp màn hình minh hoạ cách hoạt động của https://linear-easing-generator.netlify.app/.

Công cụ này lấy hàm easing JavaScript hoặc đường cong SVG làm đầu vào và tạo ra đường cong đơn giản bằng cách sử dụng linear(). Sử dụng thanh trượt để kiểm soát số điểm dừng bạn muốn và độ chính xác của các điểm dừng đó.

Ở trên cùng bên phải, bạn cũng có thể chọn một trong các giá trị đặt trước: Lò xo, Độ nảy, đàn hồi đơn giản hoặc Tốc độ được nhấn mạnh theo Material Design cũng được đưa vào.

Hỗ trợ Công cụ cho nhà phát triển

Công cụ cho nhà phát triển hỗ trợ trực quan hoá và chỉnh sửa kết quả của linear(). Hãy nhấp vào biểu tượng này để hiển thị một phần chú thích mang tính tương tác, giúp bạn kéo quanh các điểm dừng.

Ảnh chụp màn hình trình chỉnh sửa &quot;linear()&quot; của Công cụ cho nhà phát triển của Chrome.
Ảnh chụp màn hình trình chỉnh sửa "linear()" của Công cụ cho nhà phát triển của Chrome.

Tính năng Công cụ cho nhà phát triển này có trong công cụ vận chuyển của Công cụ cho nhà phát triển với Chrome 114.

Ảnh chụp của Howie Mapson trên Unsplash