Infinite sideways scroll animation of images

Viewed 1158

I'm trying to animate back and forth (or infinite scroll to the right) a bunch of images but I'm facing an issue in which when the animation starts (and when it reverses) the images are hidden outside of view.

That's because I'm using translate(-100%).

If possible, I would like to not depend of knowing the image size or limiting the viewport size to make this work.

(Ignore the speed of the animation, I'm going to set to a longer duration later)

 .slideshow {
  height: 150px;
  /*max-width: 800px;*/ /*The width of the page cannot be a problem*/
  margin: 0 auto;
  position: relative;
  overflow: hidden;
  transform: translate3d(0, 0, 0);
}

.slideshow > div {
  height: 150px;
  width: 2000px; /*I don't want to have to input a width.*/
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  transform: translate3d(0, 0, 0);
}

.move > img {
  height: 150px;
}

.slideshow .move {
animation: moveSlideshow 10s linear infinite alternate-reverse;
}

.slideshow .move:hover {
-webkit-animation-play-state: paused;
-moz-animation-play-state: paused;
-o-animation-play-state: paused;
animation-play-state: paused;
}

@keyframes moveSlideshow {
  0% {
transform: translateX(0%); 
  }
  100% { 
transform: translateX(-100%);  /*The width of the page needs to be taken into consideration*/
  }
}
<div class="slideshow">
  <div class="move">
 <img src="https://via.placeholder.com/300x150">
 <img src="https://via.placeholder.com/300x150">
 <img src="https://via.placeholder.com/300x150">
 <img src="https://via.placeholder.com/300x150">
 <img src="https://via.placeholder.com/300x150">
 <img src="https://via.placeholder.com/300x150">
  </div>
</div>
I also tried to use: transform: translateX(100%) translateX(-50px);, but it does not work.

My first goal was to make an infinite scroller, when the animation reaches the end, it should start again, but without being noticeable (smooth restart, end image needs to be followed by the start image).

If I'm unable to do that, I would like to have a back and forth animation, but starting with the last image touching the right edge of the viewport. (With the code above, the animation starts with the images to the left)

How can I fix this animation? (To enable infinite smooth scrolling or to not disappear from the view)

Edit:

I managed to make it work with the animation back and forth, by using these keyframes:

@keyframes moveSlideshow {
  0% {
    transform: translateX(0%); 
  }
  100% { 
    -ms-transform: translateX(-100%) translateX(100vw); 
    transform: translateX(calc(-100% + 100vw));  
  }
}

Now, the last image starts at the right and the first image ends at the left. The only problem is that the speed in which the animation plays changes when the viewport width changes.

1 Answers

To make the scroll continous and infinite you need to duplicate your images.

Then it's easy to achieve what you want:

Note: In the initial state, the first move element is displayed , aligned to the left. The second move element is to the right of this, and not visible because it's out of the container.

We will move both of them 100% to the left. The first one will get out of sight thru the left, and in some moment will leave a blank to the right. But the second one is moving at the same speed, so will fill the blank that the first leaves.

The animation ends when the second one has moved 100%,so it is displayed at the same place that was the first one. Now the animation starts again, and the first one is displayed instead, but you won't notce this change.

.slideshow {
  height: 150px;
  margin: 0 auto;
  position: relative;
  transform: translate3d(0, 0, 0);
  display: flex;
  width: 100%;
  overflow: hidden;
  background-color: blue;
}

.move {
  height: 100%;
  transform: translate3d(0, 0, 0);
  display: flex;
  animation: moveSlideshow 10s linear infinite;
}

.move:nth-child(2) img {
  opacity: 0.4;

}
.move > img {
  height: 150px;
  width: auto;
}


.slideshow:hover .move {
  animation-play-state: paused;
}

@keyframes moveSlideshow {
  0% {
    transform: translateX(0%);
  }
  100% {
    transform: translateX(-100%);
    /*The width of the page needs to be taken into consideration*/
  }
}
<div class="slideshow">
  <div class="move">
    <img src="https://via.placeholder.com/400x150">
    <img src="https://via.placeholder.com/300x150">
    <img src="https://via.placeholder.com/300x150">
    <img src="https://via.placeholder.com/300x150">
    <img src="https://via.placeholder.com/300x150">
    <img src="https://via.placeholder.com/200x150">
  </div>
  <div class="move">
    <img src="https://via.placeholder.com/400x150">
    <img src="https://via.placeholder.com/300x150">
    <img src="https://via.placeholder.com/300x150">
    <img src="https://via.placeholder.com/300x150">
    <img src="https://via.placeholder.com/300x150">
    <img src="https://via.placeholder.com/200x150">
  </div>
</div>

Related