页面过渡
基于路由的页面过渡系统
配置接口
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>;
路由匹配规则
模式类型
- 精确匹配:
/home
→ 与/home
完全匹配 - 通配符后缀:
/products/*
→ 匹配/products/123
- 完全通配符:
*
→ 匹配所有路由
匹配优先级
更具体的模式优先:
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模式进行匹配
操作流程
- 路由变更检测: 路由器变更路由
- 模式匹配: 使用from/to模式查找要应用的过渡
- Out动画: 对当前页面应用out过渡
- 同步: 等待out和in动画准备
- In动画: 对新页面应用in过渡
- 完成: 两个动画都完成后清理
实用示例
分层导航
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" }) },
],
};