Invert text color on mouse hover

Here is an idea using clip-path. The trick is to duplicate the text to have two layers above each other with different text color then I reveal the top one using the clip-path that I adjust with the move of the mouse.

var h =document.querySelector('h1');
var p= h.getBoundingClientRect();
var c= document.querySelector('.cursor');

document.body.onmousemove = function(e) {
  /*Adjust the cursor position*/
  c.style.left=e.clientX+'px';
  c.style.top=e.clientY+'px';
  /*Adjust the clip-path*/
  h.style.setProperty('--x',(e.clientX-p.top)+'px');
  h.style.setProperty('--y',(e.clientY-p.left)+'px');
}
body {
  cursor:none;
}
h1 {
  color: #000;
  display:inline-block;
  margin:50px;
  text-align: center;
  position:relative;
}
h1:before {
  position:absolute;
  content:attr(data-text);
  color:#fff;
  background:#000;
  clip-path: circle(20px at var(--x,-100%) var(--y,-100%));
}
.cursor {
  position:fixed;
  width:40px;
  height:40px;
  background:#000;
  border-radius:50%;
  top:0;
  left:0;
  transform:translate(-50%,-50%);
  z-index:-2;
}
<h1 data-text="WORK">WORK</h1>

<span class="cursor"></span>

Here is Another idea using radial-gradient and without duplicating the text that can work with multiple elements at the same time:

document.body.onmousemove = function(e) {
  document.documentElement.style.setProperty('--x',(e.clientX)+'px');
  document.documentElement.style.setProperty('--y',(e.clientY)+'px');
}
body {
  cursor:none;
}

.mask {
  background: 
    radial-gradient(circle 20px 
                    at var(--x,0) var(--y,0), 
                    #fff 99%,black 100%) 
                    fixed;
  background-clip: text;
  -webkit-background-clip: text;
  color:transparent;
  -webkit-text-fill-color: transparent;
}
html::before {
  content:"";
  position:fixed;
  width:40px;
  height:40px;
  background:#000;
  border-radius:50%;
  top:var(--y,0);
  left:var(--x,0);
  transform:translate(-50%,-50%);
  z-index:-2;
}
<h1 class="mask">WORK</h1>
<p class="mask">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis risus sapien. Maecenas dui orci, blandit et commodo eget, egestas quis odio. Donec eu tortor turpis. Aliquam convallis et nisi ut varius. Proin sapien erat, auctor in efficitur vel, efficitur sit amet justo. In pretium iaculis tempus. Vivamus congue</p>

<p class="mask">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis risus sapien. Maecenas dui orci, blandit et commodo eget, egestas quis odio. Donec eu tortor turpis. Aliquam convallis et nisi ut varius. Proin sapien erat, auctor in efficitur vel, efficitur sit amet justo. In pretium iaculis tempus. Vivamus congue</p>

Related question with similar ideas: Stacking circles produces a black bar on border radius

Leave a Comment