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 Dòng thời gian của thao tác cuộn và Xem tiến trình để tạo ảnh động theo hướng cuộn theo cách khai báo.

Ảnh động di chuyển theo thao tác cuộn

Hỗ trợ trình duyệt

  • 115
  • 115
  • x

Nguồn

Hoạt ảnh khi cuộn là một mẫu trải nghiệm người dùng phổ biến trên web. Ảnh động hướng cuộ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 tiến hoặc lùi trong phản hồi trực tiếp. Ví dụ: các hiệu ứng như hình nền thị sai hoặc chỉ báo đọc di chuyển khi bạn cuộn.

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

Loại ảnh động tương tự khi 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. Ví dụ: với giao diện này, các phần tử có thể mờ 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 để có được những 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. Việc này dẫn đến hai 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 theo cách không đồng bộ.
  • Các ảnh động của luồng chính có thể bị giật.

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

Từ Chrome phiên bản 115, chúng tôi đã ra mắt một bộ API và khái niệm mới mà bạn có thể dùng để bật ảnh động theo hướng cuộn khai báo: Dòng thời gian cuộn và Xem tiến trình.

Các khái niệm mới này tích hợp với API Ảnh động trên web (WAAPI)API Ảnh động CSS hiện có, cho phép chúng kế thừa những ưu điểm của các API hiện có này. Điều đó bao gồm khả năng chạy ảnh động khi cuộn chạy ra khỏi luồng chính. Có, hãy đọc chính xác: giờ đây, bạn có thể có các hoạt ảnh mượt mà, được điều khiển bằng thao tác cuộn, chạy ra khỏi chuỗi chính, chỉ với một vài dòng mã bổ sung. Không thích 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 nhóm khung hình chính bằng cách sử dụng quy tắc @keyframes. Liên kết ảnh động đó 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 lượng ảnh động. Có nhiều animation-* thuộc tính dài hơn có sẵn – animation-easing-functionanimation-fill-mode, v.v. – tất cả đều có thể được kết hợp trong cách 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 vẫn 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ể sử dụng API Ảnh động trên web để đạt được cùng một mục. 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ả trực quan 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 đính kèm với 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 bắt đầu từ 0 khi tải trang và bắt đầu đếm ngược khi thời gian đồng hồ diễn ra. Đây là dòng thời gian hoạt ảnh mặc định và cho đến bây giờ là dòng thời gian hoạt ảnh duy nhất bạn có quyền truy cập.

Thông số kỹ thuật của ảnh động điều khiển cuộn xác định hai loại tiến trình mới mà bạn có thể sử dụng:

  • Cuộn tiến trình dòng thời gian: một 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 tiến trình: 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.

Tiến trình cuộn

Dòng thời gian 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 một 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ể. Nó chuyển đổi một vị trí trong dải ô cuộn thành tỷ lệ 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 cuối biểu thị tiến trình 100%. Trong hình ảnh sau đây, bạn có thể thấy tiến trình đếm từ 0% đến 100% khi di chuyển thanh cuộn từ trên xuống dưới.

Hình ảnh trực quan về Tiến trình cuộn. Khi bạn di chuyển xuống cuối thanh cuộn, giá trị tiến trình sẽ tăng từ 0% đến 100%.

✨ Hãy tự mình dùng thử

Dòng thời gian 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 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 thanh cuộn được theo dõi. Không giống như Dòng thời gian tiến trình cuộn, vị trí tương đối của đối tượng trong thanh cuộn sẽ xác định tiến trình.

Phương thức này có phần tương đồng với cách hoạt động của IntersectionObserver, vốn có thể theo dõi mức độ hiển thị của một phần tử trong thanh cuộn. Nếu phần tử không giao nhau trong thanh cuộn, tức là phần tử đó không giao nhau. Nếu nhìn thấy được bên trong thanh cuộn, ngay cả đối với phần nhỏ nhất, thì nó giao nhau.

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

Hình ảnh trực quan về Tiến trình xem. Tiến trình sẽ tăng từ 0% đến 100% khi tiêu đề (hộp màu xanh lục) di chuyển qua thanh cuộn.

✨ Hãy tự mình dùng thử

Dòng thời gian 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 Dòng thời gian xem dựa trên kích thước của chủ đề, nhưng sẽ có thêm dòng thời gian sau.

Thực hành hiệu quả với Tiến trình cuộn

Tạo Dòng thời gian 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 tài sản 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 một đối số <scroller><axis>.

Sau đây là các giá trị được chấp nhận cho đối số <scroller>:

  • 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 của 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.

Sau đây là các giá trị được chấp nhận cho đối số <axis>:

  • 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 kết quả đo lường tiến trình dọc theo trục y của vùng chứa cuộn.
  • x: Sử dụng kết quả đo lường 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. Kết 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 đặt cố định ở đầu khung nhìn. Khi bạn cuộn trang xuống, thanh tiến trình sẽ mở rộng cho đến khi chiếm hết chiều rộng 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 để thúc đẩy ảnh động.

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

✨ Hãy tự mình 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, width không phải là ảnh động mà phần tử được thu nhỏ trên trục x bằng cách sử dụ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(). scroll() không có đối số nào, do đó, đối số này sẽ quay về giá trị mặc định.

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

Tạo Dòng thời gian 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 Dòng thời gian được đặt tên. 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 đến trình cuộn chính hoặc trình cuộn gốc, hoặc 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 Dòng thời gian tiến trình cuộn theo tên mà bạn đặt.

Để tạo một Dòng thời gian tiến trình cuộ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 giá trị nhận dạng bạn thích. Giá trị phải bắt đầu bằng --.

Để điều chỉnh trục cần theo dõi, bạn cũng phải 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 đặt thuộc tính animation-timeline trên phần tử cần được tạo ảnh động về cùng một giá trị 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 bằng cách viết tắt scroll-timeline. Ví dụ:

scroll-timeline: --my-scroller inline;

Bản minh hoạ này có một chỉ báo bước ở phía trên mỗi băng chuyền hình ảnh. Khi một băng chuyền chứa 3 hình ảnh, thanh chỉ báo sẽ bắt đầu với chiều rộng 33% để cho biết bạn đang xem hình ảnh 1 trong 3 hình ảnh. Khi hình ảnh cuối cùng trong khung hiển thị – được xác định bằng cách thanh cuộn di chuyển đến cuối – chỉ báo sẽ chiếm toàn bộ chiều rộng của thanh 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 cho băng chuyền theo chiều ngang.

✨ Hãy tự mình dùng thử

Mã đánh dấu cơ sở cho 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 ở vị trí tuyệt đối trong phần tử trình bao bọc .gallery. Kích thước ban đầu của lượt chuyển đổi được xác định bởi thuộc tính tuỳ chỉnh --num-images.

.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 chứa 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ẽ trở thành ảnh động. Bạn có thể thực hiện việc này bằng cách tham chiếu đến Dòng thời gian tiến trình cuộ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. Chuyển vào 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ó thanh cuộn mà bạn muốn theo dõi. Sử dụng document.documentElement để nhắm mục tiêu đến thanh cuộn gốc.
  • axis: Xác định 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.
const tl = new ScrollTimeline({
  source: document.documentElement,
});

Để đính kèm vào một Ảnh động trên web, hãy truyền vào dưới dạng thuộc tính timeline và bỏ qua bất kỳ duration nào 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à tăng tỷ lệ #progress trên trục x từ 0% đến 100% khi bạn cuộn trang.

✨ Hãy tự mình dùng thử

Bắt đầu thực tế với Tiến trình xem

Tạo tiến trình xem ở chế độ ẩn danh trong CSS

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

  • <axis> giống như trong 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 các giới hạn khi một phần tử được coi là có trong khung hiển thị hoặc không. Giá trị phải 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 nhau với thanh cuộn trên trục khối, hãy sử dụng view(block). Tương tự như scroll(), hãy thiết lập giá trị này làm giá trị cho thuộc tính animation-timeline và đừng quên thiết lập animation-duration thành auto.

Khi bạn sử dụng mã sau, mọi img sẽ rõ 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 các phạm vi Dòng thời gian

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

Bạn cũng có thể liên kết sự kiện đó 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 phạm vi mà sự kiện cần đính kèm. Ví dụ: điều này có thể chỉ khi chủ thể đưa vào thanh cuộn. Trong hình ảnh sau đây, tiến trình bắt đầu đếm từ 0% khi đối tượng chuyển vào vùng chứa cuộn nhưng đã đạt đến 100% từ thời điểm hoàn toàn giao nhau.

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

Bạn có thể nhắm mục tiêu theo các phạm vi Dòng thời gian của chế độ xem như sau:

  • cover: Biểu thị toàn bộ tiến trình xem tiến trình.
  • entry: Đại diện cho dải ô mà trong đó hộp chính nhập phạm vi 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 hiển thị tiến trình khung hiển thị.
  • entry-crossing: Đại diện cho dải ô mà trong đó hộp chính vượt qua cạnh đường viền kết thúc.
  • exit-crossing: Đại diện cho dải ô mà trong đó hộp chính vượt qua cạnh đường viền bắt đầu.
  • contain: Biểu thị phạm vi 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ửa cuộn. Điều này tuỳ thuộc vào việc đối tượng cao hơn hay ngắn hơn thanh cuộn.

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

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

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

animation-range: entry 0% entry 100%;

Trong JavaScript, hãy sử 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 từng tên dải ô thể hiện nội dung gì và tỷ lệ phần trăm ảnh hưởng như thế nào đến vị trí bắt đầu và kết thúc. Hãy thử đặt giá trị bắt đầu dải ô thành entry 0% và giá trị kết thúc phạm vi thành cover 50%, sau đó kéo thanh cuộn để xem kết quả tạo ảnh động.

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

Xem bản ghi

Như bạn có thể thấy khi sử dụng công cụ Xem phạm vi thời gian theo thời gian này, một số phạm vi có thể được nhắm mục tiêu theo hai tổ hợp tên phạm vi + mức bù trừ 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 phạm vi bắt đầu và kết thúc phạm vi nhắm đến cùng một tên dải ô và trải rộng toàn bộ dải ô – từ 0% đến 100%– bạn có thể rút ngắn giá trị thành chỉ là tên dải ô. Ví dụ: bạn có thể viết lại animation-range: entry 0% entry 100%; 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 sẽ mờ dần trong hình ảnh khi chúng chuyển 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 cho chế độ xem ẩn danh. Phạm vi ảnh động đã được điều chỉnh để mỗi hình ảnh đều có độ mờ hoàn toàn khi đi được nửa còn lại của thanh cuộn.

Bản minh hoạ: Tiết lộ hình ảnh

✨ Hãy tự mình dùng thử

Hiệu ứng mở rộng đạt được bằng cách sử dụng đường dẫn cắt là ả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 Dòng thời gian tiến trình xem có tên trong CSS

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

Áp dụng cùng một loại giá trị và áp dụng cùng các quy tắc cho việc tra cứu một dòng thời gian có tên.

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

Làm lại bản minh hoạ hiển thị hình ảnh lúc 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%;
}

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

✨ Hãy tự mình dùng thử

Tạo Dòng thời gian tiến trình xem trong JavaScript

Để tạo Dòng thời gian cho chế độ xem trong JavaScript, hãy tạo một thực thể mới của lớp ViewTimeline. Chuyể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ử bạn muốn theo dõi trong thanh cuộn riêng.
  • 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: Điều chỉnh phần lồng ghép (dương) hoặc phần phụ (âm) của cửa sổ cuộn khi xác định xem hộp có đang hiển thị hay không.
const tl = new ViewTimeline({
  subject: document.getElementById('subject'),
});

Để đính kèm vào một Ảnh động trên web, hãy truyền vào dưới dạng thuộc tính timeline và bỏ qua bất kỳ duration nào nếu có. Nếu muốn, hãy truyền thông tin về 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%',
});

✨ Hãy tự mình dùng thử

Thử nhiều thứ khác

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

Hãy xem bản minh hoạ danh bạ này, nơi các mục trong danh sách được tạo ảnh động. Khi một mục nhập danh sách nhập vào chức năng cuộn từ dưới cùng, nó sẽ trượt+vào đó và khi thoát khỏi chế độ cuộn ở trên cùng, nó sẽ trượt+ra.

Bản minh hoạ: Danh bạ

✨ Hãy tự mình dùng thử

Đối với bản minh hoạ này, mỗi phần tử được trang trí bằng một Dòng thời gian chế độ xem, giúp theo dõi phần tử khi phần tử đó di chuyển qua cửa sổ cuộn, nhưng hai ảnh động dạng cuộn được đính kèm vào đó. Ả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 hoạt ảnh khác nhau được đính kèm vào hai phạm vi, bạn cũng có thể tạo một bộ khung hình chính đã chứa thông tin phạm vi.

@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 về phạm vi, bạn không cần chỉ định animation-range. Kết quả y hệt như trước đây.

✨ Hãy tự mình dùng thử

Đính kèm vào Dòng thời gian cuộn không phải của đố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à Dòng thời gian chế độ xem được đặt tên chỉ giới hạn ở cuộn đối tượng cấp trên. Tuy nhiên, rất thường xuyên, phần tử cần được tạo ảnh động không phải là phần tử con của thanh cuộn cần được theo dõi.

Để làm việc này, thuộc tính timeline-scope sẽ hoạt động. Bạn sử dụng thuộc tính này để khai báo dòng thời gian có tên đó trong khi thực sự không tạo dòng thời gian đó. Khi đó, tiến trình có tên tương ứng sẽ 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 để có thể đính kèm dòng thời gian của thanh cuộn con.

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 --tl. Bất kỳ thành phần con nào của lớp này đều có thể tìm và dùng nó làm giá trị cho thuộc tính animation-timeline.
  • Phần tử .scroller thực sự xác định Dòng thời gian cuộn bằng tên --tl. Theo mặc định, chỉ các thành phần con cháu mới nhìn thấy thư mục này. Tuy nhiên, vì .parent đã được đặt là scroll-timeline-root nên thành phần này sẽ đính kèm vào thành phần hiển thị này.
  • Phần tử .subject sử dụng dòng thời gian --tl. Trình phân tích cú pháp này đi 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ả phần tử con của đối tượng cấp trên đều có thể truy cập vào dòng thời gian đó.

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.

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

Tất cả các bản minh hoạ có trong bài viết này trên trang web thu nhỏ scroll-navigation-animations.style. Trang web này có nhiều bản minh hoạ khác để làm nổi bật những gì có thể thực hiện bằng ảnh động điều hướng cuộn.

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

Bản minh hoạ: Luồng ảnh bìa

✨ Hãy tự mình dùng thử

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

Bản minh hoạ: Xếp nhóm thẻ.

✨ Hãy tự mình dùng thử

Cũng xuất hiện trong scroll-navigation-animations.style là một tập hợp các công cụ như hình ảnh hóa Tiến trình phạm vi dòng thời gian của chế độ xem đã được đưa vào trước đó trong bài đăng này.

Ảnh động di chuyển khi cuộn cũng được đề cập trong Tính năng mới trong Ảnh động trên web tại Google I/O 2023.