Lenis 平滑滚动使用指南:3 步接好,让滚动和动画同频
【免费下载链接】lenisSmooth scroll as it should be项目地址: https://gitcode.com/GitHub_Trending/le/lenis
Lenis 是一个零依赖的小体积平滑滚动库:接管浏览器原生滚动,让整页滚动变顺滑。如果你的站点要做视差、分节吸附或滚动驱动动画,它很合适。下面讲安装、调手感和常见坑。
先认识一下:几 KB,骑在原生滚动上
Lenis(拉丁语里"平滑"的意思)的做法很直接:它不伪造一层假滚动,而是监听 wheel 和 touch 事件,把浏览器真实的滚动位置朝目标"缓动"过去。因为滚动始终是浏览器在做,position: sticky、锚点链接、屏幕阅读器这些原生能力照常工作,这也是它和很多"替换滚动"方案最大的区别。
| 项目 | 说明 |
|---|---|
| 定位 | 轻量平滑滚动库,基于原生滚动,不破坏可访问性 |
| 核心能力 | 滚轮与触摸平滑、scrollTo编程滚动、官方 snap 吸附插件、React / Vue 适配器 |
| 适用场景 | 营销官网、WebGL 滚动场景、GSAP 视差、分节式站点 |
快速上手:3 步跑通
安装一行命令:npm i lenis。
然后初始化并驱动动画循环,最短路径如下:
import Lenis from 'lenis' // 让 Lenis 自己跑 requestAnimationFrame 循环 const lenis = new Lenis({ autoRaf: true }) // 订阅滚动事件:e 上带着 scroll、velocity、progress lenis.on('scroll', (e) => { console.log(e.scroll, e.progress) })第三步是 CSS:引入lenis/dist/lenis.css(源码在 packages/core/lenis.css)。它负责设置 html 高度、暂停滚动时锁住溢出,漏掉会出现页面高度异常。到这一步,页面已经能平滑滚动了。
实战场景:最常碰到的 3 个
让滚动驱动 GSAP 视差
场景是官网里随滚动移动的图片。关键点:把 Lenis 挂到 GSAP 的 ticker 上,两边共用同一个时钟,否则滚动位置和动画会各走各的。
const lenis = new Lenis() // Lenis 每变一次位置,就通知 ScrollTrigger 重算 lenis.on('scroll', ScrollTrigger.update) // 挂到 GSAP ticker;time 单位是秒,转成毫秒 gsap.ticker.add((time) => { lenis.raf(time * 1000) }) gsap.ticker.lagSmoothing(0) // 关掉滞后平滑,避免双重缓动就这几行,不要再自己写一套 raf 循环,两个时钟必然打架。
给分节页面加吸附
希望滚动停下来时"咔哒"对齐到某一节,用官方插件 lenis/snap,它和平滑滚动协作而不是对抗:new Snap(lenis, { type: 'proximity' }),再对每个区块snap.addElement(section)。三种模式:proximity(靠近才吸)、mandatory(必落点)、lock(一次一步)。
页内锚点与编程滚动
有目录导航或"回到顶部"按钮时,不用自己算偏移。初始化传anchors: true,Lenis 会接管锚点点击并平滑到位;代码里直接lenis.scrollTo('#pricing', { offset: -80 })。目标可以是数字、选择器或元素。
参数速查:最常调的就是这几个
| 参数 | 什么时候调 |
|---|---|
lerp(默认 0.1) | 手感太生硬就调大,太飘就调小;控制每帧向目标靠近的比例 |
duration/easing | 想精确控制滚轮和 scrollTo 的动画曲线;给其中一个就切换为按时间动画 |
syncTouch | 移动端也想平滑时开启;注意 iOS 16 以下可能不稳 |
wheelMultiplier/touchMultiplier | 滚轮、触摸速度与你的内容节奏不匹配时,默认都是 1 |
anchors | 页内有锚点链接需要保持可用时开启 |
allowNestedScroll | 页面存在内部滚动区(弹窗、轮播)时开启;追求性能建议改用元素的data-lenis-prevent属性 |
集成与避坑:框架接入和三个坑
React用官方适配器:<ReactLenis root>包住页面,实例的创建和销毁由 provider 接管,任何组件里用useLenis拿到最新滚动状态:
import { ReactLenis, useLenis } from 'lenis/react' function App() { useLenis((lenis) => { // 随滚动把页头淡出,progress 是 0~1 的进度 headerRef.current.style.opacity = 1 - lenis.progress }) return ( <ReactLenis root> <Header /> <Main /> </ReactLenis> ) }Vue / Nuxt同理:<vue-lenis root :options="{ autoRaf: true }">加useLenis();Nuxt 项目可直接装官方模块,见 packages/vue/nuxt。适配器都在客户端初始化实例,SSR 渲染阶段不会碰window,无需额外处理。
三个高频坑:
- 滚轮完全没反应。原因:忘了驱动动画循环。解法:传
autoRaf: true,或自己在每帧调lenis.raf(time)。 - 页面顶部高度异常、暂停滚动时出现错位。原因:没引入推荐 CSS。解法:
import 'lenis/dist/lenis.css'。 - 滚动中锚点链接失效。原因:Lenis 默认拦截锚点默认跳转,避免和平滑滚动冲突。解法:传
anchors: true;只想豁免个别元素就给它加data-lenis-prevent属性。
收尾
记住一句话就够:Lenis 是"原生滚动 + 缓动",不是假滚动,多数坑都源于忘了这一点。完整参数和方法表看 官方 README,更多玩法参考 playground/ 里的示例。
【免费下载链接】lenisSmooth scroll as it should be项目地址: https://gitcode.com/GitHub_Trending/le/lenis
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考