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, щоб анімація була присутня на всіх сторінках одразу, без дублювання коду.

Результат анімації скрол-об&#39;єкта після адаптації

Сучасна альтернатива: 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.

Головне правило: скрол-анімація має доповнювати контент, а не конкурувати з ним за увагу. Один об'єкт, плавний рух, жодної нав'язливості, і ваш сайт запам'ятається.