DevGang
Авторизоваться

Реализация эффекта плавной прокрутки и параллакса в 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 настраивает поведение эффекта плавной прокрутки:
  1. lerp: 0.1: Задает значение линейной интерполяции для эффекта прокрутки. Значение 0,1 обеспечивает плавную прокрутку. Чем меньше значение, тем плавнее прокрутка.
  2. duration: 1.5: Это продолжительность (в секундах) эффекта прокрутки. Большая длительность приводит к более медленной прокрутке.
  3. 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, плавной прокрутке и параллакс-эффектах, ознакомьтесь со следующими ресурсами:

Спасибо за прочтение! :)

Источник:

#JavaScript #React
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу