Skip to content

Всё для WordPress, веб-разработки — и не только

🔄 Анимация объекта при прокрутке: пошаговое руководство

🔄 Анимация объекта при прокрутке: пошаговое руководство

Вы заходите на сайт, скроллите страницу, и логотип в углу плавно вращается, реагируя на каждое движение колёсика. Выглядит живо, технологично и добавляет сайту ту самую «изюминку», которую замечают.

Сделать такое вращение проще, чем кажется. Вам не нужны тяжёлые библиотеки или мегабайты анимационных фреймворков. Достаточно одного 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. Минимальный рабочий код:

1const scrollObject = document.getElementById("scrollObject");
2
3window.addEventListener("scroll", () => {
4 scrollObject.style.transform = `rotate(${window.scrollY}deg)`;
5});

Что здесь происходит: window.scrollY возвращает количество пикселей, на которое страница прокручена по вертикали. Это число подставляется в CSS-функцию rotate(), один пиксель скролла равен одному градусу поворота.

Если объект вращается слишком быстро, разделите значение на коэффициент:

1const speedFactor = window.scrollY / 2;
2const scrollObject = document.getElementById("scrollObject");
3
4window.addEventListener("scroll", () => {
5 scrollObject.style.transform = `rotate(${speedFactor}deg)`;
6});

Подберите делитель под свою длину страницы. Значение /2 замедляет вращение вдвое, /4 делает его плавным и едва заметным. Для длинных лендингов ставьте /6 или /8, чтобы объект не сделал десять полных оборотов к середине страницы.

Примечание о производительности

Событие scroll срабатывает десятки раз в секунду. На простом сайте с одним transform это незаметно, но если у вас несколько анимированных объектов или тяжёлый DOM, оберните логику в requestAnimationFrame:

1const scrollObject = document.getElementById("scrollObject");
2let ticking = false;
3
4window.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.

Главное правило: скролл-анимация должна дополнять контент, а не конкурировать с ним за внимание. Один объект, плавное движение, никакой навязчивости, и ваш сайт запомнится.