Going to the Cyberpunk 2077 website in the news section , I came across the "same" effect. It appeared when hovering over the post image. I found it interesting and I decided to see how it works. In this post, I would like to share what I found.
To achieve this effect, we need to display the image 2 times, superimposing them on top of each other. The effect itself will appear in the image that lies on top.
, . .
<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 - the direction of the animation; if the alternate value is set, the animation goes from beginning to end, and then back.
The last detail remains - to describe the animation itself. For this, we will use the rule @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
}
}
Explanations for the code.
The animation is split into parts by percentage. Certain changes take place in each part.
The property clip-path
cuts a polygon from the image and applies various effects to it. For example, transform: translate(-5px)
- shifts the polygon to the left and up.
You can see what happened here .