JSFiddle - React, Tailwind, and code Playground
HTML
<script src="//cdn.jsdelivr.net/prefixfree/1.0.7/prefixfree.dynamic-dom.js"></script>
<figure data-desaturated></figure>
<figure data-original></figure>
CSS
figure{ width: 550px; height: 360px;
position: absolute; top: 0; left: 0;
margin: 0; padding: 0;
background-position: 50% 50%;
background-repeat: no-repeat;
background-image: url('https://static.pexels.com/photos/106399/pexels-photo-106399.jpeg');
}
figure[data-desaturated]{
-webkit-filter: grayscale(0.9);
}
figure[data-original]{
width: 360px;
left: -180px;
top: -180px;
border-radius: 180px;
background-position: 180px 180px;
opacity: 0;
transition: opacity 0.4s;
}
figure[data-desaturated]:hover + figure[data-original],
figure[data-original]:hover{
opacity: 1;
}
JavaScript
var data_original = $('figure[data-original]');
$('figure[data-desaturated],figure[data-original]').mousemove(function(event){
var translate_x = event.pageX,
translate_y = event.pageY,
position_x = 180 - translate_x,
position_y = 180 - translate_y;
data_original.css({
'-ms-transform': 'translate('+translate_x+'px,'+translate_y+'px)',
'-webkit-transform': 'translate('+translate_x+'px,'+translate_y+'px)',
'-moz-transform': 'translate('+translate_x+'px,'+translate_y+'px)',
'transform': 'translate('+translate_x+'px,'+translate_y+'px)',
'background-position': ''+position_x+'px '+position_y+'px'
})
});