关于 locomotive-scroll
locomotive-scroll 是面向网站开发者的 JavaScript 滚动库,适用于滚动驱动的页面。它结合平滑滚动、视口检测、视差、粘性元素和横向布局。
主要功能
- 01可配置的平滑滚动
- 02元素级视差效果
- 03视口检测与滚动事件
- 04粘性元素和横向布局
- 05程序化滚动
适用场景
- 01为落地页添加视差效果
- 02根据滚动进度同步动画
- 03构建滚动叙事网站
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ freshtechbro/ claudedesignskills --skill locomotive-scroll安装后在 Claude Code 中输入/locomotive-scroll确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/starter_locomotive/index.htmlmain.jspackage.jsonREADME.mdstyle.cssreferences/api_reference.mdgsap_integration.mdscripts/generate_config.pyintegration_helper.py详细介绍
Locomotive Scroll
使用 Locomotive Scroll 实现平滑滚动、视差效果和滚动驱动动画的综合指南。
概述
Locomotive Scroll 是一个 JavaScript 库,提供以下功能:
- 平滑滚动:支持硬件加速的平滑滚动,并可自定义缓动效果
- 视差效果:控制元素级别的速度以营造景深
- 视口检测:跟踪元素进入或离开视口的时机
- 滚动事件:监控滚动进度,以同步动画
- 粘性元素:在指定边界内固定元素
- 水平滚动:支持水平滚动布局
何时使用 Locomotive Scroll:
- 构建带有视差效果的沉浸式落地页
- 打造流畅的 Apple 风格滚动体验
- 实现滚动触发的动画
- 开发叙事类网站
- 为长篇内容增添景深和动感
权衡:
- 滚动劫持可能会影响无障碍体验(应提供禁用选项)
- 在低端设备上会带来性能开销(应检测并禁用)
- 移动设备上的触摸滚动体验有所不同(应充分测试)
- 固定定位需要变通处理
安装
npm install locomotive-scroll
// ES6
import LocomotiveScroll from 'locomotive-scroll';
import 'locomotive-scroll/dist/locomotive-scroll.css';
// Or via CDN
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/locomotive-scroll/dist/locomotive-scroll.min.css">
<script src="https://cdn.jsdelivr.net/npm/locomotive-scroll/dist/locomotive-scroll.min.js"></script>
核心概念
1. HTML 结构
每个 Locomotive Scroll 实现都需要特定的数据属性:
<div data-scroll-container>
<div data-scroll-section>
<h1 data-scroll>Basic detection</h1>
<div data-scroll data-scroll-speed="2">
Moves faster than scroll
</div>
<div data-scroll data-scroll-sticky>
Sticks within section
</div>
<div data-scroll data-scroll-id="hero">
Accessible via JavaScript
</div>
<div data-scroll data-scroll-call="fadeIn">
Triggers custom event
</div>
</div>
</div>
2. 初始化
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true,
lerp: 0.1, // Smoothness (0-1, lower = smoother)
multiplier: 1, // Speed multiplier
class: 'is-inview', // Class added to visible elements
repeat: false, // Repeat in-view detection
offset: [0, 0] // Global trigger offset [bottom, top]
});
3. 数据属性
| 属性 | 用途 | 示例 |
|---|---|---|
data-scroll | 启用检测 | data-scroll |
data-scroll-speed | 视差速度 | data-scroll-speed="2" |
data-scroll-direction | 视差方向 | data-scroll-direction="horizontal" |
data-scroll-sticky | 粘性定位 | data-scroll-sticky |
data-scroll-target | 粘性边界 | data-scroll-target="#section" |
data-scroll-offset | 触发偏移量 | data-scroll-offset="20%" |
data-scroll-repeat | 重复检测 | data-scroll-repeat |
data-scroll-call | 事件触发器 | data-scroll-call="myFunction" |
data-scroll-id | 唯一标识符 | data-scroll-id="hero" |
data-scroll-class | 自定义类 | data-scroll-class="is-visible" |
常见模式
1. 基本平滑滚动
import LocomotiveScroll from 'locomotive-scroll';
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true
});
<div data-scroll-container>
<div data-scroll-section>
<h1>Smooth scrolling enabled</h1>
</div>
</div>
2. 视差效果
<div data-scroll data-scroll-speed="0.5">
Moves slower than scroll (background effect)
</div>
<div data-scroll data-scroll-speed="3">
Moves faster than scroll (foreground effect)
</div>
<div data-scroll data-scroll-speed="-2">
Moves in opposite direction
</div>
<div data-scroll data-scroll-speed="2" data-scroll-direction="horizontal">
Moves horizontally
</div>
3. 视口检测和回调
// Track scroll progress
scroll.on('scroll', (args) => {
console.log(args.scroll.y); // Current scroll position
console.log(args.speed); // Scroll speed
console.log(args.direction); // Scroll direction
// Access specific element progress
if (args.currentElements['hero']) {
const progress = args.currentElements['hero'].progress;
console.log(`Hero progress: ${progress}`); // 0 to 1
}
});
// Call events
scroll.on('call', (value, way, obj) => {
console.log(`Event triggered: ${value}`);
// value = data-scroll-call attribute value
// way = 'enter' or 'exit'
// obj = {id, el}
});
<div data-scroll data-scroll-id="hero">Hero section</div>
<div data-scroll data-scroll-call="playVideo">Video section</div>
4. 粘性元素
<div data-scroll-section>
<div data-scroll data-scroll-sticky>
I stick while section is in view
</div>
</div>
<div id="sticky-container">
<div data-scroll data-scroll-sticky data-scroll-target="#sticky-container">
I stick within #sticky-container
</div>
</div>
5. 以编程方式滚动
// Scroll to element
scroll.scrollTo('#target-section');
// Scroll to top
scroll.scrollTo('top');
// Scroll to bottom
scroll.scrollTo('bottom');
// Scroll with options
scroll.scrollTo('#target', {
offset: -100, // Offset in pixels
duration: 1000, // Duration in ms
easing: [0.25, 0.0, 0.35, 1.0], // Cubic bezier
disableLerp: true, // Disable smooth lerp
callback: () => console.log('Scrolled!')
});
// Scroll to pixel value
scroll.scrollTo(500);
6. 水平滚动
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true,
direction: 'horizontal'
});
<div data-scroll-container>
<div data-scroll-section style="display: flex; width: 300vw;">
<div>Section 1</div>
<div>Section 2</div>
<div>Section 3</div>
</div>
</div>
7. 移动设备适配
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true,
// Tablet settings
tablet: {
smooth: true,
breakpoint: 1024
},
// Smartphone settings
smartphone: {
smooth: false, // Disable on mobile for performance
breakpoint: 768
}
});
与 GSAP ScrollTrigger 集成
Locomotive Scroll 和 GSAP ScrollTrigger 可协同工作,实现高级动画:
import LocomotiveScroll from 'locomotive-scroll';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
const locoScroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true
});
// Sync Locomotive Scroll with ScrollTrigger
locoScroll.on('scroll', ScrollTrigger.update);
ScrollTrigger.scrollerProxy('[data-scroll-container]', {
scrollTop(value) {
return arguments.length
? locoScroll.scrollTo(value, 0, 0)
: locoScroll.scroll.instance.scroll.y;
},
getBoundingClientRect() {
return {
top: 0,
left: 0,
width: window.innerWidth,
height: window.innerHeight
};
},
pinType: document.querySelector('[data-scroll-container]').style.transform
? 'transform'
: 'fixed'
});
// GSAP animation with ScrollTrigger
gsap.to('.fade-in', {
scrollTrigger: {
trigger: '.fade-in',
scroller: '[data-scroll-container]',
start: 'top bottom',
end: 'top center',
scrub: true
},
opacity: 1,
y: 0
});
// Update ScrollTrigger when Locomotive updates
ScrollTrigger.addEventListener('refresh', () => locoScroll.update());
ScrollTrigger.refresh();
实例方法
const scroll = new LocomotiveScroll();
// Lifecycle
scroll.init(); // Reinitialize
scroll.update(); // Refresh element positions
scroll.destroy(); // Clean up
scroll.start(); // Resume scrolling
scroll.stop(); // Pause scrolling
// Navigation
scroll.scrollTo(target, options);
scroll.setScroll(x, y);
// Events
scroll.on('scroll', callback);
scroll.on('call', callback);
scroll.off('scroll', callback);
性能优化
- 使用
data-scroll-section将长页面划分为多个区段:
<div data-scroll-container>
<div data-scroll-section>Section 1</div>
<div data-scroll-section>Section 2</div>
<div data-scroll-section>Section 3</div>
</div>
-
限制视差元素的数量——过多的元素可能影响性能
-
如果移动设备上的性能不佳,则禁用:
smartphone: { smooth: false }
- 在调整窗口大小时更新:
window.addEventListener('resize', () => {
scroll.update();
});
- 不再需要时销毁:
scroll.destroy();
常见问题
1. 固定定位问题
问题:平滑滚动会导致 position: fixed 元素失效
解决方案:改用 data-scroll-sticky,或将固定元素放在容器外部:
<nav style="position: fixed;">Navigation</nav>
<div data-scroll-container>
</div>
2. 图片未延迟加载
问题:所有图片同时加载
解决方案:集成延迟加载:
<img data-scroll data-src="image.jpg" class="lazy">
scroll.on('call', (func) => {
if (func === 'lazyLoad') {
// Trigger lazy load
}
});
3. 滚动位置未更新
问题:动态内容不会更新滚动位置
解决方案:在 DOM 发生变化后调用 update():
// After adding content
addDynamicContent();
scroll.update();
4. 无障碍方面的顾虑
问题:屏幕阅读器和键盘导航无法正常使用
解决方案:提供禁用选项:
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const scroll = new LocomotiveScroll({
smooth: !prefersReducedMotion
});
5. 内存泄漏
问题:路由切换时未清理滚动实例(SPA)
解决方案:卸载时务必销毁实例:
// React example
useEffect(() => {
const scroll = new LocomotiveScroll();
return () => scroll.destroy();
}, []);
6. Z 轴索引冲突
问题:视差元素的重叠顺序不正确
解决方案:为视差图层设置明确的 z-index:
[data-scroll-speed] {
position: relative;
z-index: var(--layer-depth);
}
相关技能
- gsap-scrolltrigger:高级滚动驱动动画(搭配使用)
- barba-js:与 Locomotive Scroll 集成的页面过渡效果
- scroll-reveal-libraries:适用于基础淡入效果的简易替代方案
- react-three-fiber:滚动驱动的 3D 场景(与 Locomotive 事件同步)
- motion-framer:React 中滚动动画的替代方案
资源
- 脚本:
generate_config.py- 配置生成器,integration_helper.py- GSAP 集成代码 - 参考资料:
api_reference.md- 完整 API,gsap_integration.md- GSAP ScrollTrigger 模式 - 资源文件:
starter_locomotive/- 包含示例的完整起始模板
评论
支持 Markdown