Open Richa-rani02 opened 9 months ago
I'm wondering the same. I need to get the index of the current element after arrows are clicked with infinite & centerMode true.
Hi @Richa-rani02, I was able to do a workaround when infinite & centerMode true. It's just a hunch, so I hope I'm not mistaken.
If the carouse it's set to run ltr indexes will go increasily from 3 to the end. Note: If you set rtl it will behave differently. Let's take for example an array of 4 elements [0,1,2,3]
const arr = [0,1,2,3]
Right side (arrow): in the carousel the arr it will start at 3 as 0 index because makes copies of the other elements (2 each side I believe) But we need to set currentSlide - 2 so we can hit the activeSlide with 1 element to the right from the beginning to use centerMode. And then we need to restart with a condition currentSlide - 2 === dataSize (whitout - 1 because de displacement) then equal to 0. // 3,4,5,6 // 1,2,3,0
Left side (arrow): for the left arrow, when it's in reverse, it will start at index 1 then 0 and then it will decrease from the arr last element up to 2. So we need to subtract 2 when currentSlide >= dataSize and <= 2, otherwise we should subtract dataSize - 2. // 1,0,3,2 -> carousel index sequence // 3,2,1,0 -> desired indexes
I made this function that automatically does it for you (changeSlide):
const responsive = {
superLargeDesktop: {
// the naming can be any, depends on you.
breakpoint: { max: 4000, min: 3000 },
items: 1
},
desktop: {
breakpoint: { max: 3000, min: 1024 },
items: 1
},
tablet: {
breakpoint: { max: 1024, min: 464 },
items: 1
},
mobile: {
breakpoint: { max: 464, min: 0 },
items: 1
}
};
const [activeIndex, setActiveIndex] = useState(0)
const images = [
{
src: slide1,
alt: "",
},
{
src: slide2,
alt: "",
},
{
src: slide3,
alt: "",
},
{
src: slide4,
alt: "",
},
]
const changeSlide = (previousSlide: number, currentSlide: number, dataSize: number) => {
let activeSlide = 0
// right arrow
if (previousSlide < currentSlide) activeSlide = currentSlide - 2 === dataSize ? 0 : currentSlide - 2
// left arrow
else activeSlide = currentSlide + (currentSlide <= dataSize && currentSlide >= 2 ? -2 : dataSize - 2);
setActiveIndex(activeSlide)
}
As for the carousel I did this:
<Carousel
infinite
autoPlay
centerMode
responsive={responsive}
className="w-full h-[70%] owl-carousel owl-theme text-center"
itemClass="px-1 flex justify-center"
keyBoardControl={true}
// changeSlide(previousSlide, currentSlide, dataSize = images.length)
afterChange={(previousSlide, { currentSlide }) => changeSlide(previousSlide, currentSlide, images.length)}
>
{images.map((img, i) => (
<div
key={`slide-${i}`}
className={`relative ${activeIndex !== i ? "w-[90%]" : "w-full"} h-full rounded-[10px] flex justify-center items-center bg-transparent shadow-[10px_40px_10px_5px_black]`}
>
{activeIndex !== i ?
<img
className='pointer-events-none object-contain rounded-[10px] opacity-10'
src={img.src}
alt={img.alt}
/>
:
<img
key={`slide-img-${activeIndex}`}
className='object-contain rounded-[10px]'
src={img.src}
alt={img.alt}
/>
}
</div>
)
)}
</Carousel>
I hope this help you and others too!
DESCRIPTION After change returns previousSlide and currentSlide which is working fine in case infinite=false However, when infinite={true} is used, the current index doesn't seem correct
What i am trying to achieve: want to track current index and next Index when arrow icon is clicked
Steps To Reproduce https://codesandbox.io/s/multicarousal-demo-9vzw96?file=/src/App.js
Hosted Application https://9vzw96.csb.app/