Skip to content

Elastic Band Follower

A copy-paste cursors component in pure HTML, CSS & vanilla JS. Zero dependencies, framework-agnostic, MIT-licensed.

CursorsHTMLJavaScriptCSSany framework

Copy into your project

HTML
<div class="nuda-cur2-elastic-band">
  <span class="nuda-cur2-elastic-band__anchor" aria-hidden="true"></span>
  <span class="nuda-cur2-elastic-band__band" aria-hidden="true"></span>
  <span class="nuda-cur2-elastic-band__dot" aria-hidden="true"></span>
</div>
JavaScript
/* Elastic Band Follower — a dot tracks the pointer while a stretchy
   band connects it back to the fixed anchor at the center. */
(function () {
  document.querySelectorAll('.nuda-cur2-elastic-band').forEach(function (area) {
    area.addEventListener('mousemove', function (e) {
      var rect = area.getBoundingClientRect();
      var dx = e.clientX - rect.left - rect.width / 2;
      var dy = e.clientY - rect.top - rect.height / 2;
      var dist = Math.hypot(dx, dy);
      var angle = (Math.atan2(dy, dx) * 180) / Math.PI;
      area.style.setProperty('--dx', dx + 'px');
      area.style.setProperty('--dy', dy + 'px');
      area.style.setProperty('--dist', dist.toFixed(1));
      area.style.setProperty('--angle', angle.toFixed(1) + 'deg');
    });

    area.addEventListener('mouseleave', function () {
      area.style.setProperty('--dx', '0px');
      area.style.setProperty('--dy', '0px');
      area.style.setProperty('--dist', '0');
    });
  });
})();
CSS
.nuda-cur2-elastic-band {
  --dx: 0px;
  --dy: 0px;
  --dist: 0;
  --angle: 0deg;
  position: relative;
  width: 100%;
  max-width: 220px;
  height: 120px;
  margin: 0 auto;
  border-radius: 12px;
  background: rgba(255,255,255,.02);
  border: 1px solid rgba(255,255,255,.08);
  overflow: hidden;
  cursor: none;
}

.nuda-cur2-elastic-band__anchor {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 10px;
  height: 10px;
  margin: -5px 0 0 -5px;
  border-radius: 50%;
  background: #63636e;
}

.nuda-cur2-elastic-band__band {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 1px;
  height: 2px;
  background: #e4ff54;
  transform-origin: left center;
  transform: rotate(var(--angle)) scaleX(var(--dist));
  opacity: .7;
  transition: transform .35s cubic-bezier(.34,1.56,.64,1),opacity .2s ease;
}

.nuda-cur2-elastic-band__dot {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 12px;
  height: 12px;
  margin: -6px 0 0 -6px;
  border-radius: 50%;
  background: #e4ff54;
  box-shadow: 0 0 10px rgba(228,255,84,.6);
  transform: translate(var(--dx),var(--dy));
  transition: transform .35s cubic-bezier(.34,1.56,.64,1);
}

@media (prefers-reduced-motion:reduce) {
  .nuda-cur2-elastic-band__band,.nuda-cur2-elastic-band__dot {
    transition: none;
  }
}

How to use Elastic Band Follower

Paste the HTML where you need it and the CSS into a global stylesheet (or a <style> tag). Every class is prefixed nuda- so it never collides with Tailwind or your own styles. Tweak the CSS custom properties to match your design system.

Works in React, Vue, Svelte, Astro, Next.js, Nuxt, Laravel Blade, Django, Rails — or a single .html file. No npm install, no build step.

More cursors components

← Browse all NudaUI components