Реализация эффекта плавной прокрутки и параллакса в Next.js с помощью Lenis и GSAP
В эпоху, когда увлекательные и интерактивные веб-страницы стали нормой, понимание и внедрение интерактивных функций может существенно повлиять на то, как пользователи взаимодействуют с вашим контентом. В этом блоге мы рассмотрим реализацию плавной прокрутки и параллакс-эффектов - двух важнейших элементов, которые могут поднять пользовательский интерфейс вашего сайта на новую высоту.
Мы используем Next.js, мощный фреймворк React, и задействуем возможности Lenis и GSAP (GreenSock Animation Platform), чтобы воплотить эти эффекты в жизнь. Независимо от того, являетесь ли вы опытным разработчиком или только начинаете, это руководство призвано помочь вам приобрести навыки, необходимые для интеграции эффектов плавной прокрутки и параллакса в ваши проекты на Next.js.
Вот демонстрация, которую мы создадим: Плавная прокрутка в Next.js.
Если вы предпочитаете смотреть видео, то вот видеоурок:
Что такое плавная прокрутка и эффект параллакса?
Давайте рассмотрим плавную прокрутку и эффекты параллакса.
Плавная прокрутка: Это не просто визуальное наслаждение, это улучшение путешествия пользователя по вашему сайту. Плавная прокрутка обеспечивает контролируемую, постепенную навигацию между разделами веб-страницы, а не резкие скачки, характерные для традиционной прокрутки страниц.
Речь идет не только об эстетике, но и о создании потока повествования, который будет вести пользователей через ваш контент естественным и увлекательным образом.
Эффект параллакса: представьте, что слои контента движутся с разной скоростью по мере прокрутки, создавая иллюзию глубины и погружения. Это и есть эффект параллакса.
Он добавляет 3D-чувство к двумерным веб-страницам, делая пользовательский интерфейс более интерактивным и увлекательным. При разумном использовании она может превратить простую прокрутку сайта в сюжетную историю, что позволит заинтриговать и увлечь пользователей. Чтобы воплотить эти концепции в жизнь в среде Next.js, мы используем Lenis и GSAP.
Lenis - это минималистичная библиотека, предназначенная для плавной прокрутки, предлагающая простой, но эффективный способ реализации этой функции.
GSAP - это надежный инструмент для создания высокопроизводительной анимации, в том числе эффекта параллакса.
Вместе они образуют грозный дуэт для улучшения ваших проектов Next.js. А теперь давайте приступим!
Настройка среды Next.js
Прежде чем приступить к реализации, давайте настроим среду Next.js. Во-первых, убедитесь, что в вашей системе установлен Node.js. Откройте терминал и выполните следующую команду:
npx create-next-app@latest
После запуска этой команды терминал спросит вас о нескольких вещах, которые вы можете выбрать в соответствии со следующим набором:
√ What is your project named? ... nextjs-smooth-scroll
√ Would you like to use TypeScript? ... No
√ Would you like to use ESLint? ... Yes
√ Would you like to use Tailwind CSS? ... Yes
√ Would you like to use `src/` directory? ... Yes
√ Would you like to use App Router? (recommended) ... Yes
? Would you like to customize the default import alias (@/*)? » No
После установки всех необходимых зависимостей перейдите в каталог проекта, используя cd nextjs-smooth-scoll
, и выполните следующую команду для установки библиотек прокрутки gsap и lenis.
npm install gsap @studio-freight/react-lenis
Теперь выполните npm run dev, чтобы запустить сервер разработки. Вы можете просмотреть свой проект на сайте http://localhost:3000.
Реализация плавной прокрутки с помощью Lenis
В проекте Next.js создайте файл SmoothScrolling.tsx
в папке components
. Этот компонент использует @studio-freight/react-lenis
, обертку React для библиотеки Lenis. Подробнее о ней вы можете узнать из документации.
"use client";
import { ReactLenis } from "@studio-freight/react-lenis";
function SmoothScrolling({ children }) {
return (
<ReactLenis root options={{ lerp: 0.1, duration: 1.5, smoothTouch: true }}>
{children}
</ReactLenis>
);
}
export default SmoothScrolling;
Строка 1: Мы использовали директиву use client
, поскольку хотим, чтобы этот компонент выполнялся в среде браузера, а не на сервере.
Строка 4: Компонент SmoothScrolling
принимает дочерние компоненты (children
) в качестве реквизитов. Такая конструкция позволяет всем дочерним компонентам, обернутым в SmoothScrolling
, наследовать свойство плавной прокрутки.
Строка 6: Здесь мы возвращаем компонент ReactLenis
с настроенными параметрами.
- Атрибут
root
указывает на то, чтоReactLenis
должен управлять прокруткой всей страницы. Поэтому Lenis будет инициирован с помощью<html>
прокрутки.
- Свойство
options
настраивает поведение эффекта плавной прокрутки:
lerp: 0.1
: Задает значение линейной интерполяции для эффекта прокрутки. Значение 0,1 обеспечивает плавную прокрутку. Чем меньше значение, тем плавнее прокрутка.duration: 1.5
: Это продолжительность (в секундах) эффекта прокрутки. Большая длительность приводит к более медленной прокрутке.smoothTouch: true
: Это включает плавную прокрутку на сенсорных устройствах. Вы можете попробовать различные варианты из документации.
Теперь импортируем этот компонент SmoothScrolling.jsx
в файл layout.js
и обернем его вокруг {children}
, как показано в следующем фрагменте кода.
import { Inter } from "next/font/google";
import "./globals.css";
import SmoothScrolling from "@/components/SmoothScrolling";
const inter = Inter({ subsets: ["latin"] });
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>
<SmoothScrolling>{children}</SmoothScrolling>
</body>
</html>
);
}
После правильной интеграции компонента SmoothScrolling
ваше приложение Next.js получит улучшенную прокрутку. Теперь, чтобы опробовать этот эффект прокрутки, давайте создадим один компонент ImageList.jsx
для визуализации нескольких изображений.
В папке components создайте один файл под названием ImageList.jsx
и добавьте изображения с помощью picsum.photos.
import React from "react";
import Image from "next/image";
const ImageList = () => {
return (
<>
<Image
src={"https://picsum.photos/600/400?random=1"}
alt="Image"
width={600}
height={400}
priority
sizes="50vw"
/>
<Image
src={"https://picsum.photos/600/400?random=2"}
alt="Image"
width={600}
height={400}
priority
sizes="50vw"
/>
<Image
src={"https://picsum.photos/400/600?random=3"}
alt="Image"
width={400}
height={600}
sizes="50vw"
/>
<Image
src={"https://picsum.photos/600/400?random=4"}
alt="Image"
width={600}
height={400}
sizes="50vw"
/>
<Image
src={"https://picsum.photos/600/400?random=5"}
alt="Image"
width={600}
height={400}
sizes="50vw"
/>
// Add more images if you like
</>
);
};
export default ImageList;
В данном компоненте мы использовали URL, предоставленный picsum.photos
для рендеринга изображений, вы можете изменить ширину и высоту в URL, чтобы получить изображения с различной шириной и высотой. Здесь мы использовали компонент Image
из Next.js
. Теперь перед рендерингом этого компонента мы должны добавить имя хоста picsum.photos
в файл next.config.js
, поэтому откройте ваш файл конфигурации и добавьте следующее.
const nextConfig = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "picsum.photos",
},
],
},
};
module.exports = nextConfig;
Теперь давайте отобразим компонент ImageList.jsx
в файле page.js
. Убедитесь, что вы удалили все и добавили следующий код.
import ImageList from "@/components/ImageList";
export default function Home() {
return (
<main className="p-16 xl:p-32 flex flex-col w-full items-center justify-center">
<ImageList />
</main>
);
}
Вот и все. Теперь вы сможете ощутить плавную прокрутку.
Добавление эффекта параллакса с помощью GSAP
Теперь давайте добавим эффект параллакса в наш проект с помощью GSAP (GreenSock Animation Platform). Сначала создайте компонент Parallax.jsx
в папке components
. Мы разберем компонент Parallax.jsx
, чтобы понять, как он работает, а затем посмотрим, как он используется в компоненте ImageList.jsx
. Сначала импортируем все, как показано в следующем фрагменте кода.
"use client";
import { gsap } from "gsap";
import { useEffect, useRef } from "react";
import { useWindowSize } from "@studio-freight/hamo";
import { ScrollTrigger } from "gsap/ScrollTrigger";
Здесь мы снова использовали директиву use client
, чтобы убедиться, что компонент выполняется на стороне клиента. Мы будем использовать плагин scrollTrigger
из gsap
для точного расчета/манипулирования положением изображений.
Для получения ширины окна (window width
) мы будем использовать хук useWindowSize
. Этот хук импортирован из @studio-freight/hamo
, который представляет собой пакет, содержащий список хуков, которые вы можете использовать. Он также создан studio-freight. Убедитесь, что вы установили его с помощью следующей команды:
npm i @studio-freight/hamo
Теперь добавим следующий код:
export function Parallax({ className, children, speed = 1, id = "parallax" }) {
const trigger = useRef();
const target = useRef();
const timeline = useRef();
const { width: windowWidth } = useWindowSize();
return (
<div ref={trigger} className={className}>
<div ref={target}>{children}</div>
</div>
);
}
Строка 1: Здесь мы определяем функциональный компонент Parallax с помощью реквизитов:
className
для пользовательского CSS-стилирования.children
для отображения дочерних компонентов или элементов.speed
для управления скоростью эффекта параллакса.id
для использования вScrollTrigger
Строки 2-4: Мы используем useRef
для создания ссылок:
trigger
: Элемент DOM, запускающий анимацию..target
: Элемент DOM, к которому применяется анимация.timeline
: Временная шкала GSAP для управления последовательностью анимации.
Строка 5: Здесь мы получаем ширину окна как windowWidth
с помощью хука useWindowSize()
.
Строки 8-9: Мы вернули триггерный элемент и целевой элемент. Здесь дочерние элементы обернуты в целевой элемент, который будет иметь эффект анимации.
Теперь давайте добавим useEffect
в тот же компонент и добавим анимацию.
useEffect(() => {
gsap.registerPlugin(ScrollTrigger);
const y = windowWidth * speed * 0.1;
const setY = gsap.quickSetter(target.current, "y", "px");
timeline.current = gsap.timeline({
scrollTrigger: {
id: id,
trigger: trigger.current,
scrub: true,
start: "top bottom",
end: "bottom top",
onUpdate: (e) => {
setY(e.progress * y);
},
},
});
return () => {
timeline?.current?.kill();
};
}, [id, speed, windowWidth]);
Строка 2: Эта строка регистрирует плагин ScrollTrigger
в GSAP, что позволяет нам использовать анимацию на основе прокрутки.
Строка 4: Здесь мы рассчитываем расстояние вертикального перемещения (y
) для эффекта параллакса, основываясь на ширине окна и заданной скорости.
Строка 5: Здесь мы создаем функцию, которая будет устанавливать позицию y элемента. Метод gsap.quickSetter()
- это удобный способ создать функцию, которая будет устанавливать определенное свойство для конкретного объекта. В данном случае мы хотим установить свойство y целевого элемента в пикселях.
Строка 7-18: Мы создаем временную шкалу GSAP и связываем ее с экземпляром ScrollTrigger
.
Конфигурация ScrollTrigger
включает в себя:
id
: Уникальный идентификатор экземпляраScrollTrigger
.trigger
: Элемент, запускающий анимацию прокрутки.scrub
: Если установить значениеtrue
, это сделает анимацию плавной, а не скачкообразной при прокрутке страницы вверх и вниз.start
иend
: Определите начальную и конечную точки анимации прокрутки. Для начальной это означает, что анимация начнется, когда верхняя часть элемента-триггера достигнет нижней части области просмотра, а для конечной - наоборот.onUpdate
: функция обратного вызова, которая обновляет позициюy
целевого элемента на основе прогресса прокрутки.
Строка 21: Эта функция очистки вызывается при размонтировании компонента или изменении зависимостей (id
, speed
, windowWidth
). Она гарантирует, что экземпляр ScrollTrigger
будет правильно утилизирован, чтобы предотвратить утечку памяти.
Как использовать эффект параллакса
Давайте используем компонент Parallax.jsx
в ImageList.jsx
, чтобы добавить эффект параллакса в изображения. Откройте компонент ImageList.jsx
и используйте компонент Parallax
, как показано в следующем фрагменте кода:
import React from "react";
import { Parallax } from "@/components/Parallax";
import Image from "next/image";
const ImageList = () => {
return (
<>
<Parallax speed={1} className="self-start">
<Image
src={"https://picsum.photos/600/400?random=1"}
alt="Image"
width={600}
height={400}
priority
sizes="50vw"
/>
</Parallax>
<Parallax speed={-2} className="self-end overflow-hidden">
<Image
src={"https://picsum.photos/600/400?random=2"}
alt="Image"
width={600}
height={400}
priority
sizes="50vw"
/>
</Parallax>
// ...
</>
);
};
export default ImageList;
Сначала импортируйте компонент Parallax.jsx
из папки components
и оберните в него Image
. Вы можете передавать различные значения скорости и видеть, как движутся изображения. Вы также можете добавить "overflow-hidden"
в имя класса, чтобы увидеть, как изменяется высота изображения при прокрутке.
Лучшие практики и оптимизация производительности
Использование плавной прокрутки и параллакс-эффектов может значительно улучшить эстетику и интерактивность вашего сайта. Однако важно следовать лучшим практикам, чтобы обеспечить плавность и производительность:
- Производительность: Комбинируя эти эффекты, не забывайте о производительности. Плавная прокрутка и параллакс-эффекты могут быть ресурсоемкими, особенно на устройствах низкого класса. Всегда проверяйте производительность на разных устройствах и оптимизируйте соответствующим образом.
- Опыт пользователя: Стремитесь к балансу, чтобы эффекты усиливали, а не отвлекали внимание. Тонкость является ключевым моментом - перебор может привести к путанице или перегруженности пользователей.
- Оптимизируйте изображения и активы: Большие изображения или слишком много анимации могут замедлить работу сайта. Оптимизируйте свои активы для работы в Интернете.
- Ограничьте количество анимации: Слишком много анимации может отвлекать и влиять на производительность. Используйте анимацию с умом.
- Отзывчивый дизайн: Убедитесь, что ваши анимации и эффекты адаптируются к различным размерам экрана, чтобы обеспечить стабильный пользовательский интерфейс.
- Доступность: Учитывайте пожелания пользователей, которые предпочитают сократить количество движений. При необходимости предусмотрите возможность отключения анимации.
Заключение и рекомендации
В этом блоге мы рассмотрели, как реализовать эффекты плавной прокрутки и параллакса в приложении Next.js с помощью Lenis и GSAP. Эти инструменты предлагают мощные возможности для улучшения вашего сайта, делая его более увлекательным и интерактивным. Помните, что ключ к успешной реализации - это тонкость и оптимизация производительности. Я рекомендую вам поэкспериментировать с этими техниками и посмотреть, как они могут улучшить ваши веб-проекты.
Чтобы углубить свое понимание и узнать больше о Next.js, Lenis, GSAP, плавной прокрутке и параллакс-эффектах, ознакомьтесь со следующими ресурсами:
- Next.js Documentation
- Lenis Library
- Lenis Library for React
- GSAP (GreenSock Animation Platform)
- Web Performance Optimization Techniques
Спасибо за прочтение! :)