168 lines
5.7 KiB
JavaScript
168 lines
5.7 KiB
JavaScript
/**
|
||
* Zoomify
|
||
* A jQuery plugin for simple lightboxes with zoom effect.
|
||
* http://indrimuska.github.io/zoomify
|
||
*img标签的src为列表中显示的图片链接,imgsrc为大图的链接
|
||
* (c) 2015 Indri Muska - MIT
|
||
*/
|
||
; (function ($) {
|
||
|
||
// initialization
|
||
Zoomify = function (element, options) {
|
||
var that = this;
|
||
|
||
this._zooming = false;
|
||
this._zoomed = false;
|
||
this._timeout = null;
|
||
this.$shadow = null;
|
||
this.$image = $("<img src='" + $(element).attr("imgsrc") + "' style='position:absolute;z-index:9999'/>").hide().appendTo($(element).parent());
|
||
this.options = $.extend({}, Zoomify.DEFAULTS, this.$image.data(), options);
|
||
|
||
$(element).on('click', function () {
|
||
that.$image.show();
|
||
that.zoom();
|
||
});
|
||
$(window).on('resize', function () { that.reposition(); });
|
||
$(document).on('scroll', function () { that.reposition(); });
|
||
};
|
||
Zoomify.DEFAULTS = {
|
||
duration: 200,
|
||
easing: 'linear',
|
||
scale: 0.9
|
||
};
|
||
|
||
// css utilities
|
||
Zoomify.prototype.transition = function ($element, value) {
|
||
$element.css({
|
||
'-webkit-transition': value,
|
||
'-moz-transition': value,
|
||
'-ms-transition': value,
|
||
'-o-transition': value,
|
||
'transition': value
|
||
});
|
||
};
|
||
Zoomify.prototype.addTransition = function ($element) {
|
||
this.transition($element, 'all ' + this.options.duration + 'ms ' + this.options.easing);
|
||
};
|
||
Zoomify.prototype.removeTransition = function ($element, callback) {
|
||
var that = this;
|
||
|
||
clearTimeout(this._timeout);
|
||
this._timeout = setTimeout(function () {
|
||
that.transition($element, '');
|
||
if ($.isFunction(callback)) callback.call(that);
|
||
}, this.options.duration);
|
||
};
|
||
Zoomify.prototype.transform = function (value) {
|
||
this.$image.css({
|
||
'-webkit-transform': value,
|
||
'-moz-transform': value,
|
||
'-ms-transform': value,
|
||
'-o-transform': value,
|
||
'transform': value
|
||
});
|
||
};
|
||
Zoomify.prototype.transformScaleAndTranslate = function (scale, translateX, translateY, callback) {
|
||
this.addTransition(this.$image);
|
||
this.transform('scale(' + scale + ') translate(' + translateX + 'px, ' + translateY + 'px)');
|
||
this.removeTransition(this.$image, callback);
|
||
};
|
||
|
||
// zooming functions
|
||
Zoomify.prototype.zoom = function () {
|
||
if (this._zooming) return;
|
||
|
||
if (this._zoomed) this.zoomOut();
|
||
else this.zoomIn();
|
||
};
|
||
Zoomify.prototype.zoomIn = function () {
|
||
var that = this,
|
||
transform = this.$image.css('transform');
|
||
|
||
this.transition(this.$image, 'none');
|
||
this.transform('none');
|
||
|
||
var offset = this.$image.offset(),
|
||
width = this.$image.outerWidth(),
|
||
height = this.$image.outerHeight(),
|
||
nWidth = this.$image[0].naturalWidth || +Infinity,
|
||
nHeight = this.$image[0].naturalHeight || +Infinity,
|
||
wWidth = $(window).width(),
|
||
wHeight = $(window).height(),
|
||
scaleX = Math.min(nWidth, wWidth * this.options.scale) / width,
|
||
scaleY = Math.min(nHeight, wHeight * this.options.scale) / height,
|
||
scale = Math.min(scaleX, scaleY),
|
||
translateX = (-offset.left + (wWidth - width) / 2) / scale,
|
||
translateY = (-offset.top + (wHeight - height) / 2 + $(document).scrollTop()) / scale;
|
||
|
||
this.transform(transform);
|
||
|
||
this._zooming = true;
|
||
this.$image.addClass('zoomed').trigger('zoom-in.zoomify');
|
||
setTimeout(function () {
|
||
that.addShadow();
|
||
that.transformScaleAndTranslate(scale, translateX, translateY, function () {
|
||
that._zooming = false;
|
||
that.$image.trigger('zoom-in-complete.zoomify');
|
||
});
|
||
that._zoomed = true;
|
||
});
|
||
};
|
||
Zoomify.prototype.zoomOut = function () {
|
||
var that = this;
|
||
that.$image.hide();
|
||
this._zooming = true;
|
||
this.$image.trigger('zoom-out.zoomify');
|
||
this.transformScaleAndTranslate(1, 0, 0, function () {
|
||
that._zooming = false;
|
||
that.$image.removeClass('zoomed').trigger('zoom-out-complete.zoomify');
|
||
});
|
||
this.removeShadow();
|
||
this._zoomed = false;
|
||
};
|
||
|
||
// page listener callbacks
|
||
Zoomify.prototype.reposition = function () {
|
||
if (this._zoomed) {
|
||
this.transition(this.$image, 'none');
|
||
this.zoomIn();
|
||
}
|
||
};
|
||
|
||
// shadow background
|
||
Zoomify.prototype.addShadow = function () {
|
||
var that = this;
|
||
if (this._zoomed) return;
|
||
|
||
if (that.$shadow) that.$shadow.remove();
|
||
this.$shadow = $('<div class="zoomify-shadow"></div>');
|
||
$('body').append(this.$shadow);
|
||
this.addTransition(this.$shadow);
|
||
this.$shadow.on('click', function () { that.zoomOut(); })
|
||
|
||
setTimeout(function () { that.$shadow.addClass('zoomed'); }, 10);
|
||
};
|
||
Zoomify.prototype.removeShadow = function () {
|
||
var that = this;
|
||
if (!this.$shadow) return;
|
||
|
||
this.addTransition(this.$shadow);
|
||
this.$shadow.removeClass('zoomed');
|
||
this.$image.one('zoom-out-complete.zoomify', function () {
|
||
if (that.$shadow) that.$shadow.remove();
|
||
that.$shadow = null;
|
||
});
|
||
};
|
||
|
||
// plugin definition
|
||
$.fn.zoomify = function (option) {
|
||
return this.each(function () {
|
||
var $this = $(this),
|
||
zoomify = $this.data('zoomify');
|
||
|
||
if (!zoomify) $this.data('zoomify', (zoomify = new Zoomify(this, typeof option == 'object' && option)));
|
||
if (typeof option == 'string' && ['zoom', 'zoomIn', 'zoomOut', 'reposition'].indexOf(option) >= 0) zoomify[option]();
|
||
});
|
||
};
|
||
|
||
})(jQuery); |