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
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
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
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
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
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
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
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
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
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