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页面(进入页面)

上下文对象

前一页和当前页之间的滚动差异作为第二个参数传递给视图过渡:

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与配置中的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" }) },
  ],
};