logicface
@logicface
Начинающий

Как последовательно анимировать одновременно видимые в браузере блоки при разных условиях их видимости?

Добрый день. Столкнулся с проблемой анимации. Я делаю анимацию блоков при прокрутке страницы с помощью AOS.js. Иногда бывает так, что некоторые блоки (например 3 блока) одновременно попадают в область видимости браузера. Мне нужно чтобы их анимация появления не была одновременной, но последовательной (то есть чтобы каждый блок появлялся с задержкой относительно предыдущего). Но бывает так, что эти же 3 блока не одновременно попадают в область видимости окна браузера (например, на мобильных устройствах они выстраиваются друг под другом) и в таком случае задержка должна следующего блока (2-ого и 3-его) должна отсутствовать (но если 2 блока попадают в область видимости, а третий нет, то у второго есть задержка относительно первого, а у третьего её нет). Блоков может быть различное количество. Как это правильно реализовать?

Пример такой работы можно посмотреть на сайте bannermaker.by в таблице портфолио (оно там генерируется динамически, а у меня просто статические, заранее готовые блоки).

Вот картинка как пример для большей наглядности (цифры это задержка появления блоков при попадании в область видимости):

66d9784746cde204133108.png
  • Вопрос задан
  • 75 просмотров
Решения вопроса 1
logicface
@logicface Автор вопроса
Начинающий
Всем привет. Решил свою проблему через дополнительное использование IntersectionObserver, который отслеживает блоки, помеченные AOS атрибутами. Инициализировал сам AOS через таймаут в 50 (не знаю зачем это нужно, но без этого не работает). Observer отслеживает теги, у которых еще не задан delay, как только delay через скрипт задается, блок перестает отслеживаться. Накидывание delay выполнено через FIFO. Вот рабочий код, может кому пригодиться:
const stack = []
const delayFactor = 300

const options = {
  rootMargin: '0px',
  threshold: 0.2,
}

const callback = entries => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      stack.push(entry.target)

      const delay = (stack.length - 1) * delayFactor

      entry.target.setAttribute('data-aos-delay', `${delay}`)

      setTimeout(() => {
        stack.shift()
      }, delay)
    }
  })
}

const observer = new IntersectionObserver(callback, options)

const elementsToTrack = document.querySelectorAll(
  '[data-aos]:not([data-aos-delay])'
)

elementsToTrack.forEach(element => {
  observer.observe(element)
})


Пример работы можно посмотреть на сайте: https://yourbanner.ru
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы