React 3D Carousel with Swipe effect
Tags: carousel, touch, swipe, react
Published: 2021-03-12 18:40:51

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](https://www.npmjs.com/package/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,
});
```

But fortunately, I found a way to add this feature using [Touch Events](https://developer.mozilla.org/en-US/docs/Web/API/Touch_events). And it is compatible with both android and ios.

First of all, [this](https://codesandbox.io/s/1v96j74484?view=preview) 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](https://stackoverflow.com/questions/2264072/detect-a-finger-swipe-through-javascript-on-the-iphone-and-android).

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

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

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](https://codesandbox.io/s/react-3d-spring-carousel-with-swipe-yvj51?file=/src/example.js).

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.