JSFiddle - React, Tailwind, and code Playground

by Danilo Metzker

HTML

<div class="mouse" id="mouse">
  
  <svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" id="cursor-up-left" data-name="Line Color" xmlns="http://www.w3.org/2000/svg" class="icon line-color"><path id="primary" d="M3.1,4.46l7.21,15.92A1.17,1.17,0,0,0,12.5,20l1.26-6.23L20,12.5a1.17,1.17,0,0,0,.39-2.19L4.46,3.1A1,1,0,0,0,3.1,4.46Z" style="fill: none; stroke: rgb(0, 0, 0); stroke-linecap: round; stroke-linejoin: round; stroke-width: 2;"></path></svg>
  
</div>

<a href="#">Clique aqui</a>

<div class="btn clickable" draggable="true">
  hover aqui
</div>

CSS

body,html{
  cursor: none;
  height: 100%;
}
.mouse{
  width: 20px;
  height: 20px;
  position: fixed;
  pointer-events: none;
  transition: transform 0.25s;
  transform-origin: top left;
  transform: rotate(45deg);
}

.mouse svg{
  width: 100%;
  height: 100%;
  transform: rotate(-45deg) translate(0px, -20px);
  transform-origin: top right;
}

.mouse.hover svg path{
  fill: #000 !important;
}

.mouse::before{
  width: 80px;
  height: 80px;
  content: "";
  display: block;
  position: absolute;
  left: -40px;
  top: -40px;
  border-radius: 100px;
  border: 2px solid #000;
  box-sizing: border-box;
  cursor: none;
  transform: scale(0);
  transition: 0.4s;
}

.mouse.hover::before{
  transform: scale(1);
}

.mouse.pressed::before{
  transform: scale(0.5) !important;
}

a,.btn{
  display: inline-block;
  padding: 20px;
  background: rgba(0,0,0,0.3);
  margin: 100px;
  cursor: none;
}

a:hover,.btn:hover{
  background: rgba(0,0,0,0.5);
}

JavaScript

(function() {
    document.onmousemove = handleMouseHover;
    document.onmousedown = handleMouseClick;
    document.onmouseup = handleMouseUnclick;
    document.ondragstart = handleMouseDragging;
    
    var dragging = false;
    var mouse = document.getElementById("mouse");
    var mousePos = {
    	x: 0,
      y: 0
    };
    
    function handleMouseHover(event) {
        var eventDoc, doc, body;

        event = event || window.event;

        if (event.pageX == null && event.clientX != null) {
            eventDoc = (event.target && event.target.ownerDocument) || document;
            doc = eventDoc.documentElement;
            body = eventDoc.body;

            event.pageX = event.clientX +
              (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
              (doc && doc.clientLeft || body && body.clientLeft || 0);
            event.pageY = event.clientY +
              (doc && doc.scrollTop  || body && body.scrollTop  || 0) -
              (doc && doc.clientTop  || body && body.clientTop  || 0 );
        }
        
        
				mouse.style.top = event.pageY + "px";
        mouse.style.left = event.pageX + "px";
        
        mousePos.x = event.pageX;
        mousePos.y = event.pageY;
        
        var target = document.elementFromPoint(mousePos.x, mousePos.y);
        
        if (target && (
        	target.tagName.toLowerCase() === 'a' ||
        	target.classList.contains("clickable")
        ) ){
        
          let elPos = target.getBoundingClientRect();
      
          let p1 = {
            x: elPos.left + (elPos.width / 2),
            y: elPos.top + (elPos.height / 2)
          };

          var angle = Math.atan2(mousePos.y - p1.y, mousePos.x - p1.x) * 180 / Math.PI;
          
          if( angle < 0 ) angle += 360;
          
          mouse.style.transform = "rotate(" + angle + "deg)";
          mouse.classList.add("hover");
          
        }else{
          mouse.style.transform = "rotate(45deg)";
         ...