[{"data":1,"prerenderedAt":290},["ShallowReactive",2],{"blog-infinite-parallax-scroll":3},{"id":4,"title":5,"body":6,"category":275,"date":276,"description":277,"draft":278,"extension":279,"meta":280,"navigation":281,"path":282,"seo":283,"stem":284,"tags":285,"__hash__":289},"blog\u002Fblog\u002Finfinite-parallax-scroll.md","无限视差全屏滚动",{"type":7,"value":8,"toc":263},"minimark",[9,12,30,34,39,53,63,85,89,119,123,134,210,214,228,231,240,243,246],[10,11,5],"h1",{"id":5},[13,14,15,16,20,21,24,25,29],"p",{},"全屏图片轮播不一定要用 Swiper。把原生滚动禁掉，自己接管 ",[17,18,19],"code",{},"wheel"," 和 ",[17,22,23],{},"touch","，用 ",[26,27,28],"strong",{},"prev \u002F cur \u002F next 三个 DOM 窗口","循环展示图片，配合遮罩高度动画和视差位移，就能做出无限滚动的切屏效果。下方 demo 可滚轮或滑动切换。",[31,32,33],"h2",{"id":33},"核心链路",[35,36,38],"h3",{"id":37},"_1-禁原生滚动统一输入","1. 禁原生滚动，统一输入",[13,40,41,44,45,48,49,52],{},[17,42,43],{},"html, body { overflow: hidden }","（全屏页）或容器 ",[17,46,47],{},"touch-action: none","，所有滚动意图都转成 ",[17,50,51],{},"pixelDelta","：",[54,55,60],"pre",{"className":56,"code":58,"language":59},[57],"language-text","wheel \u002F touch → applyScrollDelta → targetProgress ± step\n                                      ↓\n                              rAF lerp → progress → render()\n","text",[17,61,58],{"__ignoreMap":62},"",[13,64,65,20,67,69,70,76,77,80,81,84],{},[17,66,19],{},[17,68,23],{}," ",[26,71,72,73],{},"只改 ",[17,74,75],{},"targetProgress","，不直接改 ",[17,78,79],{},"progress","，中间用 ",[17,82,83],{},"LERP"," 平滑追赶，手感更跟手。",[35,86,88],{"id":87},"_2-三屏窗口-循环索引","2. 三屏窗口 + 循环索引",[13,90,91,92,95,96,95,99,102,103,106,107,110,111,114,115,118],{},"DOM 里始终只有三张 slide：",[17,93,94],{},"prev","、",[17,97,98],{},"cur",[17,100,101],{},"next","。当前 ",[17,104,105],{},"index"," 指向居中那张；切屏完成后 ",[17,108,109],{},"index ± 1","，重新 ",[17,112,113],{},"bindImages"," 绑定 ",[17,116,117],{},"(index-1, index, index+1)"," 取模后的图片 URL。图片列表再长，DOM 节点数也不变。",[35,120,122],{"id":121},"_3-mask-高度实现切屏","3. mask 高度实现切屏",[13,124,125,126,129,130,133],{},"每张 slide 内有一层 ",[17,127,128],{},"slide__mask","，通过改 ",[17,131,132],{},"height"," 控制图片可见区域：",[135,136,137,153],"table",{},[138,139,140],"thead",{},[141,142,143,147,150],"tr",{},[144,145,146],"th",{},"方向",[144,148,149],{},"动画",[144,151,152],{},"mask 变化",[154,155,156,180,199],"tbody",{},[141,157,158,162,167],{},[159,160,161],"td",{},"向下滚",[159,163,164],{},[17,165,166],{},"scroll-down",[159,168,169,171,172,175,176,179],{},[17,170,101],{}," 的 mask 从 ",[17,173,174],{},"0%"," → ",[17,177,178],{},"100%","，新图从上落下",[141,181,182,185,190],{},[159,183,184],{},"向上滚",[159,186,187],{},[17,188,189],{},"scroll-up",[159,191,192,171,194,175,196,198],{},[17,193,98],{},[17,195,178],{},[17,197,174],{},"，当前图收起露出上一张",[141,200,201,204,207],{},[159,202,203],{},"静止",[159,205,206],{},"idle",[159,208,209],{},"prev\u002Fcur 全显，next 隐藏",[35,211,213],{"id":212},"_4-视差位移","4. 视差位移",[13,215,216,217,220,221,223,224,227],{},"新图落下前，图片先 ",[17,218,219],{},"translateY(PARALLAX_SHIFT%)"," 偏上一点；",[17,222,79],{}," 从 0→1 时逐渐回到 0。绝对值越大，下落感越强。位移由 JS 每帧写入，不用 CSS ",[17,225,226],{},"transition","，和 lerp 进度同步。",[31,229,230],{"id":230},"在线体验",[13,232,233,234,239],{},"在 demo 区域内滚轮或上下滑动切换图片。全屏体验可打开 ",[235,236,238],"a",{"href":237},"\u002Fdemos\u002Fparallax-scroll","独立预览页","。",[241,242],"parallax-scroll-demo",{},[31,244,245],{"id":245},"小结",[13,247,248,249,252,253,256,257,20,260,262],{},"无限视差滚动的本质是 ",[26,250,251],{},"有限 DOM + 循环索引 + 自定义进度","。难点不在图片数量，而在输入统一（wheel 行\u002F页模式、触控板、触摸）、进度可逆（滚到一半往回滚能取消）、以及 ",[17,254,255],{},"prefers-reduced-motion"," 时关掉 lerp 拖尾。如果你要做类似效果，建议先把三屏窗口和 mask 动画跑通，再调 ",[17,258,259],{},"SCROLL_THRESHOLD",[17,261,83],{}," 找手感。",{"title":62,"searchDepth":264,"depth":264,"links":265},3,[266,273,274],{"id":33,"depth":267,"text":33,"children":268},2,[269,270,271,272],{"id":37,"depth":264,"text":38},{"id":87,"depth":264,"text":88},{"id":121,"depth":264,"text":122},{"id":212,"depth":264,"text":213},{"id":230,"depth":267,"text":230},{"id":245,"depth":267,"text":245},"frontend","2026-06-15","禁用原生滚动，用 wheel 与 touch 驱动 prev\u002Fcur\u002Fnext 三屏窗口，mask 高度动画与 rAF lerp 实现无限视差切屏。",false,"md",{},true,"\u002Fblog\u002Finfinite-parallax-scroll",{"title":5,"description":277},"blog\u002Finfinite-parallax-scroll",[286,287,288,23],"scroll","parallax","animation","HTL-V7yHnEHTcmos1lrSu5suLz2IHx5hmawb99kBb-0",1782309645708]