I have a grid with multiple items. Each item has its own custom cursor with the div .grid__item-cursor.
What I'm trying to achieve is when hovering an item, its cursor follows the mouse with a smooth speed.
The issue is when hovering an item, all the cursors from the document move at the same time. And there is also too much distance between the custom cursor and the mouse.
const cursors = document.querySelectorAll(".js-cursor");
let aimX = 0;
let aimY = 0;
cursors.forEach((cursor) => {
let currentX = 0;
let currentY = 0;
let speed = 0.2;
const animate = function () {
currentX += (aimX - currentX) * speed;
currentY += (aimY - currentY) * speed;
cursor.style.left = currentX + "px";
cursor.style.top = currentY + "px";
requestAnimationFrame(animate);
};
animate();
});
const posts = document.querySelectorAll(".js-post");
posts.forEach((post) => {
const cursor = post.querySelector(".js-cursor");
post.addEventListener("mousemove", function (event) {
aimX = event.pageX;
aimY = event.pageY;
});
post.addEventListener("mouseenter", function () {
cursor.classList.add("is-visible");
});
post.addEventListener("mouseleave", function () {
cursor.classList.remove("is-visible");
});
});
body {
font-family: "helvetica", arial, sans-serif;
}
.grid {
display: grid;
width: 100%;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 1rem;
grid-row-gap: 1rem;
}
.grid__item {
display: flex;
justify-content: center;
align-content: center;
position: relative;
padding: 25%;
overflow: hidden;
background-color: #333;
}
.grid__item-number {
color: #888;
font-size: 5rem;
}
.grid__item-cursor {
position: absolute;
top: 0;
left: 0;
padding: 0.25em;
background-color: red;
}
.grid__item-cursor.is-visible {
background-color: yellow;
}
<div class="grid">
<div class="grid__item js-post">
<div class="grid__item-number">1</div>
<div class="grid__item-cursor js-cursor">Read more</div>
</div>
<div class="grid__item js-post">
<div class="grid__item-number">2</div>
<div class="grid__item-cursor js-cursor">Read more</div>
</div>
<div class="grid__item js-post">
<div class="grid__item-number">3</div>
<div class="grid__item-cursor js-cursor">Read more</div>
</div>
<div class="grid__item js-post">
<div class="grid__item-number">4</div>
<div class="grid__item-cursor js-cursor">Read more</div>
</div>
<div class="grid__item js-post">
<div class="grid__item-number">5</div>
<div class="grid__item-cursor js-cursor">Read more</div>
</div>
<div class="grid__item js-post">
<div class="grid__item-number">6</div>
<div class="grid__item-cursor js-cursor">Read more</div>
</div>
<div class="grid__item js-post">
<div class="grid__item-number">7</div>
<div class="grid__item-cursor js-cursor">Read more</div>
</div>
<div class="grid__item js-post">
<div class="grid__item-number">8</div>
<div class="grid__item-cursor js-cursor">Read more</div>
</div>
</div>
animatefunction running in an interval, for all of them, all the time.