ADMIN
Ngày đăng:
Chia sẻ:
Link: https://thuanhmdev.github.io/react-framer-motion-smooth-when-wheel/
Trong thế giới phát triển web hiện đại, trải nghiệm người dùng là yếu tố quan trọng hàng đầu. Một trong những chi tiết nhỏ nhưng có thể tạo nên sự khác biệt lớn chính là hiệu ứng cuộn trang mượt mà. Thay vì cuộn trang theo cách thông thường, chúng ta có thể tạo ra một trải nghiệm cuộn mượt mà, tạo cảm giác cao cấp và chuyên nghiệp hơn cho website.
Trong bài viết này, chúng ta sẽ tìm hiểu cách tạo hiệu ứng cuộn trang mượt mà bằng cách sử dụng thư viện Framer Motion trong React. Framer Motion là một thư viện animation mạnh mẽ cho React, cung cấp các API đơn giản để tạo ra các hiệu ứng phức tạp.
npm install framer-motion
Hãy xem xét code của component SmoothScroll:
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>
</>
);
}
Hãy phân tích từng phần của code:
import { motion, useScroll, useSpring, useTransform } from "framer-motion";
import React, { useLayoutEffect, useRef, useState } from "react";
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 một animation mượt mà dựa trên physics, với các tham số có thể điều chỉnh:
mass: Điều chỉnh "quán tính" của animation. Giá trị càng lớn, animation càng chậm khi bắt đầu và kết thúc.
stiffness: Điều chỉnh "độ đàn hồi". Giá trị càng cao, animation càng nhanh và "bật" mạnh hơn.
damping: Điều chỉnh "độ mượt". Kiểm soát mức độ animation sẽ dừng lại mượt mà.
const [contentHeight, setContentHeight] = useState(0);
const contentRef = useRef<HTMLDivElement>(null);
contentHeight lưu trữ chiều cao của nội dung.
contentRef tham chiếu đến phần tử DOM chứa nội dung.
const y = useTransform(
smoothProgress,
[0, 1],
contentHeight ? [0, -(contentHeight - window.innerHeight)] : [0, 0]
);
useTransform được sử dụng để chuyển đổi giá trị cuộn thành giá trị dịch chuyển Y. Nó kiểm tra contentHeight để tránh các giá trị không hợp lệ khi component mới được mount.
useLayoutEffect(() => {
const handleResize = () => {
if (contentRef.current) {
setContentHeight(contentRef.current.scrollHeight);
}
};
handleResize();
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
Đoạn code này đảm bảo rằng contentHeight được cập nhật khi kích thước cửa sổ thay đổi.
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>
</>
);
Một div trống với chiều cao bằng contentHeight được tạo ra để giữ cho scrollbar của trình duyệt hoạt động bình thường.</br> motion.div chứa nội dung thực sự, với style position: fixed và transform y để tạo hiệu ứng cuộn mượt mà.</br>
Để sử dụng component này trong ứng dụng của bạn:
function App() {
return (
<SmoothScroll>
{/* Nội dung của trang web của bạn */}
<h1>Welcome to My Smooth Scrolling Website</h1>
<p>This content will scroll smoothly.</p>
{/* ... */}
</SmoothScroll>
);
}
Component SmoothScroll này sử dụng sức mạnh của Framer Motion để tạo ra hiệu ứng cuộn mượt mà, 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 chỉnh cảm giác của animation để phù hợp với thiết kế của mình.
link source: https://github.com/thuanhmdev/react-framer-motion-smooth-when-wheel