
Зайдя на сайт Cyberpunk 2077 в раздел новостей, я наткнулся на "тот самый" эффект. Он появлялся при наведении на изображение поста. Мне показалось это интересным и я решил посмотреть как это работает. В этом посте я хотел бы поделиться тем, что нарыл.
Для достижения этого эффекта, нам необходимо 2 раза вывести изображение, наложив их друг на друга. Сам эффект будет проявляться на изображении, которое лежит сверху.
Итак, создаем контейнер с двумя изображениями. Сами изображения будут добавлены как фон.
<div class="container"> <div class="img"></div> <div class="glitch"></div> </div>
Прописываем общие стили для дочерних элементов.
.img, .glitch { display: block; background-image: url('https://images.unsplash.com/photo-1551771685-c367c9127a03?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1000&q=80'); background-repeat: no-repeat; background-size: cover; width: 564px; height: 376px; }
Получаем 2 блока с одинаковым изображением. Далее нам необходимо сделать так, чтобы они лежали друг на друге. Для этого задаем абсолютное позиционирование для второго блока.
.glitch { position: absolute; top: 0; left: 0; right: 0; bottom: 0; } .container { position: relative; }
Отлично. Теперь самое интересное. Мы добавим анимацию при наведении на изображение.
.glitch:hover { -webkit-animation-duration:2s; animation-duration:2s; -webkit-animation-timing-function:linear; animation-timing-function:linear; -webkit-animation-iteration-count:infinite; animation-iteration-count:infinite; -webkit-animation-name:glitch-anim; animation-name:glitch-anim; -webkit-animation-direction:alternate; animation-direction:alternate }
Рассмотрим подробнее каждое свойство:
animation-duration - продолжительность анимации, 2 секунды;
animation-timing-function - используем линейную функцию, чтобы анимация происходила равномерно;
animation-iteration-count - повторяем анимацию бесконечно;
animation-name - идентификатор анимации, ее мы опишем чуть ниже;
animation-direction - направление анимации, при значении alternate анимация идет с начала до конца, а потом обратно.
Осталась последняя деталь - описать саму анимацию. Для этого воспользуемся правилом @keyframes.
Spoiler
@keyframes glitch-anim { 0% { opacity:1; -webkit-transform:translateZ(0); transform:translateZ(0); -webkit-clip-path:polygon(0 2%,100% 2%,100% 5%,0 5%); clip-path:polygon(0 2%,100% 2%,100% 5%,0 5%) } 2% { -webkit-clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%); clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%); -webkit-transform:translate(-5px); transform:translate(-5px) } 6% { -webkit-clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%); clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%); -webkit-transform:translate(5px); transform:translate(5px) } 8% { -webkit-clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%); clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%); -webkit-transform:translate(-5px); transform:translate(-5px) } 9% { -webkit-clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%); clip-path:polygon(0 78%,100% 78%,100% 100%,0 100%); -webkit-transform:translate(0); transform:translate(0) } 10% { -webkit-clip-path:polygon(0 54%,100% 54%,100% 44%,0 44%); clip-path:polygon(0 54%,100% 54%,100% 44%,0 44%); -webkit-transform:translate3d(5px,0,0); transform:translate3d(5px,0,0) } 13% { -webkit-clip-path:polygon(0 54%,100% 54%,100% 44%,0 44%); clip-path:polygon(0 54%,100% 54%,100% 44%,0 44%); -webkit-transform:translateZ(0); transform:translateZ(0) } 13.1% { -webkit-clip-path:polygon(0 0,0 0,0 0,0 0); clip-path:polygon(0 0,0 0,0 0,0 0); -webkit-transform:translate3d(5px,0,0); transform:translate3d(5px,0,0) } 15% { -webkit-clip-path:polygon(0 60%,100% 60%,100% 40%,0 40%); clip-path:polygon(0 60%,100% 60%,100% 40%,0 40%); -webkit-transform:translate3d(5px,0,0); transform:translate3d(5px,0,0) } 20% { -webkit-clip-path:polygon(0 60%,100% 60%,100% 40%,0 40%); clip-path:polygon(0 60%,100% 60%,100% 40%,0 40%); -webkit-transform:translate3d(-5px,0,0); transform:translate3d(-5px,0,0) } 20.1% { -webkit-clip-path:polygon(0 0,0 0,0 0,0 0); clip-path:polygon(0 0,0 0,0 0,0 0); -webkit-transform:translate3d(5px,0,0); transform:translate3d(5px,0,0) } 25% { -webkit-clip-path:polygon(0 85%,100% 85%,100% 40%,0 40%); clip-path:polygon(0 85%,100% 85%,100% 40%,0 40%); -webkit-transform:translate3d(5px,0,0); transform:translate3d(5px,0,0) } 30% { -webkit-clip-path:polygon(0 85%,100% 85%,100% 40%,0 40%); clip-path:polygon(0 85%,100% 85%,100% 40%,0 40%); -webkit-transform:translate3d(-5px,0,0); transform:translate3d(-5px,0,0) } 30.1% { -webkit-clip-path:polygon(0 0,0 0,0 0,0 0); clip-path:polygon(0 0,0 0,0 0,0 0) } 35% { -webkit-clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%); clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%); -webkit-transform:translate(-5px); transform:translate(-5px) } 40% { -webkit-clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%); clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%); -webkit-transform:translate(5px); transform:translate(5px) } 45% { -webkit-clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%); clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%); -webkit-transform:translate(-5px); transform:translate(-5px) } 50% { -webkit-clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%); clip-path:polygon(0 63%,100% 63%,100% 80%,0 80%); -webkit-transform:translate(0); transform:translate(0) } 55% { -webkit-clip-path:polygon(0 10%,100% 10%,100% 0,0 0); clip-path:polygon(0 10%,100% 10%,100% 0,0 0); -webkit-transform:translate3d(5px,0,0); transform:translate3d(5px,0,0) } 60% { -webkit-clip-path:polygon(0 10%,100% 10%,100% 0,0 0); clip-path:polygon(0 10%,100% 10%,100% 0,0 0); -webkit-transform:translateZ(0); transform:translateZ(0); opacity:1 } 60.1% { -webkit-clip-path:polygon(0 0,0 0,0 0,0 0); clip-path:polygon(0 0,0 0,0 0,0 0); opacity:1 } to { -webkit-clip-path:polygon(0 0,0 0,0 0,0 0); clip-path:polygon(0 0,0 0,0 0,0 0); opacity:1 } }
Пояснения к коду.
Анимация разбита на части в процентном соотношении. В каждой части происходят определенные изменения.
С помощью свойства clip-path вырезается полигон из изображения и к нему применяются различные эффекты. Например, transform: translate(-5px) - сдвигает полигон влево и вверх.
Посмотреть что получилось можно по ссылке.
