
🔄 Анимация объекта при прокрутке: пошаговое руководство
Вы заходите на сайт, скроллите страницу, и логотип в углу плавно вращается, реагируя на каждое движение колёсика. Выглядит живо, технологично и добавляет сайту ту самую «изюминку», которую замечают.
Сделать такое вращение проще, чем кажется. Вам не нужны тяжёлые библиотеки или мегабайты анимационных фреймворков. Достаточно одного div-а, нескольких строк CSS и буквально одного блока JavaScript.
Ниже, пошаговый разбор: от подготовки изображения до адаптации под мобильные экраны. Код проверенный, рабочий, без зависимостей.
💡 Быстрый обзор:
- Готовим SVG или PNG-объект и вставляем его в HTML
- Закрепляем позицию через
position: fixedи настраиваем отступы вьюпортными единицами - Добавляем JavaScript-обработчик
scroll, который поворачивает объект черезtransform: rotate() - Регулируем скорость вращения делением
window.scrollYна коэффициент - Для мобильных прописываем медиа-запрос с новой позицией и временем перехода
1. Подготовка объекта
Объектом может быть что угодно: иконка, логотип, векторная фигура, знак стрелки. Рекомендую SVG, он не теряет чёткости при трансформациях и весит копейки. Если прозрачность критична, а вектора нет, подойдёт PNG.
Разместите изображение внутри контейнера-div и положите его в body, желательно повыше. Отдельный div упрощает управление: позже вы сможете добавить соседние элементы или заменить картинку, не трогая логику позиционирования.
1 <div id="scrollContainer"> 2 <img src="img/scrollObject.svg" alt="scrollObject" id="scrollObject"> 3 </div>
Объектов может быть несколько, просто назначьте каждому уникальный id и продублируйте JS-логику с привязкой к своему элементу. Но для начала соберём один рабочий экземпляр.
2. Позиционирование через CSS
Где разместить объект? Зависит от цели:
- Правый нижний угол, миниатюрная иконка, которая не мешает контенту. Классика для блогов и портфолио.
- Левый верхний угол, индикатор положения прокрутки (progress wheel).
- По центру нижней границы, крупный декоративный элемент, привлекающий внимание к футеру.
Разберём сценарий с правым нижним углом, он универсален и не перекрывает навигацию. В CSS пропишите:
1 #scrollObject { 2 position: fixed; 3 right: 3vw; 4 bottom: 3vh; 5 top: auto; 6 width: 7vh; 7 height: auto; 8 transition: 0.1s ease-out; 9 }
Ключевое, position: fixed. Именно оно фиксирует элемент относительно окна браузера, а не документа. При скролле контент уходит, а объект остаётся на месте. Единицы vw и vh (проценты от ширины и высоты вьюпорта) автоматически подстраивают отступы под любой экран, от смартфона до 4K-монитора.
Свойство transition: 0.1s ease-out сглаживает рывки при смене положения. Для вращения его роль второстепенна, но при ресайзе или смене медиа-запроса переход выглядит опрятнее.
3. Анимация поворота на JavaScript
CSS умеет простые @keyframes, но наша задача, привязать угол поворота к положению скролла. Здесь вступает JavaScript. Минимальный рабочий код:
1 const scrollObject = document.getElementById("scrollObject"); 2 3 window.addEventListener("scroll", () => { 4 scrollObject.style.transform = `rotate(${window.scrollY}deg)`; 5 });
Что здесь происходит: window.scrollY возвращает количество пикселей, на которое страница прокручена по вертикали. Это число подставляется в CSS-функцию rotate(), один пиксель скролла равен одному градусу поворота.
Если объект вращается слишком быстро, разделите значение на коэффициент:
1 const speedFactor = window.scrollY / 2; 2 const scrollObject = document.getElementById("scrollObject"); 3 4 window.addEventListener("scroll", () => { 5 scrollObject.style.transform = `rotate(${speedFactor}deg)`; 6 });
Подберите делитель под свою длину страницы. Значение /2 замедляет вращение вдвое, /4 делает его плавным и едва заметным. Для длинных лендингов ставьте /6 или /8, чтобы объект не сделал десять полных оборотов к середине страницы.
Примечание о производительности
Событие scroll срабатывает десятки раз в секунду. На простом сайте с одним transform это незаметно, но если у вас несколько анимированных объектов или тяжёлый DOM, оберните логику в requestAnimationFrame:
1 const scrollObject = document.getElementById("scrollObject"); 2 let ticking = false; 3 4 window.addEventListener("scroll", () => { 5 if (!ticking) { 6 requestAnimationFrame(() => { 7 scrollObject.style.transform = `rotate(${window.scrollY}deg)`; 8 ticking = false; 9 }); 10 ticking = true; 11 } 12 });
requestAnimationFrame группирует вызовы в кадры синхронизации браузера (обычно 60 fps) и не гоняет пересчёт стилей на каждое событие скролла, экономия CPU и заряд батареи на мобильных.
Также добавьте will-change: transform в CSS-правило #scrollObject. Это подскажет браузеру заранее выделить слой GPU-композитинга, и вращение пойдёт аппаратно-ускоренным:
1 #scrollObject { 2 /* ... остальные свойства ... */ 3 will-change: transform; 4 }
4. Адаптация под мобильные
На экранах меньше 600 пикселей правый нижний угол может конфликтовать с меню-бургером или кнопкой «наверх». Разумное решение, сместить объект вниз по центру, чтобы он не перекрывал интерактивные элементы:
1 @media only screen and (max-width: 600px) { 2 #scrollObject { 3 transition: 0.2s ease-out; 4 margin-left: -4vh; 5 width: 8vh; 6 height: auto; 7 top: 10px; 8 left: 50%; 9 } 10 }
Объект перемещается в верхнюю часть экрана, центрируется через left: 50% с отрицательным margin-left, классический приём горизонтального центрирования. Ширина чуть увеличена (8vh вместо 7vh), чтобы компенсировать меньшее расстояние просмотра.
Обратите внимание на transition: 0.2s ease-out в медиа-запросе. При переходе с десктопа на мобильный (или при ресайзе окна) объект не «перепрыгивает» мгновенно, а плавно смещается в новую позицию за 0.2 секунды.

Если вы работаете во Vue или React, выделите скролл-объект в отдельный компонент. Так его можно повесить на корневой App.vue или в layout, чтобы анимация присутствовала на всех страницах сразу, без дублирования кода.

Современная альтернатива: CSS scroll-driven animations
В 2024-2025 браузеры на Chromium (Chrome, Edge, Opera) получили нативную поддержку animation-timeline: scroll(), анимаций, привязанных к скроллу без единой строки JavaScript. Выглядит это так:
1 @keyframes rotate { 2 to { transform: rotate(360deg); } 3 } 4 5 #scrollObject { 6 animation: rotate linear; 7 animation-timeline: scroll(); 8 }
Плюс, ноль JavaScript, минус, пока только в Chromium (Firefox и Safari в процессе внедрения). Для progressive enhancement можно комбинировать: дать CSS-версию современным браузерам, а JS-обработчик оставить фолбэком для остальных. Детали, на MDN.
⁉️🤔 Частые вопросы
Можно ли анимировать не только поворот, но и масштаб или прозрачность?
Да.
transformподдерживает несколько функций одновременно. Чтобы объект вращался и уменьшался при скролле:scrollObject.style.transform = \rotate(${window.scrollY}deg) scale(${1 - window.scrollY / 5000});. Прозрачность, черезopacityотдельно отtransform. Комбинируйте до пяти-шести параметров, но тестируйте, множественные трансформации на слабых устройствах могут дать micro-stutter. Один-два параметра плюсwill-change: transform, безопасный потолок для 60 fps.
Что лучше: SVG или PNG для анимации?
SVG, однозначно. Он масштабируется без потери чёткости при любом повороте и разрешении экрана, весит меньше, а браузер рендерит его как вектор (нет пиксельной лестницы на границах после
rotate). PNG берите, только если у вас уже готовая растровая графика и переделывать некогда. Избегайте JPEG для вращаемых объектов, после поворота артефакты сжатия становятся заметнее.
Как сделать, чтобы анимация запускалась только когда объект в зоне видимости?
Используйте
IntersectionObserver. Вместо привязки к глобальномуscrollвы отслеживаете, попал ли объект во вьюпорт, и только тогда включаете вращение. Это экономит ресурсы, когда элемент за пределами экрана. Базовый шаблон: создайте observer сthreshold: 0, в колбэке добавляйте/снимайте класс.active, а JS-обработчик скролла привяжите к наличию этого класса.
Почему на моём сайте анимация дёргается?
Три типовые причины. Первая: нет
will-change: transform, браузер не отдаёт элемент под GPU-композитинг и пересчитывает layout на каждый кадр. Вторая: к элементу применены свойства, вызывающие reflow (такие как width, height, margin или padding) внутри того же скролл-обработчика. Замените их наtransform: scale()иtransform: translate(). Третья: скролл-коллбэк выполняется безrequestAnimationFrameи плодит лишние перерисовки между кадрами. Оберните логику в rAF-паттерн (пример в разделе «Примечание о производительности»).
Обязательно ли использовать JavaScript? Есть же чистые CSS-решения.
CSS
@keyframesпривязываются ко времени, а не к позиции скролла. Да,animation-timeline: scroll()меняет правила игры, но поддержка браузерами пока неполная (см. раздел 4). На середину 2026 года JavaScript-решение сscrollY+transform, всё ещё самый надёжный кроссбраузерный способ привязать вращение к скроллу. Весь код умещается в 5 строк, не тянет зависимостей и работает от Internet Explorer 10 до свежего Chrome.
Стоит ли добавлять скролл-анимацию на ваш сайт?
Вращение объекта при прокрутке, не просто «прикольная фишка». Это микроинтеракция, которая даёт посетителю тактильную обратную связь: «я двигаю страницу, и что-то происходит». Правильно настроенная, она не раздражает и не отвлекает, а добавляет сайту индивидуальности.
Если сайт минималистичный, ограничьтесь одним небольшим объектом в углу и коэффициентом /4 или /6. Для лендингов и портфолио можно играть смелее: крупный центральный элемент с /2, комбинированная анимация поворота и масштаба, смена картинки при достижении определённого scrollY.
Главное правило: скролл-анимация должна дополнять контент, а не конкурировать с ним за внимание. Один объект, плавное движение, никакой навязчивости, и ваш сайт запомнится.



