Покадровая прорисовка

ScrollMagic — это мощная библиотека для управления анимациями на основе скролла. В центре её работы находится концепция сцен (Scenes), которые связывают скролл страницы с изменением свойств элементов. Покадровая прорисовка в ScrollMagic позволяет синхронизировать анимацию с прогрессом прокрутки, создавая эффект плавного движения или постепенного появления объектов.


Создание сцены для покадровой анимации

Базовый элемент для управления анимацией — объект ScrollMagic.Scene. Он позволяет задать точку входа анимации, её длительность и привязку к конкретному элементу:

const controller = new ScrollMagic.Controller();

const scene = new ScrollMagic.Scene({
  triggerElement: "#trigger", // Элемент, при котором начинается анимация
  duration: 500,              // Длина сцены в пикселях прокрутки
  triggerHook: 0.5            // Точка срабатывания (0 — верх, 1 — низ)
})
.setPin("#animateMe")         // Закрепление элемента на время сцены
.addTo(controller);
  • triggerElement — элемент, относительно которого будет отслеживаться скролл.
  • duration — определяет, на каком отрезке прокрутки будет происходить анимация. Для покадровой прорисовки важно, чтобы длительность соответствовала количеству кадров.
  • triggerHook — указывает, где на экране срабатывает сцена.

Синхронизация анимации с прогрессом

Для покадровой анимации ключевой параметр — прогресс сцены (scene.progress()), который возвращает число от 0 до 1, отражающее процент прокрутки:

scene.on("progress", function (event) {
  const frameIndex = Math.floor(event.progress * totalFrames);
  showFrame(frameIndex);
});
  • totalFrames — общее количество кадров.
  • showFrame(index) — функция, отвечающая за отображение конкретного кадра, например, через background-position спрайта или изменение src тега .

Использование спрайтов для покадровой анимации

Самый популярный способ реализации покадровой прорисовки — спрайт-листы:

#sprite {
  width: 500px;
  height: 500px;
  background-image: url('sprite.png');
  background-repeat: no-repeat;
  background-position: 0 0;
}
const totalFrames = 60;
const sprite = document.getElementById("sprite");

function showFrame(index) {
  const position = -index * 500; // 500px — ширина кадра
  sprite.style.backgroundPosition = `${position}px 0`;
}

Каждое изменение background-position синхронизируется с прогрессом сцены, создавая эффект покадрового воспроизведения при скролле.


Анимация CSS-свойств

ScrollMagic отлично комбинируется с GSAP для управления CSS-анимацией. Это особенно удобно при необходимости плавного перехода между состояниями элемента:

const tween = gsap.to("#box", { x: 500, rotation: 360, ease: "none" });

const scene = new ScrollMagic.Scene({
  triggerElement: "#trigger",
  duration: 800
})
.setTween(tween)
.addTo(controller);
  • ease: "none" обеспечивает линейную анимацию, что важно для точной покадровой прорисовки.
  • Можно комбинировать с изменением прозрачности, масштаба, цветов и других свойств.

Контроль проигрывания анимации

ScrollMagic позволяет проверять текущий кадр, ставить сцену на паузу и возвращать её:

scene.on("enter", () => console.log("Сцена началась"));
scene.on("leave", () => console.log("Сцена закончилась"));
scene.on("progress", event => {
  updateFrame(event.progress);
});
  • enter и leave помогают запускать дополнительные эффекты или триггеры.
  • progress используется для точной синхронизации кадров.

Интерактивные эффекты

Для более сложных визуальных решений можно комбинировать несколько сцен и привязывать их к разным элементам:

const scene1 = new ScrollMagic.Scene({ triggerElement: "#section1", duration: 400 })
  .setTween(gsap.to("#obj1", { y: 200 }))
  .addTo(controller);

const scene2 = new ScrollMagic.Scene({ triggerElement: "#section2", duration: 600 })
  .setTween(gsap.to("#obj2", { x: 300 }))
  .addTo(controller);
  • Такой подход позволяет создавать цепочку анимаций, каждая из которых срабатывает в своём сегменте прокрутки.
  • Можно комбинировать с параллакс-эффектами, закреплением элементов (setPin) и динамическим изменением классов.

Оптимизация производительности

Для плавной покадровой анимации важно соблюдать несколько правил:

  1. Использовать спрайт-листы вместо отдельных изображений. Это снижает количество перерисовок и запросов к серверу.
  2. Минимизировать обработку в событии progress. В идеале просто изменять background-position или transform.
  3. Включать аппаратное ускорение через transform: translate3d() или will-change: transform для больших объектов.
  4. Делить сцены на небольшие сегменты, если общий прогресс слишком большой, чтобы избежать рывков.

Работа с динамическими элементами

ScrollMagic поддерживает динамическое добавление элементов и изменение длины сцены:

const dynamicScene = new ScrollMagic.Scene({
  triggerElement: ".dynamic",
  duration: function() {
    return document.querySelector(".dynamic").offsetHeight;
  }
}).addTo(controller);
  • Позволяет адаптировать покадровую прорисовку под разные размеры контента и экранов.
  • Можно комбинировать с медиа-запросами, чтобы анимация оставалась корректной на мобильных устройствах.