Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not getting proper index for infinite=true #407

Open
Richa-rani02 opened this issue Sep 14, 2023 · 4 comments
Open

Not getting proper index for infinite=true #407

Richa-rani02 opened this issue Sep 14, 2023 · 4 comments

Comments

@Richa-rani02
Copy link

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/

@da8ah
Copy link

da8ah commented Sep 27, 2023

I'm wondering the same. I need to get the index of the current element after arrows are clicked with infinite & centerMode true.

@da8ah
Copy link

da8ah commented Sep 29, 2023

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!

@CMCDragonkai
Copy link

Can this get fixed upstream?

@ohenriqueroos
Copy link

@da8ah your solution worked perfectly for me! Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants