Шарик следящий за курсором мыши лагает

154
22 мая 2022, 10:20

У меня есть шарик, который следит за курсором мыши, но проблема состоит в том, что он лагает, когда я скролю. Как избавиться от этого? Я еще использую ScrollMagic вот этот пример на всю страницу, может из-за этого. И можно ли сделать следящий шарик более мягким, то есть как-то можно получить clientX и clientY с десятыми например.

Upd: у меня еще подключен плагин SmoothScroll, скорее всего это происходит из-за него, но вот как исправить проблему, потому что нужен и мягкий скролл и шарик

var X = 0;
var Y = 0;
window.addEventListener("mousemove", function (event) {
    X = event.clientX;
    Y = event.clientY;
});
function move() {
    document.getElementById('circle').style.left = X + 'px';
    document.getElementById('circle').style.top = Y + 'px';
    setTimeout(move, 10);
}
move();
.circle-cursor {
  width: 20px;
  height: 20px;
  border-radius: 100%;
  border: 3px solid #000;
  margin: -15px 0 0 -15px;
  position: fixed;
  -webkit-transition: top 0.15s, left 0.15s;
  transition: top 0.15s, left 0.15s;
  z-index: 100;
}
<body>
  <div id="circle" class="circle-cursor circle-cursor--inner"></div>
</body>

Answer 1

Лагает, потому что у элемента есть transition: top 0.15s, left 0.15s; и на каждое изменение координат: document.getElementById('circle').style.left = X + 'px'; он срабатывает + объект перемещается посредством top left, что тоже влияет. Для любого движения в css нужно использовать transform. Ну, и, 10мс - большое значение для плавной анимации, лучше использовать requestAnimationFrame, браузер сам подберет время перерисовки.

var X = 0;
var Y = 0;
var mouse = { x: 0,y: 0 };
window.addEventListener("mousemove", function(event) {
                            // смещение в центр
  mouse.x = event.clientX - circle.offsetWidth / 2;
  mouse.y = event.clientY - circle.offsetHeight / 2;
});
function move() {
  X += (mouse.x - X) * 0.1;
  Y += (mouse.y - Y) * 0.1;
  circle.style.transform = `matrix(1, 0, 0, 1, ${X}, ${Y})`;
  requestAnimationFrame(move);
}
move();
.circle-cursor {
  width: 20px;
  height: 20px;
  border: 3px solid #000;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 100;
}
<body>
  <div id="circle" class="circle-cursor circle-cursor--inner"></div>
</body>

Answer 2

Посмотрел на ответ h и остановил анимацию
Работает и на touch устройствах

const circle = document.querySelector('#circle');
const mouse = {
  x: 0,
  y: 0
};
let y = 0;
let x = 0;
function moveFunc(event) {
  const clientX = event.changedTouches ? event.changedTouches[0].clientX : event.clientX;
  const clientY = event.changedTouches ? event.changedTouches[0].clientY : event.clientY;
  mouse.x = clientX - circle.offsetWidth / 2;
  mouse.y = clientY - circle.offsetHeight / 2;
  parallax();
}
window.addEventListener('mousemove', moveFunc);
window.addEventListener('touchmove', moveFunc);
function parallax() {
  const speed = 20; // чем меньше, тем быстрее
  const nextX = (mouse.x - x) / speed;
  const nextY = (mouse.y - y) / speed;
  if (Math.abs(nextX) > 0.05 || Math.abs(nextY) > 0.05) {
    requestAnimationFrame(parallax);
  }
  // console.log(1); // Раскомментируй для проверки, что цикл не бесконечный
  x += nextX;
  y += nextY;
  circle.style.transform = `translate(${x}px, ${y}px)`;
}
parallax();
html {
  cursor: none;
}
.circle-cursor {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 3px solid #000;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 100;
}
<body>
  <div id="circle" class="circle-cursor circle-cursor--inner"></div>
</body>

READ ALSO
Как правильно сверстать страницу?

Как правильно сверстать страницу?

Создаю приложение и нужно сверстать вот такую страницуМеня интересуют конкретно 3 контейнера: хедер, сайдбар и главный контейнер(как я понял...

263
React хранение данных пользователя

React хранение данных пользователя

Мне нужно создать форму на React где пользователь может заполнить поле "О себе" как можно организовать хранение текста пользователя? Чтобы...

137
Too Many Requests у бота Nodejs / telegraf js

Too Many Requests у бота Nodejs / telegraf js

бот периодически выкидывает Error: 429: Too Many Requests: retry after 16 когда слишком много запросов, подскажите как прописать запуск бота в документации...

194