0
0
Lập trình
Harry Tran
Harry Tran106580903228332612117

Hướng Dẫn Tạo Hiệu Ứng Cuộn Mượt Mà Trong React Với Thư Viện Framer Motion

Đăng vào 5 ngày trước

• 5 phút đọc

Giới thiệu sản phẩm

Link Demo: Dùng thử hiệu ứng cuộn mượt mà

1. Giới thiệu

Trong phát triển web hiện đại, trải nghiệm người dùng là yếu tố then chốt. Hiệu ứng cuộn trang mượt mà không chỉ làm cho trang web trông chuyên nghiệp hơn mà còn mang đến cảm giác dễ chịu cho người dùng. Trong bài viết này, chúng ta sẽ tìm hiểu cách tạo hiệu ứng cuộn mượt mà trong React bằng cách sử dụng thư viện Framer Motion, nổi tiếng với khả năng tạo ra các hiệu ứng hoạt hình phức tạp một cách dễ dàng.

2. Cài đặt thư viện

Để bắt đầu, bạn cần cài đặt thư viện Framer Motion vào dự án React của mình bằng lệnh sau:

bash Copy
npm install framer-motion

3. Mã nguồn và Giải thích

Sau đây, chúng ta sẽ xem xét mã của component SmoothScroll:

javascript Copy
import { motion, useScroll, useSpring, useTransform } from "framer-motion";
import React, { useLayoutEffect, useRef, useState } from "react";

export default function SmoothScroll({
  children,
}: {
  children: React.ReactNode;
}) {
  const { scrollYProgress } = useScroll();
  const smoothProgress = useSpring(scrollYProgress, {
    mass: 0.1, 
    stiffness: 100, 
    damping: 30, 
  });

  const [contentHeight, setContentHeight] = useState(0);
  const contentRef = useRef<HTMLDivElement>(null);

  const y = useTransform(
    smoothProgress,
    [0, 1],
    contentHeight ? [0, -(contentHeight - window.innerHeight)] : [0, 0]
  );

  useLayoutEffect(() => {
    const handleResize = () => {
      if (contentRef.current) {
        setContentHeight(contentRef.current.scrollHeight);
      }
    };

    handleResize();
    window.addEventListener("resize", handleResize);

    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, []);

  return (
    <>
      <div style={{ height: contentHeight }} />
      <motion.div
        className="scrollBody"
        style={{
          y,
          position: "fixed",
          top: 0,
          left: 0,
          right: 0,
          overflowY: "hidden",
        }}
        ref={contentRef}
      >
        {children}
      </motion.div>
    </>
  );
}

3.1. Nhập các hook cần thiết

Các hook từ Framer Motion cho phép chúng ta theo dõi, điều chỉnh và áp dụng hiệu ứng hoạt hình cho các thành phần trong ứng dụng React dễ dàng và hiệu quả.

javascript Copy
import { motion, useScroll, useSpring, useTransform } from "framer-motion";
import React, { useLayoutEffect, useRef, useState } from "react";

3.2. Sử dụng các hook của Framer Motion

javascript Copy
const { scrollYProgress } = useScroll();
const smoothProgress = useSpring(scrollYProgress, {
  mass: 0.1,
  stiffness: 100,
  damping: 30,
});
  • useScroll(): theo dõi tiến trình cuộn của trang.
  • useSpring(): tạo ra animation mượt mà với các tham số cấu hình có thể điều chỉnh. Tham số bao gồm:
    • mass: quán tính của animation.
    • stiffness: độ đàn hồi của animation.
    • damping: mức độ mượt mà của animation.

3.3. Quản lý state và ref

javascript Copy
const [contentHeight, setContentHeight] = useState(0);
const contentRef = useRef<HTMLDivElement>(null);
  • contentHeight: lưu trữ chiều cao của phần nội dung.
  • contentRef: tham chiếu đến phần tử DOM chứa nội dung.

3.4. Tính toán giá trị transform

javascript Copy
const y = useTransform(
  smoothProgress,
  [0, 1],
  contentHeight ? [0, -(contentHeight - window.innerHeight)] : [0, 0]
);
  • Dùng useTransform để chuyển đổi giá trị cuộn thành giá trị dịch chuyển theo trục Y, giúp tạo ra hiệu ứng cuộn mượt mà.

3.5. Xử lý sự kiện resize

javascript Copy
useLayoutEffect(() => {
  const handleResize = () => {
    if (contentRef.current) {
      setContentHeight(contentRef.current.scrollHeight);
    }
  };

  handleResize();
  window.addEventListener("resize", handleResize);

  return () => {
    window.removeEventListener("resize", handleResize);
  };
}, []);
  • Đảm bảo chiều cao nội dung được cập nhật khi kích thước cửa sổ thay đổi để cung cấp trải nghiệm người dùng mượt mà hơn.

3.6. Render component

javascript Copy
return (
  <>
    <div style={{ height: contentHeight }} />
    <motion.div
      className="scrollBody"
      style={{
        y,
        position: "fixed",
        top: 0,
        left: 0,
        right: 0,
        overflowY: "hidden",
      }}
      ref={contentRef}
    >
      {children}
    </motion.div>
  </>
);
  • Component render gồm một div trống để giữ scrollbar hoạt động và một motion.div chứa nội dung chính với hiệu ứng cuộn mượt mà.

3.7. Cách sử dụng SmoothScroll

Bạn có thể sử dụng component này trong ứng dụng của mình như sau:

javascript Copy
function App() {
  return (
    <SmoothScroll>
      <h1>Chào Mừng Đến Với Trang Web Cuộn Mượt Mà Của Tôi</h1>
      <p>Nội dung này sẽ cuộn một cách mượt mà.</p>
    </SmoothScroll>
  );
}

Kết luận

Component SmoothScroll tận dụng sức mạnh của Framer Motion để tạo ra hiệu ứng cuộn mượt mà, giúp nâng cao trải nghiệm người dùng trên trang web của bạn. Bằng cách điều chỉnh các tham số của useSpring, bạn có thể tùy biến cảm giác của animation theo ý muốn và phong cách thiết kế của mình. Hãy thử ngay hôm nay!

Link GitHub: Nguồn Code
source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào