Реализация анимации элементов при попадании их на экран

Анимация элементов

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

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

Возьмем для примера flex-контейнер из четырех квадратных элементов. Мы хотим, чтобы при попадании в зону экрана они всплывали по очереди снизу и вставали на свое место.

HTML

Элемент должен иметь идентификатор в виде id или названия класса. При этом идентификатор должен быть уникальным. Так что, если мы анимируем одинаковые элементы, у которых одинаковый класс (что естественно), но хотим задать им разное поведение — нужно добавить к ним дополнительные классы с уникальными названиями.

<div class="my-container">
            <h2>Всплывающие по очереди элементы флекса</h2>
            <div class="my-flex">
                <div class="my-flex__item start-item-1"></div>
                <div class="my-flex__item start-item-2"></div>
                <div class="my-flex__item start-item-3"></div>
                <div class="my-flex__item start-item-4"></div>
            </div>          
        </div>

Классы start-item будут задавать первоначальное положение элементов.

CSS

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

.my-flex { 
    display: flex;
    gap: 10px;
    overflow: hidden;
}

.my-flex__item {  
    width: 100px;
    height: 100px;
    position:relative;  
    background-color:red;
}

.start-item-1, .start-item-2,
.start-item-3, .start-item-4 {       
    bottom: -100px;
}

 .final-item-1 {
    bottom: 0px;   
    transition: bottom 200ms ease;
}

.final-item-2 {
    bottom: 0px; 
    transition: bottom 400ms ease;
}

.final-item-3 {
    bottom: 0px; 
    transition: bottom 500ms ease;
}

.final-item-4 {
    bottom: 0px;
    transition: bottom 800ms ease;
}

JS

Для js у нас три задачи:

отследить момент, когда элементы окажутся в зоне видимости,

заменить стартовый стиль на финальный, для создания эффекта анимации,

запустить событие при прокрутке экрана или при обновлении страницы:

  1. Отслеживаем попадания элемента в зону видимости с помощью функции isInViewport:
let isInViewport = function (element) {
    const rect = element.getBoundingClientRect();
    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight)
        && rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
}

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

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

let startStyleReplace = function (myObject, removeStyle, addStyle) { 
    if (isInViewport(myObject)) {
        myObject.classList.remove(removeStyle);
        myObject.classList.add(addStyle);
    }
}

3. Инициализируем события.

Объекты мы получает по идентификатору (в нашем случае уникальное название класса) и записываем в константы вне функции, чтобы избежать проблем с замыканием при повторной прокрутке страницы пользователем.

const my_item1 = document.querySelector('.start-item1');
const my_item2 = document.querySelector('.start-item2');
const my_item3 = document.querySelector('.start-item3');
const my_item4 = document.querySelector('.start-item4');

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

$(window).scroll(function () {
    startStyleReplace(my_item1, 'start-item1', 'final-item-1');
    startStyleReplace(my_item2, 'start-item2', 'final-item-2');
    startStyleReplace(my_item3, 'start-item3', 'final-item-3');
    startStyleReplace(my_item4, 'start-item3', 'final-item-4');
}

$(document).ready(function () {
    startStyleReplace(my_item1, 'start-item1', 'final-item-1');
    startStyleReplace(my_item2, 'start-item2', 'final-item-2');
    startStyleReplace(my_item3, 'start-item3', 'final-item-3');
    startStyleReplace(my_item4, 'start-item3', 'final-item-4');
}

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

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



Комментарии:

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

Добавить комментарий для Milk Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

send-email

Разработка модальной формы обратной связи с отправкой на e-mail

Конечно, есть готовые плагины, реализующие модальную форму обратной связи. Но, если не хотите подвешивать быстродействие сайта, можете разработать собственную. HTML […]

google analytics

Как правильно добавить код Google Analytics на сайт WordPress

Правильный подход — присоединять действие к хуку (в нашем случае wp_head, так как google рекомендует добавлять код аналитики в head). […]

плагины vs code

Удобные плагины для разработки WordPress на VS Code (моя шпаргалка)

Если возникло желание работать с wordpress в среде VS Соde — давайте сделаем cреду более дружелюбной при помощи плагинов. Во […]