OTT 검색 서비스: Wherewatch - (3)Framer Motion dragConstraints 버그

김 주현·2023년 7월 21일
0

Wherewatch 개발일지

목록 보기
3/5

오늘도 억까 당해버렸다 ...

문제 상황

이미지 슬라이드를 만드는 도중에, 화면 Resizing에 따라서 dragConstraints가 변해야 하는 상황이 있었다. 제약을 자식 이미지 크기만큼 걸어야 해서 다음과 같이 코딩을 했다.

const LandingView = () => {
  const slideRef = useRef<HTMLDivElement>(null);
  const [childrenWidth, setChildrenWidth] = useState(0);

  useEffect(() => {
    const handleResize = (event: UIEvent) => {
      if (slideRef.current === null) return;
      
      const {scrollWidth, clientWidth} = slideRef.current;
      
      setChildrenWidth(scrollWidth - clientWidth);
    }
    
    window.addEventListener("resize", handleResize);
    handleResize();
    
    return () => window.removeEventListener("resize", handleResize);
  }, [])
  
  return (
    // ...
          <motion.div
            ref={slideRef}
            drag="x"
            dragConstraints={{ left: -childrenWidth, right: 0 }}
            className="w-max space-x-[2.22vw] whitespace-nowrap"
          >
            <ContentCard />
            <ContentCard />
            <ContentCard />
            <ContentCard />
            <ContentCard />
            <ContentCard />
          </motion.div>
    // ...
  );
};

useEffect(() => {}, [])는 DOM에 다 그려진 뒤 호출이 되니까 slideRef에 값이 들어간 상태이다. 거기에서 scrollWidth에서 clientWidth를 빼주면 제약크기가 되니까, 그걸 childrenWidth에 넣어준다. 그러면~ 밑에 dragConstraints에서 childrenWidth를 쓰고 있으니 렌더링이 진행될 것이다.

..라고 생각하고 코드를 짠 거였는데, 작동을 하지 않았다. childrenWidth의 값도 잘 계산되는 걸 확인했는데도 적용이 안 됐다. 어디까지 생각해봤냐면 저기 속성에 던져주는 게 객체라서, 새로운 객체로 변한 걸 감지를 못 했나까지 의심하기 시작했지 뭐람(삽질의 시작ㅋㅋ)

아므튼,, 이도저도 안 되길래 찾아보니까 이미 있던 오류였다.

[BUG] dragConstraints are gone when resizing the window and updating them

...Im creating a carousel that overflows the main window, and using drag with drag constraints to interact with the carousel. This all works well, but when I try to resize the window, the dragConstraints disappear and i can drag the carousel with no bounds.

대충 요약하자면 창크기를 변경하면 걸어놓은 제약이 사라진다는 내용이었다. 완전 내 상황이라 답변들을 봤는데, 같은 현상을 겪고 있는 사람들이 꽤 있더라. 수정 좀 해줘라 Framer야!

해결 방법

Framer motion 쪽에서 버그를 고쳐줘야 근본적인 해결이 되겠지만, 일단 아래와 같이 부모에 Ref를 걸어서 부모 컨테이너의 크기만큼 제약을 받는 걸로 처리가 가능하다.

<div ref={constraintsRef}>
     <motion.div drag dragConstraints={constraintsRef} ... />
</div>

이 코드를 쓰기 위해선 다음 전제가 필요하다. 부모 컨테이너는 자식 크기보다 작아야 한다.

만약 부모가 자식을 다 감싸고 있으면 이 코드는 동작하지 않는다. 당연하기도 한 게, 이미 자식이 제약 안에 있기 때문.


뭐어.. 결론적으론 코드도 더 깔끔해지긴 했지만 여전히 억까당한 기분이... 😇

profile
FE개발자 가보자고🥳

1개의 댓글

comment-user-thumbnail
2023년 7월 21일

코드 작성에 대한 세심한 고민과 자세한 설명이 잘 드러나는 글이었습니다. 개발 과정에서 발생하는 이런 문제들은 때때로 어려움을 주지만, 그만큼 개발자로서 성장하는 계기가 되기도 하니 힘내시길 바랍니다. 그리고, 여러 사람들이 겪고 있는 문제를 공유하고 해결방안을 제시한 점도 정말 좋아 보입니다. 앞으로도 좋은 글 기대하겠습니다. 화이팅!

답글 달기