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
];

対称オプション

双方向トランジションを自動生成します:

{
  from: '/home',
  to: '/about',
  transition: fade(),
  symmetric: true  // 逆方向のトランジションを自動生成
}

// 上記の設定は以下のように動作します:
// /home → /about: fade
// /about → /home: fade (自動生成)

ビュートランジションの構造

ビュートランジションは要素トランジションと同じ構造に従います:

interface ViewTransition {
  in?: (
    element: HTMLElement,
    context?: SggoiTransitionContext
  ) => TransitionConfig;
  out?: (
    element: HTMLElement,
    context?: SggoiTransitionContext
  ) => TransitionConfig;
}
  • out: fromページ(退出するページ)に適用
  • in: toページ(入ってくるページ)に適用

コンテキストオブジェクト

前のページと現在のページ間のスクロール差がビュートランジションの第2引数として渡されます:

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" }) },
  ],
};