JSFiddle - React, Tailwind, and code Playground
HTML
<div id="loup">
<img src="http://3.bp.blogspot.com/-Pv3UuU1VtIY/T7RFN54LKmI/AAAAAAAAFW8/AfVYysfr00U/s1600/paisaje-italia.jpg" />
</div>
CSS
#loup {
position:relative
}
#loup .circle{
position:absolute;
height:180px;
width:180px;
border-radius:90px;
box-shadow:-2px -3px 5px #000;
background-repeat:no-repeat;
display:none;
}
#loup img{
position:absolute
}
#loup .layer{
background:black;
opacity:0.6;
width:100%;
height:100%
}
JavaScript
$(document).ready(function(){
var obj = $("#loup"), img = obj.find("img")[0],
circle = $("<div>",{'class':'circle'}), layer = $("<div>",{'class':'layer'})
function start(){
var width = img.width, height = img.height
obj.css({width:width,height:height,margin:'auto'})
obj.append(layer)
obj.hover(function(){
circle.show(300)
},function(){
circle.hide(300)
}).mousemove(function(e){
var left = e.pageX, top = e.pageY, offset = obj.offset(),
circleSize = [circle.width(),circle.height()],
topPos = top-offset.top-(circleSize[1]/2),
leftPos = left-offset.left-(circleSize[0]/2)
circle.css({
left:leftPos+"px",
top:topPos+"px",
backgroundPosition: -leftPos + "px "+ -topPos + "px"
});
if((leftPos > width || topPos > height
|| leftPos < -circleSize[0] || topPos < -circleSize[1])){
circle.hide()
}
})
obj.append(circle.css({backgroundImage:'url('+img.src+')'}));
}
if(img.complete){
start()
}else{
img.onload = start
}
})