[React] horizontal scroling menu 구현하기

바질·2022년 9월 30일
0

react-scrolling

목록 보기
1/2

사용하는 것
react.js, typescript, styled-components, react-horizontal-scroling-menu

리액트에서 horizontal scroling을 구현해보자.

npm i react-horizontal-scrolling-menu

install하고 import 해준다.
다행히 typescript를 사용해서 type을 선언해줄 수 있다. 자세한 건 소스 코드를 보면 된다.

typescript를 사용하지 않는다면 type을 선언하지 않아도 된다.

import { ScrollMenu, VisibilityContext } from "react-horizontal-scrolling-menu";

type scrollVisibilityApiType = React.ContextType<typeof VisibilityContext>;

<ScrollMenu
   onWheel={onWheel}
   LeftArrow={LeftArrow}
   RightArrow={RightArrow}
>
              
</ScrollMenu>

나의 경우에는 휠과 버튼을 통해 컨트롤 할 예정이라 Arrow 버튼과 Wheel 이벤트를 걸어주었다. 내부는 자유롭게 작성하면 된다.

Left, Right Button

import { VisibilityContext } from "react-horizontal-scrolling-menu";


function LeftArrow() {
  const { scrollPrev } = React.useContext(VisibilityContext);

  return (
    <LeftBtn props="left" onClick={() => scrollPrev()}>
      Left
    </LeftBtn>
  );
}

function RightArrow() {
  const { scrollNext } = React.useContext(VisibilityContext);

  return (
    <RightBtn props="right" onClick={() => scrollNext()}>
      Right
    </RightBtn>
  );
}

간단하게 필요한 것만 들고 왔는데, 버튼의 css는 어떻게 꾸미든 상관없지만 scrollNext의 이름은 변경하면 안 된다.
props로 left, right를 전해주고 있는데, 이거는 생략해도 된다. 하나의 컴포넌트로 left Btn과 right Btn을 사용하기 위해 작성했지만 css가 걸려서 각각 작성해준 것이다.

Wheel

const [duration, setDuration] = React.useState(500);
const [isSlide, setIsSlide] = useState(false);

function onWheel(
    apiObj: scrollVisibilityApiType,
    ev: React.WheelEvent
  ): void {
    const isThouchpad = Math.abs(ev.deltaX) !== 0 || Math.abs(ev.deltaY) < 15;
    if (isThouchpad) {
      ev.stopPropagation();
      return;
    }
    if (ev.deltaY < 0) {
      // NOTE: for transitions

      if (!isSlide) {
        setIsSlide(true);
        apiObj.scrollPrev(undefined, undefined, undefined, { duration });
      }
      setIsSlide(false);
    } else if (ev.deltaY > 0) {
      if (!isSlide) {
        setIsSlide(true);
        apiObj.scrollNext(undefined, undefined, undefined, { duration });
      }
      setIsSlide(false);
    }
  }

isSlide라는 useState를 만들었는데, 간단하게 상태 변수라고 생각하면 될 것 같다. 슬라이드가 움직이고 있을 때는 휠을 움직여도 슬라이드 하지 말라는 뜻으로 설정했다.
없어도 될 것 같다...

처음에 라이브러리를 가져와서 사용했을 때, 생각했던 휠의 방향이 반대였다. 그럴 때는 deltaY>0, deltaY<0 안에 있는 내용을 서로 바꿔주면 정상적으로 되니 참고바란다.

휠을 아래로 내리면 deltaY는 0보다 큰 값이 나오고, 휠을 위로 올리면 deltaY는 0보다 작은 - 값이 나온다. (고정) 이걸로 휠 이벤트를 컨트롤 할 수 있으니 라이브러리가 아니어도 알아두면 좋다.

(예를 들면, 휠을 내렸을 때 애니메이션을 실행하는 방식으로)

해당 방법은 라이브러리를 사용해서 간단하게 끝났다. 정리할 때는 간단하지만 사용할 때는 꽤 애를 먹었던 거 같은데...

0개의 댓글