Hi I have some image as follows:
which has some animation from left to right then bottom then left to right and so on.
Image dimension
600 X 738
is and no and as number of squire is5x5
. I wrote css as follows to implement requirement:
.cute_angry_steam_coming_out_of_face {
border-radius: 5px;
display: inline-block;
line-height: 52px;
padding: 2px 2px 8px;
position: relative;
text-align: center;
width: 120px;
height: 148px;
animation: cute_happy_smiling_face 0 2s;
animation-iteration-count: infinite;
background-image: url('https://i.sstatic.net/gQIqY.png');
background-repeat: no-repeat;
background-size: 960px 785px;
image-rendering: -webkit-optimize-contrast;
border: 1px solid red;
}
@keyframes cute_happy_smiling_face {
0% {
background-position: 0px 0px;
}
3% {
background-position: 120px 0px;
}
6% {
background-position: 240px 0px;
}
8% {
background-position: 360px 0px;
}
11% {
background-position: 480px 0px;
}
14% {
background-position: 600px 0px;
}
17% {
background-position: 0px 148px;
}
19% {
background-position: 120px 148px;
}
22% {
background-position: 240px 148px;
}
25% {
background-position: 360px 148px;
}
28% {
background-position: 480px 148px;
}
31% {
background-position: 600px 148px;
}
33% {
background-position: 0px 295px;
}
36% {
background-position: 120px 295px;
}
39% {
background-position: 240px 295px;
}
42% {
background-position: 360px 295px;
}
44% {
background-position: 480px 295px;
}
47% {
background-position: 600px 295px;
}
50% {
background-position: 0px 443px;
}
53% {
background-position: 120px 443px;
}
56% {
background-position: 240px 443px;
}
58% {
background-position: 360px 443px;
}
61% {
background-position: 480px 443px;
}
64% {
background-position: 600px 443px;
}
67% {
background-position: 0px 590px;
}
69% {
background-position: 120px 590px;
}
72% {
background-position: 240px 590px;
}
75% {
background-position: 360px 590px;
}
78% {
background-position: 480px 590px;
}
81% {
background-position: 600px 590px;
}
83% {
background-position: 0px 738px;
}
86% {
background-position: 120px 738px;
}
89% {
background-position: 240px 738px;
}
92% {
background-position: 360px 738px;
}
94% {
background-position: 480px 738px;
}
97% {
background-position: 600px 738px;
}
}
<div class="cute_angry_steam_coming_out_of_face"></div>
But it is not animating smoothly till end. What I want with every picture it should hold for a second and position should change to next as fast it can with looping infinitely.
At the end animation will look like following
To make it easier you can consider CSS variables and the trick is to use negative values for the position based on the width height.
You have 5 rows and 5 columns and 22 images so you split the animation into 22 states (100/22 = 4.54
). On each state we increment a variable from 0
to 4
on the x-axis and when we reach 4
we reset to 0
and we increment the y-axis.
You can also easily adjust the dimension by simply changing the CSS variables so you don't need to know the width/height of the image, you only need to know the number of rows and columns
.cute_angry_steam_coming_out_of_face {
border-radius: 5px;
display: inline-block;
border: 1px solid red;
--w:120px;
--h:148px;
width: var(--w);
height: var(--h);
background-image: url('https://i.sstatic.net/gQIqY.png');
background-size: calc(5*var(--w)) calc(5*var(--h));
animation: cute_happy_smiling_face 3s infinite;
}
@keyframes cute_happy_smiling_face {
0%,4.54% {
background-position: calc(0*var(--w)) calc(0*var(--h));
}
4.55%,9.09% {
background-position: calc(-1*var(--w)) calc(0*var(--h));
}
9.10%,13.63% {
background-position: calc(-2*var(--w)) calc(0*var(--h));
}
13.64%,18.18% {
background-position: calc(-3*var(--w)) calc(0*var(--h));
}
18.19%,22.72% {
background-position: calc(-4*var(--w)) calc(0*var(--h));
}
22.73%,27.27% {
background-position: calc(0*var(--w)) calc(-1*var(--h));
}
27.28%,31.81% {
background-position: calc(-1*var(--w)) calc(-1*var(--h));
}
31.82%,36.36% {
background-position: calc(-2*var(--w)) calc(-1*var(--h));
}
36.37%,40.90% {
background-position: calc(-3*var(--w)) calc(-1*var(--h));
}
40.91%,45.45% {
background-position: calc(-4*var(--w)) calc(-1*var(--h));
}
45.46%,50% {
background-position: calc(0*var(--w)) calc(-2*var(--h));
}
50.01%,54.54% {
background-position: calc(-1*var(--w)) calc(-2*var(--h));
}
54.55%,59.09% {
background-position: calc(-2*var(--w)) calc(-2*var(--h));
}
59.10%,63.63% {
background-position: calc(-3*var(--w)) calc(-2*var(--h));
}
63.64%,68.18% {
background-position: calc(-4*var(--w)) calc(-2*var(--h));
}
68.19%,72.72% {
background-position: calc(0*var(--w)) calc(-3*var(--h));
}
72.73%,77.27% {
background-position: calc(-1*var(--w)) calc(-3*var(--h));
}
77.28%,81.81% {
background-position: calc(-2*var(--w)) calc(-3*var(--h));
}
81.82%,86.36% {
background-position: calc(-3*var(--w)) calc(-3*var(--h));
}
86.37%,90.9% {
background-position: calc(-4*var(--w)) calc(-3*var(--h));
}
90.91%,95.45% {
background-position: calc(0*var(--w)) calc(-4*var(--h));
}
95.46%,100% {
background-position: calc(-1*var(--w)) calc(-4*var(--h));
}
}
<div class="cute_angry_steam_coming_out_of_face"></div>
<div class="cute_angry_steam_coming_out_of_face" style="--w:100px;--h:120px"></div>
<div class="cute_angry_steam_coming_out_of_face" style="--w:50px;--h:80px"></div>
Another intresting idea (which I recommend) with less of code is to animate each position alone and use steps()
. This will make the code easier. The only drawback is that you will see the 3 empty slots. This method is perfect if you have exactly 5x5 images (25) and not only 22.
.cute_angry_steam_coming_out_of_face {
border-radius: 5px;
display: inline-block;
border: 1px solid red;
--w:120px;
--h:148px;
width: var(--w);
height: var(--h);
background-image: url('https://i.sstatic.net/gQIqY.png');
background-size: calc(5*var(--w)) calc(5*var(--h));
animation-name: smiling_face-x, smiling_face-y;
animation-duration: 0.5s ,2.5s; /* 2.5 = 5 x 0.5 */
animation-timing-function:steps(5);
animation-iteration-count:infinite;
}
@keyframes smiling_face-x {
100% {
background-position-x: calc(-5*var(--w));
}
}
@keyframes smiling_face-y {
100% {
background-position-y: calc(-5*var(--h));
}
}
<div class="cute_angry_steam_coming_out_of_face"></div>
<div class="cute_angry_steam_coming_out_of_face" style="--w:100px;--h:120px"></div>
<div class="cute_angry_steam_coming_out_of_face" style="--w:50px;--h:80px"></div>
Here is a more generic code consider NxM
image:
.cute_angry_steam_coming_out_of_face {
border-radius: 5px;
display: inline-block;
border: 1px solid red;
--w:120px;
--h:148px;
--n:3; /* number of rows */
--m:5; /* number of columns */
--d:2s; /*duration*/
width: var(--w);
height: var(--h);
background-image: url('https://i.sstatic.net/M2n58.png');
background-size: calc(var(--m)*var(--w)) calc(var(--n)*var(--h));
animation-name: smiling_face-x, smiling_face-y;
animation-duration: calc(var(--d)/var(--n)),var(--d);
animation-timing-function:steps(var(--m)),steps(var(--n));
animation-iteration-count:infinite;
}
@keyframes smiling_face-x {
100% {
background-position-x: calc(-1*var(--m)*var(--w));
}
}
@keyframes smiling_face-y {
100% {
background-position-y: calc(-1*var(--n)*var(--h));
}
}
<div class="cute_angry_steam_coming_out_of_face"></div>
<div class="cute_angry_steam_coming_out_of_face" style="--w:100px;--h:120px"></div>
<div class="cute_angry_steam_coming_out_of_face" style="--w:50px;--h:80px"></div>