3

I have a background (cloud) and I want to animate it horizontally. If I start the animation from the left most position then the animtion is smooth but if I start the animation from the center the it becomes abrupt.

I know why is it behaving so but not getting a clue on how to make it smooth.

See the abrupt on when starting from the middle:

.trt-clouds-1 {
  width: 100vw;
  height: 200px;
  background-image: url('https://image.flaticon.com/icons/svg/414/414927.svg');
  background-repeat: no-repeat;
  background-size: 10vw;
  animation: animatedBackground 4s linear infinite;
}

@keyframes animatedBackground {
  from {
    background-position: 30vw 0;
  }
  to {
    background-position: 100vw 0;
  }
}
<div class="trt-clouds-1"></div>

Ideally, it should start from the center, then should go to the rightmost point and then should come out from the leftmost point and continue to reach to the center.

void
  • 36,090
  • 8
  • 62
  • 107

3 Answers3

2

Solution 1: Not amazing

By your definition of "smooth" (i.e., going out the right and coming out the left), you can add additional breakpoints. Just make sure to set the percentage timings correct so that it is travelling the same speed before and after reaching the right edge.

If you make the jump between right edge and left edge fast enough, it should show smoothly.

body, html {
  overflow: hidden;
}

.trt-clouds-1 {
  width: 100vw;
  height: 200px;
  background-image: url('https://image.flaticon.com/icons/svg/414/414927.svg');
  background-repeat: no-repeat;
  background-size: 10vw;
  animation: animatedBackground 4s linear infinite;
}

@keyframes animatedBackground {
  0% {
    background-position: 30vw 0;
  }
  63.6% {
    background-position: 100vw 0;
  }
  63.6000001% {
    background-position: -10vw 0;
  }
  100% {
    background-position: 30vw 0;
  }
}
<div class="trt-clouds-1"></div>

(The animation travels 110vw total: 70 to the right, and 40 on the way back. To make it smooth, the animation spends 7/11 (63.6%) of the way going there, and the rest coming back, hence the timings.)


Solution 2: Pretty elegant

A second, more elegant option would be to use the animation-delay property with a negative start value. (This doesn't start at exactly 30vw, but you get the point).

html, body {
  overflow: hidden;
}

.trt-clouds-1 {
  width: 100vw;
  height: 200px;
  background-image: url('https://image.flaticon.com/icons/svg/414/414927.svg');
  background-repeat: no-repeat;
  background-size: 10vw;
  animation: animatedBackground 4s linear infinite;
  animation-delay: -2s;
}

@keyframes animatedBackground {
  0% {
    background-position: -10vw 0;
  }
  100% {
    background-position: 100vw 0;
  }
}
<div class="trt-clouds-1"></div>
Jonathan Lam
  • 16,831
  • 17
  • 68
  • 94
  • @void Your welcome! I think [this CSS property](https://css-tricks.com/starting-css-animations-mid-way/) might also come in handy -- wait a few minutes, and I'll add this to my answer as well if it works. – Jonathan Lam Aug 10 '19 at 05:17
0

html, body {
  overflow: hidden;
}

.trt-clouds-1 {
  width: 100vw;
  height: 200px;
  background-position: 0 0; /* or you can add -10vw 0 for more flexible view on start of load*/
  background-image: url('https://image.flaticon.com/icons/svg/414/414927.svg');
  background-repeat: no-repeat;
  background-size: 10vw;
  animation: animatedBackground 4s linear infinite;
  animation-delay: 0;
}

@keyframes animatedBackground {
  0% {
    background-position:-10vw 0;
  }
  100% {
    background-position: 100vw 0;
  }
}
<div class="trt-clouds-1"></div>

the only thing you have to is add a background position to your css

Ali Qorbani
  • 1,254
  • 8
  • 27
  • This doesn't answer OP's question, which is asking about making a smooth animation *starting from the middle*. (It also looks like you've copied my snippet, changing only the `animation-delay` -- why?) – Jonathan Lam Aug 10 '19 at 17:51
  • What exactly the meaning start smooth from middle? Yes i have copied changed it to that i think is better and easier way – Ali Qorbani Aug 10 '19 at 18:55
  • This sentence in OP's post: "Ideally, it should start from the center, then should go to the rightmost point and then should come out from the leftmost point and continue to reach to the center." He is having trouble starting it from the center. – Jonathan Lam Aug 10 '19 at 18:57
  • I don't know why it should do like that!! – Ali Qorbani Aug 10 '19 at 19:00
0

Another trick is to rely on some percentage and optimize the animation like below.

.trt-clouds-1 {
  height: 200px;
  background-image: url('https://image.flaticon.com/icons/svg/414/414927.svg');
  background-repeat: no-repeat;
  background-size: calc(200% + 10vw) 10vw;
  animation: animatedBackground 4s -2s linear infinite;
}

@keyframes animatedBackground {
  from {
    background-position:top right;
  }
}
<div class="trt-clouds-1"></div>

It will also work even with a non-full width div since we are no more relying on vw unit inside the animation:

.trt-clouds-1 {
  height: 200px;
  width:200px;
  border:1px solid;
  background-image: url('https://image.flaticon.com/icons/svg/414/414927.svg');
  background-repeat: no-repeat;
  background-size: calc(200% + 50px) 50px;
  animation: animatedBackground 4s -2s linear infinite;
}

@keyframes animatedBackground {
  from {
    background-position:top right;
  }
}
<div class="trt-clouds-1"></div>

Related question to get more details about the calculation: Using percentage values with background-position on a linear gradient


You can also consider pseudo element and translation to have better performance:

.trt-clouds-1 {
  height: 200px;
  position:relative;
  overflow:hidden;
}
.trt-clouds-1:before {
  content:"";
  position:absolute;
  top:0;
  left:0;
  width:calc(200% + 10vw);
  height:10vw;
  background-image: url('https://image.flaticon.com/icons/svg/414/414927.svg');
  background-repeat: no-repeat;
  background-size: auto 100%;
  background-position:center;
  animation: animatedBackground 4s -2s linear infinite;
}

@keyframes animatedBackground {
  from {
    transform:translate(-50%);
  }
}
<div class="trt-clouds-1"></div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415