✨ 커리어 타임라인 구현기 – 인터랙션과 구조를 함께 고려한 구성

조준형·2025년 5월 2일
0

포트폴리오

목록 보기
7/9

이번에는 포트폴리오 사이트 내 Career 섹션을 구현한 과정을 정리했다. 단순히 텍스트를 나열하는 것보다, 시간 흐름에 따라 중앙선을 기준으로 좌우 번갈아 등장하는 타임라인 형식을 채택했고, 스크롤 시 등장 애니메이션을 넣어 더욱 직관적이고 시각적으로 흥미롭게 구성했다.

🎯 목표

  • 학력, 동아리, 프로젝트 등 다양한 이력을 한눈에 보기 쉽게 나열

  • 스크롤에 반응하는 등장 애니메이션 적용

  • 좌우 번갈아 정렬된 카드 + 중앙선 + 마커 표시

🧱 기본 구조

  • Career.tsx는 타임라인 전체 섹션

  • CareerTimeline.tsx는 반복 렌더링 컴포넌트

  • careerData.ts는 이력 데이터 배열

  • CareerItem은 개별 타임라인 카드 구성

🧑‍💻 IntersectionObserver를 이용한 등장 애니메이션

IntersectionObserver를 구현해서 요소가 화면에 보일 때 애니메이션이 적용되도록 처리했다.

const [visible, setVisible] = useState(false);
const ref = useRef(null);

useEffect(() => {
  const observer = new IntersectionObserver(
    ([entry]) => setVisible(entry.isIntersecting),
    { threshold: 0.1 }
  );
  if (ref.current) observer.observe(ref.current);
  return () => observer.disconnect();
}, []);

이렇게 설정된 visible 상태를 기준으로 Tailwind 클래스를 동적으로 바꿔서 애니메이션을 적용했다:

className={`transition-all duration-700 transform
  ${visible ? "opacity-100 translate-y-0" : "opacity-0 translate-y-10"}`}

↔️ 좌우 번갈아 정렬
카드가 번갈아 왼쪽/오른쪽으로 배치되도록 index 값을 기준으로 정렬 방향을 결정했다.

const isLeft = index % 2 === 0;
🟣 중앙선 + 위치 마커 타임라인 중앙선은 absolute left-1/2로 배치하고, 각 카드의 수직 중앙에 마커(원형)를 배치했다.
/* 타임라인 중앙선 */
<div className="absolute left-1/2 transform -translate-x-1/2 h-full w-[2px] bg-indigo-300 z-0" />

/* 각 항목 위치의 원 */
<div className="absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2 w-4 h-4 bg-indigo-500 rounded-full border-4 border-white z-10" />

이 마커가 카드와 중앙선을 시각적으로 연결시켜주며, 흐름을 따라가기가 훨씬 쉬워졌다.

🧩 느낀 점

이번 작업에서는 라이브러리를 쓰지 않고 직접 인터랙션을 구현하면서, 상태 관리와 뷰포트 트리거 처리에 대한 이해가 더 깊어졌다.
IntersectionObserver는 코드도 간단하면서 성능에도 부담이 적어서 앞으로도 자주 쓸 것 같다.

특히 좌우 교차 배치와 타임라인 마커는 UI적으로도 시각적 재미를 주기 때문에, 단순 이력 나열보다 훨씬 더 강렬한 인상을 줄 수 있었다.

profile
코린이

0개의 댓글