DEV Community

loading...

React 3D Carousel with Swipe effect

Nouran Samy
・2 min read

Hello everyone. I've been working on a react project that needed to add a feature of a 3D carousel.

The package that i used was react-spring-3d-carousel. Everything was going great with the minimum requirements except for the drag or swipe effect of any slider or a normal carousel.

P.S, If you're using NextJS you will need to import the library as follows as it uses window object which is not defined in SSR

import dynamic from "next/dynamic";

const Carousel = dynamic(() => import("react-spring-3d-carousel"), {
  ssr: false,
});
Enter fullscreen mode Exit fullscreen mode

But fortunately, I found a way to add this feature using Touch Events. And it is compatible with both android and ios.

First of all, this is the demo for react 3d carousel package that i used.

For the swipe effect, i used the answer i found on this stackoverflow question here.

All you have to do is add onTouchStart and onTouchMove events listeners to the div surrounding the carousel.

<div
   style={{ width: "80%", height: "500px", margin: "0 auto" }}
   onTouchStart={handleTouchStart}
   onTouchMove={handleTouchMove}
 >
      <Carousel
        slides={slides}
        goToSlide={state.goToSlide}
        offsetRadius={state.offsetRadius}
        showNavigation={state.showNavigation}
        animationConfig={state.config}
      />
</div>
Enter fullscreen mode Exit fullscreen mode

And the functions used to detect the swipe direction are as follows:

  let xDown = null;
  let yDown = null;

  const getTouches = (evt) => {
    return (
      evt.touches || evt.originalEvent.touches // browser API
    ); // jQuery
  };

  const handleTouchStart = (evt) => {
    const firstTouch = getTouches(evt)[0];
    xDown = firstTouch.clientX;
    yDown = firstTouch.clientY;
  };

  const handleTouchMove = (evt) => {
    if (!xDown || !yDown) {
      return;
    }

    let xUp = evt.touches[0].clientX;
    let yUp = evt.touches[0].clientY;

    let xDiff = xDown - xUp;
    let yDiff = yDown - yUp;

    if (Math.abs(xDiff) > Math.abs(yDiff)) {
      /*most significant*/
      if (xDiff > 0) {
        /* left swipe */
        setState({ goToSlide: state.goToSlide + 1 });
      } else {
        /* right swipe */
        setState({ goToSlide: state.goToSlide - 1 });
      }
    } else {
      if (yDiff > 0) {
        /* up swipe */
      } else {
        /* down swipe */
      }
    }
    /* reset values */
    xDown = null;
    yDown = null;
  };
Enter fullscreen mode Exit fullscreen mode

Simply, handleTouchStart just captures the first touch x and y point and handleTouchMove detects other movements and calculate the direction from the difference between the start and new point.

So to sum up, you can find the new 3d carousel demo code with the swipe effect added to it here.

And of course you can use the touch events on any other element or feature other than a carousel.

Hope it helps someone out. Thanks for your time.

Discussion (0)