Smooth Zoom to cursor

by dariospagnolo

HTML

<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.1.0.min.js"></script>
<div id="container"></div>

JavaScript

var ui = {
    stage: null,
    layer: null,
    scale: 1,
    zoomFactor: 1.1,
    origin: {
        x: 0,
        y: 0
    },
    zoom: function(event) {
        event.preventDefault();
        var evt = event.originalEvent,
            mx = evt.clientX - ui.stage.getX(),
            my = evt.clientY - ui.stage.getY(),
            zoom = (ui.zoomFactor - (evt.wheelDelta < 0 ? 0.4 : -0.4)),
            newscale = ui.scale * zoom;
        
        ui.origin.x = mx / ui.scale + ui.origin.x - mx / newscale;
        ui.origin.y = my / ui.scale + ui.origin.y - my / newscale;

        zoomTween = new Kinetic.Tween({
            node: ui.layer, 
            duration: 0.8,
            offsetX: ui.origin.x,
            offsetY: ui.origin.y,
            scaleX: newscale,
            scaleY: newscale
        });
        zoomTween.play();

        ui.scale *= zoom;
    }
};

$(function() {
    var width = $(document).width() - 2,
        height = $(document).height() - 5;
    var stage = ui.stage = new Kinetic.Stage({
        container: 'container',
        width: width,
        height: height,
        draggable: true
    });
    var layer = ui.layer = new Kinetic.Layer();

    var box1 = ui.box = new Kinetic.Circle({
        x: 50,
        y: 50,
        radius: 50,
        fill: '#00D200',
        stroke: 'black',
        strokeWidth: 2,
        draggable: true
    });
    
    var box2 = ui.box = new Kinetic.Circle({
        x: 150,
        y: 150,
        radius: 50,
        fill: 'red',
        stroke: 'black',
        strokeWidth: 2,
        draggable: true
    });
    
    // add cursor styling
    box1.on('mouseover', function() {
        document.body.style.cursor = 'pointer';
    });
    box1.on('mouseout', function() {
        document.body.style.cursor = 'default';
    });
    
    // add cursor styling
    box2.on('mouseover', function() {
        document.body.style.cursor = 'pointer';
    });
    box2.on('mouseout', function() {
       ...