Реализация Page Transition анимаций (Barba.js) на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация Page Transition анимаций (Barba.js) на сайте
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация Page Transition анимаций (Barba.js) на сайте

Page transitions — анимированные переходы между страницами без полной перезагрузки браузера. Barba.js перехватывает навигацию, делает AJAX-запрос следующей страницы, анимирует выход текущей и вход новой. Для пользователя это выглядит как переход внутри приложения, а не перезагрузка.

Используется на multi-page сайтах (не SPA). В SPA-фреймворках (Next.js, Nuxt) — собственные механизмы роутинга с анимациями.

Установка и базовая структура

npm install @barba/core gsap
import barba from '@barba/core'
import gsap from 'gsap'

barba.init({
  debug: false,
  timeout: 5000,

  transitions: [
    {
      name: 'default-transition',

      // Вызывается до запроса следующей страницы
      async leave(data) {
        await gsap.to(data.current.container, {
          opacity: 0,
          y: -30,
          duration: 0.4,
          ease: 'power2.in',
        })
      },

      // Вызывается после загрузки следующей страницы
      async enter(data) {
        gsap.from(data.next.container, {
          opacity: 0,
          y: 30,
          duration: 0.5,
          ease: 'power2.out',
        })
      },
    },
  ],
})

HTML-разметка

Barba требует data-атрибуты для определения корневого контейнера и namespace страницы:

<!-- Каждая страница -->
<main data-barba="wrapper">
  <div data-barba="container" data-barba-namespace="home">
    <!-- Контент страницы -->
  </div>
</main>

Namespace используется для routing — применять разные переходы для разных пар страниц.

Переходы с оверлеем

Более сложный паттерн: цветной overlay выезжает поверх страницы, затем уходит, открывая новый контент.

// DOM-элемент оверлея (всегда в DOM, вне data-barba container)
const overlay = document.querySelector('.transition-overlay')

barba.init({
  transitions: [
    {
      name: 'overlay-transition',

      async leave() {
        // Оверлей въезжает снизу
        await gsap.fromTo(overlay,
          { scaleY: 0, transformOrigin: 'bottom' },
          { scaleY: 1, duration: 0.5, ease: 'power3.inOut' }
        )
      },

      async enter(data) {
        // Новая страница уже готова — оверлей уходит вверх
        await gsap.to(overlay, {
          scaleY: 0,
          transformOrigin: 'top',
          duration: 0.5,
          ease: 'power3.inOut',
        })

        // Анимация контента новой страницы
        gsap.from(data.next.container.querySelectorAll('[data-animate-in]'), {
          opacity: 0,
          y: 40,
          stagger: 0.08,
          duration: 0.6,
          ease: 'power2.out',
        })
      },
    },
  ],
})
.transition-overlay {
  position: fixed;
  inset: 0;
  background: #0a0a0a;
  z-index: 9000;
  transform: scaleY(0);
  transform-origin: bottom;
  pointer-events: none;
}

Routing — разные переходы для разных страниц

barba.init({
  transitions: [
    // Переход с главной на кейсы
    {
      name: 'home-to-work',
      from: { namespace: ['home'] },
      to: { namespace: ['work'] },

      async leave(data) {
        const title = data.current.container.querySelector('.hero-title')
        await gsap.to(title, {
          xPercent: -100,
          opacity: 0,
          duration: 0.6,
        })
      },

      async enter(data) {
        // ...
      },
    },

    // Переход со страницы проекта назад
    {
      name: 'project-back',
      from: { namespace: ['project'] },

      async leave(data) {
        // Клип-маска схлопывается до thumbnail
        const hero = data.current.container.querySelector('.project-hero')
        const targetRect = document.querySelector('.work-thumb.is-active')?.getBoundingClientRect()

        if (targetRect) {
          await gsap.to(hero, {
            clipPath: `inset(${targetRect.top}px ${window.innerWidth - targetRect.right}px ${window.innerHeight - targetRect.bottom}px ${targetRect.left}px)`,
            duration: 0.6,
            ease: 'power3.inOut',
          })
        }
      },
    },

    // Дефолтный — для всего остального
    {
      name: 'default',
      async leave(data) {
        await gsap.to(data.current.container, { opacity: 0, duration: 0.3 })
      },
      enter(data) {
        gsap.from(data.next.container, { opacity: 0, duration: 0.3 })
      },
    },
  ],
})

Жизненный цикл и переинициализация

Главная сложность Barba: скрипты, которые инициализировали компоненты на странице, нужно запускать заново при каждом переходе.

// Инициализация компонентов страницы
function initPage(container: HTMLElement) {
  // ScrollTrigger — обязательно обновить
  ScrollTrigger.refresh()

  // Lenis — сбросить позицию
  lenis?.scrollTo(0, { immediate: true })

  // Компоненты, привязанные к DOM
  container.querySelectorAll('[data-slider]').forEach(initSlider)
  container.querySelectorAll('[data-counter]').forEach(initCounter)
}

barba.hooks.after((data) => {
  initPage(data.next.container)
})

// Убивать предыдущие инстансы перед уходом
barba.hooks.beforeLeave((data) => {
  // Destroy ScrollTrigger instances привязанные к текущему контейнеру
  ScrollTrigger.getAll()
    .filter(st => data.current.container.contains(st.trigger as HTMLElement))
    .forEach(st => st.kill())
})

Prefetch

Barba не загружает следующую страницу заранее из коробки. Для instant transitions — @barba/prefetch:

npm install @barba/prefetch
import barba from '@barba/core'
import barbaPrefetch from '@barba/prefetch'

barba.use(barbaPrefetch)

barba.init({ ... })
// Теперь страницы prefetch-ятся при hover на ссылках

SEO и аналитика

AJAX-переходы не вызывают стандартных page view событий. GA4 нужно триггерить вручную:

barba.hooks.after(({ next }) => {
  // GA4
  if (typeof gtag !== 'undefined') {
    gtag('event', 'page_view', {
      page_title: next.html.match(/<title>(.*?)<\/title>/)?.[1] || '',
      page_location: window.location.href,
      page_path: window.location.pathname,
    })
  }

  // Обновление title и meta
  const nextHead = new DOMParser()
    .parseFromString(next.html, 'text/html')
    .head

  document.title = nextHead.querySelector('title')?.textContent || ''

  // Meta description
  const desc = nextHead.querySelector('meta[name="description"]')
  if (desc) {
    document.querySelector('meta[name="description"]')
      ?.setAttribute('content', desc.getAttribute('content') || '')
  }
})

Сроки

Базовые переходы fade/slide для 2–3 типов страниц — 2–3 дня. Сложные морфинг-переходы с анимацией элементов, prefetch, интеграцией ScrollTrigger и Lenis, обновлением аналитики — 5–8 дней.