mcpField
L
locomotive-scroll

locomotive-scroll

github.com/freshtechbro设计与 UI1.2k2.6k 次安装49 周前更新
代码仓库

关于 locomotive-scroll

locomotive-scroll 是面向网站开发者的 JavaScript 滚动库,适用于滚动驱动的页面。它结合平滑滚动、视口检测、视差、粘性元素和横向布局。

主要功能

  1. 01可配置的平滑滚动
  2. 02元素级视差效果
  3. 03视口检测与滚动事件
  4. 04粘性元素和横向布局
  5. 05程序化滚动

适用场景

  1. 01为落地页添加视差效果
  2. 02根据滚动进度同步动画
  3. 03构建滚动叙事网站

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/freshtechbro/claudedesignskills --skill locomotive-scroll

安装后在 Claude Code 中输入/locomotive-scroll确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/starter_locomotive/
index.html
main.js
package.json
README.md
style.css
references/
api_reference.md
gsap_integration.md
scripts/
generate_config.py
integration_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);

性能优化

  1. 使用 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>
  1. 限制视差元素的数量——过多的元素可能影响性能

  2. 如果移动设备上的性能不佳,则禁用:

smartphone: { smooth: false }
  1. 在调整窗口大小时更新:
window.addEventListener('resize', () => {
  scroll.update();
});
  1. 不再需要时销毁:
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