Tạo ảnh động cho các phần tử khi cuộn bằng ảnh động theo hướng cuộn

Tìm hiểu cách sử dụng tính năng Dòng thời gian cuộn và Xem dòng thời gian để tạo ảnh động dựa trên thao tác cuộn theo cách khai báo.

Ảnh động dựa trên thao tác cuộn

Hỗ trợ trình duyệt

  • Chrome: 115.
  • Cạnh: 115.
  • Firefox: sau một lá cờ.
  • Safari: không được hỗ trợ.

Nguồn

Ảnh động điều khiển cuộn là một mẫu trải nghiệm người dùng phổ biến trên web. Ảnh động di chuyển được liên kết với vị trí cuộn của vùng chứa cuộn. Điều này có nghĩa là khi bạn cuộn lên hoặc xuống, ảnh động được liên kết sẽ tua đi hoặc tua lại trong phản hồi trực tiếp. Ví dụ: những hiệu ứng như hình nền thị sai hoặc chỉ báo đọc có chuyển động khi bạn cuộn.

Chỉ báo đọc ở phía trên tài liệu, được điều khiển bằng thao tác cuộn.

Một loại ảnh động tương tự dựa trên thao tác cuộn là ảnh động được liên kết với vị trí của một phần tử trong vùng chứa cuộn của nó. Ví dụ: với tính năng này, các phần tử có thể rõ dần khi xuất hiện.

Hình ảnh trên trang này mờ dần khi xuất hiện.

Cách cổ điển để đạt được các loại hiệu ứng này là phản hồi các sự kiện cuộn trên luồng chính, dẫn đến 2 vấn đề chính:

  • Các trình duyệt hiện đại thực hiện thao tác cuộn trên một quy trình riêng biệt và do đó phân phối các sự kiện cuộn một cách không đồng bộ.
  • Ảnh động trong luồng chính có thể bị giật.

Điều này khiến việc tạo các ảnh động điều khiển cuộn hiệu suất đồng bộ với thao tác cuộn không thể hoặc rất khó khăn.

Từ Chrome phiên bản 115, bạn có thể dùng một bộ API và khái niệm mới để bật ảnh động dựa trên thao tác cuộn khai báo: Cuộn dòng thời gian và Xem dòng thời gian.

Các khái niệm mới này tích hợp với API Ảnh động web (WAAPI)CSS Ảnh động API hiện có, cho phép chúng kế thừa những lợi thế mà các API hiện có này mang lại. Điều đó bao gồm khả năng làm cho ảnh động theo hướng cuộn chạy ra khỏi luồng chính. Có, hãy đọc đúng nội dung đó: giờ đây, bạn có thể có hoạt ảnh mượt mà, được điều khiển bằng thao tác cuộn, chạy khỏi chuỗi chính, chỉ với một vài dòng mã bổ sung. Bạn không thích điểm gì?!

Ảnh động trên web, bản tóm tắt ngắn gọn

Ảnh động trên web bằng CSS

Để tạo ảnh động trong CSS, hãy xác định một tập hợp các khung hình chính bằng quy tắc tại @keyframes. Liên kết thành phần này với một phần tử bằng thuộc tính animation-name, đồng thời thiết lập animation-duration để xác định thời gian cần để ảnh động. Hiện có nhiều thuộc tính dài animation-* khác – animation-easing-functionanimation-fill-mode – chỉ là một số thuộc tính có thể kết hợp được trong viết tắt animation.

Ví dụ: dưới đây là ảnh động tăng tỷ lệ một phần tử trên trục X trong khi đồng thời thay đổi màu nền của phần tử đó:

@keyframes scale-up {
  from {
    background-color: red;
    transform: scaleX(0);
  }
  to {
    background-color: darkred;
    transform: scaleX(1);
  }
}

#progressbar {
  animation: 2.5s linear forwards scale-up;
}

Ảnh động trên web bằng JavaScript

Trong JavaScript, bạn có thể dùng API Ảnh động trên web để đạt được giống hệt như vậy. Bạn có thể thực hiện việc này bằng cách tạo các thực thể AnimationKeyFrameEffect mới hoặc sử dụng phương thức Element animate() ngắn hơn nhiều.

document.querySelector('#progressbar').animate(
  {
    backgroundColor: ['red', 'darkred'],
    transform: ['scaleX(0)', 'scaleX(1)'],
  },
  {
    duration: 2500,
    fill: 'forwards',
    easing: 'linear',
   }
);

Kết quả hình ảnh này của đoạn mã JavaScript ở trên giống với phiên bản CSS trước đó.

Dòng thời gian ảnh động

Theo mặc định, ảnh động được đính kèm vào một phần tử sẽ chạy trên tiến trình của tài liệu. Thời gian gốc của thời gian bắt đầu từ 0 khi trang tải và bắt đầu tua đi khi thời gian đồng hồ tăng dần. Đây là dòng thời gian ảnh động mặc định và cho đến bây giờ là dòng thời gian ảnh động duy nhất mà bạn có quyền truy cập.

Thông số kỹ thuật về ảnh động theo hướng cuộn xác định hai loại dòng thời gian mới mà bạn có thể sử dụng:

  • Dòng thời gian tiến trình cuộn: dòng thời gian được liên kết với vị trí cuộn của vùng chứa cuộn dọc theo một trục cụ thể.
  • Xem tiến trình: một dòng thời gian được liên kết với vị trí tương đối của một phần tử cụ thể trong vùng chứa cuộn của phần tử đó.

Tiến trình cuộn

Tiến trình cuộn là một dòng thời gian ảnh động được liên kết với tiến trình ở vị trí cuộn của vùng chứa cuộn – còn được gọi là scrollport hoặc scroller – dọc theo một trục cụ thể. Hàm này chuyển đổi vị trí trong dải ô cuộn thành phần trăm tiến trình.

Vị trí cuộn bắt đầu biểu thị tiến trình 0% và vị trí cuộn kết thúc biểu thị tiến trình 100%. Trong hình minh hoạ sau đây, bạn có thể thấy tiến trình được tính từ 0% đến 100% khi bạn di chuyển từ trên xuống dưới.

Hình ảnh về Tiến trình cuộn. Khi bạn cuộn xuống cuối thanh cuộn, giá trị tiến trình sẽ tăng từ 0% lên 100%.

✨ Dùng thử

Dòng thời gian của tiến trình cuộn thường được viết tắt thành "Cuộn dòng thời gian".

Xem tiến trình

Loại dòng thời gian này được liên kết với tiến trình tương đối của một phần tử cụ thể trong vùng chứa cuộn. Giống như Dòng thời gian tiến trình cuộn, độ lệch cuộn của trình cuộn được theo dõi. Không giống như Tiến trình cuộn, vị trí tương đối của một chủ thể trong trình cuộn đó xác định tiến trình.

Điều này tương đương với cách hoạt động của IntersectionObserver. Khả năng này có thể theo dõi mức độ hiển thị của một phần tử trong trình cuộn. Nếu phần tử không hiển thị trong trình cuộn thì phần tử này không giao nhau. Nếu phần này hiện bên trong thanh cuộn (ngay cả với phần nhỏ nhất) thì phần tử này đang giao nhau.

Tiến trình xem bắt đầu từ thời điểm một đối tượng bắt đầu giao với trình cuộn và kết thúc khi đối tượng ngừng giao với trình cuộn. Trong hình ảnh dưới đây, bạn có thể thấy tiến trình bắt đầu đếm từ 0% khi đối tượng đi vào vùng chứa cuộn và đạt 100% tại thời điểm đối tượng rời khỏi vùng chứa cuộn.

Hình ảnh về Tiến trình xem. Tiến trình sẽ tăng từ 0% đến 100% khi chủ thể (hộp màu xanh lục) đi qua thanh cuộn.

✨ Dùng thử

Tiến trình xem tiến trình thường được viết tắt thành "Xem dòng thời gian". Bạn có thể nhắm mục tiêu các phần cụ thể của Chế độ xem dòng thời gian dựa trên kích thước của đối tượng, nhưng sẽ dựa vào quy mô của đối tượng đó nhiều hơn sau đó.

Thực hành với Tiến trình cuộn

Tạo Tiến trình cuộn ẩn danh trong CSS

Cách dễ nhất để tạo Dòng thời gian cuộn trong CSS là sử dụng hàm scroll(). Thao tác này sẽ tạo một Dòng thời gian cuộn ẩn danh mà bạn có thể đặt làm giá trị cho thuộc tính animation-timeline mới.

Ví dụ:

@keyframes animate-it { … }

.subject {
  animation: animate-it linear;
  animation-timeline: scroll(root block);
}

Hàm scroll() chấp nhận <scroller> và đối số <axis>.

Các giá trị được chấp nhận cho đối số <scroller> như sau:

  • nearest: Sử dụng vùng chứa cuộn đối tượng cấp trên gần nhất (mặc định).
  • root: Sử dụng khung nhìn tài liệu làm vùng chứa cuộn.
  • self: Sử dụng chính phần tử đó làm vùng chứa cuộn.

Các giá trị được chấp nhận cho đối số <axis> như sau:

  • block: Sử dụng phép đo tiến trình dọc theo trục khối của vùng chứa cuộn (mặc định).
  • inline: Sử dụng phép đo tiến trình dọc theo trục cùng dòng của vùng chứa cuộn.
  • y: Sử dụng phép đo tiến trình dọc theo trục y của vùng chứa cuộn.
  • x: Sử dụng phép đo tiến trình dọc theo trục x của vùng chứa cuộn.

Ví dụ: để liên kết một ảnh động với trình cuộn gốc trên trục khối, các giá trị cần truyền vào scroll()rootblock. Tổng hợp lại, giá trị là scroll(root block).

Bản minh hoạ: Chỉ báo tiến trình đọc

Bản minh hoạ này có chỉ báo tiến trình đọc được cố định ở đầu khung nhìn. Khi bạn di chuyển xuống phía dưới trang, thanh tiến trình sẽ tăng lên cho đến khi chiếm toàn bộ chiều rộng của khung nhìn khi đến cuối tài liệu. Dòng thời gian tiến trình cuộn ẩn danh được dùng để điều khiển ảnh động.

Bản minh hoạ: Chỉ báo tiến trình đọc.

✨ Dùng thử

Chỉ báo tiến trình đọc được đặt ở đầu trang theo vị trí cố định. Để tận dụng ảnh động kết hợp, không phải width đang được tạo ảnh động mà phần tử được thu nhỏ trên trục x bằng transform.

<body>
  <div id="progress"></div>
  …
</body>
@keyframes grow-progress {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

#progress {
  position: fixed;
  left: 0; top: 0;
  width: 100%; height: 1em;
  background: red;

  transform-origin: 0 50%;
  animation: grow-progress auto linear;
  animation-timeline: scroll();
}

Dòng thời gian của ảnh động grow-progress trên phần tử #progress được đặt thành dòng thời gian ẩn danh được tạo bằng scroll(). Không có đối số nào được cung cấp cho scroll(), do đó, hàm này sẽ quay về giá trị mặc định.

Trình cuộn mặc định cần theo dõi là nearest và trục mặc định là block. Thao tác này sẽ nhắm mục tiêu hiệu quả trình cuộn gốc vì đó là trình cuộn gần nhất của phần tử #progress, đồng thời theo dõi hướng khối của thành phần này.

Tạo Tiến trình cuộn có tên trong CSS

Một cách khác để xác định Dòng thời gian tiến trình cuộn là sử dụng một tiến trình được đặt tên. Tính năng này chi tiết hơn một chút nhưng có thể hữu ích khi bạn không nhắm mục tiêu trình cuộn cha hay trình cuộn gốc hay khi trang sử dụng nhiều dòng thời gian hoặc khi tính năng tra cứu tự động không hoạt động. Bằng cách này, bạn có thể xác định Tiến trình cuộn theo tên mà bạn đặt cho tiến trình đó.

Để tạo Dòng thời gian tiến trình cuộn được đặt tên trên một phần tử, hãy đặt thuộc tính CSS scroll-timeline-name trên vùng chứa cuộn thành một giá trị nhận dạng theo ý bạn. Giá trị này phải bắt đầu bằng --.

Để điều chỉnh trục cần theo dõi, bạn cũng cần khai báo thuộc tính scroll-timeline-axis. Các giá trị được phép giống với đối số <axis> của scroll().

Cuối cùng, để liên kết ảnh động với Dòng thời gian tiến trình cuộn, hãy thiết lập thuộc tính animation-timeline trên phần tử cần tạo ảnh động thành giá trị giống với giá trị nhận dạng dùng cho scroll-timeline-name.

Ví dụ về mã:

@keyframes animate-it { … }

.scroller {
  scroll-timeline-name: --my-scroller;
  scroll-timeline-axis: inline;
}

.scroller .subject {
  animation: animate-it linear;
  animation-timeline: --my-scroller;
}

Nếu muốn, bạn có thể kết hợp scroll-timeline-namescroll-timeline-axis trong cách viết tắt scroll-timeline. Ví dụ:

scroll-timeline: --my-scroller inline;

Bản minh hoạ này cho thấy một chỉ báo bước hiển thị phía trên mỗi băng chuyền hình ảnh. Khi băng chuyền chứa ba hình ảnh, thanh chỉ báo sẽ bắt đầu với chiều rộng là 33% để cho biết bạn hiện đang xem hình ảnh một trong ba hình ảnh. Khi hình ảnh cuối cùng trong chế độ xem–được xác định bởi trình cuộn khi cuộn đến cuối–chỉ báo sẽ chiếm toàn bộ chiều rộng của trình cuộn. Dòng thời gian tiến trình cuộn có tên được dùng để điều khiển ảnh động.

Bản minh hoạ: Chỉ báo bước theo băng chuyền theo chiều ngang.

✨ Dùng thử

Mã đánh dấu cơ bản cho một thư viện là:

<div class="gallery" style="--num-images: 2;">
  <div class="gallery__scrollcontainer">
    <div class="gallery__progress"></div>
    <div class="gallery__entry">…</div>
    <div class="gallery__entry">…</div>
  </div>
</div>

Phần tử .gallery__progress được đặt tuyệt đối trong phần tử trình bao bọc .gallery. Kích thước ban đầu của hình ảnh này do thuộc tính tuỳ chỉnh --num-images xác định.

.gallery {
  position: relative;
}


.gallery__progress {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 1em;
  transform: scaleX(calc(1 / var(--num-images)));
}

.gallery__scrollcontainer bố trí các phần tử .gallery__entry bên trong theo chiều ngang và là phần tử cuộn được. Bằng cách theo dõi vị trí cuộn, .gallery__progress sẽ được tạo ảnh động. Bạn có thể thực hiện việc này bằng cách tham chiếu đến Tiến trình cuộn có tên --gallery__scrollcontainer.

@keyframes grow-progress {
  to { transform: scaleX(1); }
}

.gallery__scrollcontainer {
  overflow-x: scroll;
  scroll-timeline: --gallery__scrollcontainer inline;
}
.gallery__progress {
  animation: auto grow-progress linear forwards;
  animation-timeline: --gallery__scrollcontainer;
}

Tạo Tiến trình cuộn bằng JavaScript

Để tạo Dòng thời gian cuộn trong JavaScript, hãy tạo một thực thể mới của lớp ScrollTimeline. Truyền vào một túi thuộc tính có sourceaxis mà bạn muốn theo dõi.

  • source: Tham chiếu đến phần tử có trình cuộn mà bạn muốn theo dõi. Sử dụng document.documentElement để nhắm mục tiêu trình cuộn gốc.
  • axis: Xác định trục nào cần theo dõi. Tương tự như biến thể CSS, các giá trị được chấp nhận là block, inline, xy.
const tl = new ScrollTimeline({
  source: document.documentElement,
});

Để đính kèm ảnh động này vào Ảnh động trên web, hãy truyền thuộc tính này vào dưới dạng thuộc tính timeline và bỏ qua mọi duration (nếu có).

$el.animate({
  opacity: [0, 1],
}, {
  timeline: tl,
});

Bản minh hoạ: Chỉ báo tiến trình đọc, đã xem lại

Để tạo lại chỉ báo tiến trình đọc bằng JavaScript, trong khi sử dụng cùng một mã đánh dấu, hãy sử dụng mã JavaScript sau:

const $progressbar = document.querySelector('#progress');

$progressbar.style.transformOrigin = '0% 50%';
$progressbar.animate(
  {
    transform: ['scaleX(0)', 'scaleX(1)'],
  },
  {
    fill: 'forwards',
    timeline: new ScrollTimeline({
      source: document.documentElement,
    }),
  }
);

Kết quả hình ảnh giống hệt trong phiên bản CSS: timeline được tạo theo dõi trình cuộn gốc và mở rộng #progress trên trục x từ 0% đến 100% khi bạn cuộn trang.

✨ Dùng thử

Thực hành nhờ tính năng Xem tiến trình

Tạo Dòng thời gian tiến trình chế độ xem ẩn danh trong CSS

Để tạo Dòng thời gian tiến trình xem, hãy sử dụng hàm view(). Các đối số được chấp nhận của lớp này là <axis><view-timeline-inset>.

  • <axis> giống với Dòng thời gian tiến trình cuộn và xác định trục cần theo dõi. Giá trị mặc định là block.
  • Với <view-timeline-inset>, bạn có thể chỉ định độ lệch (dương hoặc âm) để điều chỉnh giới hạn khi một phần tử có được coi là có trong khung hiển thị hay không. Giá trị này phải là tỷ lệ phần trăm hoặc auto, trong đó auto là giá trị mặc định.

Ví dụ: để liên kết ảnh động với một phần tử giao cắt với trình cuộn của nó trên trục khối, hãy sử dụng view(block). Tương tự như scroll(), hãy đặt giá trị này làm giá trị cho thuộc tính animation-timeline và đừng quên đặt animation-duration thành auto.

Khi sử dụng mã sau, mọi img sẽ mờ dần khi đi qua khung nhìn trong khi bạn cuộn.

@keyframes reveal {
  from { opacity: 0; }
  to { opacity: 1; }
}

img {
  animation: reveal linear;
  animation-timeline: view();
}

Intermezzo: Xem phạm vi Dòng thời gian

Theo mặc định, ảnh động liên kết với Chế độ xem dòng thời gian sẽ đính kèm vào toàn bộ phạm vi dòng thời gian. Quá trình này bắt đầu từ thời điểm đối tượng chuẩn bị đi vào cổng cuộn và kết thúc khi đối tượng đã hoàn toàn rời khỏi cổng cuộn.

Bạn cũng có thể liên kết dải ô đó với một phần cụ thể của Dòng thời gian của Chế độ xem bằng cách chỉ định dải ô cần đính kèm. Ví dụ: điều này có thể chỉ khi chủ thể đang vào trình cuộn. Trong hình ảnh sau đây, tiến trình bắt đầu được tính từ 0% khi đối tượng đi vào vùng chứa cuộn nhưng đã đạt đến 100% kể từ thời điểm đối tượng hoàn toàn giao cắt với nhau.

Chế độ xem Dòng thời gian được thiết lập để theo dõi phạm vi mục nhập của đối tượng. Ảnh động chỉ chạy khi chủ thể vào cửa sổ cuộn.

Phạm vi Xem dòng thời gian mà bạn có thể nhắm đến là:

  • cover: Biểu thị toàn bộ tiến trình xem.
  • entry: Biểu thị dải ô mà trong đó hộp chính nhập phạm vi chế độ hiển thị tiến trình xem.
  • exit: Biểu thị dải ô mà trong đó hộp chính thoát khỏi phạm vi chế độ hiển thị tiến trình xem.
  • entry-crossing: Đại diện cho dải ô mà hộp chính vượt qua cạnh viền cuối.
  • exit-crossing: Đại diện cho dải ô mà hộp chính vượt qua cạnh đường viền bắt đầu.
  • contain: Biểu thị dải ô mà trong đó hộp chính nằm hoàn toàn hoặc che phủ toàn bộ phạm vi hiển thị tiến trình khung hiển thị trong cổng cuộn. Điều này phụ thuộc vào việc đối tượng cao hơn hay thấp hơn trình cuộn.

Để xác định một dải ô, bạn phải đặt dải ô bắt đầu và kết thúc dải ô. Mỗi dải ô bao gồm tên dải ô (xem danh sách ở trên) và một giá trị bù trừ dải ô để xác định vị trí trong tên dải ô đó. Mức chênh lệch phạm vi thường là tỷ lệ phần trăm dao động từ 0% đến 100%. Tuy nhiên, bạn cũng có thể chỉ định độ dài cố định như 20em.

Ví dụ: nếu bạn muốn chạy ảnh động từ thời điểm chủ thể nhập vào, hãy chọn entry 0% làm dải ô bắt đầu. Để hoàn tất trước thời điểm chủ thể nhập, hãy chọn entry 100% làm giá trị cho điểm kết thúc của phạm vi.

Trong CSS, bạn đặt giá trị này bằng thuộc tính animation-range. Ví dụ:

animation-range: entry 0% entry 100%;

Trong JavaScript, hãy dùng các thuộc tính rangeStartrangeEnd.

$el.animate(
  keyframes,
  {
    timeline: tl,
    rangeStart: 'entry 0%',
    rangeEnd: 'entry 100%',
  }
);

Sử dụng công cụ được nhúng bên dưới để xem nội dung của từng tên dải ô và cách tỷ lệ phần trăm ảnh hưởng đến vị trí bắt đầu và kết thúc. Hãy thử đặt phạm vi bắt đầu thành entry 0% và kết thúc phạm vi thành cover 50%, sau đó kéo thanh cuộn để xem kết quả ảnh động.

Trình hiển thị chế độ xem phạm vi dòng thời gian, có tại https://goo.gle/view-timeline-range-tool

Xem bản ghi

Như bạn có thể nhận thấy khi sử dụng các công cụ Xem phạm vi dòng thời gian này, một số phạm vi có thể được nhắm mục tiêu bằng hai tổ hợp tên dải ô + độ lệch phạm vi khác nhau. Ví dụ: entry 0%, entry-crossing 0%cover 0% đều nhắm đến cùng một khu vực.

Khi dải ô nhắm mục tiêu cùng một tên dải ô và trải dài toàn bộ dải ô (từ 0% đến 100%), bạn có thể rút ngắn giá trị thành tên dải ô một cách đơn giản. Ví dụ: animation-range: entry 0% entry 100%; có thể được viết lại thành animation-range: entry ngắn hơn nhiều.

Bản minh hoạ: Hiển thị hình ảnh

Bản minh hoạ này mờ dần trong hình ảnh khi chúng vào cửa sổ cuộn. Bạn có thể thực hiện việc này bằng cách sử dụng Dòng thời gian trong Chế độ xem ẩn danh. Phạm vi hoạt ảnh đã được điều chỉnh để mỗi hình ảnh có độ mờ hoàn toàn khi cuộn được một nửa.

Bản minh hoạ: Hiển thị hình ảnh

✨ Dùng thử

Hiệu ứng mở rộng đạt được bằng cách sử dụng đường dẫn clip được tạo ảnh động. CSS được sử dụng cho hiệu ứng này là:

@keyframes reveal {
  from { opacity: 0; clip-path: inset(0% 60% 0% 50%); }
  to { opacity: 1; clip-path: inset(0% 0% 0% 0%); }
}

.revealing-image {
  animation: auto linear reveal both;
  animation-timeline: view();
  animation-range: entry 25% cover 50%;
}

Tạo Tiến trình xem có tên trong CSS

Tương tự như cách Dòng thời gian cuộn đã đặt tên cho các phiên bản, bạn cũng có thể tạo Dòng thời gian cho chế độ xem được đặt tên. Thay vì sử dụng các thuộc tính scroll-timeline-*, bạn sẽ sử dụng các biến thể chứa tiền tố view-timeline-, cụ thể là view-timeline-nameview-timeline-axis.

Cùng một loại giá trị được áp dụng và các quy tắc tương tự để tra cứu một tiến trình đã đặt tên sẽ được áp dụng.

Bản minh hoạ: Hiển thị hình ảnh, được xem lại

Làm lại bản minh hoạ tiết lộ hình ảnh trước đó, mã được sửa đổi sẽ có dạng như sau:

.revealing-image {
  view-timeline-name: --revealing-image;
  view-timeline-axis: block;

  animation: auto linear reveal both;
  animation-timeline: --revealing-image;
  animation-range: entry 25% cover 50%;
}

Bằng cách sử dụng view-timeline-name: revealing-image, phần tử sẽ được theo dõi trong trình cuộn gần nhất. Sau đó, chính giá trị này sẽ được dùng làm giá trị cho thuộc tính animation-timeline. Hình ảnh đầu ra vẫn giống hệt như trước.

✨ Dùng thử

Tạo tiến trình xem trong JavaScript

Để tạo Chế độ xem dòng thời gian trong JavaScript, hãy tạo một thực thể mới của lớp ViewTimeline. Truyền vào túi thuộc tính có subject mà bạn muốn theo dõi, axisinset.

  • subject: Tham chiếu đến phần tử mà bạn muốn theo dõi trong trình cuộn của riêng phần tử đó.
  • axis: Trục cần theo dõi. Tương tự như biến thể CSS, các giá trị được chấp nhận là block, inline, xy.
  • inset: Phần điều chỉnh (dương) hoặc phần lồng ghép (âm) của cổng cuộn khi xác định xem hộp có nằm trong khung nhìn hay không.
const tl = new ViewTimeline({
  subject: document.getElementById('subject'),
});

Để đính kèm ảnh động này vào Ảnh động trên web, hãy truyền thuộc tính này vào dưới dạng thuộc tính timeline và bỏ qua mọi duration (nếu có). Nếu muốn, hãy truyền thông tin dải ô bằng cách sử dụng các thuộc tính rangeStartrangeEnd.

$el.animate({
  opacity: [0, 1],
}, {
  timeline: tl,
  rangeStart: 'entry 25%',
  rangeEnd: 'cover 50%',
});

✨ Dùng thử

Các tính năng khác đang chờ bạn khám phá

Đính kèm vào nhiều phạm vi của Chế độ xem dòng thời gian bằng một bộ khung hình chính

Hãy xem phần minh hoạ danh bạ này, trong đó các mục trong danh sách được làm động. Khi một mục nhập danh sách đi vào cửa sổ cuộn từ dưới cùng, mục này sẽ trượt +mờ dần vào và khi thoát khỏi cửa sổ cuộn ở trên cùng, mục này sẽ trượt+ mờ đi.

Ví dụ minh hoạ: Danh bạ

✨ Dùng thử

Đối với bản minh hoạ này, mỗi phần tử được trang trí bằng một Khung hiển thị Dòng thời gian để theo dõi phần tử khi phần tử đó đi qua cửa sổ cuộn. Tuy nhiên, có 2 ảnh động dựa trên thao tác cuộn được đính kèm vào phần tử đó. Ảnh động animate-in được đính kèm vào phạm vi entry của dòng thời gian và ảnh động animate-out vào phạm vi exit của dòng thời gian.

@keyframes animate-in {
  0% { opacity: 0; transform: translateY(100%); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes animate-out {
  0% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-100%); }
}

#list-view li {
  animation: animate-in linear forwards,
             animate-out linear forwards;
  animation-timeline: view();
  animation-range: entry, exit;
}

Thay vì chạy hai ảnh động khác nhau được đính kèm vào hai dải ô khác nhau, bạn cũng có thể tạo một tập hợp các khung hình chính đã chứa thông tin dải ô.

@keyframes animate-in-and-out {
  entry 0%  {
    opacity: 0; transform: translateY(100%);
  }
  entry 100%  {
    opacity: 1; transform: translateY(0);
  }
  exit 0% {
    opacity: 1; transform: translateY(0);
  }
  exit 100% {
    opacity: 0; transform: translateY(-100%);
  }
}

#list-view li {
  animation: linear animate-in-and-out;
  animation-timeline: view();
}

Vì các khung hình chính chứa thông tin phạm vi nên bạn không cần chỉ định animation-range. Kết quả vẫn giống hệt như trước đây.

✨ Dùng thử

Đính kèm vào một dòng thời gian cuộn không phải đối tượng cấp trên

Cơ chế tra cứu cho Dòng thời gian cuộn được đặt tên và Xem dòng thời gian được đặt tên chỉ giới hạn trong việc cuộn đối tượng cấp trên. Tuy nhiên, phần tử cần được tạo ảnh động thường không phải là phần tử con của trình cuộn cần được theo dõi.

Để làm được điều này, thuộc tính timeline-scope sẽ được đưa vào sử dụng. Bạn sử dụng thuộc tính này để khai báo dòng thời gian có tên đó mà không thực sự tạo. Điều này giúp dòng thời gian có tên đó có phạm vi rộng hơn. Trong thực tế, bạn sử dụng thuộc tính timeline-scope trên một phần tử mẹ dùng chung để dòng thời gian của trình cuộn con có thể đính kèm vào phần tử đó.

Ví dụ:

.parent {
  timeline-scope: --tl;
}
.parent .scroller {
  scroll-timeline: --tl;
}
.parent .scroller ~ .subject {
  animation: animate linear;
  animation-timeline: --tl;
}

Trong đoạn mã này:

  • Phần tử .parent khai báo dòng thời gian có tên là --tl. Bất kỳ phần tử con nào của thuộc tính này đều có thể tìm thấy và sử dụng làm giá trị cho thuộc tính animation-timeline.
  • Phần tử .scroller thực sự xác định một Dòng thời gian cuộn có tên là --tl. Theo mặc định, thành phần này chỉ hiển thị với các thành phần con nhưng vì .parent đã đặt thành scroll-timeline-root nên thành phần này sẽ đính kèm vào thành phần kết hợp này.
  • Phần tử .subject sử dụng tiến trình --tl. Hàm này di chuyển lên cây đối tượng cấp trên và tìm thấy --tl trên .parent. Với --tl trên .parent trỏ đến --tl của .scroller, về cơ bản, .subject sẽ theo dõi Tiến trình cuộn của .scroller.

Nói cách khác, bạn có thể sử dụng timeline-root để di chuyển dòng thời gian lên đối tượng cấp trên (còn gọi là chuyển lên trên) để tất cả con của đối tượng cấp trên đều truy cập được.

Bạn có thể sử dụng thuộc tính timeline-scope với cả Dòng thời gian cuộn và Dòng thời gian xem.

Bản minh hoạ và tài nguyên khác

Tất cả bản minh hoạ được đề cập trong bài viết này về trang web thu nhỏ kiểu cuộn-navigation-Animations.style. Trang web còn có nhiều bản minh hoạ khác để làm nổi bật những việc có thể làm với ảnh động dựa trên thao tác cuộn.

Một trong những bản minh hoạ bổ sung là danh sách bìa đĩa nhạc. Mỗi trang bìa xoay ở chế độ 3D vì nó lấy tiêu điểm trung tâm.

Bản minh hoạ: Quy trình bìa sách

✨ Dùng thử

Hoặc bản minh hoạ các thẻ xếp chồng này tận dụng position: sticky. Khi các thẻ xếp chồng lên nhau, các thẻ đã bị mắc kẹt sẽ thu nhỏ, tạo ra hiệu ứng chiều sâu đẹp mắt. Cuối cùng, toàn bộ ngăn xếp sẽ trượt ra khỏi khung hiển thị dưới dạng một nhóm.

Bản minh hoạ: Các thẻ xếp chồng.

✨ Dùng thử

Ngoài ra, có một bộ công cụ xuất hiện nổi bật trên scroll-navigation-animations.style là bộ công cụ, chẳng hạn như hình ảnh trực quan về Tiến trình xem phạm vi dòng thời gian đã có trong phần trước của bài đăng này.

Ảnh động dựa trên thao tác cuộn cũng được đề cập trong bài viết Tính năng mới về Ảnh động trên web tại Google I/O 2023.