页面往下滚,先是一屏引导文字,接着画面被钉住不动:中央一个带圆角的小窗里露出一张风景照,随着滚轮继续往下,这个窗口沿四个方向同时展开,圆角逐渐拉直,最终铺满整个视口;紧接着标题淡入并向上归位,副标题稍晚一拍跟上。再继续滚,页面才解除钉住,恢复正常流动。
整段动画的进度完全由滚动位置决定——往回滚它就倒放。这种“可倒带”的手感是它和普通入场动画最大的区别:用户不会错过效果,也不会因为滚太快而看到半截。
这段滚动展开动画的四个要点
展开靠 clip-path 而不是缩放。初始是一个从四边向内收进的矩形裁剪,动画把内收量归零。图片本身始终铺满整屏、尺寸不变,所以展开过程中画面不会被拉伸变形,也不会出现分辨率不够导致的模糊。
圆角是被一起动画的。裁剪矩形自带圆角参数,从 8 像素过渡到 0,让“小窗变全屏”的观感更完整。
滚动钉住加进度绑定。触发器把这一屏钉在视口里,动画时长被映射到一段额外的滚动距离上,平滑系数让动画略微追赶滚轮,手感更顺。
文字是第二阶段,不是同时。两段动画排在同一条时间线上先后执行,文字还带错开间隔,形成“画面先打开、文字后落位”的层次。
三处值得说明的实现选择
其一,用 inset 裁剪的写法很关键。初始值写成视口单位:
clip-path: inset(25vh 20vw round 8px);
用 vh 与 vw 而不是百分比,好处是无论容器多高多宽,初始小窗的比例都相对视口稳定;而结束值全部归零,动画首尾都是合法且可插值的同类型值——这是 clip-path 能被平滑过渡的前提。若首尾写成不同的形状函数(比如从 circle 到 inset),浏览器无法插值,动画就会直接跳变。
其二,滚动距离用相对值而非固定像素。结束位置写成相对起点再滚一个半屏的高度,这样在笔记本和大屏上,完成整段动画所需的滚动量是成比例的,不会出现小屏上转瞬即过、大屏上要滚很久的割裂感。
其三,平滑系数带来了“追赶感”。进度绑定不是硬跟随,而是设了一个约一秒的追赶时间。快速滚动时动画会稍稍滞后再赶上,这一点点延迟让整体显得有重量;设为直接跟随则会显得生硬,尤其在触控板上会抖。
拿到源码后能改什么
最常改的三处:初始裁剪窗的大小(那两个视口单位的值决定小窗多大)、初始圆角、以及滚动区间长度。想让效果更戏剧化,就把初始窗口做得更小、圆角更大;想更含蓄,反过来即可。
文字部分的初始状态写在样式里(透明且下移),动画负责把它们归位。要加第三行文案,直接写进那个文字容器并把选择器包含进去即可,错开间隔会自动生效。想让文字更早出现,把它调整为与展开动画部分重叠即可,时间线支持在指定位置插入。
换图片只改一处路径。建议选中心构图的照片:小窗阶段只能看到中间一块,展开后才露出全貌,中心有主体的图片这个过程最有惊喜感。图片上还叠了一层轻微压暗滤镜,为的是保证白色文字的可读性,换成浅色图片时可以适当加深。
运行提示:动画依赖 GSAP 及其滚动触发插件,页面从 CDN 加载这两个文件,离线或内网环境请先下载到本地并改引用路径。字体同样来自网络,加载失败会退回系统字体。可直接双击 index.html 打开。建议使用近两年版本的 Chrome、Edge、Firefox 或 Safari。详细运行方法请参见压缩包内的帮助文档。
关于滚动展开特效的常见问题
能不能改成从圆形展开?
可以,但要保证动画首尾使用同一种裁剪函数。用 circle() 时把半径从小值动画到足以覆盖整屏的大值即可,不要在中途切换函数类型。
手机上体验如何?
可用。钉住与滚动绑定在移动端同样有效,但要注意移动浏览器地址栏收起会改变视口高度,导致初始裁剪窗尺寸跳动。对移动端可以把初始值改用固定比例或改用动态视口单位。
可以在同一页面放多段这样的动画吗?
可以。每段各自建一条时间线并绑定自己的触发元素即可,注意相邻两段的滚动区间不要重叠,否则钉住范围会互相干扰。
为什么我加长了文案,展开后文字会溢出?
文字容器没有设最大宽度,长文案在宽屏上会拉得很开。给容器加一个最大宽度并居中,同时把标题字号改成随视口缩放的写法,就能解决。
它适合放在哪里
这是典型的高端落地页开场手法,适合民宿与酒店、旅游目的地、房产项目、汽车与腕表等重视觉的品牌首页,也常用于案例页的章节过渡。结构极简——一张图、一段文案、两段动画,接进现有页面几乎没有成本。裁剪展开、滚动绑定与文字错开入场的完整写法都在源码里,注释清楚,下载后可查看。