Also, react to mouse events and set CSS custom properties accordingly to update the registered paint. See JS below.

Support: Chrome/Opera (paint worklet), Chrome with flags (transition on custom properties)

1
2
3
4
5
6
.el {
  background-image: url(...);
}
.el::after {
  background-color: hsla(300, 100%, 50%, .75);
  mix-blend-mode: multiply;
}
@supports (mask-image: paint(circle)) {
  .el.is-loaded::after {
    mask-image: paint(circle);
  }
}
el.addEventListener('mousemove', evt => {
  el.style.cssText = `--size: 150; --x: ${evt.offsetX}; --y: ${evt.offsetY}`
})
el.addEventListener('mouseenter', evt => {
  el.style.cssText = `--size: 150; --x: ${evt.offsetX}; --y: ${evt.offsetY}`
})
el.addEventListener('mouseleave', evt => {
  el.style.cssText = `--size: 0; --x: ${evt.offsetX}; --y: ${evt.offsetY}`
})