238 lines
5.9 KiB
JavaScript
238 lines
5.9 KiB
JavaScript
|
/*!
|
||
|
Zoom 1.7.21
|
||
|
license: MIT
|
||
|
http://www.jacklmoore.com/zoom
|
||
|
*/
|
||
|
(function ($) {
|
||
|
var defaults = {
|
||
|
url: false,
|
||
|
callback: false,
|
||
|
target: false,
|
||
|
duration: 120,
|
||
|
on: 'mouseover', // other options: grab, click, toggle
|
||
|
touch: true, // enables a touch fallback
|
||
|
onZoomIn: false,
|
||
|
onZoomOut: false,
|
||
|
magnify: 1
|
||
|
};
|
||
|
|
||
|
// Core Zoom Logic, independent of event listeners.
|
||
|
$.zoom = function(target, source, img, magnify) {
|
||
|
var targetHeight,
|
||
|
targetWidth,
|
||
|
sourceHeight,
|
||
|
sourceWidth,
|
||
|
xRatio,
|
||
|
yRatio,
|
||
|
offset,
|
||
|
$target = $(target),
|
||
|
position = $target.css('position'),
|
||
|
$source = $(source);
|
||
|
|
||
|
// The parent element needs positioning so that the zoomed element can be correctly positioned within.
|
||
|
target.style.position = /(absolute|fixed)/.test(position) ? position : 'relative';
|
||
|
target.style.overflow = 'hidden';
|
||
|
img.style.width = img.style.height = '';
|
||
|
|
||
|
$(img)
|
||
|
.addClass('zoomImg')
|
||
|
.css({
|
||
|
position: 'absolute',
|
||
|
top: 0,
|
||
|
left: 0,
|
||
|
opacity: 0,
|
||
|
width: img.width * magnify,
|
||
|
height: img.height * magnify,
|
||
|
border: 'none',
|
||
|
maxWidth: 'none',
|
||
|
maxHeight: 'none'
|
||
|
})
|
||
|
.appendTo(target);
|
||
|
|
||
|
return {
|
||
|
init: function() {
|
||
|
targetWidth = $target.outerWidth();
|
||
|
targetHeight = $target.outerHeight();
|
||
|
|
||
|
if (source === target) {
|
||
|
sourceWidth = targetWidth;
|
||
|
sourceHeight = targetHeight;
|
||
|
} else {
|
||
|
sourceWidth = $source.outerWidth();
|
||
|
sourceHeight = $source.outerHeight();
|
||
|
}
|
||
|
|
||
|
xRatio = (img.width - targetWidth) / sourceWidth;
|
||
|
yRatio = (img.height - targetHeight) / sourceHeight;
|
||
|
|
||
|
offset = $source.offset();
|
||
|
},
|
||
|
move: function (e) {
|
||
|
var left = (e.pageX - offset.left),
|
||
|
top = (e.pageY - offset.top);
|
||
|
|
||
|
top = Math.max(Math.min(top, sourceHeight), 0);
|
||
|
left = Math.max(Math.min(left, sourceWidth), 0);
|
||
|
|
||
|
img.style.left = (left * -xRatio) + 'px';
|
||
|
img.style.top = (top * -yRatio) + 'px';
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
|
||
|
$.fn.zoom = function (options) {
|
||
|
return this.each(function () {
|
||
|
var
|
||
|
settings = $.extend({}, defaults, options || {}),
|
||
|
//target will display the zoomed image
|
||
|
target = settings.target && $(settings.target)[0] || this,
|
||
|
//source will provide zoom location info (thumbnail)
|
||
|
source = this,
|
||
|
$source = $(source),
|
||
|
img = document.createElement('img'),
|
||
|
$img = $(img),
|
||
|
mousemove = 'mousemove.zoom',
|
||
|
clicked = false,
|
||
|
touched = false;
|
||
|
|
||
|
// If a url wasn't specified, look for an image element.
|
||
|
if (!settings.url) {
|
||
|
var srcElement = source.querySelector('img');
|
||
|
if (srcElement) {
|
||
|
settings.url = srcElement.getAttribute('data-src') || srcElement.currentSrc || srcElement.src;
|
||
|
settings.alt = srcElement.getAttribute('data-alt') || srcElement.alt;
|
||
|
}
|
||
|
if (!settings.url) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$source.one('zoom.destroy', function(position, overflow){
|
||
|
$source.off(".zoom");
|
||
|
target.style.position = position;
|
||
|
target.style.overflow = overflow;
|
||
|
img.onload = null;
|
||
|
$img.remove();
|
||
|
}.bind(this, target.style.position, target.style.overflow));
|
||
|
|
||
|
img.onload = function () {
|
||
|
var zoom = $.zoom(target, source, img, settings.magnify);
|
||
|
|
||
|
function start(e) {
|
||
|
zoom.init();
|
||
|
zoom.move(e);
|
||
|
|
||
|
// Skip the fade-in for IE8 and lower since it chokes on fading-in
|
||
|
// and changing position based on mousemovement at the same time.
|
||
|
$img.stop()
|
||
|
.fadeTo($.support.opacity ? settings.duration : 0, 1, 'function' === typeof settings.onZoomIn ? settings.onZoomIn.call(img) : false);
|
||
|
}
|
||
|
|
||
|
function stop() {
|
||
|
$img.stop()
|
||
|
.fadeTo(settings.duration, 0, 'function' === typeof settings.onZoomOut ? settings.onZoomOut.call(img) : false);
|
||
|
}
|
||
|
|
||
|
// Mouse events
|
||
|
if (settings.on === 'grab') {
|
||
|
$source
|
||
|
.on('mousedown.zoom',
|
||
|
function (e) {
|
||
|
if (e.which === 1) {
|
||
|
$(document).one('mouseup.zoom',
|
||
|
function () {
|
||
|
stop();
|
||
|
|
||
|
$(document).off(mousemove, zoom.move);
|
||
|
}
|
||
|
);
|
||
|
|
||
|
start(e);
|
||
|
|
||
|
$(document).on(mousemove, zoom.move);
|
||
|
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
} else if (settings.on === 'click') {
|
||
|
$source.on('click.zoom',
|
||
|
function (e) {
|
||
|
if (clicked) {
|
||
|
// bubble the event up to the document to trigger the unbind.
|
||
|
return;
|
||
|
} else {
|
||
|
clicked = true;
|
||
|
start(e);
|
||
|
$(document).on(mousemove, zoom.move);
|
||
|
$(document).one('click.zoom',
|
||
|
function () {
|
||
|
stop();
|
||
|
clicked = false;
|
||
|
$(document).off(mousemove, zoom.move);
|
||
|
}
|
||
|
);
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
} else if (settings.on === 'toggle') {
|
||
|
$source.on('click.zoom',
|
||
|
function (e) {
|
||
|
if (clicked) {
|
||
|
stop();
|
||
|
} else {
|
||
|
start(e);
|
||
|
}
|
||
|
clicked = !clicked;
|
||
|
}
|
||
|
);
|
||
|
} else if (settings.on === 'mouseover') {
|
||
|
zoom.init(); // Preemptively call init because IE7 will fire the mousemove handler before the hover handler.
|
||
|
|
||
|
$source
|
||
|
.on('mouseenter.zoom', start)
|
||
|
.on('mouseleave.zoom', stop)
|
||
|
.on(mousemove, zoom.move);
|
||
|
}
|
||
|
|
||
|
// Touch fallback
|
||
|
if (settings.touch) {
|
||
|
$source
|
||
|
.on('touchstart.zoom', function (e) {
|
||
|
e.preventDefault();
|
||
|
if (touched) {
|
||
|
touched = false;
|
||
|
stop();
|
||
|
} else {
|
||
|
touched = true;
|
||
|
start( e.originalEvent.touches[0] || e.originalEvent.changedTouches[0] );
|
||
|
}
|
||
|
})
|
||
|
.on('touchmove.zoom', function (e) {
|
||
|
e.preventDefault();
|
||
|
zoom.move( e.originalEvent.touches[0] || e.originalEvent.changedTouches[0] );
|
||
|
})
|
||
|
.on('touchend.zoom', function (e) {
|
||
|
e.preventDefault();
|
||
|
if (touched) {
|
||
|
touched = false;
|
||
|
stop();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
if ('function' === typeof settings.callback) {
|
||
|
settings.callback.call(img);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
img.setAttribute('role', 'presentation');
|
||
|
img.alt = settings.alt || '';
|
||
|
img.src = settings.url;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
$.fn.zoom.defaults = defaults;
|
||
|
}(window.jQuery));
|