Контекст выполнения (this) в callbacks

GSAP (GreenSock Animation Platform) предоставляет мощный и гибкий API для создания анимаций в JavaScript. Одним из ключевых аспектов при работе с анимациями является понимание контекста выполнения внутри callback-функций. GSAP активно использует callbacks для обработки событий анимации: начала, завершения, обновления и повторов. Контекст выполнения (this) в этих функциях играет критически важную роль, особенно при сложных цепочках анимаций и работе с несколькими элементами одновременно.

Основные типы callback-функций

GSAP поддерживает следующие наиболее часто используемые callback-функции:

  • onStart — вызывается в момент запуска анимации.
  • onUpdate — вызывается при каждом кадре анимации.
  • onComplete — вызывается по завершении анимации.
  • onRepeat — вызывается при каждом повторении анимации, если установлен параметр repeat.

Каждая из этих функций может быть передана в объект конфигурации при создании tween или timeline.

gsap.to(".box", {
  x: 200,
  duration: 2,
  onStart: function() {
    console.log(this); // контекст выполнения
  },
  onComplete: function() {
    console.log(this);
  }
});

Значение this внутри callback

Внутри callback-функций this ссылается на сам tween или timeline, к которому привязан callback. Это позволяет управлять анимацией напрямую:

  • Получать текущие значения свойств через методы progress(), time() или duration().
  • Влиять на анимацию: останавливать, ускорять, изменять параметры в реальном времени.
  • Использовать свойства targets() для работы с анимируемыми элементами.
gsap.to(".box", {
  x: 300,
  duration: 3,
  onUpdate: function() {
    console.log("Прогресс анимации:", this.progress());
    console.log("Анимируемые элементы:", this.targets());
  }
});

Отличие стрелочных функций от обычных

Стрелочные функции не имеют собственного контекста выполнения и наследуют this из внешней области видимости. Это важно учитывать, если необходимо использовать возможности GSAP, связанные с контекстом:

gsap.to(".circle", {
  x: 150,
  duration: 2,
  onComplete: () => {
    console.log(this); // this будет указывать на внешний scope, а не на tween
  }
});

Для доступа к tween внутри callback необходимо использовать обычную функцию или сохранять ссылку на tween:

const tween = gsap.to(".circle", {
  x: 150,
  duration: 2,
  onComplete: function() {
    console.log(this); // правильный контекст: Tween
  }
});

Доступ к элементам через this.targets()

Метод targets() возвращает массив DOM-элементов, к которым применена анимация. Это особенно удобно при работе с группами элементов и для динамического изменения свойств:

gsap.to(".item", {
  y: 100,
  duration: 1,
  stagger: 0.2,
  onComplete: function() {
    this.targets().forEach(el => el.style.backgroundColor = "red");
  }
});

Контекст в timelines

Для timeline контекст выполнения в callbacks также ссылается на сам timeline. Это позволяет управлять последовательностью анимаций целиком:

const tl = gsap.timeline({
  onComplete: function() {
    console.log("Timeline завершён", this);
    console.log("Общее количество элементов:", this.targets().length);
  }
});

tl.to(".box", {x: 100, duration: 1})
  .to(".circle", {y: 50, duration: 1});

Использование this в timeline также позволяет изменять скорость (timeScale) или позицию текущей анимации (seek) динамически внутри callback.

Практические советы

  • Для работы с tween или timeline внутри callbacks всегда использовать обычные функции, чтобы this корректно ссылался на объект анимации.
  • Если требуется использовать стрелочные функции, сохранять tween в отдельную переменную для доступа к методам GSAP.
  • Методы targets(), progress(), time(), duration() дают полный контроль над текущей анимацией и элементами.
  • Комбинирование this с stagger и групповой анимацией позволяет создавать сложные эффекты без дополнительной привязки переменных.

Контекст выполнения в GSAP является фундаментальной частью архитектуры анимаций. Правильное использование this открывает возможности для динамического контроля анимации, синхронизации сложных последовательностей и взаимодействия с DOM-элементами на каждом кадре анимации.