Locomotive Scroll 实战指南:基于 Lenis 的轻量级视口检测与平滑滚动视差方案
【免费下载链接】locomotive-scroll Detection of elements in viewport smooth scrolling with parallax.项目地址https://gitcode.com/gh_mirrors/lo/locomotive-scroll点击查看免费下载本文以开源仓库 locomotive-scroll 的官方 README 为主线系统讲解这一轻量级现代滚动库的安装、初始化、核心特性与源码实现原理。读者将掌握如何通过data-scroll系列声明式属性实现元素视口检测、视差动画与平滑滚动并能基于源码理解双 Intersection Observer 架构、触屏降级等底层机制直接上手落地到自己的前端项目中。什么是 Locomotive ScrollLocomotive Scroll 是一个轻量、现代的滚动库核心能力是检测视口内的元素并为其提供平滑滚动与视差动画项目源码注释原语Detection of elements in viewport smooth scrolling with parallax见 packages/lib/index.ts。它的技术底座是 Lenis 中描述为Detection of elements in viewport smooth scrolling with parallax effects。它在设计上有几个关键取向声明式驱动无需编写大量 JS通过 HTML 属性如data-scroll-speed、data-scroll-call即可为任意元素开启视口检测与视差效果TypeScript 优先整个库完全使用 TypeScript 编写并导出完整类型定义支持 IDE 智能提示性能敏感通过双 Intersection Observer 区分「触发类」与「动画类」元素避免每帧全量计算。快速开始Quick Start1. 安装npm install locomotive-scroll从仓库的 packages/lib/package.json 可以看到该库声明了lenis: 1.3.17作为唯一运行时依赖并要求node 20。2. 引入 JavaScriptimport LocomotiveScroll from locomotive-scroll; const scroll new LocomotiveScroll();实例化时会自动完成三件事见 packages/lib/index.ts 的_init方法创建一个 Lenis 实例new Lenis({ ...this.lenisOptions })承载平滑滚动在requestAnimationFrame中创建Core实例扫描[data-scroll]元素并注册两套 Intersection Observer默认自动启动渲染循环autoStart默认为true。3. 引入基础样式import locomotive-scroll/dist/locomotive-scroll.css;4. 在 HTML 中声明滚动元素div>link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/locomotive-scroll/bundled/locomotive-scroll.css / script srchttps://cdn.jsdelivr.net/npm/locomotive-scroll/bundled/locomotive-scroll.min.js/script script const locomotiveScroll new LocomotiveScroll(); /script更完整的安装与使用细节见 安装指南 与 使用指南。核心特性解析README 列出了六项核心特性下面逐条结合源码展开。轻量Lightweight打包体积仅9.4kBgzippedREADME 明确标注。作为对比这一定位决定了它适合作为页面滚动增强层而不是重型动画框架的替代品。TypeScript 优先TypeScript First整个库packages/lib/index.ts、packages/lib/types.ts 及 core 目录均为 TypeScript 实现所有公开选项、属性、回调与实例方法都有完整类型声明。例如 packages/lib/types.ts 中定义了ILocomotiveScrollOptionsexport interface ILocomotiveScrollOptions { lenisOptions?: LenisOptions; triggerRootMargin?: string; rafRootMargin?: string; autoStart?: boolean; scrollCallback?(scrollValues: ILenisScrollValues): void; initCustomTicker?(render: () void): void; destroyCustomTicker?(render: () void): void; }实例化时还会把版本号写入window.locomotiveScrollVersion见 packages/lib/index.ts便于排查页面中运行的版本。基于 Lenis 构建Built on Lenis使用 Lenis最新稳定版仓库锁定的lenis 1.3.17直接获得其性能优化过的平滑滚动内核。所有 Lenis 实例配置通过lenisOptions透传见 packages/lib/index.ts因此你既能使用 Locomotive 的声明式 API也能完整控制 Lenis 的底层行为lerp、duration、orientation等。双 Intersection ObserverDual Intersection Observers这是 Locomotive Scroll 最核心的架构创新。在 packages/lib/core/Core.ts 的_init中所有[data-scroll]元素会被拆分为两批注册到两个独立的IntersectionObserver上Observer默认 rootMargin服务对象职责Trigger IO-1px -1px -1px -1px仅需「进出视口」触发的元素data-scroll、data-scroll-class、data-scroll-call等触发inview/outOfView回调、添加类名元素离开视口后若未声明data-scroll-repeat则自动unobserve见 packages/lib/core/IO.tsRAF IO100% 100% 100% 100%上下左右各扩展一个视口尺寸需要每帧计算的元素含data-scroll-offset、data-scroll-position、data-scroll-css-progress、data-scroll-event-progress、data-scroll-speed进入扩展区域后开启该元素的setInteractivityOn纳入每帧 RAF 更新队列离开后关闭见 packages/lib/core/IO.ts判断元素归属的_checkRafNeeded逻辑在 packages/lib/core/Core.ts只有使用了需要连续插值计算的属性如非默认的scrollOffset/scrollPosition、合法的scrollSpeed、scrollCssProgress/scrollEventProgress时才走 RAF 队列其余仅触发类元素完全由 IO 事件驱动。这避免了「所有元素每帧参与计算」的性能浪费。智能触屏检测Smart Touch Detection构造时通过ontouchstart in window || navigator.maxTouchPoints 0判断是否为触屏设备见 packages/lib/index.ts。触屏设备上视差效果data-scroll-speed默认自动禁用以换取原生滚动的流畅度渲染回调中的smooth参数为falseScrollElement会跳过 transform 位移见 packages/lib/core/ScrollElement.ts若确需在移动端启用视差可给元素加data-scroll-enable-touch-speed属性。无障碍Accessible保留原生滚动条不做自定义滚动条遮罩因此键盘、屏幕阅读器与系统滚动行为不受干扰支持键盘导航与标准 ARIA 语义滚动定位scrollTo完全基于标准 DOM 定位。视口检测与视差的核心原理理解data-scroll系列属性前先看它在源码中的落地。核心类ScrollElementpackages/lib/core/ScrollElement.ts在构造时解析元素上的全部data-*属性this.attributes { scrollClass: this.$el.dataset[scrollClass] ?? is-inview, scrollOffset: this.$el.dataset[scrollOffset] ?? 0,0, scrollPosition: this.$el.dataset[scrollPosition] ?? start,end, scrollCssProgress: this.$el.dataset[scrollCssProgress] ! undefined, scrollEventProgress: this.$el.dataset[scrollEventProgress] ?? null, scrollSpeed: this.$el.dataset[scrollSpeed] ! undefined ? parseFloat(this.$el.dataset[scrollSpeed]) : null, scrollRepeat: this.$el.dataset[scrollRepeat] ! undefined, scrollCall: this.$el.dataset[scrollCall] ?? null, scrollIgnoreFold: this.$el.dataset[scrollIgnoreFold] ! undefined, scrollEnableTouchSpeed: this.$el.dataset[scrollEnableTouchSpeed] ! undefined, };每帧渲染时进入 RAF 队列的元素会计算progress0~1 的进度值并映射为视差位移packages/lib/core/ScrollElement.tsdisplacement progress × containerSize × speed × -1其中containerSize是 Lenis 滚动容器的高垂直或宽水平progress对普通元素映射到-1 ~ 1、对首屏fold内元素映射到0 ~ 1——这就是为什么速度值相对容器尺寸而非像素不同屏幕下效果自然缩放。数学工具函数clamp、mapRange、normalize等位于 packages/lib/utils/maths.ts。data-scroll 系列属性速查下面是仓库文档 属性参考 中定义的完整属性清单均与 README 强调的「视口检测 视差」直接相关。data-scroll启用检测div />div>div />data-scroll-class自定义进入类名类型string默认is-inviewdiv>div>div>window.addEventListener(scrollEvent, (e) { const { target, way, from } e.detail; console.log(target: ${target}, way: ${way}, from: ${from}); });data-scroll-css-progressCSS 变量进度声明后元素上会写入 CSS 变量--progress0~1可直接用于 CSS 动画对应源码常量PROGRESS_CSS_VAR --progress见 packages/lib/core/ScrollElement.ts[data-scroll-css-progress] { opacity: var(--progress); }data-scroll-event-progress事件进度元素滚动过程中持续派发指定自定义事件detail携带target与progress0~1div>window.addEventListener(progressEvent, (e) { const { target, progress } e.detail; console.log(target: ${target}, progress: ${progress}); });data-scroll-to 系列平滑定位属性说明data-scroll-to阻止默认点击并平滑滚动到目标目标取自元素href或data-scroll-to-hrefdata-scroll-to-href自定义滚动目标CSS 选择器data-scroll-to-offset目标偏移数字等效scroll-padding-topdata-scroll-to-duration滚动动画时长秒a href#section>!-- 触屏设备默认禁用视差 -- div>const locomotiveScroll new LocomotiveScroll({ lenisOptions: { wrapper: window, content: document.documentElement, lerp: 0.1, duration: 1.2, orientation: vertical, gestureOrientation: vertical, smoothWheel: true, smoothTouch: false, wheelMultiplier: 1, touchMultiplier: 2, normalizeWheel: true, easing: (t) Math.min(1, 1.001 - Math.pow(2, -10 * t)), }, });triggerRootMargin / rafRootMargin默认-1px -1px -1px -1px/100% 100% 100% 100%分别控制 Trigger IO 与 RAF IO 的rootMargin见 packages/lib/core/Core.ts 中的默认常量TRIGGER_ROOT_MARGIN与RAF_ROOT_MARGIN。RAF 默认扩展 100% 视口是为了让data-scroll-speed这类元素在尚未进入视口前就开始计算位移。const locomotiveScroll new LocomotiveScroll({ triggerRootMargin: -1px -1px -1px -1px, rafRootMargin: 100% 100% 100% 100%, });autoStart类型boolean默认true关闭自动启动后可手动控制渲染循环const locomotiveScroll new LocomotiveScroll({ autoStart: false }); setTimeout(() { locomotiveScroll.start(); }, 2000);scrollCallback类型function订阅 Lenis 的scroll事件回调参数为{ scroll, limit, velocity, direction, progress }类型见 packages/lib/types.ts 的ILenisScrollValuesfunction onScroll({ scroll, limit, velocity, direction, progress }) { console.log(scroll, limit, velocity, direction, progress); } const locomotiveScroll new LocomotiveScroll({ scrollCallback: onScroll });initCustomTicker / destroyCustomTicker类型function用外部 ticker如 GSAP替换默认的requestAnimationFrame循环。两者必须成对声明否则会在控制台给出警告见 packages/lib/index.tsimport { gsap } from gsap/all; const locomotiveScroll new LocomotiveScroll({ initCustomTicker: (render) { gsap.ticker.add(render); }, destroyCustomTicker: (render) { gsap.ticker.remove(render); }, });实例方法Methods完整参考见 方法文档所有方法在 packages/lib/index.ts 中均有对应实现。方法说明start()/stop()手动启动/停止渲染循环配合autoStart: false使用start/stop实现见 packages/lib/index.tsdestroy()销毁实例停止循环、解绑事件、销毁 Lenis 与 Core见 packages/lib/index.tsresize()手动触发重算库已通过 Lenis 的onContentResize/onWrapperResize自动同步尺寸变化见 packages/lib/index.ts一般无需手动调用scrollTo(target, options)平滑滚动到目标target可为数字、HTMLElement或字符串CSS 选择器/关键字top、bottom等options支持offset、lerp、duration、immediate、lock、force、easing、onComplete见 packages/lib/index.tsaddScrollElements($newContainer)/removeScrollElements($oldContainer)动态 DOMAjax 渲染等场景下增量注册/注销容器内的[data-scroll]元素见 packages/lib/index.ts 与 packages/lib/core/Core.tsconst locomotiveScroll new LocomotiveScroll({ autoStart: false }); requestAnimationFrame(() { locomotiveScroll.start(); }); // 动态插入内容后 const $newContainer document.getElementById(containerToAdd); locomotiveScroll.addScrollElements($newContainer);水平滚动与自定义滚动容器水平滚动orientation: horizontal时推荐附加以下 CSS文档 使用指南 明确建议/* Only necessary with horizontal scrolling */ html[data-scroll-orientationhorizontal] { body { width: fit-content; } [data-scroll-container] { display: flex; } }自定义滚动容器const locomotiveScroll new LocomotiveScroll({ lenisOptions: { wrapper: document.querySelector(.scroll-container), content: document.querySelector(.scroll-content), }, });div classscroll-container styleheight: 100vh; overflow: hidden; div classscroll-content div>赞分享【免费下载链接】locomotive-scroll Detection of elements in viewport smooth scrolling with parallax.项目地址https://gitcode.com/gh_mirrors/lo/locomotive-scroll点击查看免费下载相关推荐Locomotive Scroll v5 技术详解基于 Lenis 的视口检测、平滑滚动与视差动画实践Locomotive Scroll v5 技术详解基于 Lenis 的视口检测、平滑滚动与视差动画实践 导读 本文是 Locomotive Scroll v5Locomotive Scroll 5.x 使用指南视口检测、视差平滑滚动与 Lenis 集成Locomotive Scroll 5.x 使用指南视口检测、视差平滑滚动与 Lenis 集成 本指南围绕当前仓库中 packages/lib 下的核心库展开Locomotive-Scroll 终极指南从零掌握视差滚动与视口检测Locomotive Scroll 终极指南从零掌握视差滚动与视口检测 Locomotive Scroll 是一个功能强大的JavaScript库专门上一篇ConEmu高级配置打造个性化Windows终端环境下一篇3步掌握柔性车间智能调度图神经网络与强化学习实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考