repeatRefresh для динамических повторений

GSAP (GreenSock Animation Platform) предоставляет мощные инструменты для управления анимациями в JavaScript. Одним из важных аспектов динамических анимаций является повторение с обновлением начальных значений, для чего используется свойство repeatRefresh. Оно особенно полезно при работе с элементами, чьи свойства могут изменяться в процессе или между повторениями анимации.


Основные концепции repeatRefresh

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

Синтаксис:

gsap.to(".element", {
  x: 300,
  duration: 2,
  repeat: 3,
  repeatRefresh: true
});
  • repeat — количество повторений анимации. Значение -1 задает бесконечный цикл.
  • repeatRefresh — булево значение. При true GSAP пересчитает стартовые значения перед каждой итерацией.
  • duration — длительность одной анимации в секундах.

Когда repeatRefresh необходим

  1. Динамическая позиция элементов Если элемент перемещается или меняет свойства через другие скрипты или пользовательские события, без repeatRefresh повторение будет использовать исходное значение, заданное при первой анимации.

  2. Рандомизация анимаций При создании случайных эффектов, таких как разлет элементов, свойство repeatRefresh: true гарантирует пересчет новых случайных значений перед каждым повтором.

  3. Изменение размеров и стилей Если размеры элементов зависят от текущей верстки или контента, repeatRefresh позволяет анимации корректно адаптироваться к новым условиям.


Примеры использования

Перемещение элементов с динамическим стартом:

gsap.to(".box", {
  x: () => Math.random() * 500, // случайная позиция
  duration: 1,
  repeat: 5,
  repeatRefresh: true // пересчет позиции перед каждым повтором
});

В этом примере каждая итерация перемещает элемент на новое случайное расстояние.


Изменение цвета с динамическим выбором:

gsap.to(".circle", {
  backgroundColor: () => `hsl(${Math.random() * 360}, 80%, 60%)`,
  duration: 0.8,
  repeat: 4,
  repeatRefresh: true
});

Цвет круга будет обновляться при каждом повторении, создавая эффект постоянно изменяющейся анимации.


Важные нюансы

  • repeatRefresh работает только с анимациями, где свойства могут быть функциями или изменяться динамически. Статические значения без функции пересчитываться не будут.
  • Не следует использовать repeatRefresh: true для анимаций с фиксированными ключевыми кадрами или трансформациями, которые должны оставаться постоянными, так как это может привести к непредсказуемым результатам.
  • Комбинация yoyo: true и repeatRefresh: true позволяет создавать анимации, которые не только меняют направление, но и обновляют стартовые значения на каждом повторе, что полезно для живых и интерактивных интерфейсов.

Продвинутые сценарии

Случайная анимация нескольких элементов с последовательным повторением:

gsap.utils.toArray(".dot").forEach(dot => {
  gsap.to(dot, {
    y: () => Math.random() * 200,
    x: () => Math.random() * 200,
    duration: 1.5,
    repeat: -1,
    repeatRefresh: true,
    ease: "power1.inOut"
  });
});

Каждый элемент получает свою уникальную траекторию при каждом повторе. Без repeatRefresh все повторения двигались бы по одной и той же линии.


Использование с Timeline:

const tl = gsap.timeline({ repeat: 3, repeatRefresh: true });

tl.to(".box1", { x: 200, duration: 1 })
  .to(".box2", { y: 150, duration: 1 }, "<")
  .to(".box3", { rotation: 360, duration: 1 }, "<");

При таком подходе весь таймлайн пересчитывает значения перед каждым повтором, что позволяет работать с изменяемыми свойствами всех включенных элементов.


Практические рекомендации

  • Использовать repeatRefresh для динамических и интерактивных анимаций, где стартовые значения элементов не статичны.
  • Для анимаций, повторяющихся с фиксированными координатами или стилями, отключать repeatRefresh, чтобы избежать лишних вычислений.
  • Комбинировать с функциями генерации случайных значений для создания непредсказуемого, живого движения элементов.
  • Тестировать анимации на производительность при большом количестве элементов, так как пересчет значений на каждый повтор может быть затратным.