I have a carousel where an arbitrary number of images can be shown.
It currently looks like below, where the problem is that the amount carousel indicators quickly gets out of hand.
I want to try to do something similar to how Airbnb has it, where it only shows a maximum of 5 dots at any given time. I found an example of an implementation of this on codesandbox, but I'm using Blazor and not React, making it kind of hard to directly translate it.
To show what I'm talking about, their carousel looks like this
My current implementation in Blazor looks like his
<span >
@for (int i = 0; i < Imgs.Count; i )
{
<span class='progress-dot @( currentImage == i ? "active" : "")'></span>
}
</span>
where currentImage
is just tracking the index of the active image. This just couples with some simple css to show which one is active.
.progress-dots {
position: absolute;
bottom: 5px;
left: 5px;
right: 5px;
display: flex;
justify-content: center;
span.progress-dot {
width: 0.45rem;
height: 0.45rem;
border-radius: 50%;
background: rgba(174, 174, 174, 0.453);
margin: 0.2rem 0.15rem;
&.active {
background: #FFF;
}
}
}
Here is a Blazor repl with a stripped down version of my own implementation to test how it works.
CodePudding user response:
You want to take into account the edge cases. The solution I am giving can probably be improved or cleaner, I just focused on a working example.
<div >
<span >
@{
int imgIncMin = 0;
int imgIncMax = Imgs.Count;
int dotsDisplayed = DotsDisplayedAround * 2 1;
if(Imgs.Count > dotsDisplayed){
if(currentImage < DotsDisplayedAround){
imgIncMin = 0;
imgIncMax = dotsDisplayed;
}
else if(currentImage DotsDisplayedAround >= Imgs.Count){
imgIncMin = Imgs.Count - dotsDisplayed;
imgIncMax = Imgs.Count;
}
else{
imgIncMin = currentImage - DotsDisplayedAround;
imgIncMax = currentImage DotsDisplayedAround 1;
}
}
}
@for (int i = imgIncMin; i < imgIncMax; i )
{
<span class='progress-dot @( currentImage == i ? "active" : "")'></span>
}
</span>
</div>
<div @onclick='() => { currentImage = currentImage - 1 >= 0 ? currentImage - 1 : Imgs.Count - 1 ; }'>Previous</div>
<div @onclick='() => { currentImage = (currentImage 1) % Imgs.Count; }'>Next</div>
@code {
const int DotsDisplayedAround = 2;
int currentImage = 0;
List<string> Imgs = new List<string>() { "", "", "", "", "", "", ""};
}