Шоу прокрутки (часть 2 JavaScript)

Шоу прокрутки (часть 2 - JavaScript)

После того, как мы добавили базовые стили, но прежде, чем мы действительно напишем какой-либо JavaScript, нам нужно позаботиться о том, какие именно анимации мы собираемся получить..

Animate.CSS

Вот набор CSS-анимаций, которые вы можете использовать заранее: https://daneden.github.io/animate.css/ .

На работе большинству клиентов нужен эффект fadeInUp, который мы и будем использовать здесь..

Я предполагаю, что вы уже загрузили исходные файлы и даже добавили в свой документ необходимый тег ссылки для загрузки объявлений..

Поскольку наш раздел Intro будет виден при загрузке сайта, мы можем настроить его на запуск анимации при загрузке страницы..

Для этого просто добавьте классы animation и fadeInUp сразу после вводного класса..

В ожидании

Теперь отметим элементы, которые мы хотим показать с таким же эффектом, как только они появятся на экране при прокрутке посетителями сайта..

Я добавил ожидающий класс:

  • .Featured__title
  • каждый .feature__item
  • .columns__title
  • оба .column__item
  • .gallery__list

Сделаем их изначально прозрачными с помощью следующего CSS:

.в ожидании {непрозрачность: 0; }

JavaScript

Настал долгожданный момент: давайте сдвинемся с места!

Начнем с выбора всех элементов, которые мы хотим анимировать:

const pendingAnimation = document.querySelectorAll (‘. ожидание’);

querySelectorAll () принимает селектор CSS в качестве аргумента и возвращает все элементы, которые ему соответствуют..

В этом случае мы выполнили метод непосредственно в документе, который захватит все элементы с ожидающим классом. Но мы могли бы запустить querySelectorAll () для другого элемента и взять только его дочерние элементы, соответствующие селектору..

Затем давайте создадим пустую функцию, которая будет выполнять эту работу и убедиться, что она запускается при каждой прокрутке и изменении размера, потому что тогда вам может потребоваться анимация:

window.addEventListener (‘прокрутка’, animateIn); window.addEventListener (‘изменить размер’, animateIn);
функция animateIn (e) {}

requestAnimationFrame ()

Добавим внутрь animateIn ():

requestAnimationFrame (функция () {});

Это указывает браузеру выполнить код из функции обратного вызова только после рисования следующего кадра. Что по-прежнему происходит 60 раз в секунду

Читать также:  Бандлеры

Такая отсрочка кода очень важна при обработке событий, которые могут происходить быстро и много раз (более 60) в секунду:

  • прокрутка
  • изменить размер
  • мышь

Используя requestAnimationFrame (), мы гарантируем, что браузер не будет пытаться выполнять одни и те же вычисления 2-3 или более раз между двумя последовательными кадрами, при условии, что обновление одного кадра будет видно посетителям..

Всегда вставляйте код из функции обработчика вышеуказанных событий в requestAnimationFrame ().

fadeInUp

Теперь давайте прокрутим каждый ожидающий элемент, чтобы увидеть, виден ли он:

const scrollInPosition = window.scrollY + window.innerHeight * 0.9;
pendingAnimation.forEach (function (el) {if (el.offsetTop scrollInPosition) {el.classList.remove (‘pending’); el.classList.add (‘animated’, ‘fadeInUp’);} else {el.classList. remove (‘анимированный’, ‘fadeInUp’); el.classList.add (‘ожидающий’);}});

window.scrollY — насколько мы прокручиваем экран вниз.

window.innerHeight Я думаю, вы можете угадать высоту экрана. Мы умножаем его на 0,9, потому что хотим, чтобы анимация происходила, когда элемент проходит 10% нижней части экрана. Он должен быть хотя бы немного виден, иначе анимация останется за пределами экрана и весь эффект будет потерян..

forEach () позволяет нам циклически повторять все результаты из коллекции pendingAnimation. Эта коллекция — не обычный массив (о массивах мы говорили раньше), а NodeList. В чем разница не такая уж и значительная. Важно знать, что обычные циклы for и while применяются с большим объемом записи, а forEach () может применяться как к массиву, так и к NodeList..

el.offsetTop сообщает нам, на сколько пикселей по вертикали от верха страницы расположен элемент. Если значение меньше scrollInPosition (если больше) — значит пора показать элемент.

classList.remove () и classList.add () снова должны быть очень ясными, что они добавляют / удаляют классы текущего элемента..

Наконец, у нас есть else, который меняет логику. В верхней части написано:

Как только элемент проходит более 10% нижнего края того, что в настоящее время видно после прокрутки — добавьте классы анимации.

Читать также:  Параллакс с фиксированным фоном

После еще мы говорим:

Как только вы прокручиваете вверх и элемент слишком сильно опускается — удалите его классы анимации и снова сделайте его скрытым..

Это позволяет нам прокручивать назад, а затем снова вниз, чтобы снова воспроизвести анимацию. Если вместо этого вы хотите, чтобы предмет, который когда-то выглядел так, не двигался, вы можете удалить часть else. Тем не менее, это для меня больше удовольствия, и, по крайней мере, во время разработки это позволяет мне легко видеть анимацию снова и снова, не перезагружая страницу..

Последний раздел расширяет страницу

Если вы очень быстро прокрутите вниз, вы увидите, что галерея становится выше, а затем снова опускается..

Это связано с тем, что элементы на их отображении не только анимируются для полной видимости, но и перемещаются вверх. Чтобы такой рост был, они должны сначала спуститься. Это делает секцию выше (для сбора элементов), а когда они перемещаются вверх, высота спинки контейнера уменьшается..

Давайте просто добавим в раздел overflow: hidden, чтобы этого не произошло..

Задержка в последовательных элементах

Однако неинтересно, чтобы одновременно выходили разные столбцы .features и .columns. Как-то, конечно, мне хотелось бы, чтобы хотя бы каждый следующий элемент в серии имел небольшую задержку..

Там, где у нас есть до 2-3-4 последовательных элементов, мы можем сделать это с небольшим дополнительным CSS:

.feature__item.animated: nth-child (2) {задержка анимации: 200 мс; } .feature__item.animated: nth-child (3) {задержка анимации: 400 мс; }
.column__item.animated: nth-child (2) {задержка анимации: 200 мс; }

nth-child указывает, какой последовательный элемент мы хотим выбрать. Мы используем animation-delay, чтобы отложить начало анимации для этого элемента (в случае 200 или 400 миллисекунд).

Задержка каждой фотографии из галереи

Однако, поскольку у нас в галерее 16 фотографий, если нам нужно описать задержку для каждой из них аналогичным образом, нам придется написать довольно унифицированный код. Это должно сказать нам, что мы что-то делаем неправильно..

Читать также:  Начало работы в JavaScript циклы

Вместо этого лучше прибегнуть к немного большему количеству JS-кода, чтобы эффект работал с бесконечным количеством изображений из галереи..

Но сначала давайте добавим ожидающий класс к первому изображению. Это послужит началом, и должно быть что-то, что его «подтолкнет». Пусть это будет код JS, который у нас уже есть.

Затем выделим все картинки:

const galleryItems = document.querySelectorAll (‘. gallery__item’);

Давайте установим opacity: 0 для каждого через JS, потому что у них нет ожидающего класса для применения таких стилей:

galleryItems.forEach (функция (gi) {gi.style.opacity = 0;
gi.addEventListener (‘запуск анимации’, функция (e) {const next = e.currentTarget.nextElementSibling;
if (next! == null) {setTimeout (функция) (next.classList.add (‘анимированный’, ‘fadeInUp’);}, 100); }})});

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

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

Что там происходит:

  1. берем следующий элемент (следующий li)
  2. проверяем, действительно ли мы что-то взяли (в случае обработки последнего снимка — рядом взять нечего)
  3. установить setTimeout () для выполнения через 100 миллисекунд
  4. При выполнении тайм-аута мы применяем новые классы к «следующей» картинке.
  5. Когда он начинает анимироваться, он запускает цепную реакцию, выбирая следующую и анимируя ее еще через 100 миллисекунд.

Однако для того, чтобы скрыть элементы для прокрутки вверх для работы, мы также должны добавить следующий код в else нашей функции animateIn:

if (el.classList.contains (‘gallery__item’)) {galleryItems.forEach (function (gi) {gi.classList.remove (‘animated’, ‘fadeInUp’); gi.style.opacity = 0;}); }

Просто скрывая первое изображение (то, что с ожидающим классом), мы удаляем анимированные классы и классы fadeInUp и все остальные..

Пример

Вы можете увидеть демонстрацию финальной версии на https://magadanski.com/demo/parallax-fade-in-up/.

Понравилась статья? Поделиться с друзьями:
Что нужно знать пользователю?