사용하는 것
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 이벤트를 걸어주었다. 내부는 자유롭게 작성하면 된다.
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가 걸려서 각각 작성해준 것이다.
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보다 작은 - 값이 나온다. (고정) 이걸로 휠 이벤트를 컨트롤 할 수 있으니 라이브러리가 아니어도 알아두면 좋다.
(예를 들면, 휠을 내렸을 때 애니메이션을 실행하는 방식으로)
해당 방법은 라이브러리를 사용해서 간단하게 끝났다. 정리할 때는 간단하지만 사용할 때는 꽤 애를 먹었던 거 같은데...