JSFiddle - React, Tailwind, and code Playground

HTML

<div class="crsr1 hidden">A</div>
<div class="crsr2 hidden">T</div>

CSS

body {
  margin: 0px;
}

.crsr1, .crsr2 {
  width: 76px;
  height: 76px;
  border: 2px solid #000;
  border-radius: 50%;
  text-align: center;
  font-size: 20px;
}

.cursor {
  position: fixed;
  cursor: default;
  user-select: none;
  left: var(--tleft);
  top: var(--ttop);  
  transform: rotate(var(--angle)) scaleY(var(--scale));
}
.transitioned {
  transition: transform var(--smoothness) linear;
}
.hidden {
  display: none;
}

JavaScript

class Follower {
  // Default options
  threshold = 4;
  smoothness = 10;
  stretchRate = 100;
  stretchMax = 300;
  stretchSlow = 125;
  baseAngle = Math.PI / 2;
  // Class initialization
  initialized = false;
  // Listens mousemove event
  static moveCursor (e) {
    if (Follower.active) {
      Follower.prototype.crsrMove.call(Follower.active, e);
    }
  }
  static active = null;
  // Adds/removes mousemove listener
  static init () {
    if (this.initialized) {
      document.removeEventListener('mousemove', this.moveCursor);
      if (this.active) {
        this.active.cursor.classList.add('hidden');
      }
    } else {
      document.addEventListener('mousemove', this.moveCursor);
    }
    this.initialized = !this.initialized;
  }
  // Base values of instances
  x = -1000;
  y = -1000;
  angle = 0;
  restoreTimer = -1;
  stamp = 0;
  speed = [0];
  // Prototype properties
  constructor (selector) {
    this.cursor = document.querySelector(selector);
    this.restore = this.restore.bind(this);
  }
  // Activates a new cursor
  activate (options = {}) {
  	// Remove the old cursor
    if (Follower.active) {
      Follower.active.cursor.classList.add('hidden');
      Follower.active.cursor.classList.remove('cursor', 'transitioned');
    }
  	// Set the new cursor
    Object.assign(this, options);
    this.setCss = this.cursor.style.setProperty.bind(this.cursor.style);
    this.cursor.classList.remove('hidden');
    this.cHW = this.cursor.offsetWidth / 2;
    this.cHH = this.cursor.offsetHeight / 2;
    this.setCss('--smoothness', this.smoothness / 100 + 's');
    this.cursor.classList.add('cursor');
    setTimeout(() => this.cursor.classList.add('transitioned'), 0); // Snap to the current angle
    this.crsrMove({clientX: this.x, clientY: this.y});
    Follower.active = this;    
    return this;
  }
  // Moves the cursor with effects
  crsrMove (e) {
    clearTimeout(this.restoreTimer); // Cancel reset timer
    const PI = Math.PI,
      pi = PI / 2,
    ...