SSGOI

페이지 전환

라우트 기반 페이지 전환 시스템

설정 인터페이스

SsgoiConfig

interface SsgoiConfig {
  transitions: Array<{
    from: string; // 출발 경로 패턴
    to: string; // 도착 경로 패턴
    transition: SggoiTransition;
    symmetric?: boolean; // 양방향 전환 자동 생성
  }>;
  defaultTransition?: SggoiTransition;
}

기본 설정

import { Ssgoi } from "@ssgoi/react";
import { fade, slide } from "@ssgoi/react/view-transitions";

const config = {
  defaultTransition: fade(),
  transitions: [
    { from: "/", to: "/about", transition: slide({ direction: "left" }) },
    { from: "/about", to: "/", transition: slide({ direction: "right" }) },
  ],
};

<Ssgoi config={config}>{children}</Ssgoi>;

경로 매칭 규칙

패턴 종류

  1. 정확한 매칭: /home/home과 정확히 일치
  2. 와일드카드 접미사: /products/*/products/123 매칭
  3. 전체 와일드카드: * → 모든 경로 매칭

매칭 우선순위

더 구체적인 패턴이 우선 적용됩니다:

transitions: [
  // 1순위: 정확한 매칭
  { from: "/blog/post-1", to: "/blog/post-2", transition: slide() },

  // 2순위: 와일드카드 매칭
  { from: "/blog/*", to: "/blog/*", transition: fade() },

  // 3순위: defaultTransition
];

Symmetric 옵션

양방향 전환을 자동으로 생성합니다:

{
  from: '/home',
  to: '/about',
  transition: fade(),
  symmetric: true  // 자동으로 반대 방향 전환 생성
}

// 위 설정은 다음과 같이 동작:
// /home → /about: fade
// /about → /home: fade (자동 생성)

View Transition 구조

View Transition도 Element Transition과 동일한 형태입니다:

interface ViewTransition {
  in?: (
    element: HTMLElement,
    context?: SggoiTransitionContext
  ) => TransitionConfig;
  out?: (
    element: HTMLElement,
    context?: SggoiTransitionContext
  ) => TransitionConfig;
}
  • out: from 페이지(나가는 페이지)에 적용
  • in: to 페이지(들어오는 페이지)에 적용

Context 객체

View Transition의 두 번째 인자로 전페이지와 현재페이지의 스크롤 차이가 전달됩니다:

interface SggoiTransitionContext {
  scrollOffset: {
    x: number; // 전페이지와 현재페이지의 스크롤 X 차이
    y: number; // 전페이지와 현재페이지의 스크롤 Y 차이
  };
}

// 사용 예: 스크롤 위치를 고려한 트랜지션
const scrollAwareTransition = {
  in: (element, context) => {
    const { scrollOffset } = context;
    return {
      prepare: (el) => {
        // 스크롤 차이만큼 이동시켜 시작
        el.style.transform = `translateY(${-scrollOffset.y}px)`;
      },
      tick: (progress) => ({
        // 원래 위치로 돌아오기
        transform: `translateY(${-scrollOffset.y * (1 - progress)}px)`,
      }),
    };
  },
};

SsgoiTransition 컴포넌트

각 페이지를 감싸는 래퍼 컴포넌트:

<SsgoiTransition id="/page-path">
  <PageContent />
</SsgoiTransition>
  • id: 경로 매칭에 사용되는 식별자
  • 이 ID가 config의 from/to 패턴과 매칭됨

동작 흐름

  1. 경로 변경 감지: 라우터가 경로 변경
  2. 패턴 매칭: from/to 패턴으로 적용할 트랜지션 찾기
  3. Out 애니메이션: 현재 페이지에 out 트랜지션 적용
  4. 동기화: out과 in 애니메이션 준비 대기
  5. In 애니메이션: 새 페이지에 in 트랜지션 적용
  6. 완료: 두 애니메이션이 모두 완료되면 정리

실제 사용 예제

계층적 네비게이션

const config = {
  transitions: [
    // 목록 → 상세
    {
      from: "/products",
      to: "/products/*",
      transition: scale({ from: 0.95 }),
      symmetric: true, // 상세 → 목록도 자동 처리
    },

    // 탭 네비게이션
    { from: "/tab1", to: "/tab2", transition: slide({ direction: "left" }) },
    { from: "/tab2", to: "/tab3", transition: slide({ direction: "left" }) },
    { from: "/tab3", to: "/tab2", transition: slide({ direction: "right" }) },
    { from: "/tab2", to: "/tab1", transition: slide({ direction: "right" }) },
  ],
};