sag1v / react-elastic-carousel

A flexible and responsive carousel component for react https://sag1v.github.io/react-elastic-carousel
MIT License
348 stars 149 forks source link

Infinite looping of children #9

Open oyeanuj opened 6 years ago

oyeanuj commented 6 years ago

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?

sag1v commented 6 years ago

@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:

PriyaJainDev commented 4 years ago

How to enable infinite loop property?

Anu-Ujin commented 4 years ago

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

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

sag1v commented 4 years ago

@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.

christo-pr commented 4 years ago

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

sag1v commented 4 years ago

@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

christo-pr commented 4 years ago

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!

pacholoamit commented 4 years ago

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 :)

alienbuild commented 3 years ago

bump ^ :)

Mamasakhlisi commented 3 years ago

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

sag1v commented 3 years ago

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

Ramishscrapper commented 3 years ago

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

Julienblc commented 3 years ago

Can't wait the infinite :)

sulmanazhar2 commented 3 years ago

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

liemhoanglong commented 3 years ago

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)

aamin21 commented 3 years ago

Any update on this? Thank you!

aks998 commented 3 years ago

Any update on this?

zhkvivan commented 2 years ago

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

Thanks!

SaGaR1084 commented 2 years ago

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)
            }
        }
    }}
>
krishna-truepill commented 2 years ago

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

Thanks!

TorsuD commented 2 years ago

Hi @sag1v still waiting on the infinite loop.

Thanks!

criscar1998 commented 2 years ago

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>

);
amanzrx4 commented 2 years ago

Thanks a lot @criscar1998 , worked for me!

thediveshsharma commented 2 years ago

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..

psuriya2020 commented 2 years ago

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
            }
          }
        }}
      >
chrehman commented 2 years ago

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>
talist225 commented 1 year ago

Hey Sagiv did u create a loop function already?

Fahad98723 commented 1 year ago

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

kant146 commented 1 year ago

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
}}

>