无限视差全屏滚动
禁用原生滚动,用 wheel 与 touch 驱动 prev/cur/next 三屏窗口,mask 高度动画与 rAF lerp 实现无限视差切屏。
无限视差全屏滚动
全屏图片轮播不一定要用 Swiper。把原生滚动禁掉,自己接管 wheel 和 touch,用 prev / cur / next 三个 DOM 窗口循环展示图片,配合遮罩高度动画和视差位移,就能做出无限滚动的切屏效果。下方 demo 可滚轮或滑动切换。
核心链路
1. 禁原生滚动,统一输入
html, body { overflow: hidden }(全屏页)或容器 touch-action: none,所有滚动意图都转成 pixelDelta:
wheel / touch → applyScrollDelta → targetProgress ± step
↓
rAF lerp → progress → render()
wheel 和 touch 只改 targetProgress,不直接改 progress,中间用 LERP 平滑追赶,手感更跟手。
2. 三屏窗口 + 循环索引
DOM 里始终只有三张 slide:prev、cur、next。当前 index 指向居中那张;切屏完成后 index ± 1,重新 bindImages 绑定 (index-1, index, index+1) 取模后的图片 URL。图片列表再长,DOM 节点数也不变。
3. mask 高度实现切屏
每张 slide 内有一层 slide__mask,通过改 height 控制图片可见区域:
| 方向 | 动画 | mask 变化 |
|---|---|---|
| 向下滚 | scroll-down | next 的 mask 从 0% → 100%,新图从上落下 |
| 向上滚 | scroll-up | cur 的 mask 从 100% → 0%,当前图收起露出上一张 |
| 静止 | idle | prev/cur 全显,next 隐藏 |
4. 视差位移
新图落下前,图片先 translateY(PARALLAX_SHIFT%) 偏上一点;progress 从 0→1 时逐渐回到 0。绝对值越大,下落感越强。位移由 JS 每帧写入,不用 CSS transition,和 lerp 进度同步。
在线体验
在 demo 区域内滚轮或上下滑动切换图片。全屏体验可打开 独立预览页。
小结
无限视差滚动的本质是 有限 DOM + 循环索引 + 自定义进度。难点不在图片数量,而在输入统一(wheel 行/页模式、触控板、触摸)、进度可逆(滚到一半往回滚能取消)、以及 prefers-reduced-motion 时关掉 lerp 拖尾。如果你要做类似效果,建议先把三屏窗口和 mask 动画跑通,再调 SCROLL_THRESHOLD 和 LERP 找手感。