前端

无限视差全屏滚动

禁用原生滚动,用 wheel 与 touch 驱动 prev/cur/next 三屏窗口,mask 高度动画与 rAF lerp 实现无限视差切屏。

#scroll #parallax #animation #touch

无限视差全屏滚动

全屏图片轮播不一定要用 Swiper。把原生滚动禁掉,自己接管 wheeltouch,用 prev / cur / next 三个 DOM 窗口循环展示图片,配合遮罩高度动画和视差位移,就能做出无限滚动的切屏效果。下方 demo 可滚轮或滑动切换。

核心链路

1. 禁原生滚动,统一输入

html, body { overflow: hidden }(全屏页)或容器 touch-action: none,所有滚动意图都转成 pixelDelta

wheel / touch → applyScrollDelta → targetProgress ± step
                                      ↓
                              rAF lerp → progress → render()

wheeltouch 只改 targetProgress,不直接改 progress,中间用 LERP 平滑追赶,手感更跟手。

2. 三屏窗口 + 循环索引

DOM 里始终只有三张 slide:prevcurnext。当前 index 指向居中那张;切屏完成后 index ± 1,重新 bindImages 绑定 (index-1, index, index+1) 取模后的图片 URL。图片列表再长,DOM 节点数也不变。

3. mask 高度实现切屏

每张 slide 内有一层 slide__mask,通过改 height 控制图片可见区域:

方向动画mask 变化
向下滚scroll-downnext 的 mask 从 0%100%,新图从上落下
向上滚scroll-upcur 的 mask 从 100%0%,当前图收起露出上一张
静止idleprev/cur 全显,next 隐藏

4. 视差位移

新图落下前,图片先 translateY(PARALLAX_SHIFT%) 偏上一点;progress 从 0→1 时逐渐回到 0。绝对值越大,下落感越强。位移由 JS 每帧写入,不用 CSS transition,和 lerp 进度同步。

在线体验

在 demo 区域内滚轮或上下滑动切换图片。全屏体验可打开 独立预览页

正在加载视差滚动…

小结

无限视差滚动的本质是 有限 DOM + 循环索引 + 自定义进度。难点不在图片数量,而在输入统一(wheel 行/页模式、触控板、触摸)、进度可逆(滚到一半往回滚能取消)、以及 prefers-reduced-motion 时关掉 lerp 拖尾。如果你要做类似效果,建议先把三屏窗口和 mask 动画跑通,再调 SCROLL_THRESHOLDLERP 找手感。