<div class="mask"></div>
:root {
  --mouse-x: 50%;
  --mouse-y: 50%;
}

body {
  margin: 0;
  height: 100vh;
  background-image: url(https://since1979.dev/wp-content/uploads/2022/01/todd-quackenbush-x5SRhkFajrA-unsplash.jpg);
  background-position: center center;
  background-size: cover;
}

.mask {
  width: 100vw;
  height: 100vh;
  background-color: hsla(0,0%,0%, 0.9);
  mask: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 40px,
    black 150px
  );
  -webkit-mask: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 40px,
    black 150px
  );
}


// Get a reference to the .mask element.
const mask = document.querySelector('.mask');

// Add an event to catch mouse movements.
document.addEventListener('pointermove', (pos) => {
  
    // Calculate mouse position in percentages.
    let x = parseInt( pos.clientX / window.innerWidth * 100 );
    let y = parseInt( pos.clientY / window.innerHeight * 100 );
  
    // Update the custom property values on the body.
    mask.style.setProperty('--mouse-x', x + '%');
    mask.style.setProperty('--mouse-y', y + '%'); 
  
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.