Загружаем каталог…
Загружаем каталог…
카드 확장 애니메이션 시리즈 — 1편 에서 만든 걸 실제로 여러 화면에 붙여보다가 만난 버그 기록. 증상 목록 화면에서 스크롤을 한참 내린 뒤, 아래쪽에 있는 카드를 클릭해서 확대 애니메이션을 시작했다. 그런데 확대된 결과물이 스크롤로 옮겨놓은 그 위치가 아니라, 스크롤하지 않았을 때 카드가 있었을 "원래 자리"에서 튀어나왔다. 1차 가설 (틀림) 처음엔 position: fixed 가 transform 이 걸린 조상 요소 때문에 뷰포트가 아닌 엉뚱한 기준점을 잡은 게 아닐까 의심했다. 클릭 시점에 캡처한 좌표, URL로 넘겨받은 좌표, 실제로 렌더링된 위치 — 이 세 값을 디버그 로그로 찍어 비교했더니 셋 다 정확히 일치 했다. 좌표 계산 자체는 문제가 없었다는 뜻이다. 2차 가설 (맞음) 좌표 문제가 아니라면 남은 건 애니메이션 자체가 "어디서 시작하는지"를 다르게 알고 있다는 것. 여기서 원인을 찾았다. 카드에 붙인 layoutId 가 항목의 id만으로 만들어져 있었다. 즉 목록 페이지의 진짜 카드와, 상세 페이지로 넘어가면서 만든 애니메이션용 카드가 같은 layoutId 문자열 을 쓰고 있었던 것이다. Next.js 같은 프레임워크의 클라이언트 사이드 네비게이션은 브라우저를 새로고침하지 않고, 같은 JS 런타임 안에서 화면 트리만 바꾼다. 그런데 Motion(구 Framer Motion)의 layoutId 는 그 요소가 화면에서 사라진 뒤에도 한동안 "마지막으로 어디 있었는지"를 전역으로 기억 한다. 문제는 목록의 카드는 스크롤한다고 해서 다시 측정되지 않는다는 점이다(스크롤은 레이아웃 변경이 아니라서 Motion이 재계산할 이유가 없다). 그래서 Motion이 기억하고 있는 그 카드의 위치는 스크롤하기 전, 페이지를 처음 열었을 때의 자연스러운 리스트 순서상 위치 였다. 우리가 넘긴 좌표는 무시되고, Motion은 그 "오래된 기억" 위치에서부터 애니메이션을 시작해버린 것이다. 해결 카드 컴포넌트에 layoutId 를 조합할 때 접두어(prefix)를 옵션으로 받을 수 있게 만들고, 다른 화면에서 애니메이션을 시작할 땐 anchor-${item.id} 처럼 목록 페이지가 쓰는 layoutId 와 절대 겹치지 않는 문자열 을 붙였다. 이렇게 하면 Motion 입장에서는 완전히 별개의 요소로 인식해서, 엉뚱한 과거 위치를 기억해올 일이 없다. // 목록 페이지의 카드 <motion.div layoutId={`card-${item.id}`}>...</motion.div> // 다른 페이지에서 시작하는 애니메이션 (접두어로 완전히 분리) <motion.div layoutId={`anchor-${item.id}`}>...</motion.div> 왜 처음엔 안 보였나 같은 페이지 안에서만 카드를 펼쳤다 접었다 하는 시나리오에서는 이 문제가 전혀 드러나지 않는다. layoutId 가 겹치는 두 요소가 "같은 화면 안에서, 한쪽이 사라지고 다른 쪽이 나타나는" 상황에서는 오히려 그게 의도된 동작(모핑)이기 때문이다. 문제는 페이지 이동을 낀 채로 같은 layoutId 를 다시 쓸 때만 나타난다 — 그래서 단일 페이지 안의 테스트만으로는 잡히지 않고, 실제로 목록 → 상세를 오가며 확인해야 드러나는 종류의 버그였다. 일반화하면 layoutId 를 쓰는 shared layout 애니메이션을 여러 화면에 걸쳐 쓸 계획이라면, "이 id가 다른 화면의 다른 요소와 우연히 겹치지 않는가" 를 미리 점검해볼 가치가 있다. Motion 공식 문서도 비슷한 이유로 LayoutGroup 에 id 를 줘서 네임스페이스를 분리하는 방법을 안내하고 있다 — 같은 페이지 안에 같은 컴포넌트가 여러 번 렌더링될 때 layoutId 가 서로 충돌하지 않게 하기 위한 것인데, 여기서 겪은 "페이지를 넘나드는 충돌"도 결국 같은 종류의 문제(의도치 않은 layoutId 겹침)라는 점에서 원리는 같다. 출처 Motion 공식 문서, <motion /> 컴포넌트: https://motion.dev/docs/react-motion-component Motion 공식 문서, LayoutGroup (id로 layoutId 네임스페이스 분리하는 공식 패턴): https://framer.com/docs/layout-group/
То, что RADAR обнаружил и классифицировал для этой возможности. Это опубликованный источником текст, а не подтверждение, что предложение ещё действует.
Motion의 `layoutId`, 페이지를 넘어가면 예전 위치를 착각한다. 카드 확장 애니메이션 시리즈 — 1편 에서 만든 걸 실제로 여러 화면에 붙여보다가 만난 버그 기록. 증상 목록 화면에서 스크롤을 한참 내린 뒤, 아래쪽에 있는 카드를 클릭해서 확대 애니메이션을 시작했다. 그런데 확대된 결과물이 스크롤로 옮겨놓은 그 위치가 아니라, 스크롤하지 않았을 때 카드가 있었을 "원래 자리"에서 튀어나왔다. 1차 가설 (틀림) 처음엔 position: fixed 가 transform 이 걸린 조상 요소 때문에 뷰포트가 아닌 엉뚱한 기준점을 잡은 게 아닐까 의심했다. 클릭 시점에 캡처한 좌표, URL로 넘겨받은 좌표, 실제로 렌더링된 위치 — 이 세 값을 디버그 로그로 찍어 비교했더니 셋 다 정확히 일치 했다.…
Открыть источник