Lenis:轻量级平滑滚动库手册——3 个核心机制 + 4 个实战场景 + 配置速查
Lenis轻量级平滑滚动库手册——3 个核心机制 4 个实战场景 配置速查【免费下载链接】lenisSmooth scroll as it should be项目地址: https://gitcode.com/GitHub_Trending/le/lenisLenis 是一款轻量级、零依赖的平滑滚动库仅数 KB 体积它包裹浏览器原生滚动而非用 transform 伪造位移因此 sticky 与锚点链接原样保留。适合需要做视差、WebGL 滚动同步、滚动驱动动画的前端开发者。读完你能完成初始化、调参并接入 GSAP 与 React/Vue 生态。快速上手三步开启平滑滚动安装npm i lenis然后在入口文件里引入、初始化、加上推荐 CSS共三步。import Lenis from lenis import lenis/dist/lenis.css // 推荐 CSS负责 stopped 态与嵌套容器的 overscroll 行为 // autoRaf: true 让实例内部自动跑 requestAnimationFrame 循环 // 不开启的话必须每帧手动调 lenis.raf(time) const lenis new Lenis({ autoRaf: true }) // 位置变化的每一帧都会触发progress / velocity 等属性直接读实例即可 lenis.on(scroll, (e) { console.log(e.animatedScroll, e.progress) }) // 参考 README Setup 一节实例定义见 packages/core/src/lenis.ts不想搭构建环境也有一行版HTML 里引lenis.css和lenis.min.js然后执行new Lenis({ autoRaf: true, autoToggle: true, anchors: true, allowNestedScroll: true, naiveDimensions: true, stopInertiaOnNavigate: true })README 的 No-code usage 一节列出了这组全功能参数组合能顺带处理模态框、锚点、页面切换时的滚动复位。想看源码可以直接 clonegit clone https://gitcode.com/GitHub_Trending/le/lenis。核心机制拆解轻量与顺滑背后的 3 个设计决策包裹原生滚动而不是用 transform 伪造设计意图多数平滑滚动库用虚拟画布方案——把页面塞进容器、用 transform 位移来模拟滚动。Lenis 反其道而行真正调用浏览器滚动。packages/core/src/lenis.ts文件头的注释把链路写得明明白白监听wheel事件并preventDefault阻止原生跳动 → 归一化 delta → 累加进targetScroll→ 平滑地把scrollTo动画到目标值没有动画在跑时则退化为监听原生scroll事件。与传统做法的差异一目了然对比项Lenis原生滚动方案传统 transform 虚拟滚动实现方式真实scrollTo({ behavior: instant })驱动 window对容器做 translate 位移position: sticky/ fixed原样生效会失效需额外补偿锚点链接、键盘可达性原样保留需手工重建收益是 README 里 Runs on native scroll 那条特性position: sticky、锚点链接和无障碍交互全部不牺牲。注意setScroll里特意用behavior: instant就是为了绕过页面自己声明的scroll-behaviorCSS避免双重平滑。两种手感二选一damp 插值与固定时长缓动 Lenis 的手感由Animate类packages/core/src/animate.ts提供它不是一种算法而是两种// 参考 packages/core/src/animate.tsadvance 方法摘录 advance(deltaTime: number) { if (this.duration this.easing) { // 模式一时间驱动。按 duration 走完整条 easing 曲线 this.currentTime deltaTime const linearProgress clamp(0, this.currentTime / this.duration, 1) const easedProgress linearProgress 1 ? 1 : this.easing(linearProgress) this.value this.from (this.to - this.from) * easedProgress } else if (this.lerp) { // 模式二指数阻尼。damp 公式 1 - e^(-lambda·dt)帧率无关 this.value damp(this.value, this.to, this.lerp * 60, deltaTime) } else { // 两者都没给直接跳到终点 this.value this.to } }差异点传统库通常只给一组固定缓动曲线帧率一波动手感就漂移。damp用1 - Math.exp(-lambda * dt)packages/core/src/maths.ts做到帧率无关60Hz 和 120Hz 屏幕上衰减曲线一致默认lerp: 0.1一个数就能调滑多远给duration easing则走标准时间轴默认缓动是Math.min(1, 1.001 - 2 ** (-10 * t))。收益滚轮的滑行感更接近真实惯性而不是匀速补间。先归一化输入再统一状态输出不同硬件的滚轮 delta 量纲完全不同像素、行、页面。packages/core/src/virtual-scroll.ts把deltaMode统一换算按行滚动的设备乘以LINE_HEIGHT 100 / 6按页滚动的乘以视口尺寸再乘wheelMultiplier/touchMultiplier。触摸端还补了两处细节touchend时按sign(delta) × |velocity|^1.7touchInertiaExponent默认 1.7模拟抬手后的惯性滑行iOS 上如果手指落在文本选区手柄 40px 半径内lenis.ts的isTouchOnSelectionHandle会把事件让给系统去调整选区而不是滚动。输出侧则把状态写成 CSS 类lenis、lenis-smooth、lenis-stopped、lenis-locked随状态自动增删。配套packages/core/lenis.css做了三件小事——html.lenis { height: auto }修正页面高度给data-lenis-prevent元素加overscroll-behavior: contain防链式回弹lenis-smooth期间给 iframe 加pointer-events: none防止 iframe 吞掉 wheel 事件。另外原生滚动停下 400ms 后velocity归零、isScrolling复位动画结束后还会派发自定义scrollend事件方便下游做滚动停止逻辑。实战场景几乎一定会遇到的 4 个需求让嵌套容器保持原生滚动场景页面里有抽屉、模态框或横向卡片列表落在它们上面滚动时不希望外层页面跟着滚。思路两档粒度。粗粒度开allowNestedScroll实例会自动检测可滚动子元素并放行原生滚动细粒度用data-lenis-prevent属性另有-wheel、-touch、-vertical、-horizontal变体或prevent回调在事件冒泡路径上精确豁免。// 参考 README Nested scroll 一节 const lenis new Lenis({ allowNestedScroll: true, // 粗粒度自动识别嵌套可滚动元素 // 细粒度二选一给元素加>// 参考 README GSAP ScrollTrigger 一节 const lenis new Lenis() // 每帧把 Lenis 的滚动状态喂给 ScrollTrigger lenis.on(scroll, ScrollTrigger.update) // 用 GSAP 的 ticker 驱动 Lenis gsap.ticker.add((time) { lenis.raf(time * 1000) // ticker 的时间单位是秒转成毫秒 }) // 关闭 GSAP 的滞后平滑否则快速滚动会累积延迟 gsap.ticker.lagSmoothing(0)坑gsap.ticker回调的时间单位是秒漏乘 1000 会让动画慢十倍lagSmoothing(0)忘了关快速滚动时动画与位置脱节这是 README Troubleshooting 里专门点名的一条。开启无限滚动模式场景品牌页、作品集的网格希望滚到尽头回到开头。思路一个开关infinite: true。开启后scroll取值器会用modulo(animatedScroll, limit)按回卷值输出scrollTo的目标也会自动选距离最近的方向超过limit / 2就往回绕。// 参考 playground/infinite/test.ts new Lenis({ infinite: true, // 循环滚动scroll 取值器按 limit 自动取模 autoRaf: true, syncTouch: true, // README 注明触摸设备开启 infinite 需要它 })坑触摸设备上必须同时开syncTouch: true否则惯性触摸会直接打断回卷逻辑。搭建横向滚动区段场景产品画廊、步骤展示需要一段横向滚动的区域。思路不用全局实例单独new Lenis({ wrapper: 容器, orientation: horizontal })挂在具体容器上scrollTo支持right、end等关键字。坑orientation设为horizontal时gestureOrientation默认自动变both见lenis.ts构造参数默认值横向纵向的 delta 都会进来如果你的横向区段嵌在纵向页面里注意用eventsTarget收窄监听范围并配合overscroll控制边界处的行为。配置速查常用参数与调优点核心参数默认值均可在packages/core/src/types.ts的 JSDoc 中核对参数默认值作用autoRaffalse实例内部自跑requestAnimationFrame循环不开则需手动lenis.raf(time)lerp0.1滚轮平滑的线性插值强度0~1定义滑行距离duration未设置回落 lerp 模式动画时长秒与easing配套一旦提供lerp即被忽略easing(t) Math.min(1, 1.001 - 2 ** (-10 * t))时间模式下的缓动曲线smoothWheeltrue滚轮输入是否走平滑syncTouchfalse模拟原生触摸滚动并同步位置iOS16 可能不稳syncTouchLerp0.075触摸惯性阶段的插值系数touchInertiaExponent1.7触摸抬手后的惯性强度指数wheelMultiplier/touchMultiplier1滚轮 / 触摸输入灵敏度orientationvertical滚动轴向horizontal需配合具体wrapperinfinitefalse无限循环滚动overscrolltrue类 CSSoverscroll-behavior的边界回弹anchorsfalse接管锚点链接点击并平滑滚动allowNestedScrollfalse自动放行嵌套可滚动元素的滚动naiveDimensionsfalse用简化的尺寸计算有性能代价autoTogglefalse按 wrapper 的 overflow 自动 start/stopstopInertiaOnNavigatefalse点击站内链接时清除滚动惯性进阶参数3 条以内各附原因prevent: (node) boolean——按节点豁免平滑。比allowNestedScroll省因为不需要每次事件遍历 DOM。virtualScroll: (data) boolean——在输入被消费前改写或否决它返回false即放弃本次输入适合按住某个键时不平滑这类条件交互。naiveDimensions——改用scrollHeight - clientHeight直接算limit逻辑更简单README 标注有性能影响谨慎开启。性能调优3 条以内各附原因一定引入lenis.cssdata-lenis-prevent元素的overscroll-behavior: contain靠它生效少了会看到弹性回弹把外层页面带滚。scroll事件每帧触发回调里只读随实例带来的scroll/progress/velocity都是现成属性零布局读取确需读布局就自行节流。页面尺寸完全固定时可设autoResize: false并手动调resize()内部ResizeObserver的重算本身带 250ms 防抖packages/core/src/dimensions.ts对静态页面是一次可省的开销。生态集成与常见问题接入 React 与 Vue 官方适配层Reactpackages/react/LenisProvider包裹应用后创建实例组件内用useLenis(callback, deps, priority)注册滚动回调回调按 priority 排序执行、卸载时自动移除packages/react/src/use-lenis.ts。Vue / Nuxtpackages/vue/同构的 provider useLenisNuxt 模块在packages/vue/nuxt/module.ts集成示例见playground/nuxt/plugins/lenis.ts。吸附插件packages/snap/new Snap(lenis, { type })snap.add(500 或元素)。type支持proximity默认、mandatory、lockdistanceThreshold默认50%、判定防抖 500mspackages/snap/src/snap.ts它监听的是 Lenis 的virtual-scroll事件不与主滚动逻辑打架。常见问题现象 → 原因 → 解决现象初始化后页面滚动毫无平滑感。原因autoRaf默认false内部动画没有每帧推进。解决开autoRaf: true或在自己的循环里每帧lenis.raf(time)README Troubleshooting 第一条。现象stop()之后仍能被滚。原因.lenis-stopped { overflow: clip }依赖推荐 CSS没引入lenis.css时类名没有实际效果。解决引入lenis/dist/lenis.css。现象锚点链接点了没反应。原因Lenis 默认在滚动期间拦截锚点行为。解决anchors: true或传ScrollToOptionshash 含特殊字符也能正常定位内部走decodeURIComponent解码lenis.ts的onClick。现象平滑滚动时 iframe 内容点不动。原因lenis.css在lenis-smooth期间故意给 iframe 加pointer-events: none防止它吞掉 wheel 事件导致滚动卡死。解决需要交互时给 iframe 外层加data-lenis-prevent。现象Safari 帧率卡在 60fps省电模式只剩 30fps。原因WebKit 对requestAnimationFrame的上限README Limitations 列出的已知 bug与系统省电策略。解决属环境限制而非参数问题不要为 Safari 单独加补帧逻辑。继续去哪儿核心源码packages/core/src/lenis.ts、选项类型与默认值packages/core/src/types.ts插件与适配层snap 吸附插件、React 适配层、Vue 与 Nuxt 模块可运行的演示playground 目录core / horizontal / infinite / snap / touch-debug 各有独立示例想深入原理先读 MANIFESTO.md参与开发看 CONTRIBUTING.mdlenis.ts文件头那六行注释加maths.ts里的damp就是这套滚动系统的全部骨架——改一个参数之前先看这两处比翻文档更快。【免费下载链接】lenisSmooth scroll as it should be项目地址: https://gitcode.com/GitHub_Trending/le/lenis创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

降AI率全指南:从检测原理到8款工具评测与人工润色技巧

降AI率全指南:从检测原理到8款工具评测与人工润色技巧

1. 别急着找工具:先搞懂降AI率到底在降什么每次期末季,总能在各种群里看到有人问“有没有靠谱的降AI率工具”。尤其本科生写课程论文、毕业设计开题报告的时候,辛辛苦苦写了三千字,丢进查重系统一看,红字标得触目惊心&…

2026/9/23 4:51:14 阅读更多 →
Noi浏览器批量提问教程:如何把同一个问题一次发给5个AI

Noi浏览器批量提问教程:如何把同一个问题一次发给5个AI

Noi浏览器批量提问教程:如何把同一个问题一次发给5个AI 【免费下载链接】Noi 🚀 Less chaos. More flow. 项目地址: https://gitcode.com/GitHub_Trending/no/Noi 需要向ChatGPT、Claude、通义千问等多个AI平台索要同一问题的答案时,N…

2026/9/23 5:26:29 阅读更多 →
ESP32语音助手音频打断问题全解析:旧声音为何迟迟不停?

ESP32语音助手音频打断问题全解析:旧声音为何迟迟不停?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/22 6:56:11 阅读更多 →

最新新闻

fidder避坑指南

fidder避坑指南

3个步骤搞定Fiddler环境,源码解析助你避坑 配置环境就卡半天,这大概是每个后端或测试工程师在接入 Fiddler 时的共同噩梦。你下载了安装包,双击运行,结果浏览器毫无反应,或者抓包全是乱码,甚至直接导致服务崩溃。别急,今天我不讲虚的…

2026/9/23 9:48:25 阅读更多 →
前端实现table表格高亮demo,vue+elementui

前端实现table表格高亮demo,vue+elementui

<template><div><el-table ref"myTable" :data"tableData" style"width:100%"><el-table-column prop"data" lable"日期" width"180"><template slot-scope"scope"><…

2026/9/23 9:48:25 阅读更多 →
unity urp的内置后期效果参数

unity urp的内置后期效果参数

效果参数详解1. Tonemapping 色调映射参数含义展厅 Mode映射算法&#xff1a;None&#xff08;不映射&#xff0c;易死白&#xff09;/ Neutral&#xff08;中性&#xff09;/ ACES&#xff08;电影感&#xff0c;对比更稳&#xff09;ACES2. Bloom 泛光参数含义推荐Threshold多…

2026/9/23 9:48:25 阅读更多 →
惠普1020打印机驱动:3步解决报错,兼顾性能优化实战

惠普1020打印机驱动:3步解决报错,兼顾性能优化实战

惠普1020打印机驱动:3步解决报错,兼顾性能优化实战 刚接手新设备,打印测试页直接弹出一堆红色报错,StackTrace 满屏乱窜,根本看不懂哪行代码崩了?别急,这不仅是驱动问题,更是系统调用链路的 性能优化…

2026/9/23 9:48:25 阅读更多 →
5分钟搞定必死陷阱:Python与Go进程控制完整示例对比

5分钟搞定必死陷阱:Python与Go进程控制完整示例对比

5分钟搞定必死陷阱:Python与Go进程控制完整示例对比 官方文档翻了三遍还是晕头转向?别急,直接上干货。很多老铁在搞自动化运维或者后端服务时,卡在进程管理的“必死”问题上,其实就是没看懂 完整示例…

2026/9/23 9:48:25 阅读更多 →
UVC摄像头开发实战:C++与C#双语言采集方案与避坑指南

UVC摄像头开发实战:C++与C#双语言采集方案与避坑指南

简介&#xff1a;这份资源面向从事USB摄像头开发的C与C#程序员&#xff0c;聚焦UVC&#xff08;USB Video Class&#xff09;设备驱动与应用开发这一细分领域。UVC标准让摄像头无需专用驱动即可在Windows、Linux、macOS上完成视频传输&#xff0c;而包内代码正是围绕该协议展开…

2026/9/23 9:47:24 阅读更多 →

日新闻

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A…

2026/9/23 0:00:23 阅读更多 →
2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我 刚把开发环境的显示器从1080P换到2K,跑老项目直接报错,版本升级后 API…

2026/9/23 0:01:25 阅读更多 →
3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点 官方文档翻了三遍还是云里雾里?别急,美眉图在实战项目中常被用来做数据可视化,但它的原理比你想的简单。今天咱们直接上手,用一个完整的小项目把美眉图跑通,不再死磕那些冗长的理论说明。…

2026/9/23 0:01:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事&#xff1a;用Flutter给OpenHarmony做一款游戏集合类的App&#xff0c;说白了就是把若干小游戏塞进一个壳里&#xff0c;用统一入口分发。这个方向本身不算新鲜&#xff0c;真正让我花了不少心思的&#xff0c;是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档&#xff0c;最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事&#xff1a;今天在表后面多加了两个空白行&#xff0c;明天给客户交稿前发现整个章节的编号全部错位&#xff0c;光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年&#xff0c;说实话&#xff0c;第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年&#xff0c;流量惨淡、功能臃肿、代码自己都懒得看第二遍之后&#xff0c;我才慢慢琢磨明白一个道理&#xff1a;第一个网站是练手&…

2026/9/22 8:51:04 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践&#xff1a;原型怎样变成可用功能分类&#xff1a;[AI/大模型]细分主题&#xff1a;AI 增强型 CI/CD 流水线自动化与 GitOps 实践&#xff1a;Agent 工作流、工具调用与任务拆解&#xff1a;从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战&#xff1a;复盘记录怎样真正派上用场分类&#xff1a;[工程技术]细分主题&#xff1a;Kubernetes 生产环境运维与排障实战&#xff1a;可复制的项目复盘模板与决策记录大部分团队的事故复盘报告&#xff0c;最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理&#xff1a;核心链路应该先拆哪一步分类&#xff1a;[工程技术]细分主题&#xff1a;Docker 容器化技术与镜像安全管理&#xff1a;核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用&#xff08;包含 Web 接口、后台…

2026/9/22 2:43:42 阅读更多 →