四屏整页的图片,滚动切换时不是简单地滑上去:下一屏从画面正中间裂开一个圆形缺口,随着滚动迅速扩大直到盖满整屏,缺口里的图片同时从缩小、透明放大到略微超出边界。往回滚,整个过程严丝合缝地倒放。每屏中央有一个跳转链接,点它会平滑滚到指定屏。技术上是 CSS 的滚动吸附配 GSAP 的 ScrollTrigger,遮罩用的是 clip-path 的圆形裁剪。
这个切屏的三个要点
图层被搬到了固定层。脚本启动时把每一屏的画面从文档流里取出来,统一塞进一个固定定位的容器,剩下的 section 变成纯粹的滚动占位,只负责提供滚动距离。
动画进度绑死滚动。用的是无平滑的实时跟随模式,所以画面推进和滚轮是一对一的,随时停住都能停在中间状态。
进场和退场是两条时间线。一条负责圆形扩开与图片放大,另一条负责当前屏在被盖住前的缩放与淡出,两条各自绑定不同的滚动区间。
圆的半径为什么要现算
要让圆形缺口盖满整个屏幕,半径必须大于视口的半对角线。源码没有写死一个数,而是在动画执行时取当前视口尺寸:
clipPath: () => "circle(" + Math.max(innerHeight, innerWidth) + "px)"写成函数而不是固定值,意味着每次刷新计算时都会重新取一遍,窗口缩放或手机旋转后不会出现「圆没盖满、边角露出上一屏」的情况。这是用 clip-path 做全屏揭示时最容易踩的坑。
能改的地方
屏数不限,复制一段 section 结构并把跳转链接指向下一屏的 id 即可。圆形扩开的速度感由缓动曲线控制,换成先慢后快或加一点回弹都会明显改变观感。想把圆换成别的形状,直接把 clip-path 的值从 circle 换成 inset 或 polygon,时间线其余部分不用动。图片替换为自己的素材即可,建议用横向大图。
常见问题
本地打开是白屏?
页面用 ES 模块从 CDN 引入 GSAP,需要通过本地服务器访问,直接双击 HTML 会被模块的跨域限制挡住。离线使用请把 GSAP 下载到本地并改写引入映射。
滚动不吸附,停在两屏之间?
吸附由 CSS 的滚动吸附属性实现,注意它作用在滚动容器上而不是 body。如果把这套结构嵌进别的布局,要确认外层容器的高度和溢出设置没有把吸附破坏掉。
手机上顺滑吗?
动画只改 clip-path、transform 和透明度,性能开销不大;但移动端浏览器的地址栏收放会改变视口高度,建议配合动态视口单位使用,避免切换时出现跳动。
适合用在哪
品牌故事页、产品发布的整屏叙事、摄影与旅行站点的图集浏览,以及需要强仪式感的落地页。图层重组、双时间线绑定与圆形遮罩的完整写法都在脚本里,下载后可查看。