У меня есть шарик, который следит за курсором мыши, но проблема состоит в том, что он лагает, когда я скролю. Как избавиться от этого? Я еще использую 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>
Лагает, потому что у элемента есть 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>
Посмотрел на ответ 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>
Сборка персонального компьютера от Artline: умный выбор для современных пользователей