Css cuộn trơn tru

Xin chào các bạn, hiện tại chắc các bạn cũng đã thấy nhiều trang web sẽ có các hiệu ứng phụ thuộc vào vị trí khi các bạn scroll nhỉ? . GSAP và Đầu máy. Giờ mình cùng tìm hiểu từng cái nhé

1/ GSAP

1. 1/ Giới thiệu

GSAP là một thư viện giúp các bạn có thể cấu hình hoạt hình theo ý mình. Mình ví dụ khi các bạn bấm vào nút 1 nút nhưng các bạn muốn có 3 hoạt ảnh chéo nhau như đang chạy đc hoạt ảnh đầu xong chạy tiếp hoạt ảnh 2 và 3 sau đó. Thì nếu các bạn viết bằng javascript + css không thì nó sẽ rất phức tạp và cầu kỳ. Thì GSAP sẽ giúp chúng ta giải quyết vấn đề này. Dưới dây là 1 số mẫu mà bạn có thể xem qua để có thể hình dung tốt hơn

Css cuộn trơn tru
Nguồn. https. //sizzer. nl/

Css cuộn trơn tru
Nguồn. https. //36days-21. phản xạ. điện tử/

Như các bạn đã thấy 1 series hoạt hình được xuất hiện, thì nếu chúng ta viết thuần không thì vô là thấy không biết mình viết xong là cái web đi về đâu luôn…

Bên cạnh đó GSAP còn có các plugin hỗ trợ khác trong quá trình dev nữa

1. 2/ Một số plugin hỗ trợ

  • Flip
    ScrollTrigger (Ở bài này chúng ta sẽ sử dụng tới ScrollTrigger)
  • MotionPathPlugin
  • PixiPlugin
  • MorphSVGPlugin

Ngoài ra còn có các plugin hỗ trợ khác nữa, các bạn có thể tham khảo thêm tại. https. //greensock. com/gsap-plugins/

2/ Đầu máy

2. 1/ Giới thiệu

Đầu máy là một thư viện giúp cho trang web của bạn có thể cuộn mượt mà hơn. Và khi mượt mà hơn thì hoạt hình của các bạn cũng sẽ hoạt động một cách trơn tru hơn. Nhưng nếu chỉ có vậy thì không có gì đặc biệt cả. By Locomotive còn một số tính năng khá tiện lợi và hữu ích mà mình thấy. Mục tiếp theo mình sẽ giải bài về tính năng của nó

2. 2/ Tính năng của đầu máy

  • Kiểm soát tốc độ. cho phép các bạn có thể cấu hình tốc độ cuộn của trang web trong một lần cuộn
  • Hướng cuộn. allow you can config / detect scrolling by vertical or vertical
  • yếu tố cố định. tức là bạn cuộn sửa phần tử hoặc thành phần trong khoảng thời gian bao nhiêu đó thay vì bạn cuộn phát qua thành phần khác như bình thường

Các bạn có thể xem bản demo của thư viện ngay tại đây. https. //đầu máymtl. github. io/đầu máy cuộn/

3/ Kết hợp Đầu máy và GSAP để làm phim hoạt hình

3. 1/ Cài đặt đầu máy và GSAP

Trước tiên các bạn cần cài đặt Locomotive và GSAP trước, các bạn có thể tải theo link mình để bên dưới.
Đầu máy. https. //github. com/locomotivemtl/locomotive-scroll
GSAP. https. //greensock. com/

3. 2/ Tạo ảnh động

Đầu tiên chúng ta sẽ tạo tệp HTML trước

Locomotive Scroll + ScrollTrigger

Line sẽ chạy dựa trên process của khi scroll tới section, khi các bạn khai báoscrub: true

Pin section cho đến khi end: 100%.

Pha màu thêm 1 chút animation chứ các bạn nhỉ xD

DONE!

Sau đó là thêm 1 chút css để tạo kiểu lại

.panel {
  height: 100vh;
}
.panel.relative{
  position:relative;
  overflow:hidden;
}
.row{
  display:flex;
  width:100%;
  height:100%;
}
.col-3{
  flex:0 0 calc(100% / 4);
  max-width:0 0 calc(100% / 4);
  width:100%;
  transition:transform .25s ease;
}
.bg-pannel{
  position:absolute;
  top:0;
  left:0;
  width:100%;
  height:100%;
  z-index:-1;
}
.line {
  width: 100%;
  max-width: 800px;
  height: 8px;
  margin: 0 0 10px 0;
  position: relative;
  display: inline-block;
  background-color: rgba(255,255,255,1);
}

.blue {
    background-color: #2c7ad2;
    background-image: radial-gradient(circle at 47% 14%, rgba(205, 205, 205,0.04) 0%, rgba(205, 205, 205,0.04) 43%,transparent 43%, transparent 100%),radial-gradient(circle at 35% 12%, rgba(215, 215, 215,0.04) 0%, rgba(215, 215, 215,0.04) 4%,transparent 4%, transparent 100%),radial-gradient(circle at 1% 35%, rgba(24, 24, 24,0.04) 0%, rgba(24, 24, 24,0.04) 37%,transparent 37%, transparent 100%),radial-gradient(circle at 21% 1%, rgba(0, 0, 0,0.04) 0%, rgba(0, 0, 0,0.04) 26%,transparent 26%, transparent 100%),radial-gradient(circle at 23% 82%, rgba(249, 249, 249,0.04) 0%, rgba(249, 249, 249,0.04) 60%,transparent 60%, transparent 100%),radial-gradient(circle at 11% 54%, rgba(251, 251, 251,0.04) 0%, rgba(251, 251, 251,0.04) 23%,transparent 23%, transparent 100%),radial-gradient(circle at 69% 68%, rgba(234, 234, 234,0.04) 0%, rgba(234, 234, 234,0.04) 10%,transparent 10%, transparent 100%),linear-gradient(90deg, #2c7ad2,#1568c6);
}
.gray {
    background-color: #777;
    background-image: radial-gradient(circle at 47% 14%, rgba(205, 205, 205,0.04) 0%, rgba(205, 205, 205,0.04) 43%,transparent 43%, transparent 100%),radial-gradient(circle at 35% 12%, rgba(215, 215, 215,0.04) 0%, rgba(215, 215, 215,0.04) 4%,transparent 4%, transparent 100%),radial-gradient(circle at 1% 35%, rgba(24, 24, 24,0.04) 0%, rgba(24, 24, 24,0.04) 37%,transparent 37%, transparent 100%),radial-gradient(circle at 21% 1%, rgba(0, 0, 0,0.04) 0%, rgba(0, 0, 0,0.04) 26%,transparent 26%, transparent 100%),radial-gradient(circle at 23% 82%, rgba(249, 249, 249,0.04) 0%, rgba(249, 249, 249,0.04) 60%,transparent 60%, transparent 100%),radial-gradient(circle at 11% 54%, rgba(251, 251, 251,0.04) 0%, rgba(251, 251, 251,0.04) 23%,transparent 23%, transparent 100%),radial-gradient(circle at 69% 68%, rgba(234, 234, 234,0.04) 0%, rgba(234, 234, 234,0.04) 10%,transparent 10%, transparent 100%),linear-gradient(90deg, #777,#606060);
}
.orange {
    background-color: #e77614;
    background-image: radial-gradient(circle at 46% 40%, rgba(228, 228, 228,0.06) 0%, rgba(228, 228, 228,0.06) 13%,transparent 13%, transparent 100%),radial-gradient(circle at 11% 41%, rgba(198, 198, 198,0.06) 0%, rgba(198, 198, 198,0.06) 19%,transparent 19%, transparent 100%),radial-gradient(circle at 52% 23%, rgba(14, 14, 14,0.06) 0%, rgba(14, 14, 14,0.06) 69%,transparent 69%, transparent 100%),radial-gradient(circle at 13% 85%, rgba(148, 148, 148,0.06) 0%, rgba(148, 148, 148,0.06) 44%,transparent 44%, transparent 100%),radial-gradient(circle at 57% 74%, rgba(232, 232, 232,0.06) 0%, rgba(232, 232, 232,0.06) 21%,transparent 21%, transparent 100%),radial-gradient(circle at 59% 54%, rgba(39, 39, 39,0.06) 0%, rgba(39, 39, 39,0.06) 49%,transparent 49%, transparent 100%),radial-gradient(circle at 98% 38%, rgba(157, 157, 157,0.06) 0%, rgba(157, 157, 157,0.06) 24%,transparent 24%, transparent 100%),radial-gradient(circle at 8% 6%, rgba(60, 60, 60,0.06) 0%, rgba(60, 60, 60,0.06) 12%,transparent 12%, transparent 100%),linear-gradient(90deg, #ff7600, #ff7600);
}
.purple {
    background-color: #8d3dae;
    background-image: radial-gradient(circle at 47% 14%, rgba(205, 205, 205,0.04) 0%, rgba(205, 205, 205,0.04) 43%,transparent 43%, transparent 100%),radial-gradient(circle at 35% 12%, rgba(215, 215, 215,0.04) 0%, rgba(215, 215, 215,0.04) 4%,transparent 4%, transparent 100%),radial-gradient(circle at 1% 35%, rgba(24, 24, 24,0.04) 0%, rgba(24, 24, 24,0.04) 37%,transparent 37%, transparent 100%),radial-gradient(circle at 21% 1%, rgba(0, 0, 0,0.04) 0%, rgba(0, 0, 0,0.04) 26%,transparent 26%, transparent 100%),radial-gradient(circle at 23% 82%, rgba(249, 249, 249,0.04) 0%, rgba(249, 249, 249,0.04) 60%,transparent 60%, transparent 100%),radial-gradient(circle at 11% 54%, rgba(251, 251, 251,0.04) 0%, rgba(251, 251, 251,0.04) 23%,transparent 23%, transparent 100%),radial-gradient(circle at 69% 68%, rgba(234, 234, 234,0.04) 0%, rgba(234, 234, 234,0.04) 10%,transparent 10%, transparent 100%),linear-gradient(90deg, #8d3dae,#8d3dae);
}

Ok vậy là phần đầu tiên của hoạt ảnh khi chúng ta xây dựng html/css trước, giờ sẽ là việc chúng ta tạo hoạt ảnh nhé. Trước hết thì mình sẽ tạo file js

Đầu tiên, thì mình sẽ khai báo đăng ký plugin ScrollTrigger và DOM tới lớp scroll-smooth để tạo scroll smooth bằng Locomotive

gsap.registerPlugin(ScrollTrigger);

const locoScroll = new LocomotiveScroll({
  el: document.querySelector(".smooth-scroll"),
  smooth: true
});

// Dòng này có tác dụng là để mỗi lần các bạn scroll nó sẽ sync với position của section / element trong browser
locoScroll.on("scroll", ScrollTrigger.update);

// Kế tiếp mình set cho scrollTrigger dùng class smooth-scroll để trigger animation. Vì hiện tại chúng ta đang dùng class này để sử dụng locomotive
ScrollTrigger.scrollerProxy(".smooth-scroll", {
  scrollTop(value) {
    return arguments.length ? locoScroll.scrollTo(value, 0, 0) : locoScroll.scroll.instance.scroll.y;
  },
  getBoundingClientRect() {
    return {top: 0, left: 0, width: window.innerWidth, height: window.innerHeight};
  },
});

Về cách nhập ScrollTrigger các bạn có thể theo liên kết sau.

Tại đây, các bạn cuộn xuống bên dưới và sẽ thấy một giao diện như thế này rồi chọn phần cách bạn nhập gsap, sau đó mã trình duyệt bên dưới sẽ hiển thị ra 1 đoạn mã nhập cho các bạn

Css cuộn trơn tru

Kế tiếp mình sẽ thực hiện hoạt hình khi chúng ta cuộn đến phần đầu tiên với thông số chà. thật,

gsap.from(".line-1", { // class của component sẽ thực hiện animation. Class này phải nằm trong component trigger bên dưới nhé. dưới 
  scrollTrigger: {
    trigger: ".line-1", // class của component các bạn muốn trigger tới
    scroller: ".smooth-scroll", // proxy scroll
    scrub: true,
    start: "top top",
    end: "+=100%",
    onUpdate(self) { // đây là method update của trigger, các bạn có thể dùng nó để tùy biến animation thêm nếu cần thiết, truyền self vào để các bạn nắm rõ hơn nó sẽ trả về gì.
      console.log(self)
    }
  },
  scaleX: 0, // set animation từ bao nhiêu đó cho đến 100% (process)
  transformOrigin: "left center", 
  ease: "none"
});

Css cuộn trơn tru

Kế hoạch nữa là chúng ta sẽ tạo hoạt ảnh với ghim. thật

gsap.from(".line-2", {
  scrollTrigger: {
    trigger: ".panel.orange",
    scroller: ".smooth-scroll",
    scrub: true,
    pin: true,
    start: "top top",
    end: "+=100%",
    onUpdate() {
      console.log("Update")
    }
  },
  scaleX: 0, 
  transformOrigin: "left center", 
  ease: "none"
});

Css cuộn trơn tru

Và thêm một cái nữa là mình sẽ kết hợp 2 hoạt ảnh với nhau bằng cách sử dụng dòng thời gian của gsap

var tl = gsap.timeline({
    scrollTrigger: {
      trigger: ".panel.relative",
      scroller: ".smooth-scroll",
      scrub: true,
      pin: true,
      start: "top top",
      end: "+=100%",
      onUpdate() {
        console.log("Update")
      }
    }
  });

tl.from(".purple", {translateY: "+=100%",ease: "none"}, 0).to(".purple", {translateY: "+=0%",ease: "none"}, 0);

tl.from(".panel.relative .gray", {translateY: "+=100%",ease: "none"}, 0).to(".panel.relative .gray", {translateY: "+=0%",ease: "none"}, 0);

tl.from(".panel.relative .orange", {translateY: "-=100%",ease: "none"}, 0).to(".panel.relative .orange", {translateY: "+=0%",ease: "none"}, 0);

tl.from(".panel.relative .blue", {translateY: "-=100%",ease: "none"}, 0).to(".panel.relative .blue", {translateY: "+=0%",ease: "none"}, 0);

tl.from(".panel.relative p", {scale: 0.3, rotation:45, autoAlpha: 0, ease: "power2"})
  .from(".line-3", {scaleX: 0, transformOrigin: "left center", ease: "none"}, 1);

ScrollTrigger.addEventListener("refresh", () => locoScroll.update()); // Mỗi lần window browser thay đổi, StrollTrigger refresh lại và update locomotive

ScrollTrigger.refresh();

Ở đây các bạn có thể thấy khác với những cái khác, thay vì gsap. to thì mình dùng gsap. mốc thời gian. Tức thời là dòng thời gian của hoạt hình. Phần config animation thì mình vẫn sẽ làm như cũ. But you to note các phần tiếp theo nhé. Ở các dòng kế tiếp, mình khai báo từ và đến hoạt hình tức thời sẽ bắt đầu từ và kết thúc tại

cú pháp. from(“element”, {option css animation}, duration) (Tương tự như vậy với to)

Từ đó các bạn có thể hiểu rằng, ở phần mình khai báo thời lượng là 0 tức nó sẽ thực hiện đầu tiên, sau đó sẽ là hoạt hình tiếp theo, theo thứ tự thời lượng tăng dần. And under wire is results

Css cuộn trơn tru

4/ Tổng kết

Như vậy đám mình đã giới thiệu cho các bạn cách tạo hoạt ảnh và điều khiển chúng khi bạn cuộn trình duyệt của mình. Đồng thời cũng giới thiệu cho các bạn đã biết về 2 thư viện GSAP để tạo hoạt ảnh và Đầu máy để kết hợp với scrollTrigger của gsap. Hi vọng bài viết sẽ bổ sung và giúp ích cho các bạn có thể mở rộng ý tưởng về hoạt hình cho website của các bạn. Hẹn gặp các bạn trong bài truy cập. Và dưới đây chính là toàn bộ kết quả của chúng tôi