/* This plugin is developed by Yordan Stoev Page: http://yordanstoev.com/blog/zoomple-simple-jquery-plugin-for-image-zoom/ version : 2.0 */ (function($){ var ZoompleOverlay = (function(){ var instance; function init(){ var $overlay, $el, visible, timeoutId, $eylet, $img, eyletSize = {}; function showOverlay($el){ $overlay.trigger('showoverlay.zoomple'); $overlay.css({ left: $el.offset().left, top: $el.offset().top, width: $el.width(), height: $el.height(), display : "block"}); visible = true; $img = $el; } function moveOverlay(){ if(visible){ $overlay.css({ left: $img.offset().left, top: $img.offset().top, width: $img.width(), height: $img.height()}); } } function delayedHideOverlay(){ timeoutId = setTimeout(hideOverlay, 100); } function hideOverlay(){ $overlay.trigger('hideoverlay.zoomple'); visible = false; $overlay.css({'left': 'auto', 'top': 'auto', 'width': 'auto', 'height': 'auto',display : "none"}); } function cancelTimeout(){ if(timeoutId){ clearTimeout(timeoutId); timeoutId = null; } } function getEl(){ return $overlay; } function getEylet(){ return $eylet; } function setEyletSize(width, height){ $eylet.css({width : width, height : height}); eyletSize.width = width; eyletSize.height = height; } function getEyletSize(){ return eyletSize; } function moveEylet(css){ return $eylet.css(css); } function clearEylet(){ return $eylet.css({background : 'transparent'}); } $overlay = $("
").appendTo("body"); $eylet = $overlay.find(".eyelet"); $overlay.on("mouseleave", hideOverlay); $overlay.on("mouseenter", cancelTimeout); return { showOverlay : showOverlay, hideOverlay : hideOverlay, delayedHideOverlay : delayedHideOverlay, getEl : getEl, setEyletSize : setEyletSize, getEyletSize : getEyletSize, getEylet : getEylet, moveEylet : moveEylet, clearEylet : clearEylet } } return{ getInstance : function(){ if(!instance) instance = init(); return instance; } } })(); var Zoomple = function(element, options){ this.$element = $(element), this.options = $.extend({}, Zoomple.DEFAULTS, options), this.timer = null, this.pageX = null, this.pageY = null, this.$cursor = null, this.$holder = null, this.overlay = null, this.$overlay = null, this.stopLoading = false; this.init(); } Zoomple.DEFAULTS = { attachWindowToMouse : true, blankURL : 'blank.gif', bgColor : '#fff', delay : 1, loaderURL : 'loader.gif', offset : {x : 5,y : 5}, roundedCorners : false, source : 'href', showCursor : false, showOverlay : false, windowPosition : {x : 'right', y : 'top'}, zoomWidth : 300, zoomHeight : 300 } Zoomple.prototype.init = function(){ // if the overlay is displayed the window can follow the mouse cause the overlay will overlap it if(this.options.showOverlay){ this.options.attachWindowToMouse = false; this.options.showCursor = false; } if(!($('#zoomple_previewholder').length)) { $('body').append('
'); } this.$holder = $("#zoomple_previewholder"); this.overlay = ZoompleOverlay.getInstance(); this.$overlay = this.overlay.getEl(); this.$cursor = this.$holder.find(".cursor"); this.$element.find('img').on('mouseenter.zoomple',$.proxy(this.showZoom,this,this.$element.find('img'))); this.$element.find('img').on('mouseleave.zoomple',$.proxy(this.hideOverlay,this)); } Zoomple.prototype.showZoom = function($img,e ){ e.preventDefault(); e.stopPropagation(); this.$overlay.on('hideoverlay.zoomple',$.proxy(this.hideZoom,this)); this.$overlay.on('mousemove.zoomple',$.proxy(this.moveZoom,this,this.$element.find('img'))); this.overlay.showOverlay(this.$element.find('img')); var options = this.options; var e = $.Event('zoomshow.zoomple',{zoomple : this}); this.$element.trigger(e); if (e.isDefaultPrevented()) return; this.setOverlay(); this.setCursor(); this.setRounded(); this.setImageOverlay(); this.delaier($img.parent().attr(options.source),$img.attr('alt')); } Zoomple.prototype.hideZoom = function(e){ if(e && e.stopPropagation) e.stopPropagation(); if(e && e.preventDefault) e.preventDefault(); clearTimeout(this.timer); this.$overlay.off('hideoverlay.zoomple'); this.$overlay.off('mousemove.zoomple'); this.stopLoading = false; this.$holder.find("img").css({"background" : " url("+this.options.blankURL+") 50% 50% no-repeat",'left' : 'auto','top' : 'auto','width' : 'auto','height' : 'auto'}); this.$holder.find("p").html(''); this.$holder.removeClass("zp-visible"); var e = $.Event('zoomhide.zoomple',{zoomple : this}); this.$element.trigger(e); this.hideImageOverlay(); this.clearEylet(); this.clearCaption(); } Zoomple.prototype.moveZoom = function($target,e){ e.preventDefault(); e.stopPropagation(); this.pageX = e.pageX; this.pageY = e.pageY; this.positionZoom($target,e); } Zoomple.prototype.hideOverlay = function( e){ this.overlay.delayedHideOverlay(); } Zoomple.prototype.positionZoom = function($target,e){ var options = this.options, x = ((e.pageX - $target.offset().left) / $target.width() )*100, y = ((e.pageY - $target.offset().top) / $target.height())*100; if(this.options.attachWindowToMouse){ thumbPosition = { left : ( e.pageX ), top : ( e.pageY ), right : Math.round($(window).width() - ( e.pageX - options.offset.x)), bottom : Math.round($(window).height() - ( e.pageY - options.offset.y))}; if(($(window).height() + $(window).scrollTop() - options.zoomHeight - options.offset.y) > thumbPosition.top){ this.$holder.css({'top' : Math.round(thumbPosition.top + options.offset.y) + "px"}); }else{ this.$holder.css({'top' : Math.round(thumbPosition.top - options.zoomHeight - options.offset.y) + "px"}); } if(($(window).width() + $(window).scrollLeft() - options.zoomWidth - options.offset.x) > thumbPosition.left){ this.$holder.css({ 'left' : Math.round(thumbPosition.left + options.offset.x) + "px"}); }else{ this.$holder.css({ 'left' : Math.round(thumbPosition.left - options.zoomWidth - options.offset.x) }); } }else{ var leftPos = Math.round($target.offset().left - options.offset.x - options.zoomWidth); var rightPos = Math.round($target.offset().left + $target.width() + options.offset.x); var topPos = Math.round($target.offset().top - options.offset.y); var bottomPos = Math.round($target.offset().top + $target.height() - options.zoomHeight + options.offset.y); if(options.windowPosition.y == 'top') this.$holder.css({'top' : topPos + "px"}); if(options.windowPosition.x == 'left') this.$holder.css({'left' : leftPos + "px"}); if(options.windowPosition.y == 'bottom') this.$holder.css({'top' : bottomPos + "px"}); if(options.windowPosition.x == 'right') this.$holder.css({'left' : rightPos + "px"}); } var $img = this.$holder.find("img"), left = -($img.width() - options.zoomWidth)*x/100, top = -($img.height() - options.zoomHeight)*y/100; if(options.showCursor || options.roundedCorners){ left += (options.zoomWidth)*(50-x)/100; top += (options.zoomHeight)*(50-y)/100; } this.$cursor.css({"left" : 50 +"% ","top": 50 +"%"}); if(this.options.showOverlay){ var eyletPos = this.moveEylet(Math.round(e.pageX - $target.offset().left) , Math.round(e.pageY - $target.offset().top)), width = $img.width(), height = $img.height(); this.moveImageOverlay(-Math.round(width*eyletPos.x),-Math.round(height*eyletPos.y) , $img ); }else{ $img.css({"left" : left +"px ","top": top+"px"}); } } Zoomple.prototype.delaier = function(imgRefUrl,imgDescription) { this.stopLoading = true; this.timer = setTimeout($.proxy(this.delaiedZoom,this,imgRefUrl,imgDescription), this.options.delay); } Zoomple.prototype.delaiedZoom = function(imgRefUrl,imgDescription){ var self = this; self.$holder.css({"width" : self.options.zoomWidth + "px","height" : self.options.zoomHeight + "px"}); self.$holder.find(".image_wrap").css({"background" : " url(" + self.options.loaderURL +") 50% 50% no-repeat"}); var objImagePreloader = new Image() src = imgRefUrl+"?" + new Date().getTime(); objImagePreloader.src = src; if(self.stopLoading){ self.$holder.addClass("zp-visible"); self.$holder.find("img").attr("src",src); //self.$holder.css({"background-image" : " url("+self.options.loaderURL+")"}); if($.trim(imgDescription).length) self.$holder.find(".caption-wrap").html('
'+imgDescription+'
'); } $(objImagePreloader).load(function() { if(self.stopLoading){ self.$holder.addClass("zp-visible"); self.$holder.find(".image_wrap").css({ "background" : self.options.bgColor}); self.$holder.find("img").css({"width" : this.width + "px","height" : this.height + "px"}).attr({"src":src, "width" : this.width, "height" : this.height}); self.$holder.css({"background-image" : " none"}); if($.trim(imgDescription).length) self.$holder.find(".caption-wrap").html('
'+imgDescription+'
'); var e = { pageX : self.pageX, pageY : self.pageY}; if(self.options.showOverlay) self.setupEylet(); self.positionZoom(self.$element.find('img'),e); } }); } Zoomple.prototype.setCursor = function(){ if(this.options.showCursor){ this.$cursor.css("display","block"); }else{ this.$cursor.css("display","none"); } } Zoomple.prototype.setRounded = function(){ if(this.options.roundedCorners){ this.$holder.addClass("rounded"); }else{ this.$holder.removeClass("rounded"); } } Zoomple.prototype.setOverlay = function(){ if(this.options.showOverlay){ this.$overlay.addClass("preview"); }else{ this.$overlay.removeClass("preview"); } } Zoomple.prototype.setupEylet = function(){ var eylet = this.overlay.getEylet(), img = this.$element.find('img'), imgBig = this.$holder.find("img"), ratioW = this.options.zoomWidth/imgBig.width(), ratioH = this.options.zoomHeight/imgBig.height(); eylet.css({background : "url("+img.attr('src')+") 0 0 no-repeat"}); this.overlay.setEyletSize(Math.round(ratioW*img.width()), Math.round(ratioH*img.height())); } Zoomple.prototype.clearEylet = function(){ this.overlay.clearEylet(); } Zoomple.prototype.moveEylet = function(mouseX, mouseY){ var eylet = this.overlay.getEylet(), size = this.overlay.getEyletSize(), left = Math.round(mouseX - size.width/2), top = Math.round(mouseY - size.height/2), img = this.$element.find('img'); if(left <= 0){ left = 0; } if(left >= img.width() - size.width){ left = img.width() - size.width; } if(top <= 0){ top = 0; } if(top >= img.height() - size.height){ top = img.height() - size.height; } this.overlay.moveEylet({top : top, left : left}); eylet.css({backgroundPosition : -left+"px "+ -top+"px"}); return {x : left/img.width(), y : top/img.height()} } Zoomple.prototype.setImageOverlay = function(){ var $overlay = $("#zoomple_image_overlay"), $img = this.$element.is("img") ? this.$element : this.$element.find("img") ; $overlay.css({'left': Math.round($img.offset().left), 'top': Math.round($img.offset().top), 'width': $img.width(), 'height': $img.height()}); } Zoomple.prototype.hideImageOverlay = function(){ $("#zoomple_image_overlay").css({'left': 'auto', 'top': 'auto', 'width': 'auto', 'height': 'auto'}); } Zoomple.prototype.moveImageOverlay = function(left, top, $img){ var size = {width : this.options.zoomWidth, height : this.options.zoomHeight}; if(left >= 0){ left = 0; } if(left <= size.width - $img.width()){ left = size.width - $img.width(); } if(top >= 0){ top = 0; } if(top <= size.height - $img.height()){ top = size.height - $img.height(); } $img.css({left : left+"px ", top : top+"px"}); } Zoomple.prototype.clearCaption = function(){ this.$holder.find(".caption").remove(); } $.fn.zoomple = function (options) { return this.each(function () { if (!$.data(this, 'zoomple')) { $.data(this, 'zoomple', new Zoomple( this, options )); } }); } })(jQuery);