整屏只有一张照片,但它不是静止的:往下滚动,画面会像被一台手持相机带着走——先推近到某个角落,再沿一条弧线平移到另一处,途中伴随轻微的倾斜和缩放,停下时又稳稳对准下一个细节。整套运动由五条看不见的路径定义,镜头就沿着它们依次走完。技术上是 SVG 承载画面,GSAP 的 ScrollTrigger 与运动路径插件驱动镜头,脚本不到五十行。
镜头是怎么被带着走的
移动的不是镜头,是画面。有一个半径为零的「焦点」沿路径运动,画面层则取它坐标的相反数做平移,于是焦点走到哪里,哪里就被移到屏幕中央。
缩放和平移分开两层。外层只管缩放与旋转,内层只管平移,互不干扰,调参数时不会牵一发动全身。
跟随带阻尼。平移没有直接赋值,而是走了一个带缓动的补间,所以镜头会稍微滞后于滚动,手持感就来自这一点延迟。
五条路径拼成一段运镜
五条路径写在 SVG 里,是普通的贝塞尔曲线,肉眼不可见。时间线按 0、1、2、3、4 的节点依次让焦点走完它们,每一段同时配一个缩放与旋转的目标值:
.to(".focal-point", { motionPath: paths[2] }, 2)这种写法的好处是,想改运镜只需要在图上重画那条曲线,代码一行不用动——路径本身就是可视化的参数。缩放值在 2 到 3.3 之间来回,旋转在正负几度之间摆动,幅度刻意留得很小,因为在放大的画面上,一两度的倾斜看起来已经相当明显了。
能改的地方
换图只需替换 SVG 里 image 的地址,建议用像素较高的横图,因为镜头会推到两三倍。路径可以用任意矢量工具画好后把 d 属性粘进来,数量不限,增减后记得同步调整时间线上的节点序号。滚动总长度由那六个占位 section 决定,想让运镜更慢就加 section。每段的缩放与旋转目标值都写在对应行,可逐段微调。
常见问题
画面糊了?
镜头会把图放大到两三倍,原图分辨率不足就会明显发虚。建议横向像素在 3000 以上,或者针对推近的重点区域单独准备高清切片。
滚动到一半镜头乱跳?
多为路径节点序号和时间线位置对不上。每条路径都要有对应的时间位置,中间不能缺号,否则后续片段会被挤到一起。
手机上能用吗?
能。滚动驱动在触摸端同样有效,但放大后的画面在窄屏上可见范围很小,建议为移动端单独降低缩放倍数,或改用一张竖构图的底图。
适合用在哪
展品与藏品的细节导览、地图与园区介绍、产品大图的分区讲解,以及需要「带着观众看」的叙事型落地页。焦点反向平移、分层缩放与路径运镜的完整写法都在脚本里,下载后可查看。