JSFiddle - React, Tailwind, and code Playground

by BaliBalo

HTML

<script src="https://raw.github.com/brandonaaron/jquery-mousewheel/master/jquery.mousewheel.js"></script>
<canvas id="lol" width="800" height="600"></canvas>

JavaScript

function comeCloser(what, goal, limit, factor)
{
    return Math.abs(goal - what) < limit ? goal : what + (goal - what) * factor;
}
var img = new Image();
img.src = 'http://www.randomimage.us/files/adgar.jpg';
var $c = $('#lol'), c = $c[0], ctx = c.getContext('2d');
var mDownOff = {x: 0, y: 0}, mDownImOff = {x: 0, y: 0}, mDown = false;
var cOff = $c.offset();
var imgOff = {left: 0, top: 0}, imgOff2 = {left: 0, top: 0};
var zoom = 1, zoom2 = 1;
function tick()
{
    imgOff.left = comeCloser(imgOff.left, imgOff2.left, 0, 0.2);
    imgOff.top = comeCloser(imgOff.top, imgOff2.top, 0, 0.2);
    zoom = comeCloser(zoom, zoom2, 0, 0.2);
    draw();
}
function draw()
{
    ctx.clearRect(0,0,c.width, c.height);
    ctx.drawImage(img, 0, 0, img.width, img.height, Math.round(imgOff.left), Math.round(imgOff.top), Math.round(zoom * img.width), Math.round(zoom * img.height));
}
setInterval(tick, 16);
$c.on('mousedown', function(e)
{
    mDownOff.x = e.pageX - cOff.left;
    mDownOff.y = e.pageY - cOff.top;
    mDownImOff.x = imgOff.left;
    mDownImOff.y = imgOff.top;
    mDown = true
}).on('mousemove', function(e)
{
    if(mDown)
    {
        imgOff2.left = mDownImOff.x + e.pageX - cOff.left - mDownOff.x;
        imgOff2.top = mDownImOff.y + e.pageY - cOff.top - mDownOff.y;
    }
}).on('mouseup', function(e)
{
    mDown = false;
});
$c.on('mousewheel', function(e, delta)
{
    e.preventDefault();
    zoom2 = zoom * (1 + delta * 0.3);
    var mOnC = {x: e.pageX - cOff.left, y: e.pageY - cOff.top};
    var mOnIm = {x: (mOnC.x - imgOff.left) / zoom, y: (mOnC.y - imgOff.top) / zoom};
    imgOff2.left = imgOff.left - mOnIm.x * (zoom2 - zoom);
    imgOff2.top = imgOff.top - mOnIm.y * (zoom2 - zoom);
});