Lenis là một thư viện JavaScript hiện đại giúp bạn tạo trải nghiệm cuộn mượt mà (smooth scroll) cho các trang web, đặc biệt phù hợp với các trang có nhiều hiệu ứng thị giác như landing page, portfolio, hoặc các website mang tính tương tác cao.
🌀 Giới thiệu tổng quan về Lenis
-
Trang chính: https://lenis.studiofreight.com
-
Tác giả: Studio Freight (cùng nhóm đã tạo ra GSAP plugin
ScrollTriggervà thư việnLocomotive Scroll) -
Viết bằng: JavaScript thuần, hỗ trợ framework như React, Next.js, Vue, v.v.
✨ Ưu điểm nổi bật
| Tính năng | Mô tả |
|---|---|
Smooth Scroll |
Tạo cuộn mượt, có thể tùy chỉnh tốc độ, easing. |
GPU-accelerated |
Tận dụng tối đa hiệu suất phần cứng (sử dụng requestAnimationFrame). |
Scroll Proxy |
Dễ tích hợp với các thư viện như GSAP, Three.js, Lenis + ScrollTrigger. |
Custom Scroll Container |
Hỗ trợ scroll trong container thay vì toàn trang. |
Framework Friendly |
Dễ tích hợp trong các SPA như Next.js / React / Vue. |
🛠 Cách cài đặt
Dùng npm:
npm install @studio-freight/lenis
Dùng CDN:
<script src="https://cdn.jsdelivr.net/npm/@studio-freight/lenis@latest/bundled/lenis.min.js"></script>
🔧 Cách sử dụng cơ bản
import Lenis from '@studio-freight/lenis';
const lenis = new Lenis({
duration: 1.2,
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), // easing function
smooth: true,
});
function raf(time) {
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
🧩 Tích hợp với ScrollTrigger (GSAP)
Lenis hoạt động rất tốt khi kết hợp với ScrollTrigger:
import { ScrollTrigger } from "gsap/ScrollTrigger";
import gsap from "gsap";
gsap.registerPlugin(ScrollTrigger);
// Cập nhật ScrollTrigger với Lenis
lenis.on('scroll', ScrollTrigger.update);
// Tự động gọi RAF
gsap.ticker.add((time) => {
lenis.raf(time * 1000); // convert to ms
});
🧠 Khi nào nên dùng Lenis?
-
Khi bạn muốn tạo trải nghiệm cuộn mượt, hiện đại và có chiều sâu.
-
Khi bạn sử dụng nhiều animation cuộn (scroll animation) hoặc parallax.
-
Khi bạn cần một thư viện nhẹ, dễ tích hợp mà vẫn mạnh mẽ.
🧪 So sánh nhanh
| Thư viện | Mượt cuộn | Tùy chỉnh easing | Hiệu suất cao | Dễ dùng | Kích thước |
|---|---|---|---|---|---|
| Lenis | ✅ | ✅ | ✅ | ✅ | Nhẹ (~6kb) |
| Locomotive Scroll | ✅ | ❌ (hạn chế) | ❌ | Trung bình | ~40kb |
| Smooth Scrollbar | ✅ | ✅ | ❌ | Trung bình | ~60kb |
Nếu bạn đang xây dựng một trang hiện đại, sáng tạo hoặc mang tính trình diễn cao (như portfolio, agency, motion website), Lenis là một lựa chọn rất tốt trong năm 2025.
Dưới đây là những thuộc tính và phương thức cơ bản của Lenis mà bạn cần biết để bắt đầu sử dụng ngay, dù bạn dùng JavaScript thuần hay tích hợp vào React/Next.js:
✅ 1. Thuộc tính khởi tạo (options)
Khi tạo instance new Lenis(), bạn có thể truyền vào các tùy chọn sau:
| Thuộc tính | Kiểu | Mặc định | Ý nghĩa |
|---|---|---|---|
duration |
number |
1.2 |
Thời gian cuộn (0 → tức thời, >1 → mượt hơn). |
easing |
function |
t => t |
Hàm easing cho scroll animation (giống easing trong animation). |
smooth |
boolean |
true |
Bật/tắt cuộn mượt. |
smoothTouch |
boolean |
false |
Bật cuộn mượt trên thiết bị cảm ứng. |
orientation |
'vertical' / 'horizontal' / 'both' |
'vertical' |
Scroll theo chiều nào. |
gestureOrientation |
'vertical' / 'horizontal' / 'both' |
'vertical' |
Cho phép người dùng điều khiển scroll theo chiều nào. |
mouseMultiplier |
number |
1 |
Tốc độ cuộn chuột. |
touchMultiplier |
number |
1 |
Tốc độ cuộn cảm ứng. |
normalizeWheel |
boolean |
false |
Bật để chuẩn hóa cuộn chuột trên các thiết bị khác nhau. |
✅ 2. Phương thức cơ bản
| Phương thức | Mô tả |
|---|---|
lenis.raf(time) |
Gọi mỗi frame để cập nhật scroll. Dùng với requestAnimationFrame. |
lenis.scrollTo(target, options?) |
Cuộn tới một phần tử hoặc vị trí. |
lenis.on('scroll', callback) |
Lắng nghe sự kiện scroll. |
lenis.start() |
Bật lại scroll (sau khi stop). |
lenis.stop() |
Dừng scroll. |
lenis.destroy() |
Hủy instance và loại bỏ listener. |
✅ 3. Dùng scrollTo
lenis.scrollTo('#section-2');
Có thể truyền thêm options:
lenis.scrollTo('#section-2', {
offset: -100,
duration: 2,
easing: (t) => t * t,
});
| Option | Mô tả |
|---|---|
offset |
Dịch chuyển thêm từ vị trí target. |
duration |
Thời gian scroll. |
easing |
Hàm easing riêng cho cuộn này. |
✅ 4. Sử dụng raf đúng cách
Đây là bắt buộc để Lenis hoạt động đúng:
function raf(time) {
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
Trong React / Next.js, bạn nên đặt trong useEffect.
✅ 5. Lắng nghe sự kiện scroll
lenis.on('scroll', ({ scroll, limit, velocity, direction, progress }) => {
console.log(scroll); // vị trí scroll hiện tại
});
Bạn có thể dùng để trigger animation, lazyload...
📌 Tổng kết nhanh
| Cần nhớ | Mục đích |
|---|---|
new Lenis(options) |
Tạo scroll mượt |
lenis.raf(time) |
Gọi mỗi frame để hoạt động |
lenis.scrollTo(target) |
Cuộn đến chỗ nào đó |
lenis.on('scroll', cb) |
Theo dõi trạng thái scroll |
lenis.stop() / start() |
Tạm ngưng / bật lại scroll |
Nếu bạn đang dùng React / Next.js, mình có thể hướng dẫn thêm cách tích hợp clean trong useEffect và requestAnimationFrame. Bạn cần không?