JSFiddle - React, Tailwind, and code Playground
HTML
<article data-ref="poc105.0">
<img src="http://fpm.xn--mickal-tva.name/data/poc105/image/poc105.0.small.jpg"/>
</article>
CSS
.a025 {
-webkit-transition: .25s;
-moz-transition: .25s;
-o-transition: .25s;
-ms-transition: .25s;
transition: .25s;
}
article { width:260px; height:260px; }
JavaScript
$.fn.zoom = function(opt){
var $elem = $(this);
if(opt === undefined) opt = {stick:30};
var stick = (opt.stick === undefined)?30:opt.stick;
var s2 = stick*2;
return $elem.each(function(){
var $e = $(this);
var ref = $e.data('ref');
var src = 'http://fpm.xn--mickal-tva.name/data/poc105/image/'+ref+'.460.jpg';
var $i = $('<img/>').on('load',function(){ // temp image to preload big picture
// image was downloaded
var d = { w:$e.width(), h:$e.height(), iw:this.width, ih:this.height };
d.mx = d.w - s2; // stick zone sizes
d.my = d.h - s2;
d.sr = d.w / d.mx; // image / stick zone ratio
d.wr = ( (d.iw - d.w) / d.w ) * d.sr; // combined big size / original size & stick ratios
d.hr = ( (d.ih - d.h) / d.h ) * d.sr;
$e.css({ background:'url('+src+')',
backgroundSize:d.w+'px '+d.h+'px',
backgroundRepeat:"no-repeat"
});
// use css transition only for hover zoom
$e.bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ $e.removeClass("a025"); });
// hover our container
$e.hover(function(){ $e.addClass("a025").css({ backgroundSize:d.iw+'px '+d.ih+'px' }); }, // zoom
function(){ $e.addClass("a025").css({ backgroundSize:d.w +'px '+d.h +'px', backgroundPosition:"center center" }); } // 100%
).on("mousemove",function(e){
var x = ((e.pageX - (this.offsetLeft + s2)) + stick)*d.wr; // convert mouse <> stick zone and apply ratio
var y = ((e.pageY - (this.offsetTop + s2)) + stick)*d.hr;
(x<0)?x=0:(x>d.mx)?x=d.mx:x; // crop
(y<0)?y=0:(y>d.my)?y=d.my:y;
...