레퍼런스를 눈이 아니라 코드로 뜯어서 만든 스크롤 모션 히어로

소개

스타디장님께서 참고 영상에서 남기셨던 2개를 레퍼런스로 참고했습니다.

  • https://1784.navercorp.com/ — 배경 영상이 루프로 돌고, 스크롤하는 동안 화면이 고정된 채 텍스트가 변형되는 히어로

  • https://www.codeit.kr/ — 아래로 내려가도 섹션마다 다른 모션이 나와 지루할 틈이 없는 구성

레퍼런스를 눈으로 보고 흉내내지 않는다. 브라우저에서 실제 코드를 뜯어 수치를 가져온다.

결과적으로 이 원칙 하나가 이번 주차에서 가장 크게 남았습니다. 눈으로 봤을 때 제가 이해한 것과 실제 코드가 달랐기 때문입니다.

사용한 브랜드는 1·2주차에서 만든 가상 향수 브랜드 LAPIS를 그대로 이어서 썼습니다. 색·타이포·모션 토큰이 이미 있어서 디자인 결정에 시간을 쓰지 않고 모션에만 집중할 수 있었습니다.

결과물: https://art-ruby.github.io/lapis-homepage/week3-hero/


진행 방법

사용한 도구: Claude Code (구현·레퍼런스 분석), Claude Design (시안 탐색), Mixkit (배경 영상)

계획 세우기

사용한 프롬프트 전문

지피터스 디자인 스터디 3주차 실습을 위한 후킹한 웹사이트의 히어로 섹션 만들기 프로젝트
1. https://1784.navercorp.com/
2. https://www.codeit.kr/
첫번째 네이버 홈페이지의 히어로 섹션의 스크롤에 반응하는 텍스트 모션과 뒤에서 루프로 돌아가는 영상을 지닌 웹사이트 그리고 그 이후 아래 섹션들은 코드잇 사이트 처럼 섹션마다 지루하지 않도록 모션들이 동작하는 사이트를 우리가 그대로 클로드 코드와 클로드 디자인으로 구현해보고 스터디원들도 그대로 따라할 수 있도록 실습 안내까지 하고 싶어
같이 실행 계획을 세워보자

이 한 번의 요청으로 결과물 목록(사이트·실습 가이드·발표 자료), 섹션별 모션 배정표, 기술 방향(라이브러리 없이 바닐라)까지 담긴 계획을 받았고, 여기에 “좋아”로 승인한 뒤 실제 제작에 들어갔습니다.

레퍼런스를 눈이 아니라 콘솔로 확인하기

“네이버는 이렇게 움직이는 것 같다”는 관찰로 끝내지 않고, 두 사이트를 열어 개발자 도구 콘솔에서 실제 스타일시트에 정의된 애니메이션 구간(keyframes)을 그대로 꺼내서 확인했습니다. 코드잇처럼 CSS가 외부 CDN에 있어 콘솔에서 직접 안 보이면, 그 파일을 받아와서 안의 정의를 찾는 방식으로 우회했습니다.

이 과정에서 눈으로 봤던 것과 다른 사실이 두 개 나왔습니다.

  • 1784의 타이틀 단어는 ‘들어오는’ 게 아니라 ‘통과’합니다. 왼쪽 밖에서 들어온 단어는 화면 중앙을 지나 오른쪽 밖으로 빠져나가고, 오른쪽에서 들어온 단어는 반대로 왼쪽으로 빠집니다. 처음엔 “좌우에서 번갈아 들어온다” 정도로만 봤는데, 실제로는 들어오는 방향과 나가는 방향이 항상 반대였습니다. 그리고 타이틀이 한 덩어리 텍스트가 아니라 단어별로 4조각 나뉜 별개의 요소였습니다.

  • 코드잇의 반복 모션은 ‘배경 장식’이 아니라 ‘장면’입니다.

“안 움직여요” 버그를 같이 진단하기

사용한 프롬프트 전문

모션적용 안됐어. 화면 움직이지 않아

원인을 추적한 결과, 코드 문제가 아니라 PC의 Windows 접근성 설정에서 애니메이션 효과 자체가 꺼져 있었던 것이었습니다. 그래서 브라우저가 모든 페이지에 “모션을 줄여 달라”는 신호를 보내고 있었고, 사이트는 그 요청을 충실히 따라 모든 모션을 끈 상태였던 겁니다. 코드는 의도대로 동작했는데 정작 눈으로 확인할 방법이 없었던 셈입니다. 수동으로 모션을 켤 수 있는 버튼을 추가했습니다.

카드에 역동성 더하기

여기까지 만들고 나니 “움직이기는 하는데 역동적이지는 않다”는 느낌이 들었습니다.

사용한 프롬프트 전문

모션을 켜서 보는 것도 좋지만 움직임만 있지 역동성이 느껴지도록 하나의 화면에 대면 완전 확대, 나머지 2개는 작아지거나 사라지도록 화면 설정

노트(Top·Heart·Base) 카드 3장 중 하나에 마우스를 올리면 그 카드만 크게 펼쳐지고 나머지 둘은 흐려지며 작아지는 것으로 반영했습니다. 실제 측정값입니다.

Top

Heart (호버)

Base

349 → 119px

349 → 809px

349 → 119px

이미지 높이

420px

560px

420px

설명 노출 높이

55.8px

186px

55.8px

가운데 카드가 2배 넘게 벌어지고 양옆은 흐려지면서 좁아지니, 단순히 “움직인다”가 아니라 “하나에 시선이 집중된다”는 느낌이 살아났습니다.


결과와 배운 점

꿀팁 1 — 레퍼런스는 눈으로 보지 말고 콘솔로 읽으세요

이번 주차에서 제일 크게 남은 것입니다. 눈으로 본 해석이 두 번 다 틀렸습니다.

눈으로 본 것

실제 코드

단어가 좌우에서 들어온다

들어왔다가 반대쪽으로 통과해 나간다

은은한 배경 애니메이션

5개 요소가 시점을 나눠 쓰는 하나의 장면

“비슷하게 만들어줘”라고 하면 AI도 눈으로 본 수준의 결과를 냅니다. 콘솔에서 확인한 실제 수치를 프롬프트에 그대로 넘겨주면 결과물의 밀도가 확 달라집니다.

꿀팁 2 — 격자 레이아웃으로 카드 크기를 바꾸면 전환이 아예 안 걸립니다

격자 기반 레이아웃 속성(예: grid-column, grid-area)으로 카드의 자리나 크기를 바꾸면, 브라우저가 전환 애니메이션 자체를 만들어주지 않고 그냥 순간이동합니다. 진행 중인 애니메이션 목록을 확인하는 함수(getAnimations())로 물어보면 빈 배열이 돌아오는 걸로 이 사실을 확인할 수 있었습니다.

폭이나 위치를 부드럽게 바꾸고 싶으면 두 가지 중 하나를 쓰는 게 안전합니다.

  • flex 레이아웃의 flex-grow — 그냥 숫자값이라 어디서나 자연스럽게 애니메이션됩니다

  • 절대 위치(좌표를 px로 직접 지정) — 형제 요소에 영향을 주지 않아 고정된 무대 안에서 안전합니다

flex를 쓸 땐 min-width: 0을 같이 넣는 걸 잊지 않아야 합니다. 이게 없으면 안의 이미지가 카드를 밀어내서 양옆 카드가 줄어들지 않습니다.

시행착오 — 지속시간을 0으로 만드는 걸로는 모션이 안 꺼집니다

접근성 처리를 “애니메이션 지속시간을 전부 0에 가깝게 낮춘다”로 끝내는 경우가 많은데, 이걸론 부족하다는 걸 알게 됐습니다.

지속시간 설정은 일반적인 상태 전환에만 효과가 있습니다. 그런데 스크롤을 따라 화면이 고정된 채 변형되는 효과는 그런 전환이 아니라 스크롤 위치에 직접 묶여 계산되는 값이라, 시간이 아니라 스크롤이 재생하는 셈입니다. 그래서 지속시간을 아무리 낮춰도 꿈쩍도 하지 않았습니다. 초 단위를 직접 박아 넣은 무한 반복 애니메이션도 마찬가지였습니다.

결국 “모션 켜짐/꺼짐”을 나타내는 별도의 스위치 값을 하나 두고, 스크롤 계산에 그 값을 곱하는 방식으로 해결했습니다. 그리고 애니메이션을 끄는 것만으로는 안 되고, 꺼졌을 때의 최종 모습까지 같이 지정해야 한다는 것도 배웠습니다. 안 그러면 요소가 화면 밖 시작 위치에 투명한 채로 얼어붙어 영영 안 보이는 상태가 됩니다.

시행착오 2 — 위치 속성을 하나 바꿨더니 가로 스크롤이 생겼습니다

접근성 처리를 하다가 가로로 살짝 넘치는 문제가 생겼습니다. 원인이 재밌었습니다.

부모 요소의 위치 지정 방식을 바꾸는 순간, 그 안에서 절대 위치로 놓여 있던 배경 영상이 크기를 계산하는 기준 자체가 다른 요소로 옮겨갔습니다. 원래는 잘림 처리가 걸린 요소를 기준으로 계산되던 확대 효과가, 잘림 처리가 없는 요소를 기준으로 다시 계산되면서 그대로 삐져나온 것이었습니다. 부모의 위치 지정 방식을 바꾸면 자식이 좌표를 계산하는 기준도 함께 바뀐다는 걸 몸으로 배웠습니다.


도움 받은 글

1
1개의 답글
밀어주고 끌어주는

온·오프라인 AI 스터디

AI로 어디까지 할 수 있는지
직접 확인하실 분만 신청하세요.