Three.js и WebGL

Для начала работы с Locomotive Scroll необходимо подключить библиотеку через npm или CDN. Основная идея библиотеки — управление скроллом с плавной инерцией и возможность триггерить события при достижении определённых элементов страницы.

import LocomotiveScroll from 'locomotive-scroll';

const scroll = new LocomotiveScroll({
    el: document.querySelector('[data-scroll-container]'),
    smooth: true,
    multiplier: 1.0,
    inertia: 0.75,
    getDirection: true,
    getSpeed: true
});
  • el — контейнер, внутри которого будет работать плавный скролл.
  • smooth — включает плавную анимацию прокрутки.
  • multiplier — скорость прокрутки относительно стандартной.
  • inertia — коэффициент замедления инерции.
  • getDirection и getSpeed — позволяют отслеживать направление и скорость движения.

Основные события и методы

Locomotive Scroll предоставляет набор событий для отслеживания позиции элементов и состояния прокрутки:

  • scroll — вызывается при каждом кадре скролла.
  • call — триггерится при достижении элемента с атрибутом data-scroll-call.
  • update — используется для обновления состояния скролла после динамических изменений контента.

Пример использования события scroll:

scroll.on('scroll', (args) => {
    console.log('Позиция скролла:', args.scroll.y);
    console.log('Скорость скролла:', args.speed);
});

Для обновления скролла после добавления элементов:

scroll.update();

Интеграция с Three.js

Использование Locomotive Scroll вместе с Three.js позволяет создавать сложные параллакс-эффекты и синхронизировать 3D-сцены с прокруткой страницы. Основная концепция — привязка позиции камеры к текущему положению скролла.

import * as THREE from 'three';

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshNormalMaterial();
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

camera.position.z = 5;

scroll.on('scroll', (args) => {
    camera.position.y = -args.scroll.y * 0.01; // синхронизация движения камеры с прокруткой
});

function animate() {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}
animate();
  • Значение -args.scroll.y * 0.01 масштабирует движение скролла для контроля чувствительности камеры.
  • Такой подход позволяет реализовать плавные 3D-переходы, где объекты перемещаются пропорционально прокрутке страницы.

Параллакс-эффекты на элементах DOM

Locomotive Scroll умеет работать с атрибутами data-scroll-speed и data-scroll-position, что позволяет создавать эффекты параллакса для DOM-элементов поверх 3D-сцены:

<div data-scroll-container>
    <div data-scroll data-scroll-speed="2">Элемент с быстрым параллаксом</div>
    <div data-scroll data-scroll-speed="-1">Элемент с обратным параллаксом</div>
</div>
  • data-scroll-speed регулирует скорость движения относительно скролла контейнера.
  • Отрицательные значения создают эффект движения в противоположном направлении.

Оптимизация производительности

Работа с Three.js и Locomotive Scroll требует внимания к производительности:

  1. Debounce событий скролла при сложных вычислениях.
  2. Использование requestAnimationFrame для обновления рендеринга 3D-сцены.
  3. Обновление размеров рендерера при ресайзе окна:
window.addEventListener('resize', () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
    scroll.update();
});
  1. Отключение ненужных элементов за пределами экрана для снижения нагрузки на GPU.

Работа с секциями и триггерами

Locomotive Scroll позволяет организовать скролл-секции и триггерить анимации в Three.js:

<section data-scroll-section>
    <div data-scroll data-scroll-call="animateCube">Секция с кубом</div>
</section>
scroll.on('call', (value, way, obj) => {
    if (value === 'animateCube') {
        if (way === 'enter') {
            gsap.to(cube.rotation, { y: Math.PI, duration: 2 });
        }
    }
});
  • way принимает значения enter или leave, позволяя запускать анимацию при входе и выходе элемента из зоны видимости.
  • Триггеры легко синхронизируются с 3D-анимациями и параллакс-эффектами на DOM.

Адаптивность и мобильные устройства

Locomotive Scroll поддерживает адаптивный скролл:

const scroll = new LocomotiveScroll({
    el: document.querySelector('[data-scroll-container]'),
    smooth: true,
    smartphone: {
        smooth: true
    },
    tablet: {
        smooth: true
    }
});
  • smartphone и tablet позволяют задать отдельные настройки для мобильных устройств.
  • Это важно для плавной интеграции с Three.js, где производительность на мобильных может отличаться.

Совмещение с GSAP и другими библиотеками

Для сложных анимаций 3D-объектов можно использовать GSAP, синхронизируя её с событиями скролла:

scroll.on('scroll', ({ scroll }) => {
    gsap.to(cube.position, {
        x: scroll.y * 0.01,
        y: Math.sin(scroll.y * 0.01),
        duration: 0.3
    });
});

Такой подход позволяет сочетать плавный скролл с динамическими 3D-анимациями, создавая эффект живой страницы с реакцией на движение пользователя.

Итоговая структура

Эффективная интеграция Locomotive Scroll с Three.js строится на трёх ключевых компонентах:

  1. Контейнер скроллаdata-scroll-container для контроля позиции и плавности прокрутки.
  2. События скролла и триггеры — синхронизация с анимациями и 3D-сценой.
  3. Параллакс-эффекты и адаптивность — DOM-элементы и 3D-объекты реагируют на движение пользователя с различной скоростью и направлением.

Такой подход обеспечивает гибкость и позволяет создавать современные интерактивные интерфейсы с плавными эффектами и высокопроизводительной визуализацией.