EchoBlog

整理首屏资源

8%
EchoBlog
返回文章
前端开发

用 GSAP 打造丝滑的页面过渡动画

记录一次在 Nuxt 中实现页面切换动画的实践与思考。

用 GSAP 打造丝滑的页面过渡动画

页面过渡不是为了炫技,而是为了让用户理解“我从哪里来,又到了哪里去”。在个人博客里,动效可以更轻一点:进入时有层次,离开时不打扰阅读,滚动时给一点反馈。

基本思路

我会把动效拆成三类:首屏进入、列表 stagger、滚动进度。首屏进入负责建立情绪,列表 stagger 让信息更容易扫描,滚动进度则给长页面一个方向感。它们不应该互相争抢注意力,而是像页面自己的呼吸。

实际设计时,我先把页面拆成几个稳定层级:导航、主标题、正文卡片、侧边信息。动画只作用在层级切换上,不直接改变内容结构。这样后续即使调整布局,动效依然可以复用。

在 Nuxt 中落地

Nuxt 的页面结构天然适合做局部动效。页面只需要给关键模块加上稳定的选择器,然后在客户端用 GSAP 处理进入节奏。这样不会污染内容层,也不会把样式写成难以维护的状态机。

我的习惯是让组件只声明“这里可以被动画处理”,真正的时间线放在 composable 里。比如卡片统一使用 data-animate 标记,页面挂载后再收集这些节点。这样不同页面可以共用同一套 reveal 逻辑,也能统一处理销毁。

TypeScript
const scope = gsap.context(() => {
  gsap.from('[data-animate]', {
    y: 18,
    opacity: 0,
    duration: 0.64,
    ease: 'power3.out',
    stagger: 0.08
  })
}, root)

这段代码的重点不是参数,而是边界:动画只读取 root 内的节点,并在页面卸载时统一 revert。否则切换路由几次后,页面状态会变得很难追踪。

页面切换的节奏

页面切换可以分成两个阶段:旧页面离开,新页面进入。个人博客不需要复杂的转场遮罩,最稳定的做法是让旧页面轻微淡出,新页面带一点位移进入。切换应该快,不能让用户觉得等待是动效的一部分。

如果页面内容来自异步数据,动画要等关键内容准备好再启动。否则用户会看到空卡片先动,文字后出现,这种错位会让动效显得廉价。

控制克制

好的动效应该能被感觉到,但不应该抢走内容注意力。我的默认规则是:位移短、时间短、缓动柔和,并尊重系统的减少动态效果设置。

我会给自己设几条限制:

  • 单个 reveal 动画尽量控制在 700ms 内。
  • 列表 stagger 不超过 100ms,否则大列表会拖慢阅读。
  • 不给正文段落逐段加动画,正文是阅读对象,不是舞台。
  • 系统开启减少动态效果时,所有装饰动画都应该停止。

最后

GSAP 很强,但页面动效真正难的不是 API,而是判断“哪里不该动”。个人博客的气质应该来自内容和排版,动效只是帮助页面更自然地出现。