Реалізація 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-атрибути для визначення корневого контейнера та простору імен сторінки:

<!-- Кожна сторінка -->
<main data-barba="wrapper">
  <div data-barba="container" data-barba-namespace="home">
    <!-- Вміст сторінки -->
  </div>
</main>

Простір імен використовується для рутингу — застосовувати різні переходи для різних пар сторінок.

Переходи з оверлеєм

Більш складний паттерн: кольоровий overlay їде поверх сторінки, потім йде, відкриваючи новий вміст.

// DOM-елемент оверлея (завжди в DOM, поза data-barba контейнером)
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;
}

Рутинг — Різні переходи для різних сторінок

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) {
        // Клип-маска схлопується до мініатюри
        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 не завантажує наступну сторінку заздалегідь з коробки. Для миттєвих переходів — @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 дні. Складні morphing-переходи з анімацією елементів, prefetch, інтеграцією ScrollTrigger та Lenis, оновленням аналітики — 5–8 днів.