跳到正文

滚动驱动动画

Scroll-driven Animation

中级网页App

滚动驱动动画(Scroll-driven Animation)是把动画的进度直接绑定到滚动位置上:滚到一半,动画就停在一半;往回滚,动画就倒着放。阅读进度条、随滚动收起的导航栏都是典型例子,用户的手指就是动画的播放头。

你可能会说:「文章往下滚的时候,顶部导航能不能跟着手指一点点变小,往回滚又慢慢变大?」

读之前建议先了解

动手看看

正在加载演示…

要点

  1. 1

    时间轴换成了滚动位置

    普通动画按时间播放:触发后 400 毫秒从开始走到结束,和你滚了多少无关。滚动驱动动画把「时间」换成「滚动位置」:比如前 120 像素的滚动对应导航栏从大到小的整个过程,滚了 60 像素就收起一半。用户停下,动画就停;往回滚,动画就倒着走,所以它总是跟手的。

  2. 2

    CSS 已经可以直接写

    新的 CSS 提供了 animation-timeline:scroll() 把动画绑定到某个滚动容器的滚动进度,view() 绑定到某个元素穿过视野的进度。写好普通的 @keyframes,再指定时间轴,浏览器会自己按滚动推进,不占用主线程,滚起来很顺。较新的 Chromium 系浏览器已经支持,其他浏览器的支持情况要先查一下,不支持时用脚本监听滚动、每帧算进度来补,或者干脆保持静态。

  3. 3

    只动便宜的属性

    滚动时每一帧都会更新动画,所以要尽量只动 transform 和 opacity。如果改的是 height、top、font-size,每一帧都要重新排版,页面复杂时就会发涩。像导航栏收起,可以用 transform 缩放和位移来做视觉上的变小,而不是真的改高度。

容易混淆的地方

滚动显现是滚到某个位置时触发、然后按时间播放,只有「放」和「没放」两种状态;滚动驱动动画的进度随滚动连续变化,可以停在中间。视差滚动是滚动驱动动画的一种具体用法:几个图层按不同速度随滚动移动。

什么时候用

适合用

  • 长文章顶部的阅读进度条,长度直接等于读到了全文的百分之几。
  • 博客或文档的导航栏,随着往下滚逐渐收起成紧凑版本,往回滚再展开。
  • 产品介绍页里,某张产品图随着这一段滚过视野逐渐旋转、展开,讲解它的结构。

不适合用

  • 只想让内容进入视野时出现一次时,不需要绑定滚动进度;用滚动显现更简单。
  • 按钮点击、表单提交这类和滚动无关的反馈,别绑到滚动上;用普通的过渡或动画。
  • 动画内容很重、低端设备已经滚动卡顿时,别再加逐帧计算的滚动动画;先保证滚动流畅。

练一练

你想让博客的导航栏随着往下滚逐渐变小,用户停在中途时它也停在中间状态。应该怎么做?

让 AI 帮你做

请给【需要随滚动变化的元素,如:文章页顶部导航栏和阅读进度条】做成滚动驱动动画。先阅读页面结构、滚动发生在哪个容器,以及项目里已有的动画写法和要兼容的浏览器。要求:动画进度直接绑定滚动位置(如导航栏在前 120 像素内从大变小,进度条长度等于全文阅读比例),停在中途就停在中间,往回滚就倒着走;优先用 CSS animation-timeline,不支持时用脚本按帧计算并做节流;只动 transform 和 opacity。开启减少动效时保留进度条,去掉大幅变化。不改无关代码。最后说明在支持和不支持的浏览器里分别怎么验证。

接下来学什么