Реалізація GSAP-анімацій на сайті

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

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

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація GSAP-анімацій на сайті
Середня
~3-5 робочих днів
Часті питання

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

Етапи розробки

Останні роботи

  • 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

Реалізація GSAP-анімацій на сайті

GSAP (GreenSock Animation Platform) — промисловий стандарт для складних веб-анімацій. На відміну від CSS-анімацій, GSAP забезпечує точний контроль над часовими шкалами, підтримує групування та послідовності, стабільно працює в Safari і коректно паузує/перемотує. Платна ліцензія потрібна лише для плагінів (ScrollTrigger, MorphSVG тощо) — базовий GSAP 3 є безкоштовним і достатнім для більшості завдань.

Встановлення та базова конфігурація

npm install gsap
# ScrollTrigger входить до основного пакету

Для Next.js і React важливо переконатись, що GSAP не виконується на сервері (SSR):

// lib/gsap.ts — централізована ініціалізація
import { gsap } from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'
import { ScrollToPlugin } from 'gsap/ScrollToPlugin'

if (typeof window !== 'undefined') {
  gsap.registerPlugin(ScrollTrigger, ScrollToPlugin)

  // Налаштування глобальних параметрів
  gsap.config({
    nullTargetWarn: false, // не попереджувати про null-елементи
    trialWarn: false,
  })

  // Скидаємо ScrollTrigger при resize (важливо для мобільних)
  ScrollTrigger.config({
    ignoreMobileResize: true,
  })
}

export { gsap, ScrollTrigger }

Hero-анімація при завантаженні сторінки

// components/HeroSection.tsx
import { useEffect, useRef } from 'react'
import { gsap } from '../lib/gsap'

export function HeroSection() {
  const containerRef = useRef<HTMLDivElement>(null)
  const headlineRef = useRef<HTMLHeadingElement>(null)
  const sublineRef = useRef<HTMLParagraphElement>(null)
  const ctaRef = useRef<HTMLButtonElement>(null)
  const imageRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    const ctx = gsap.context(() => {
      // Часова шкала входу
      const tl = gsap.timeline({
        defaults: { ease: 'power3.out', duration: 0.8 },
      })

      tl
        .from(headlineRef.current, {
          y: 60,
          opacity: 0,
          duration: 1,
        })
        .from(
          sublineRef.current,
          { y: 40, opacity: 0 },
          '-=0.5' // перекриття -0.5с
        )
        .from(
          ctaRef.current,
          { y: 20, opacity: 0, scale: 0.95 },
          '-=0.4'
        )
        .from(
          imageRef.current,
          {
            x: 80,
            opacity: 0,
            duration: 1.2,
            ease: 'power2.out',
          },
          '<-0.6' // відносно попереднього старту
        )
    }, containerRef)

    return () => ctx.revert() // очистка при розмонтуванні
  }, [])

  return (
    <div ref={containerRef} className="hero-container">
      <h1 ref={headlineRef}>Заголовок</h1>
      <p ref={sublineRef}>Підзаголовок</p>
      <button ref={ctaRef}>Почати</button>
      <div ref={imageRef} className="hero-image" />
    </div>
  )
}

gsap.context() — обов'язковий паттерн для React: він скопіює всі GSAP-цілі до containerRef і коректно видалить анімації при виклику ctx.revert().

ScrollTrigger: анімації при скролі

// components/FeatureCards.tsx
import { useEffect, useRef } from 'react'
import { gsap, ScrollTrigger } from '../lib/gsap'

export function FeatureCards() {
  const sectionRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    const ctx = gsap.context(() => {
      // Stagger-анімація карточок при вході у viewport
      gsap.from('.feature-card', {
        y: 80,
        opacity: 0,
        duration: 0.7,
        stagger: 0.15,
        ease: 'power2.out',
        scrollTrigger: {
          trigger: sectionRef.current,
          start: 'top 75%',   // анімація стартує коли секція на 75% від верху
          end: 'bottom 20%',
          toggleActions: 'play none none reverse',
          // play = вперед при вході, reverse = назад при виході вгору
        },
      })

      // Паралакс для фонового зображення
      gsap.to('.section-bg', {
        yPercent: -30,
        ease: 'none',
        scrollTrigger: {
          trigger: sectionRef.current,
          start: 'top bottom',
          end: 'bottom top',
          scrub: true, // прив'язка до позиції скролу
        },
      })
    }, sectionRef)

    return () => ctx.revert()
  }, [])

  return (
    <div ref={sectionRef} className="features-section">
      <div className="section-bg" />
      {[1, 2, 3].map(i => (
        <div key={i} className="feature-card">Card {i}</div>
      ))}
    </div>
  )
}

Горизонтальний скролл з ScrollTrigger

Популярний ефект — секція з горизонтальною прокруткою при вертикальному скролі:

// components/HorizontalScroll.tsx
import { useEffect, useRef } from 'react'
import { gsap, ScrollTrigger } from '../lib/gsap'

export function HorizontalScroll({ items }: { items: string[] }) {
  const containerRef = useRef<HTMLDivElement>(null)
  const trackRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    const ctx = gsap.context(() => {
      const track = trackRef.current!
      const totalWidth = track.scrollWidth - track.offsetWidth

      gsap.to(track, {
        x: -totalWidth,
        ease: 'none',
        scrollTrigger: {
          trigger: containerRef.current,
          pin: true,           // фіксуємо секцію
          scrub: 1,            // гладкість 1с
          start: 'top top',
          end: `+=${totalWidth}`, // довжина скролу = ширина контенту
          invalidateOnRefresh: true, // пересчіт при resize
        },
      })
    }, containerRef)

    return () => ctx.revert()
  }, [])

  return (
    <div ref={containerRef} className="overflow-hidden">
      <div ref={trackRef} className="flex gap-8 w-max py-20">
        {items.map((item, i) => (
          <div key={i} className="w-[400px] h-[300px] flex-shrink-0 bg-gray-100 rounded-xl flex items-center justify-center">
            {item}
          </div>
        ))}
      </div>
    </div>
  )
}

Користувацькі функції прискорення

GSAP підтримує CustomEase для унікальних кривих прискорення:

import { CustomEase } from 'gsap/CustomEase'
gsap.registerPlugin(CustomEase)

// Створюємо з cubic-bezier або SVG path
CustomEase.create('myBounce', 'M0,0 C0.14,0 0.242,0.438 0.272,0.561 0.313,0.728 0.354,0.963 0.362,1 0.37,0.985 0.414,0.873 0.455,0.811')

gsap.to('.element', {
  x: 300,
  ease: 'myBounce',
  duration: 1.2,
})

Очистка при навігації (Next.js App Router)

У Next.js 13+ з App Router компоненти монтуються/демонтуються при навігації. ScrollTrigger потрібно коректно видаляти:

// hooks/useGSAPScrollTrigger.ts
import { useEffect, useLayoutEffect } from 'react'
import { gsap, ScrollTrigger } from '../lib/gsap'

// useLayoutEffect для синхронного вимірювання DOM
export function useGSAPScrollTrigger(
  setup: (context: gsap.Context) => void,
  deps: any[] = []
) {
  const isomorphicEffect =
    typeof window !== 'undefined' ? useLayoutEffect : useEffect

  isomorphicEffect(() => {
    const ctx = gsap.context(setup)
    return () => {
      ctx.revert()
      // Явний killAll потрібен при швидкій навігації
      ScrollTrigger.getAll().forEach(t => t.kill())
    }
  }, deps)
}

Продуктивність

Кілька правил для плавних 60fps:

  • Анімувати лише transform і opacity — вони не викликають reflow
  • Використовувати will-change: transform лише для активних анімацій, видаляти після
  • gsap.set() замість CSS для початкових станів — GSAP оптимізує батчинг
  • ScrollTrigger.batch() для великої кількості однотипних елементів замість окремих екземплярів
// Оптимізований batch для великих списків
ScrollTrigger.batch('.list-item', {
  onEnter: elements => {
    gsap.from(elements, {
      opacity: 0,
      y: 40,
      stagger: 0.1,
      duration: 0.6,
    })
  },
  start: 'top 85%',
})

Типові терміни

Hero-анімація + 2–3 ScrollTrigger-секції — 1–2 робочих дні. Повний набір анімацій для лендинга (горизонтальний скролл, pin-секції, stagger-списки, паралакс) — 4–6 робочих днів. Користувацькі анімації для складних інтерактивних сцен — окремої оцінки після технічного завдання.