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

Autoplay not infinite loop and the manual loop does not match the position #214

Closed senapahlevi closed 2 years ago

senapahlevi commented 3 years ago

hello I'm a newbie maybe this is a bug or my mistake. Can experts maybe help me? , I tried autoplay successfully but when in the last position it didn't experience an infinite loop, and also managed to apply the loop manually it worked, while when I slide to the initial position it should jump to the last position but can be seen in the ouput in my results this is not correct, which is at the 10th index should be the correct index 11th (last position)

{ "name": "zz-frontend", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build && next export", "start": "next start" }, "dependencies": { "axios": "^0.21.0", "bootstrap": "^4.5.3", "jquery": "^3.5.1", "next": "10.0.2", "node-sass": "^5.0.0", "nprogress": "^0.2.0", "popper.js": "^1.16.1", "pure-react-carousel": "^1.27.6", "react": "17.0.1", "react-alice-carousel": "^2.5.1", "react-dom": "17.0.1", "react-elastic-carousel": "^0.9.5", "react-hook-form": "^6.11.5", "react-reveal": "^1.2.2", "react-select": "^3.1.1", "react-slick": "^0.27.13", "react-toastify": "^6.1.0", "slick-carousel": "^1.8.1", "styled-components": "^5.2.1", "swiper": "^6.6.0" }


  const partnerships = [
  {
    company: "/images/partner/1.png"
  },
  {
    company: "/images/partner/2.png"
  },
  {
    company: "/images/partner/3.png"
  },
  {
    company: "/images/partner/4.png"
  },
  {
    company: "/images/partner/5.png"
  },
  {
    company: "/images/partner/6.png"
  },
  {
    company: "/images/partner/7.png"
  },
  {
    company: "/images/partner/8.png"
  },
  {
    company: "/images/partner/9.png"
  },
  {
    company: "/images/partner/10.png"
  },
  {
    company: "/images/partner/11.png"
  }
];

function App() {
  let carouselRef = 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(partnerships.length);
    }
  };

  return (
    <div className="App">
      <hr className="seperator" />
      <div className="carousel-wrapper">
        <Carousel
          ref={carouselRef}
          enableAutoPlay
          autoPlaySpeed={1000}
          itemsToShow={1}
          onPrevStart={onPrevStart}
          onNextStart={onNextStart}
        >
          {partnerships.map((item, i) => {
            return (
              <div className="col-md-12" key={i}>
                <img src={item.company} alt="company" />
              </div>
            );
          })}
        </Carousel>
      </div>
    </div>
  );
}

I have also followed the reference from here https://github.com/sag1v/react-elastic-carousel/issues/9#issuecomment-814577856

here my output output file

IuriiSol commented 3 years ago

Hey, I'm noob too, but I have solved my problem with setInterval, and it works perfect on my project. You can try it too. const Data = [];

const getData = () => { users.map((user) => { if(user.isPromoted == true){ Data.push(user); } }) } getData();

const carouselRef = React.useRef(null); const onNextStart = (currentItem, nextItem) => { if (currentItem.index === nextItem.index) { carouselRef.current.goTo(0); } }; const onPrevStart = (currentItem, nextItem) => { if (currentItem.index === nextItem.index) { carouselRef.current.goTo(Data.length); } };

const Loop = (currentItem) => { if (currentItem.index == Data.length - 1) { setTimeout(() => { carouselRef.current.goTo(0); }, 1500); } };

then just add it like here:

      <Carousel
        onChange={Loop}
        ref={carouselRef}
        onPrevStart={onPrevStart}
        onNextStart={onNextStart}
        disableArrowsOnEnd={false}
        enableAutoPlay autoPlaySpeed={4500}
        itemPadding={[0, 5]}
        className={classes.carousel}
      >
ehubbell commented 2 years ago

@IuriiSol solution worked for me however the loop method causes some funky behavior if you don't disable the nextButton on the final slide. Seems related to the `Loop' function not canceling if the user clicks next from the final slide (which should take them to the first slide).

Definitely fixable but worth noting.

tannguyencse19 commented 2 years ago

You can do like this

const onNextStart = (currentItem, nextItem) => {
    if (nextItem.index === partnerships.length - 1) { // we hit the last item, go to first item
      setTimeout(() => {
        carouselRef.current.goTo(0);
      }, 1000); // 1000 = Your autoPlaySpeed declare in Carousel's prop
    }
  };
stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.