|
/**
* Zoomify
* A jQuery plugin for simple lightboxes with zoom effect.
* http://indrimuska.github.io/zoomify
*
* (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 = $(element).addClass('zoomify');
this.options = $.extend({}, Zoomify.DEFAULTS, this.$image.data(), options);
this.$image.on('click', function () { 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.$image.css("opacity",1)
this.$image.css("height","auto")
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;
this.$image.css("opacity",0)
this.$image.css("height","100%")
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);
|