Multiple image trails following cursor with Javascript

I’m trying to create multiple image trails for a grid. Each trail follow the cursor, I found an example on Codepen to illustrate the effect I’m looking for. The example is made with GSAP, but for this project I would prefer not using any libraries.

I’ve success to make the block of images following the cursor but I don’t find the way to reproduce the effect in Javascript.

const posts = document.querySelectorAll('.js-post');

let activePost = null;
let activeCursor = null;
let currentX = 0, 
    currentY = 0;
let aimX = 0, 
    aimY = 0;
const speed = 0.2;

const animate = () => {
  if (activeCursor) {
    currentX += (aimX - currentX) * speed;
    currentY += (aimY - currentY) * speed;
    activeCursor.style.left = currentX + 'px';
    activeCursor.style.top = currentY + 'px';
  }
  requestAnimationFrame(animate);
};

animate();

posts.forEach(post => {
  
  

post.addEventListener('mouseenter', (e) => {
    // Hide the previous grid element's cursor immediately, if any.
    if (activePost && activePost !== post && activeCursor) {
      activeCursor.classList.remove('is-visible');
      // Reset the previous cursor to 0,0 relative to its container.
      activeCursor.style.left = '0px';
      activeCursor.style.top = '0px';
    }
    activePost = post;
    activeCursor = post.querySelector('.js-cursor');

    // Get grid item's bounding rectangle for local coordinate conversion.
    const rect = post.getBoundingClientRect();
    currentX = e.clientX - rect.left;
    currentY = e.clientY - rect.top;
    aimX = currentX;
    aimY = currentY;
    
    // Position the cursor immediately at the mouse's location.
    activeCursor.style.left = currentX + 'px';
    activeCursor.style.top = currentY + 'px';
    activeCursor.classList.add('is-visible');
  });

  post.addEventListener('mousemove', (e) => {
    if (activePost === post && activeCursor) {
      const rect = post.getBoundingClientRect();
      aimX = e.clientX - rect.left;
      aimY = e.clientY - rect.top;
    }
  });

  post.addEventListener('mouseleave', () => {
    if (activePost === post && activeCursor) {
      activeCursor.classList.remove('is-visible');
      // Reset the coordinates to the top-left (0,0) of the grid element.
      activeCursor.style.left = '0px';
      activeCursor.style.top = '0px';
      // Also reset the internal coordinates so the next activation starts from 0,0.
      currentX = 0;
      currentY = 0;
      aimX = 0;
      aimY = 0;
      activePost = null;
      activeCursor = null;
    }
  });
});
body{
  font-family: 'helvetica', arial, sans-serif;
}

.grid{
  display: grid;
  width: 100%;
  grid-template-columns: repeat(2, 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;
  width: 150px;
  height: 200px;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: -1;
  opacity: 0;
  
  transition: opacity .3s ease .1s;
}

.grid__item-cursor.is-visible{
  z-index: 1;
  opacity: 1;
}

.grid__item-image{
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
<div class="grid">
  
  <div class="grid__item js-post">
    <div class="grid__item-number">1</div>
    <div class="grid__item-cursor js-cursor">
       <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2022/11/13/18/09/canyon-7589820_1280.jpg">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2022/11/02/22/33/autumn-7566201_1280.jpg">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2023/04/05/09/44/landscape-7901065_1280.jpg">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2020/09/04/16/18/mountains-5544365_1280.jpg">
    </div>
  </div>
  
  <div class="grid__item js-post">
    <div class="grid__item-number">2</div>
    <div class="grid__item-cursor js-cursor">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2022/11/13/18/09/canyon-7589820_1280.jpg">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2022/11/02/22/33/autumn-7566201_1280.jpg">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2023/04/05/09/44/landscape-7901065_1280.jpg">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2020/09/04/16/18/mountains-5544365_1280.jpg">
    </div>
  </div>
  
  <div class="grid__item js-post">
    <div class="grid__item-number">3</div>
    <div class="grid__item-cursor js-cursor">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2022/11/13/18/09/canyon-7589820_1280.jpg">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2022/11/02/22/33/autumn-7566201_1280.jpg">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2023/04/05/09/44/landscape-7901065_1280.jpg">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2020/09/04/16/18/mountains-5544365_1280.jpg">
    </div>
  </div>
  
  <div class="grid__item js-post">
    <div class="grid__item-number">4</div>
    <div class="grid__item-cursor js-cursor">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2022/11/13/18/09/canyon-7589820_1280.jpg">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2022/11/02/22/33/autumn-7566201_1280.jpg">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2023/04/05/09/44/landscape-7901065_1280.jpg">
      <img class="grid__item-image js-image" src="https://cdn.pixabay.com/photo/2020/09/04/16/18/mountains-5544365_1280.jpg">
    </div>
  </div>
  
</div>