<body>
  <div class='cursor'>
    <div class="pointer-container">
      <div class="pointer"></div>
    </div>
    <div class="circle-container">
      <div class="circle"></div>
    </div>
  </div>
  <main>
    <a>Link Here</a>
    <h1>Lorem Ipsum</h1>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore aspernatur, magnam officiis, consectetur cumque cum, quo non quia debitis suscipit totam rem rerum. Totam repellat molestias, assumenda harum iusto fugit.</p>
    <a>Link Here</a>
    <h1>Lorem Ipsum</h1>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore aspernatur, magnam officiis, consectetur cumque cum, quo non quia debitis suscipit totam rem rerum. Totam repellat molestias, assumenda harum iusto fugit.</p>
  </main>
</body>


  

  
  
/* resets */
html {
  box-sizing: border-box;
}

*, *:before, *:after {
  box-sizing: inherit;
}

/* main */

body{
  cursor: none;
  min-height: 150vh;
}

a {
  display: block;
  width: fit-content;
  block-size: fit-content;
  padding: 10px;
  background-color: gray;
  cursor: pointer;
}

.pointer-container,
.circle-container {
  position: fixed;
  pointer-events: none;
  width: 80px;
  height: 80px;
}

.pointer,
.circle {
  width: 100%;
  height: 100%;
  border-radius: 50%;
}

/* cursor */
.pointer-container {
  padding: 35px;
  transition: transform .1s;
  
  .pointer {
    background-color: black;
  }
}

.circle-container {
  display: flex;
  width: 80px;
  height: 80px;
  padding: 20px;
  transition:
    transform .18s linear,
    padding .2s linear;
  
  .circle {
    width: 100%;
    height: 100%;
    border: 3px solid black;
  }
  
  &.a-hover {
    padding: 40px;
  }
}

View Compiled
window.addEventListener('DOMContentLoaded', function(event){
  
  const pointer = document.querySelector('.pointer-container')
  const circle = document.querySelector('.circle-container')

  const moveCursor = function (event) {
    const mouseY = event.clientY - 45;
    const mouseX = event.clientX - 45;

    requestAnimationFrame(function(event) {
      circle.style.transform = `translate(${mouseX}px, ${mouseY}px)`;
      pointer.style.transform = `translate(${mouseX}px, ${mouseY}px)`;
    })
  }

  const hoverHandler = function (event) {
    const entered = event.type === 'mouseenter'
    circle.classList.toggle('a-hover', entered)
  }

  const links = document.querySelectorAll('a')

  document.body.addEventListener('mousemove', _.throttle(moveCursor, 0))

  links.forEach(function(link) {
    link.addEventListener('mouseenter', hoverHandler)
    link.addEventListener('mouseleave', hoverHandler)
  })
})




Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdn.jsdelivr.net/npm/@mig8447/lodash-debounce-throttle@4.17.5/dist/lodash-debounce-throttle.min.js