Синхронизация в Locomotive Scroll строится на привязке поведения элементов к текущей позиции скролла. Библиотека перехватывает стандартную прокрутку, создаёт виртуальную систему координат и обновляет состояние элементов при каждом изменении положения.
Ключевой механизм — отслеживание позиции контейнера и вычисление
относительного положения каждого элемента с атрибутами
data-scroll.
При инициализации создаётся экземпляр:
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true
});
После этого:
data-scroll регистрируются во внутренней
системеСинхронизация достигается через:
scroll.y)data-scrollАктивирует элемент в системе наблюдения.
<div data-scroll></div>
data-scroll-speedОпределяет скорость движения элемента относительно прокрутки.
<div data-scroll data-scroll-speed="2"></div>
1 — стандартная скорость>1 — ускорение (параллакс)<1 — замедлениеdata-scroll-directionЗадаёт направление смещения:
<div data-scroll data-scroll-speed="1" data-scroll-direction="horizontal"></div>
Возможные значения:
vertical (по умолчанию)horizontalLocomotive Scroll предоставляет событие scroll,
позволяющее синхронизировать пользовательскую логику:
scroll.on('scroll', (args) => {
console.log(args.scroll.y);
});
Объект args содержит:
scroll.x, scroll.y — текущая позицияlimit — границы прокруткиdirection — направлениеspeed — скорость прокруткиПример синхронизации анимации:
scroll.on('scroll', ({ scroll }) => {
const opacity = scroll.y / 500;
document.querySelector('.box').style.opacity = opacity;
});
data-scroll-callПозволяет вызывать события при попадании элемента в область видимости.
<div data-scroll data-scroll-call="animateBox"></div>
Обработка:
scroll.on('call', (value, way, obj) => {
if (value === 'animateBox' && way === 'enter') {
obj.el.classList.add('active');
}
});
Параметры:
value — имя событияway — enter или leaveobj.el — DOM-элементКаждый элемент имеет внутренние параметры:
top — верхняя границаbottom — нижняя границаprogress — процент прохождения viewportИспользование progress:
scroll.on('scroll', (args) => {
args.currentElements['my-element-id']?.progress;
});
HTML:
<div
data-scroll
data-scroll-id="my-element-id">
</div>
progress изменяется от 0 до
1:
0 — элемент только появился1 — полностью прошёл экранПример:
scroll.on('scroll', (args) => {
const el = args.currentElements['my-element-id'];
if (el) {
const scale = 1 + el.progress;
el.el.style.transform = `scale(${scale})`;
}
});
Библиотека автоматически добавляет классы:
is-inview — элемент в зоне видимостиhas-scroll-scrolling — идёт прокруткаhas-scroll-smooth — включён smooth режимПример:
[data-scroll] {
opacity: 0;
transition: opacity 0.6s;
}
[data-scroll].is-inview {
opacity: 1;
}
Это позволяет синхронизировать визуальные эффекты без JavaScript.
data-scroll-sectionОптимизация синхронизации достигается разделением контента:
<section data-scroll-section>
<div data-scroll></div>
</section>
Каждая секция:
data-scroll-offsetОпределяет момент срабатывания:
<div data-scroll data-scroll-offset="100,50"></div>
Формат:
"topOffset,bottomOffset"
Параметр lerp управляет плавностью:
const scroll = new LocomotiveScroll({
smooth: true,
lerp: 0.1
});
0 — резкое движение0.1–0.2 — плавная инерция>0.3 — сильное сглаживаниеСинхронизация зависит от этого параметра:
lerp события запаздываютПри динамических изменениях DOM:
scroll.update();
Используется после:
Без вызова update синхронизация нарушается.
Метод scrollTo позволяет синхронизировать переходы:
scroll.scrollTo('#section', {
offset: -100,
duration: 800
});
Параметры:
offset — дополнительное смещениеduration — длительностьeasing — функция сглаживанияДля горизонтальных эффектов:
const scroll = new LocomotiveScroll({
el: container,
direction: 'horizontal'
});
Синхронизация работает аналогично, но через
scroll.x.
Для сложных сценариев:
function raf() {
scroll.update();
requestAnimationFrame(raf);
}
raf();
Позволяет:
1. Несоответствие позиций
data-scroll-container2. Дёргание анимаций
lerpscroll обработчике3. Элементы не реагируют
data-scrollupdate()<div data-scroll-container>
<section data-scroll-section>
<div
data-scroll
data-scroll-speed="2"
data-scroll-id="box">
</div>
</section>
</div>
scroll.on('scroll', (args) => {
const box = args.currentElements['box'];
if (box) {
const rotate = box.progress * 360;
box.el.style.transform = `rotate(${rotate}deg)`;
}
});
В этом примере:
progress