Hello, this is part one of the series - Implementing infinite mode in a Carousel that rocks by putting your algorithm knowledge into use.
A while back i built a fully customizable Carousel library called react-multi-carousel which you can find on github or the npm registry that supports multiple items and server-side rendering. Everything was working well up to my expectation except for the infinite mode.
The original solution i used for the infinite mode was that
- If we are scrolling at the end of the Carousel, everything gets slided back to the beginning.
- If we are at the beginning of the Carousel, and we keep scrolling backward, everything gets slided back to the end of the Carousel.
You might think this works, but unfortunately there's a lot of improvement that can be done still. When we are sliding back to either the beginning or the end, we get the very ugly sliding effect or animation especially when we have a lot of items in the Carousel to slide through. So my idea was to implement a different type of infinite mode that would allow the next set of items to appear when we are approaching the end or beginning of the Carousel, so that we get the 'never-ending' effects which seems to have the best user experience.
But trust me, implementing such feature that supports multiple items, server-side rendering and allowing the user to drag and swipe multiple items at a time is hard! It took me nearly two weeks to make the feature finally stable. And i wanted to share with you my solution with the following:
- Design a algorithm to pre-clone the first set and last set of items. (The exact number will be discussed later).
- Assemble the clones and our original carousel items together into an array.
- Design a algorithm to detect whether or not the "cloned" elements are visible on the screen and we are happened to be at the end/start of the Carousel.
- If 3rd condition mentioned above is met, we cancel all animation and slide to a suitable position where we would have enough previous and next items to show very quickly at a fast pace so that the users won't even notice such process ever happened to get the "infinite" effect.
- Enable the animation back at the right moment.
The steps above might seem very clear, but the implementation is actually very difficult considering there are too many edge cases in terms of the existing features that we have to support.
- We must render the Carousel items nicely on the server-side. Once we are on the client-side, we need to do the cloning immediately and move our Carousel items to the correct position by canceling the animation. The timing of when the cancel the animation and the so-called correct position must be carefully calculated with our algorithm.
- How many items should we clone? What if we don't have enough items in the Carousel for us to clone? What if there are too many? What if the user wants to slide many items at a time, in this case do we still have the time to cancel the animation and move our carousel items into the right position without the user noticing?
- How do we differentiate if an element is clone or original? If the item is a clone, how can we find the original one which is the couter part? Another algorithm needs to be developed for this as well.
- How do we handle resizing if the user is switching from landscape to portrait, how do we preserve the same position before the switching as the number of Carousel items we are showing will be different?
- We might end up into callback hell as some of the operations are asynchronous and some are even done with the "setTimeout" due to the animation duration !
In part two of this series, we will tackle these problems with code and of course - coffee.
Interested in knowing how i built the Carousel at the first place? Check out my other series here.