react-elastic-carousel icon indicating copy to clipboard operation
react-elastic-carousel copied to clipboard

Infinite looping of children

Open oyeanuj opened this issue 5 years ago • 29 comments

Hi @sag1v, thank you for creating this library!

Describe the solution you'd like I'd love to be able to loop through to the first item, if I click on "next" from the last item, so creating an infinite loop of the children.

Describe alternatives you've considered Maybe using an event handler to see if this is the last child, in which case onNext can call goTo with the first slide index?

oyeanuj avatar Oct 20 '18 22:10 oyeanuj

@oyeanuj Thanks. This could be a great addition to react-elastic-carousel indeed!

Maybe using an event handler to see if this is the last child, in which case onNext can call goTo with the first slide index?

This is a relatively easy thing to do, however I think with this approach we will get a "backwards" animation and it won't feel like an infinite loop.

rca loop

I think we should add copies or move slides to the next / prev positions to make it look infinite. Of course we would need to consider all edge cases like 1 visible item vs 12 visible items for example.

Anyway PR's are more than welcome, so feel free to hop in. :wave:

sag1v avatar Oct 20 '18 22:10 sag1v

How to enable infinite loop property?

PriyaJainDev avatar Jun 20 '20 19:06 PriyaJainDev

@sag1v How to enable infinite loop ? Is there any demo?

Is this pull request added? https://github.com/sag1v/react-elastic-carousel/pull/17

Anu-Ujin avatar Sep 21 '20 04:09 Anu-Ujin

@Anu-Ujin #17 was not added, you can read my comment about it.

I am working on this feature these days (finally got some time to do it). I hope i can make it happen by the end of this month or next.

sag1v avatar Sep 21 '20 07:09 sag1v

Not sure if it worth it (since @sag1v is already working on this feature) but for now I got it working with a bit of logic:

const itemsPerPage = 3
const items = [...]
const carouselRef = useRef(null);
const totalPages = Math.ceil(items.length / itemsPerPage)
let resetTimeout;

<Carousel
    ref={carouselRef}
    enableAutoPlay
    autoPlaySpeed={1500} // same time
    onNextEnd={({ index }) => {
         clearTimeout(resetTimeout)
         if (index + 1 === totalPages) {
            resetTimeout = setTimeout(() => {
               carouselRef.current.goTo(0)
           }, 1500) // same time
         }
    }}
    itemsToShow={itemsPerPage}
>
{items.map(() => ...)}
</Carousel>

This still doesn't feel like an infinite loop, is more like a "backwards" animation

christo-pr avatar Oct 09 '20 14:10 christo-pr

@christo-pr Not sure why you had to use the timer, but you are right in that it feels like going backwards.

I mentioned this in my comment above https://github.com/sag1v/react-elastic-carousel/issues/9#issuecomment-431623497

sag1v avatar Oct 09 '20 15:10 sag1v

The timer is just to mimic the autoPlaySpeed that's why I mention it in my example, looking forward to use the inifite prop.

Thanks for the work!

christo-pr avatar Oct 09 '20 15:10 christo-pr

Hello, how's the infinite scroll feature coming up? A lot of us would appreciate it if you added the feature to the official package. thanks and more power :)

pacholoamit avatar Oct 17 '20 15:10 pacholoamit

bump ^ :)

alienbuild avatar Feb 06 '21 20:02 alienbuild

Not sure if it worth it (since @sag1v is already working on this feature) but for now I got it working with a bit of logic:

const itemsPerPage = 3
const items = [...]
const carouselRef = useRef(null);
const totalPages = Math.ceil(items.length / itemsPerPage)
let resetTimeout;

<Carousel
    ref={carouselRef}
    enableAutoPlay
    autoPlaySpeed={1500} // same time
    onNextEnd={({ index }) => {
         clearTimeout(resetTimeout)
         if (index + 1 === totalPages) {
            resetTimeout = setTimeout(() => {
               carouselRef.current.goTo(0)
           }, 1500) // same time
         }
    }}
    itemsToShow={itemsPerPage}
>
{items.map(() => ...)}
</Carousel>

This still doesn't feel like an infinite loop, is more like a "backwards" animation

Root change and give me error, TypeError: Cannot read property 'goTo' of null

Mamasakhlisi avatar Mar 01 '21 09:03 Mamasakhlisi

Yeah, well this year was brutal for me (time wise) and i didn't have much time to work on that feature as i thought i would. When i had time, I preferred to invest it on critical bugs an issues.

Gonna try free some time this month

sag1v avatar Mar 03 '21 13:03 sag1v

how to enable loop in react elastic carousel does anyone know about it?

Ramishscrapper avatar Mar 08 '21 18:03 Ramishscrapper

Can't wait the infinite :)

Julienblc avatar Mar 30 '21 08:03 Julienblc

Not sure if it worth it (since @sag1v is already working on this feature) but for now I got it working with a bit of logic:

const itemsPerPage = 3
const items = [...]
const carouselRef = useRef(null);
const totalPages = Math.ceil(items.length / itemsPerPage)
let resetTimeout;

<Carousel
    ref={carouselRef}
    enableAutoPlay
    autoPlaySpeed={1500} // same time
    onNextEnd={({ index }) => {
         clearTimeout(resetTimeout)
         if (index + 1 === totalPages) {
            resetTimeout = setTimeout(() => {
               carouselRef.current.goTo(0)
           }, 1500) // same time
         }
    }}
    itemsToShow={itemsPerPage}
>
{items.map(() => ...)}
</Carousel>

This still doesn't feel like an infinite loop, is more like a "backwards" animation

Root change and give me error, TypeError: Cannot read property 'goTo' of null

What if i have custom breakpoints for responsive for example i have these breakpoints and iteamstoshow


 const breakPoints = [
    { width: 1, itemsToShow: 1 },
    { width: 550, itemsToShow: 2, itemsToScroll: 2, pagination: false },
    { width: 850, itemsToShow: 3 },
    { width: 1150, itemsToShow: 4, itemsToScroll: 2 },
    { width: 1450, itemsToShow: 5 },
    { width: 1750, itemsToShow: 6 },
  ];

What will i do in this situation

sulmanazhar2 avatar Mar 31 '21 11:03 sulmanazhar2

I do like @sag1v and it work 👍

const carouselRef = React.useRef(null);
const onNextStart = (currentItem, nextItem) => {
  if (currentItem.index === nextItem.index) {
    // we hit the last item, go to first item
    carouselRef.current.goTo(0);
  }
};
const onPrevStart = (currentItem, nextItem) => {
  if (currentItem.index === nextItem.index) {
    // we hit the first item, go to last item
    carouselRef.current.goTo(universities.length);
  }
};
<Carousel
  className='carousel-university'
  breakPoints={breakPoints}
  ref={carouselRef}
  onPrevStart={onPrevStart}
  onNextStart={onNextStart}
  disableArrowsOnEnd={false}
>

It's work good when I click the button prev or next but when I use MOUSE SWIPE next at the last item it's go to the second item not first item (itemsToShow is 1)

liemhoanglong avatar Apr 07 '21 03:04 liemhoanglong

Any update on this? Thank you!

aamin21 avatar Jul 09 '21 15:07 aamin21

Any update on this?

aks998 avatar Oct 11 '21 11:10 aks998

Hi @sag1v thanks for the great carousel slider! It's 2022 now and we're still waiting for infinite loop!

Thanks!

zhkvivan avatar Jan 27 '22 14:01 zhkvivan

try this it's working for me

    const carouselRef = useRef(null);

<Carousel
    ref={carouselRef}
    enableAutoPlay={isAutoSwipe}
    showArrows={false}
    itemPadding={[0, 20]}
    outerSpacing={60}
    autoPlaySpeed={3000}
    itemsToShow={itemsPerPage}
    onNextEnd={({ index }) => {
        clearTimeout(resetTimeout)
        if (index + 1 === totalPages) {
            if (carouselRef?.current?.goTo) {
                resetTimeout = setTimeout(() => {
                    if (carouselRef?.current?.goTo) {
                        carouselRef.current.goTo(0)
                    }
                }, 3000)
            }
        }
    }}
>

SaGaR1084 avatar Feb 01 '22 10:02 SaGaR1084

Hi, @sag1v thanks for the great carousel slider! we're waiting for an infinite loop.

Thanks!

krishna-truepill avatar Feb 22 '22 15:02 krishna-truepill

Hi @sag1v still waiting on the infinite loop.

Thanks!

TorsuD avatar Jun 11 '22 02:06 TorsuD

Solution:

    const carouselRef = useRef(null);
    let resetTimeout;
    
    return(

 <Carousel
                    ref={carouselRef}
                    pagination={false}
                    enableAutoPlay={true}
                    showArrows={false}
                    autoPlaySpeed={4000}
                    isRTL={false}
                    onNextEnd={({ index }) => {
                        clearTimeout(resetTimeout);
                        resetTimeout = setTimeout(() => {
                            carouselRef?.current?.goTo(0);
                        }, 4000); // same time
                    }}
                    >
                    
                    {....}
                    
                    </carrousel>


);

criscar1998 avatar Jun 28 '22 16:06 criscar1998

Thanks a lot @criscar1998 , worked for me!

amanzrx4 avatar Aug 04 '22 08:08 amanzrx4

I did this to create a infinite loop effect (NOTE: I works only with arrow button, with auto play it stops at last slide)

// replace infinite array with your array name // //infinite array is a state I create which store my array ( since my array comes from API)

const carouselRef = React.useRef(null);

const onNextStart = (currentItem, nextItem) => { if (currentItem.index === nextItem.index) { // carouselRef.current.goTo(0); const newArray = [...infiniteArray]; newArray.push(newArray.shift()); setInfiniteArray(newArray); } }; const onPrevStart = (currentItem, nextItem) => { if (currentItem.index === nextItem.index) { const newArray = [...infiniteArray]; newArray.unshift(newArray.pop()); setInfiniteArray(newArray); } };

<Carousel breakPoints={breakPoints} // enableAutoPlay // autoPlaySpeed={5000} infiniteLoop={true} renderArrow={myArrow} className='carouselMain' dots={true} ref={carouselRef} onPrevStart={onPrevStart} onNextStart={onNextStart} >

LET ME KNOW IF YOU CAN MAKE IT WORK WITH AUTOPLAY WITH THIS REFERENCE... UPVOTE IF IT HELPS YOU..

thediveshsharma avatar Aug 16 '22 06:08 thediveshsharma

Best Solution:

const carouselRef = React.useRef(null);
let resetTimeout;
<Carousel
        ref={carouselRef}
        breakPoints={breakPoints}
        showArrows={false}
        className="cursor-pointer"
        enableAutoPlay
        autoPlaySpeed={2000}
        itemPadding={[0, 20]}
        isRTL={false}
        onNextEnd={({ index }) => {
          if (
            carouselRef?.current.state.activePage ===
            carouselRef?.current.state.pages.length - 1
          ) {
            const itemsPerPage = Math.floor(
              carouselRef?.current.props.children.length /
                carouselRef?.current.getNumOfPages()
            );

            if (itemsPerPage === carouselRef?.current.state.activeIndex) {
              clearTimeout(resetTimeout);
              resetTimeout = setTimeout(() => {
                carouselRef?.current?.goTo(0);
              }, 2000); // same time
            }
          }
        }}
      >

psuriya2020 avatar Aug 21 '22 06:08 psuriya2020

This solution is worked for me:

const carouselRef = React.useRef(null); // declare at state level
let resetTimeout; //decalre at state level
<Carousel
                ref={carouselRef}
                enableMouseSwipe={true} itemsToShow={1} renderArrow={myArrow}
                pagination={false} renderPagination={myPagination}
                enableAutoPlay={true}
                autoPlaySpeed={1000}
                onNextEnd={({ index }) => {
                  console.log("index",index,banners.length)
                  if(index===banners.length-1){
                    clearTimeout(resetTimeout);
                    resetTimeout = setTimeout(() => {
                      carouselRef?.current?.goTo(0);
                    }, 1000); // same time
                  } 
                }}
              >
                {banners.map((b, index) => (
                  <Slide key={`banerssss-${index}`} b={b} />

                ))}
    </Carousel>
 

chrehman avatar Sep 23 '22 10:09 chrehman

Hey Sagiv did u create a loop function already?

talist225 avatar Mar 09 '23 11:03 talist225

Sagiv did u create infinite function? because when we import elastic dynnamically in next js that gotTo(0) function not working

Fahad98723 avatar May 06 '23 07:05 Fahad98723

Perfect Solution ✅: const carouselRef = useRef(null); let resetTimeout;

<Carousel breakPoints={breakpoint} loop={true}
easing="cubic-bezier(1,.15,.55,1.54)" tiltEasing="cubic-bezier(0.110, 1, 1.000, 0.210)" transitionMs={1000}

ref={carouselRef}
pagination={true}
enableAutoPlay={true}
showArrows={true}
autoPlaySpeed={4000}
isRTL={false}
onNextEnd={({ index }) => {
    clearTimeout(resetTimeout);
    resetTimeout = setTimeout(() => {
        carouselRef?.current?.goTo(0);
    }, 4000); // same time
}}

>

kant146 avatar Sep 27 '23 20:09 kant146