Статьи

Создание анимации на основе прокрутки с использованием jQuery и CSS3

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

Сегодня я расскажу о методике, которую вы можете адаптировать к своим веб-проектам — запускать анимацию при прокрутке в предварительно заданную область. Эти анимации будут созданы с использованием CSS- преобразований и CSS- переходов . Мы также будем использовать jQuery для определения, когда элементы видны, и для добавления / удаления соответствующих классов.

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

Зачем запускать анимацию на свитке?

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

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

Анимация с помощью CSS или с помощью jQuery?

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

Я буду использовать преобразования через CSS, однако всегда есть переменные, которые необходимо учитывать в зависимости от вашей ситуации. Я бы принял во внимание следующие факторы:

Совместимость браузера

Поскольку наше решение будет основано на преобразованиях, совместимость нашего браузера будет ограничена теми, которые поддерживают либо 2D-преобразования, либо 3D-преобразования.

Все современные браузеры будут поддерживать 3D-преобразования, а некоторые из старых браузеров, таких как Internet Explorer 9 и Opera 11.5, будут поддерживать 2D-преобразования . Общая поддержка как настольных, так и мобильных браузеров является всеобъемлющей.

Анимационный метод jQuery работает в любом (нормальном) браузере, если вы используете версию библиотеки 1.X. В jQuery 2.X удалена поддержка IE8 и ниже, поэтому используйте ее только в том случае, если вам не нужна поддержка устаревших браузеров (удачи вам!).

скорость

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

В примерах будут использоваться 3D-преобразования с 2D-отступлением для старых браузеров. Мы хотим форсировать аппаратное ускорение для скорости, поэтому 3D-преобразование является обязательным (мы будем использовать translate3d вместе с другими функциями, которые вызывают ускорение рендеринга на GPU).

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

Примечание

Мы все знаем, что jQuery !== JavaScript , верно? Что ж, получается, что использование vanilla JS для анимации может быть не такой уж плохой идеей. Хотя это выходит за рамки данного руководства, здесь есть две отличные статьи на эту тему для тех, кто хочет узнать больше:

Теперь вернемся к шоу …

Обнаружение элементов анимации в поле зрения

Общая цель этого метода — просмотреть все наши элементы, которые мы пометили как анимируемые, а затем определить, находятся ли они в настоящее время в области просмотра. Давайте рассмотрим, как мы этого добьемся:

Кэширование селектора

Прокрутка — это дорогое дело. Если вы присоедините прослушиватель событий к событию scroll , он будет срабатывать много раз, когда пользователь прокручивает страницу. Поскольку мы будем вызывать наши функции измерения / вычисления всякий раз, когда пользователь выполняет прокрутку, хорошей идеей будет хранить элементы, возвращаемые нашими селекторами, в переменных. Это называется кэшированием селекторов и позволяет нам не запрашивать DOM снова и снова.

В нашем скрипте мы будем ссылаться как на объект window и на коллекцию элементов, которые мы хотим анимировать.

 //Cache reference to window and animation items var $animation_elements = $('.animation-element'); var $window = $(window); 

Обратите внимание на знак доллара перед переменными. Это соглашение, указывающее, что они содержат объект jQuery или коллекцию объектов.

Присоединение к событию прокрутки

Затем мы создаем наш обработчик событий, который прослушивает событие scroll . Это будет срабатывать, когда мы прокручиваем страницу. Мы передаем ему ссылку на нашу функцию check_if_in_view (к которой мы вернемся через минуту). При каждом запуске события прокрутки эта функция будет выполняться.

 $window.on('scroll', check_if_in_view); 

Обработка изменения размера

Поскольку мы рассчитываем высоту и ширину, нам необходимо учитывать изменения ориентации наряду с общим изменением размера.

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

 $window.on('scroll resize', check_if_in_view); 

Кроме того, мы также используем метод триггера jQuery для запуска события scroll как только DOM будет готов. Мы делаем это так, что если какой-либо из элементов, которые должны быть анимированы, находится в области просмотра, они будут обнаружены как в виде, а анимация применена, как если бы мы прокручивали

 $window.trigger('scroll'); 

Обнаружение положения прокрутки

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

 function check_if_in_view() { var window_height = $window.height(); var window_top_position = $window.scrollTop(); var window_bottom_position = (window_top_position + window_height); $.each($animation_elements, function() { var $element = $(this); var element_height = $element.outerHeight(); var element_top_position = $element.offset().top; var element_bottom_position = (element_top_position + element_height); //check to see if this current container is within viewport if ((element_bottom_position >= window_top_position) && (element_top_position <= window_bottom_position)) { $element.addClass('in-view'); } else { $element.removeClass('in-view'); } }); } поле function check_if_in_view() { var window_height = $window.height(); var window_top_position = $window.scrollTop(); var window_bottom_position = (window_top_position + window_height); $.each($animation_elements, function() { var $element = $(this); var element_height = $element.outerHeight(); var element_top_position = $element.offset().top; var element_bottom_position = (element_top_position + element_height); //check to see if this current container is within viewport if ((element_bottom_position >= window_top_position) && (element_top_position <= window_bottom_position)) { $element.addClass('in-view'); } else { $element.removeClass('in-view'); } }); } поле function check_if_in_view() { var window_height = $window.height(); var window_top_position = $window.scrollTop(); var window_bottom_position = (window_top_position + window_height); $.each($animation_elements, function() { var $element = $(this); var element_height = $element.outerHeight(); var element_top_position = $element.offset().top; var element_bottom_position = (element_top_position + element_height); //check to see if this current container is within viewport if ((element_bottom_position >= window_top_position) && (element_top_position <= window_bottom_position)) { $element.addClass('in-view'); } else { $element.removeClass('in-view'); } }); } 

Давайте разберемся, что здесь происходит.

Функция check_if_in_view первоначально вызывается, когда DOM готов, а затем каждый раз, когда мы изменяем размер или прокручиваем.

Мы получаем текущую высоту окна, а также его верхнюю и нижнюю позиции, чтобы мы знали, на какую область мы смотрим.

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

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

Вот наглядный пример

Определить, находится ли элемент в области просмотра

Расчет высоты и ширины

В нашей функции обнаружения нам нужно получить высоты и положения различных элементов, чтобы правильно вычислять вещи, именно здесь мы использовали функции height jQuery. Важно иметь представление о том, как работают эти функции высоты

высота () и ширина ()

Функции height() и width() возвращают высоту или ширину элемента. Они исключают все отступы, границы и поля.

Пример высоты и ширины jQuery

Для полной разбивки посетите документацию по высоте или ширине .

innerHeight () и innerWidth ()

Функции innerHeight() и innerWidth() возвращают высоту или ширину элемента, включая его дополнительные отступы (однако исключаются как границы, так и поля)

Пример jQuery innerHeight и innerWidth

Для полной разбивки посетите документацию innerHeight или innerWidth .

externalHeight () и outerWidth ()

Функции outerHeight() и outerWidth() возвращают высоту или ширину элемента и включают его отступы и границу.

Кроме того, вы также можете указать включение полей, передав значение true в функцию.

Пример jQuery outerHeight и outerWidth

Для полной разбивки посетите документацию outerHeight или outerWidth

Примеры анимации прокрутки

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

Все элементы, которые вы хотите переместить, должны иметь стандартный класс, такой как animation-element который устанавливает его положение как относительное или абсолютное. Кроме того, если вы собираетесь создать несколько эффектов, вы можете создать соответствующие классы, такие как slide-left которые можно комбинировать с классом in-view . Затем вы должны применить преобразование к классу, такому как animation-element.slide-left.inview

Слайд слева

Для нашего первого примера мы будем скользить по элементам слева при входе в область просмотра. Мы достигаем этого, используя translate3d на наших элементах оси x.

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

Исчезать снизу

На этот раз мы будем потускать наши элементы снизу вверх, пока пользователь прокручивает. Мы достигаем этого через translate3d на оси Y элемента.

Для этого примера я перечислил информацию о курсе по темам в структуре сетки. Когда пользователь прокручивает страницу вниз, каждая отображаемая карта будет появляться и двигаться вверх, отображая информацию о курсе.

Многошаговая анимация

В нашем последнем примере мы будем использовать многоступенчатую анимацию. Для этого мы определим пользовательские keyframe animations которые сочетают rotation с translation . Этот тип анимации может помочь продемонстрировать области вашего веб-сайта (для этого примера мы показываем профили сотрудников).

Где отсюда?

Отсюда вы можете взять изученные вами концепции и применить их к своим проектам.

Теперь, когда вы можете определить, когда элемент находится в поле зрения, вы можете связать дополнительные преобразования или эффекты для создания интерактивных интерфейсов. Например, когда элемент входит в область просмотра (и после его преобразования), вы можете затем преобразовать дополнительные элементы, такие как замирание в заголовке, масштабирование в изображении и т. Д.

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