JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://rawgithub.com/brandonaaron/jquery-mousewheel/master/jquery.mousewheel.js"></script>
<div id="container">
<img id="image" width="640" height="480" src="https://proxy.duckduckgo.com/iu/?u=https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2F7%2F7b%2FDarktable_icon.svg%2F1200px-Darktable_icon.svg.png&f=1"
/>
<div id="zoom_wrapper">
<div id="zoom"></div>
</div>
</div>
CSS
#container {
width:400px;
height:300px;
border:1px solid black;
overflow:hidden;
position:relative;
background: #151515;
}
#zoom_wrapper {
position:absolute;
z-index:1;
left:30px;
top:30px;
}
#image {
margin:auto;
position:absolute;
left:0;
right:0;
top:0;
bottom:0;
-webkit-transition: ease 0.4s all;
-moz-transition: ease 0.4s all;
-ms-transition: ease 0.4s all;
-o-transition: ease 0.4s all;
transition: ease 0.4s all;
}
JavaScript
$(document).ready(function() {
var c = $('#container'), im = $('#image'), z = $('#zoom');
var imageHeight = 480,
imageWidth = 640,
contWidth = c.width(),
contHeight = c.height();
var ratio = Math.min(contWidth * 0.9 / imageWidth, contHeight * 0.9 / imageHeight);
im.css({
'height': imageHeight * ratio + 'px',
'width': imageWidth * ratio + 'px'
});
var currentScale = 1, currentLocation = {x: 180, y: 135}, mouseLocation = {x: 180, y: 135};
var minZoom = 0.1, maxZoom = 10, zoomFactor = 0.2, moveSmooth = 0.2;
//Increase moveSmooth for more moving intensity when zooming
//When moveSmooth = 1, pointed point is centered at every mousewheel impulsion
var zoomFactorInvertLog = 1 / Math.log(zoomFactor);
c.on('mousewheel', function(e, delta) {
var cOffset = c.offset();
mouseLocation.x = e.pageX - cOffset.left;
mouseLocation.y = e.pageY - cOffset.top;
var newZoom = Math.max(minZoom, Math.min(maxZoom, currentScale * (1 + delta * zoomFactor)));
var sliderVal = Math.log(newZoom) * zoomFactorInvertLog;
if(slidInvert) sliderVal = slidMin + slidMax - sliderVal;
z.slider('value', sliderVal);
zoom(newZoom);
});
var slidMin = Math.log(minZoom) * zoomFactorInvertLog, slidMax = Math.log(maxZoom) * zoomFactorInvertLog;
var slidInvert = (slidMin > slidMax);
z.slider({
orientation: 'vertical',
min: Math.min(slidMin, slidMax),
max: Math.max(slidMin, slidMax),
step: Math.abs(slidMin - slidMax) / 20,
value: slidMin + slidMax
}).on('slide slidechange', function (event, ui) {
var v = slidInvert ? slidMin + slidMax - ui.value : ui.value;
var newZoom = Math.pow(zoomFactor, v);
zoom(newZoom);
});
function zoom(scale)
{
if(scale <= 1)
{
currentLocation.x = im.width() / 2;
currentLocation.y = im.height() / 2;
}
...