1

I am attempting to build an image zoom/panner using JS/jQuery. I have so far managed to get the zoom working using the mousewheel to zoom in/out, but it currently only zooms in on the center point each time.

Like with Google maps I want to be able to zoom in on the point where the mouse cursor is, but am unsure on the code to do this.

I have setup a fiddle with my progress so far: http://jsfiddle.net/quirksmode/XrKLN/1/

Any help would be massively appreciated :-)

My code is:

// Plugin to allow for button holds
jQuery.fn.mousehold = function (timeout, f) {
if (timeout && typeof timeout == 'function') {
    f = timeout;
    timeout = 100;
}
if (f && typeof f == 'function') {
    var timer = 0;
    var fireStep = 0;
    return this.each(function () {
        jQuery(this).mousedown(function () {
            fireStep = 1;
            var ctr = 0;
            var t = this;
            timer = setInterval(function () {
                ctr++;
                f.call(t, ctr);
                fireStep = 2;
            }, timeout);
        })

        clearMousehold = function () {
            clearInterval(timer);
            if (fireStep == 1) f.call(this, 1);
            fireStep = 0;
        }

        jQuery(this).mouseout(clearMousehold);
        jQuery(this).mouseup(clearMousehold);
    })
}
}


/**
* CSS3 Transform helper
*/
var cssTransformScale = function (x, y, z) {
return {
    '-webkit-transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
        '-moz-transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
        '-ms-transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
        '-o-transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
        'transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
};

};




$(document).ready(function () {

var assetViewer = {
    name: 'assetViewer',
    defaults: {
        $assetWrap: $('#asset-wrap'),
        $assetImg: $('.asset-img'),
        imgSrc: "http://lorempixel.com/1600/760/",
        zoomScale: 0.01,
        initialZoom: 1,
        currentZoom: 1,
        maxZoom: 3,
        minZoom: 1,
        $zoomIn: $('#zoom-in'),
        $zoomOut: $('#zoom-out')
    },
    init: function (options) {
        var me = this;
        this.options = $.extend(this.defaults, options);

        this.appendImage();
        this.bindEvents();
    },
    appendImage: function () {
        var me = this;
        this.options.$assetWrap.append('<div class="asset-holder"><div class="asset-inner-wrap"><img class="asset-img" src="' + this.options.imgSrc + '" /></div></div>');
        me.options.$assetImg = $(me.options.$assetImg.selector); // Using .selector to refresh the element
    },
    bindEvents: function () {
        var me = this;

        me.options.$zoomIn.mousehold(1, function () {
            me.zoom("+", 1);
        })
        me.options.$zoomOut.mousehold(1, function () {
            me.zoom("-", 1);
        })

        me.options.$assetImg.mousewheel(function (event, delta) {
            if (delta > 0) me.zoom("+", delta);
            else if (delta < 0) me.zoom("-", Math.abs(delta)); // Forces the negative to become a positive

            return false; // prevent default
        });
    },
    zoom: function (direction, delta) {
        var me = this;

        //console.log();

        if ((me.options.currentZoom >= me.options.minZoom) && (me.options.currentZoom <= me.options.maxZoom)) {
            var scale = (direction === "+") ? me.options.currentZoom += (me.options.zoomScale * delta) : me.options.currentZoom -= (me.options.zoomScale * delta);

            // Set the Zoom Bounds
            if (me.options.currentZoom <= me.options.minZoom) {
                scale = me.options.currentZoom = me.options.minZoom;
            }
            if (me.options.currentZoom >= me.options.maxZoom) {
                scale = me.options.currentZoom = me.options.maxZoom;
            }
            me.options.$assetImg.css(cssTransformScale(scale, scale, scale));
        }

    }

}

assetViewer.init();

});

1 Answers1

0

I have done something very similar to what you are trying to achieve and I have a div within a div and then used the left and top CSS attributes of the child div to navigate around the image via a minimap image.

ShellZero
  • 4,415
  • 12
  • 38
  • 56
Deano
  • 176
  • 1
  • 12
  • The minimap is the next step for me once I get the zooming working, I don't suppose you have any code examples to share, or advice on how I can achieve this? – David Plunkett Apr 27 '14 at 22:03
  • sorry dave I dont ill see if i can find someithing thats relevant – Deano Apr 28 '14 at 09:33
  • Dave, I coded the initial mockup for the minimap for this site here http://fsp.pvxgateway.com/de/event/392 they then had their own team build it into their site which you can see here. I dont have the original code that I wrote but you could interrogate it with firebug and get a log of the info. Hope this helps. – Deano Apr 28 '14 at 19:45