user12660992
user12660992

Reputation: 59

React-slick: Adding animation while sliding

I had created a slider using react slick now there is a requirement to change transition and animation of slides on prev and next button click. Got some help that add class to currently active slide while changing slide and add animation and transition effect to it. And remove after it slides completely changed. I tried but it is not working as expecting. First it is not adding classe on next or prev button button click Second it is adding class on swiping slide but it disturbs other carousel items Here is my code

  const settings = {
    slidesToShow: 1,
    slidesToScroll: 1,
    arrows: false,
    autoplay: false,
    autoplaySpeed: 2000,
    infinite: false,
    beforeChange,
    afterChange,
    useCSS: false,
    useTransform : false
  }

  const beforeChange = (prev: number, next: number) => {
    let element = document.querySelector('.slick-active');
    element?.classList.add('next-slide-anim');
    setIndex(next);
  };

  const afterChange = (index : number) => {
    let element = document.querySelector('.slick-active');
    element.classList.remove('next-slide-anim')
  };

  const settings = {
    slidesToShow: 1,
    slidesToScroll: 1,
    arrows: false,
    autoplay: false,
    autoplaySpeed: 2000,
    infinite: false,
    beforeChange,
    afterChange,
    useCSS: false,
    useTransform : false
  }

  const next = () => {
    sliderRef.current.slickNext()
  };

  const previous = () => {
    sliderRef.current.slickPrev();
  };

 <div className="home-slider">
            <div className="carousel">
              <Slider {...settings} className="carousel-inner" ref={ref => sliderRef.current = ref}>
                {
                  slides.map((slide: any, index) => (
                    <div className="carousel-item" key={index} ref={ref => carouselRef.current = ref}>
                      <div className="slide-content">
                        {index !== slides.length - 1 &&
                          <>
                            <h3>{slide.username}</h3>
                            <span id="user-icon-link">
                              <Link to="/" target="_blank">
                                <img src="/images/homeScreen/instagram.png" alt="link-icon" width="20" height="20" />{slide.userlink}</Link>
                            </span>
                          </>
                        }
                      </div>
                      <img src={slide.path} alt="Chicago" width="1100" height="500" />
                    </div>
                  ))
                }
              </Slider>
              {((slides.length !== 0) && (index !== slides.length - 1)) &&
                <>
                  {(index !== 0) && <a href="#/" className="carousel-control-prev" onClick={previous}>
                    <img src="/images/homeScreen/skipnewbtn.png" alt="Los Angeles" />
                  </a>}
                  {index !== slides.length - 1 && <a href="#/" className="carousel-control-next" id="next-btn" onClick={next}  >
                    <img src="/images/homeScreen/fast-forward-button.gif" alt="Los Angeles" />
                  </a>}
                </>
              }
            </div>
          </div>

Upvotes: 1

Views: 8734

Answers (2)

Anselme C.
Anselme C.

Reputation: 1

Response of Ed is good, but need one more trick !

beforeChange is triggerd before react-slick add his internal classes like "current-slide", so next-slide-anim is override and animation don't show up...

To correct this we need to call a Timeout function to trigger code on next tick.

const beforeChange = (prev: number, next: number) => {
  const prevSlideElement = slider.current.innerSlider.list.querySelector(`[data-index="${prev}"]`);
  const nextSlideElement = slider.current.innerSlider.list.querySelector(`[data-index="${next}"]`);
  setTimeout(() => {
    prevSlideElement.classList.remove('next-slide-anim');
    nextSlideElement.classList.add('next-slide-anim');
  });
}

Upvotes: 0

Ed Lucas
Ed Lucas

Reputation: 7305

Instead of using .slick-active, you can get the slide elements in your beforeChange by using the index values passed to the function and then add/remove the classes from the appropriate slides. Without seeing your CSS, I'm guessing that you want to add your animation in the beforeChange, but if it works out better, you could always move the classList.add() to your afterChange.

const beforeChange = (prev: number, next: number) => {
  const prevSlideElement = slider.current.innerSlider.list.querySelector(`[data-index="${prev}"]`);
  const nextSlideElement = slider.current.innerSlider.list.querySelector(`[data-index="${next}"]`);

  prevSlideElement.classList.remove('next-slide-anim');
  nextSlideElement.classList.add('next-slide-anim');
}

Upvotes: 0

Related Questions