© 2008-2024 г.
Все права защищены
Алексей Костюк

Решено. Спойлер изображения как в Телеграме на CSS+JS

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

Собственно это и есть реализация моего спойлера

Не буду мучать вас писаниной и сразу дам код. Моя HTML структура вывода изображения такая:

<figure class="post__image post__image--center">
    <img loading="lazy" src="image.jpg" height="839" width="1072" alt="" class="is-loaded">
</figure>

Теперь, чтобы сделать спойлер мне нужно добавить класс spoiler к тегу figure, а у вас это может быть div или что-то другое и получаю такой код:

<figure class="spoiler post__image post__image--center">
    <img loading="lazy" src="image.jpg" height="839" width="1072" alt="" class="is-loaded">
</figure>

JS обработка

Скрипт мне нужен для того, чтобы:

  1. Добавить перед изображением блок blur-block, чтобы он мылил изображение.
  2. После изображения добавить блок dots с точками, которые я буду анимировать на CSS.
  3. Обработка клика при нажатии на изображение, чтобы скрывать спойлер.
document.addEventListener('DOMContentLoaded', () => {
    document.querySelectorAll('.spoiler').forEach(spoiler => {
        // Создаём блок блюра
        const blurBlock = document.createElement('div');
        blurBlock.classList.add('blur-block');
        spoiler.appendChild(blurBlock);

        // Создаём контейнер для точек
        const dotsContainer = document.createElement('div');
        dotsContainer.classList.add('dots');
        spoiler.appendChild(dotsContainer);

        // Генерируем точки
        const numberOfDots = 350; // Количество точек
        const fragment = document.createDocumentFragment(); // Для оптимизации

        for (let i = 0; i < numberOfDots; i++) {
            const dot = document.createElement('div');
            dot.classList.add('dot');

            // Задаём случайное начальное положение точки
            dot.style.top = `${Math.random() * 100}%`;
            dot.style.left = `${Math.random() * 100}%`;

            // Случайное смещение по времени для анимации
            dot.style.animationDelay = `${Math.random() * 10}s`;

            fragment.appendChild(dot);
        }
        dotsContainer.appendChild(fragment);

        // Добавляем обработчик клика
        spoiler.addEventListener('click', () => {
            blurBlock.style.opacity = '0'; // Скрываем блюр
            dotsContainer.style.opacity = '0'; // Скрываем точки

            // Убираем блоки из потока после завершения анимации
            setTimeout(() => {
                blurBlock.style.display = 'none';
                dotsContainer.style.display = 'none';
            }, 300); // 300 мс — время исчезновения
        });
    });
});

Скрипт я снабдил комментариями, какой код за что отвечает. Как подключить скрипт JS надеюсь вы знаете.

В этой строке вы можете задать количество анимированных точек на спойлере:

 const numberOfDots = 350;

CSS оформление спойлера

.spoiler {
    position: relative;
    cursor: pointer;
    overflow: hidden;
}

.spoiler img {
    position: relative;
    z-index: 1;
    display: block;
}

.spoiler .blur-block {
    position: absolute;
    inset: 0;
    z-index: 2;
    background: rgb(0 0 0 / 53%);
    backdrop-filter: blur(35px) brightness(1.1);
    transition: opacity .3s ease;
    border-radius: 20px;
    overflow: hidden;
}
.spoiler .dots {
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
}
.spoiler .dot {
    position: absolute;
    width: 2px;
    height: 2px;
    background: white;
    opacity: 0.8;
    border-radius: 50%;
    animation: move-dot 10s infinite ease-in-out;
}

@keyframes move-dot {
    0% {
        transform: translate(0, 0);
    }
    25% {
        transform: translate(50px, -30px);
    }
    50% {
        transform: translate(-20px, 50px);
    }
    75% {
        transform: translate(-30px, -20px);
    }
    100% {
        transform: translate(0, 0);
    }
}

Свойство @keyframes move-dot  отвечает за анимацию точек внутри спойлера. Вы можете скорректировать его по своему вкусу или оставить как есть.

Ну вот и все на сегодня. Удачных вам проектов.

Привет Username! Я Алексей Костюк
14 лет занимаюсь тем, что помогаю людям создавать сайты и дизайн, настраивать рекламу, продвигать проекты в Интернете. Я создал этот блог, чтобы делиться своим опытом и мыслями, а если вы хотите, то можете меня поддержать, это поможет мне создавать больше полезных статей для вас.

Похожие посты

Решено. Слайдер Swiper не прокручивает слайды если количество в slidesPerView равно количеству слайдов

Столкнулся с одним багом, а может это так задумал разработчик Swiper Slider, что если количество слайдов равно количеству указанных для показа в параметре slidesPerView, то…