Anime.js предоставляет мощные средства для создания анимации элементов на странице, управляемой скроллом. Для реализации такого эффекта необходимо комбинировать возможности anime.js с событиями прокрутки браузера. Основной подход заключается в изменении свойств объектов в зависимости от текущей позиции скролла, что позволяет создавать плавные и интерактивные переходы.
Для отслеживания скролла используется объект window и
событие scroll:
window.addEventListener('scroll', () => {
const scrollY = window.scrollY || window.pageYOffset;
});
Переменная scrollY хранит текущее смещение страницы по
вертикали. Это значение становится ключевым параметром для вычисления
прогресса анимации.
В отличие от классических анимаций, управляемых таймером или циклом, анимация скролла требует прямой связи со значением прокрутки. Например, для изменения прозрачности элемента в зависимости от скролла можно использовать следующую конструкцию:
const box = document.querySelector('.box');
window.addEventListener('scroll', () => {
const scrollY = window.scrollY;
const progress = Math.min(scrollY / 500, 1); // нормализуем значение до 0–1
anime({
targets: box,
opacity: progress,
duration: 0,
easing: 'linear'
});
});
Ключевые моменты:
duration: 0 гарантирует мгновенное обновление значения
без задержки, чтобы анимация точно соответствовала скроллу.progress вычисляется как отношение текущего скролла к
заданной длине анимации, что позволяет создавать динамические эффекты на
всей странице.Для придания более выразительных эффектов используют CSS-трансформации:
window.addEventListener('scroll', () => {
const scrollY = window.scrollY;
const progress = Math.min(scrollY / 800, 1);
anime({
targets: box,
translateX: progress * 300, // смещение по X
rotate: progress * 360, // вращение
scale: 1 + progress * 0.5,
duration: 0,
easing: 'linear'
});
});
Особенности:
progress позволяет плавно
масштабировать, вращать и перемещать элементы.duration: 0 делает анимацию «жестко
привязанной» к скроллу, без временной интерполяции.Для сложных интерфейсов часто требуется запуск нескольких анимаций
одновременно при скролле. Это реализуется через массив
targets или независимые вызовы anime():
const items = document.querySelectorAll('.item');
window.addEventListener('scroll', () => {
const scrollY = window.scrollY;
const progress = Math.min(scrollY / 1000, 1);
items.forEach((item, index) => {
anime({
targets: item,
translateY: progress * 50 * (index + 1),
opacity: progress,
duration: 0,
easing: 'linear'
});
});
});
Преимущества:
Анимации на скролле могут нагрузить браузер. Для повышения производительности используют:
requestAnimationFrame для
синхронизации обновлений с кадрами рендеринга:let ticking = false;
window.addEventListener('scroll', () => {
if (!ticking) {
window.requestAnimationFrame(() => {
const scrollY = window.scrollY;
const progress = Math.min(scrollY / 500, 1);
anime({
targets: box,
translateY: progress * 200,
opacity: progress,
duration: 0,
easing: 'linear'
});
ticking = false;
});
ticking = true;
}
});
targets, анимация которых происходит одновременно.Для эффектов «входа в экран» элементов используют проверку положения относительно окна:
const sections = document.querySelectorAll('.section');
function animateSections() {
const windowHeight = window.innerHeight;
sections.forEach(section => {
const rect = section.getBoundingClientRect();
const progress = Math.min(Math.max((windowHeight - rect.top) / windowHeight, 0), 1);
anime({
targets: section,
translateY: 50 * (1 - progress),
opacity: progress,
duration: 0,
easing: 'linear'
});
});
}
window.addEventListener('scroll', animateSections);
animateSections();
Пояснения:
getBoundingClientRect() позволяет вычислить, насколько
элемент видим в текущем окне.Anime.js отлично интегрируется с библиотеками, которые управляют
скроллом, такими как Locomotive Scroll или
GSAP ScrollTrigger. В таких случаях значения скролла
получают из API этих библиотек, но логика применения к
anime() остаётся идентичной: вычисление прогресса →
обновление свойств элементов мгновенно.