diff --git a/static/js/jquery.ez-plus.js b/static/js/jquery.ez-plus.js new file mode 100644 index 00000000..c2c5cc85 --- /dev/null +++ b/static/js/jquery.ez-plus.js @@ -0,0 +1,1929 @@ +/* jshint -W071, -W074 */ +/* global jQuery:false */ + +/* Disabled options are: + * W071: This function has too many statements + * W074: This function's cyclomatic complexity is too high + */ + +/* + * jQuery ezPlus 1.1.11 + * Demo's and documentation: + * http://igorlino.github.io/elevatezoom-plus/ + * + * licensed under MIT license. + * http://en.wikipedia.org/wiki/MIT_License + * + */ + +if (typeof Object.create !== 'function') { + Object.create = function (obj) { + function F() { + } + + F.prototype = obj; + return new F(); + }; +} + +(function ($, window, document, undefined) { + var EZP = { + init: function (options, elem) { + var self = this; + var $galleries; + + self.elem = elem; + self.$elem = $(elem); + + self.options = $.extend({}, $.fn.ezPlus.options, self.responsiveConfig(options || {})); + + self.imageSrc = self.$elem.data(self.options.attrImageZoomSrc) ? self.$elem.data(self.options.attrImageZoomSrc) : self.$elem.attr('src'); + + if (!self.options.enabled) { + return; + } + + //TINT OVERRIDE SETTINGS + if (self.options.tint) { + self.options.lensColour = 'none'; //colour of the lens background + self.options.lensOpacity = '1'; //opacity of the lens + } + //INNER OVERRIDE SETTINGS + if (self.options.zoomType === 'inner') { + self.options.showLens = false; + } + + //UUID WHEN MISSING IDENTIFIER + if (self.options.zoomId === -1) { + self.options.zoomId = generateUUID(); + } + + //Remove alt on hover + + self.$elem.parent().removeAttr('title').removeAttr('alt'); + + self.zoomImage = self.imageSrc; + + self.refresh(1); + + //Create the image swap from the gallery + $galleries = $(self.options.gallery ? ('#' + self.options.gallery) : self.options.gallerySelector); + $galleries.on('click.zoom', self.options.galleryItem, function (e) { + + //Set a class on the currently active gallery image + if (self.options.galleryActiveClass) { + $(self.options.galleryItem, $galleries).removeClass(self.options.galleryActiveClass); + $(this).addClass(self.options.galleryActiveClass); + } + //stop any link on the a tag from working + if (this.tagName === 'A') { + e.preventDefault(); + } + + //call the swap image function + if ($(this).data(self.options.attrImageZoomSrc)) { + self.zoomImagePre = $(this).data(self.options.attrImageZoomSrc); + } + else { + self.zoomImagePre = $(this).data('image'); + } + self.swaptheimage($(this).data('image'), self.zoomImagePre); + if (this.tagName === 'A') { + return false; + } + }); + + function generateUUID() { + var d = new Date().getTime(); + var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + var r = (d + Math.random() * 16) % 16 | 0; + d = Math.floor(d / 16); + return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16); + }); + return uuid; + } + }, + refresh: function (length) { + var self = this; + + setTimeout(function () { + self.fetch(self.imageSrc, self.$elem, self.options.minZoomLevel); + + }, length || self.options.refresh); + }, + fetch: function (imgsrc, element, minZoom) { + //get the image + var self = this; + var newImg = new Image(); + newImg.onload = function () { + //set the large image dimensions - used to calculte ratio's + if (newImg.width / element.width() <= minZoom) { + self.largeWidth = element.width() * minZoom; + } else { + self.largeWidth = newImg.width; + } + if (newImg.height / element.height() <= minZoom) { + self.largeHeight = element.height() * minZoom; + } else { + self.largeHeight = newImg.height; + } + //once image is loaded start the calls + self.startZoom(); + self.currentImage = self.imageSrc; + //let caller know image has been loaded + self.options.onZoomedImageLoaded(self.$elem); + }; + self.setImageSource(newImg, imgsrc); // this must be done AFTER setting onload + + return; + }, + setImageSource: function (image, src) { + //sets an image's source. + image.src = src; + }, + startZoom: function () { + var self = this; + //get dimensions of the non zoomed image + self.nzWidth = self.$elem.width(); + self.nzHeight = self.$elem.height(); + + //activated elements + self.isWindowActive = false; + self.isLensActive = false; + self.isTintActive = false; + self.overWindow = false; + + //CrossFade Wrapper + if (self.options.imageCrossfade) { + self.zoomWrap = self.$elem.wrap('
'); + self.$elem.css('position', 'absolute'); + } + + self.zoomLock = 1; + self.scrollingLock = false; + self.changeBgSize = false; + self.currentZoomLevel = self.options.zoomLevel; + + //get offset of the non zoomed image + self.nzOffset = self.$elem.offset(); + //calculate the width ratio of the large/small image + self.widthRatio = (self.largeWidth / self.currentZoomLevel) / self.nzWidth; + self.heightRatio = (self.largeHeight / self.currentZoomLevel) / self.nzHeight; + + function getWindowZoomStyle() { + return 'overflow: hidden;' + + 'background-position: 0px 0px;text-align:center;' + + 'background-color: ' + String(self.options.zoomWindowBgColour) + ';' + + 'width: ' + String(self.options.zoomWindowWidth) + 'px;' + + 'height: ' + String(self.options.zoomWindowHeight) + 'px;' + + 'float: left;' + + 'background-size: ' + self.largeWidth / self.currentZoomLevel + 'px ' + self.largeHeight / self.currentZoomLevel + 'px;' + + 'display: none;z-index:100;' + + 'border: ' + String(self.options.borderSize) + 'px solid ' + self.options.borderColour + ';' + + 'background-repeat: no-repeat;' + + 'position: absolute;'; + } + + //if window zoom + if (self.options.zoomType === 'window') { + self.zoomWindowStyle = getWindowZoomStyle(); + } + + function getInnerZoomStyle() { + //has a border been put on the image? Lets cater for this + var borderWidth = self.$elem.css('border-left-width'); + + return 'overflow: hidden;' + + 'margin-left: ' + String(borderWidth) + ';' + + 'margin-top: ' + String(borderWidth) + ';' + + 'background-position: 0px 0px;' + + 'width: ' + String(self.nzWidth) + 'px;' + + 'height: ' + String(self.nzHeight) + 'px;' + + 'float: left;' + + 'display: none;' + + 'cursor:' + (self.options.cursor) + ';' + + 'border: ' + String(self.options.borderSize) + 'px solid ' + self.options.borderColour + ';' + + 'background-repeat: no-repeat;' + + 'position: absolute;'; + } + + //if inner zoom + if (self.options.zoomType === 'inner') { + self.zoomWindowStyle = getInnerZoomStyle(); + } + + function getWindowLensStyle() { + // adjust images less than the window height + + if (self.nzHeight < self.options.zoomWindowHeight / self.heightRatio) { + self.lensHeight = self.nzHeight; + } + else { + self.lensHeight = String(self.options.zoomWindowHeight / self.heightRatio); + } + if (self.largeWidth < self.options.zoomWindowWidth) { + self.lensWidth = self.nzWidth; + } + else { + self.lensWidth = String(self.options.zoomWindowWidth / self.widthRatio); + } + + return 'background-position: 0px 0px;width: ' + String((self.options.zoomWindowWidth) / self.widthRatio) + 'px;' + + 'height: ' + String((self.options.zoomWindowHeight) / self.heightRatio) + + 'px;float: right;display: none;' + + 'overflow: hidden;' + + 'z-index: 999;' + + 'opacity:' + (self.options.lensOpacity) + ';filter: alpha(opacity = ' + (self.options.lensOpacity * 100) + '); zoom:1;' + + 'width:' + self.lensWidth + 'px;' + + 'height:' + self.lensHeight + 'px;' + + 'background-color:' + (self.options.lensColour) + ';' + + 'cursor:' + (self.options.cursor) + ';' + + 'border: ' + (self.options.lensBorderSize) + 'px' + + ' solid ' + (self.options.lensBorderColour) + ';background-repeat: no-repeat;position: absolute;'; + } + + //lens style for window zoom + if (self.options.zoomType === 'window') { + self.lensStyle = getWindowLensStyle(); + } + + //tint style + self.tintStyle = 'display: block;' + + 'position: absolute;' + + 'background-color: ' + self.options.tintColour + ';' + + 'filter:alpha(opacity=0);' + + 'opacity: 0;' + + 'width: ' + self.nzWidth + 'px;' + + 'height: ' + self.nzHeight + 'px;'; + + //lens style for lens zoom with optional round for modern browsers + self.lensRound = ''; + + if (self.options.zoomType === 'lens') { + self.lensStyle = 'background-position: 0px 0px;' + + 'float: left;display: none;' + + 'border: ' + String(self.options.borderSize) + 'px solid ' + self.options.borderColour + ';' + + 'width:' + String(self.options.lensSize) + 'px;' + + 'height:' + String(self.options.lensSize) + 'px;' + + 'background-repeat: no-repeat;position: absolute;'; + } + + //does not round in all browsers + if (self.options.lensShape === 'round') { + self.lensRound = 'border-top-left-radius: ' + String(self.options.lensSize / 2 + self.options.borderSize) + 'px;' + + 'border-top-right-radius: ' + String(self.options.lensSize / 2 + self.options.borderSize) + 'px;' + + 'border-bottom-left-radius: ' + String(self.options.lensSize / 2 + self.options.borderSize) + 'px;' + + 'border-bottom-right-radius: ' + String(self.options.lensSize / 2 + self.options.borderSize) + 'px;'; + } + + //create the div's + "" + //self.zoomContainer = $('
').addClass('zoomContainer').css({"position":"relative", "height":self.nzHeight, "width":self.nzWidth}); + + self.zoomContainer = + $('
'); + if (self.$elem.attr('id')) { + self.zoomContainer.attr('id', self.$elem.attr('id') + '-zoomContainer'); + } + $(self.options.zoomContainerAppendTo).append(self.zoomContainer); + + //this will add overflow hidden and contrain the lens on lens mode + if (self.options.containLensZoom && self.options.zoomType === 'lens') { + self.zoomContainer.css('overflow', 'hidden'); + } + if (self.options.zoomType !== 'inner') { + self.zoomLens = $('
 
') + .appendTo(self.zoomContainer) + .click(function () { + self.$elem.trigger('click'); + }); + + if (self.options.tint) { + self.tintContainer = $('
').addClass('tintContainer'); + self.zoomTint = $('
'); + + self.zoomLens.wrap(self.tintContainer); + + self.zoomTintcss = self.zoomLens.after(self.zoomTint); + + //if tint enabled - set an image to show over the tint + + self.zoomTintImage = $('') + .appendTo(self.zoomLens) + .click(function () { + + self.$elem.trigger('click'); + }); + } + } + + var targetZoomContainer = isNaN(self.options.zoomWindowPosition) ? 'body' : self.zoomContainer; + //create zoom window + self.zoomWindow = $('
 
') + .appendTo(targetZoomContainer).click(function () { + self.$elem.trigger('click'); + }); + self.zoomWindowContainer = $('
').addClass('zoomWindowContainer').css('width', self.options.zoomWindowWidth); + self.zoomWindow.wrap(self.zoomWindowContainer); + + // self.captionStyle = "text-align: left;background-color: black;'+ + // 'color: white;font-weight: bold;padding: 10px;font-family: sans-serif;font-size: 11px"; + // self.zoomCaption = $('
INSERT ALT TAG
').appendTo(self.zoomWindow.parent()); + + if (self.options.zoomType === 'lens') { + self.zoomLens.css('background-image', 'url("' + self.imageSrc + '")'); + } + if (self.options.zoomType === 'window') { + self.zoomWindow.css('background-image', 'url("' + self.imageSrc + '")'); + } + if (self.options.zoomType === 'inner') { + self.zoomWindow.css('background-image', 'url("' + self.imageSrc + '")'); + } + + /*-------------------END THE ZOOM WINDOW AND LENS----------------------------------*/ + if (self.options.touchEnabled) { + //touch events + self.$elem.bind('touchmove.ezpspace', function (e) { + e.preventDefault(); + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + self.setPosition(touch); + }); + self.zoomContainer.bind('touchmove.ezpspace', function (e) { + if (self.options.zoomType === 'inner') { + self.showHideWindow('show'); + + } + e.preventDefault(); + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + self.setPosition(touch); + + }); + self.zoomContainer.bind('touchend.ezpspace', function (e) { + self.showHideWindow('hide'); + if (self.options.showLens) { + self.showHideLens('hide'); + } + if (self.options.tint && self.options.zoomType !== 'inner') { + self.showHideTint('hide'); + } + }); + + self.$elem.bind('touchend.ezpspace', function (e) { + self.showHideWindow('hide'); + if (self.options.showLens) { + self.showHideLens('hide'); + } + if (self.options.tint && self.options.zoomType !== 'inner') { + self.showHideTint('hide'); + } + }); + if (self.options.showLens) { + self.zoomLens.bind('touchmove.ezpspace', function (e) { + + e.preventDefault(); + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + self.setPosition(touch); + }); + + self.zoomLens.bind('touchend.ezpspace', function (e) { + self.showHideWindow('hide'); + if (self.options.showLens) { + self.showHideLens('hide'); + } + if (self.options.tint && self.options.zoomType !== 'inner') { + self.showHideTint('hide'); + } + }); + } + } + //Needed to work in IE + self.$elem.bind('mousemove.ezpspace', function (e) { + if (self.overWindow === false) { + self.setElements('show'); + } + //make sure on orientation change the setposition is not fired + if (self.lastX !== e.clientX || self.lastY !== e.clientY) { + self.setPosition(e); + self.currentLoc = e; + } + self.lastX = e.clientX; + self.lastY = e.clientY; + + }); + + self.zoomContainer.bind('click.ezpspace touchstart.ezpspace', self.options.onImageClick); + + self.zoomContainer.bind('mousemove.ezpspace', function (e) { + if (self.overWindow === false) { + self.setElements('show'); + } + mouseMoveZoomHandler(e); + }); + + function mouseMoveZoomHandler(e) { + //self.overWindow = true; + //make sure on orientation change the setposition is not fired + if (self.lastX !== e.clientX || self.lastY !== e.clientY) { + self.setPosition(e); + self.currentLoc = e; + } + self.lastX = e.clientX; + self.lastY = e.clientY; + } + + var elementToTrack = null; + if (self.options.zoomType !== 'inner') { + elementToTrack = self.zoomLens; + } + if (self.options.tint && self.options.zoomType !== 'inner') { + elementToTrack = self.zoomTint; + } + if (self.options.zoomType === 'inner') { + elementToTrack = self.zoomWindow; + } + + //register the mouse tracking + if (elementToTrack) { + elementToTrack.bind('mousemove.ezpspace', mouseMoveZoomHandler); + } + + // lensFadeOut: 500, zoomTintFadeIn + self.zoomContainer.add(self.$elem).mouseenter(function () { + if (self.overWindow === false) { + self.setElements('show'); + } + }).mouseleave(function () { + if (!self.scrollLock) { + self.setElements('hide'); + self.options.onDestroy(self.$elem); + } + }); + //end ove image + + if (self.options.zoomType !== 'inner') { + self.zoomWindow.mouseenter(function () { + self.overWindow = true; + self.setElements('hide'); + }).mouseleave(function () { + self.overWindow = false; + }); + } + //end ove image + + // var delta = parseInt(e.originalEvent.wheelDelta || -e.originalEvent.detail); + + // $(this).empty(); + // return false; + + //fix for initial zoom setting + //if (self.options.zoomLevel !== 1) { + // self.changeZoomLevel(self.currentZoomLevel); + //} + //set the min zoomlevel + if (self.options.minZoomLevel) { + self.minZoomLevel = self.options.minZoomLevel; + } + else { + self.minZoomLevel = self.options.scrollZoomIncrement * 2; + } + + if (self.options.scrollZoom) { + //see compatibility of mouse events at https://developer.mozilla.org/en-US/docs/Web/Events/mousewheel + self.zoomContainer.add(self.$elem).bind('wheel DOMMouseScroll MozMousePixelScroll', function (e) { + // in IE there is issue with firing of mouseleave - So check whether still scrolling + // and on mouseleave check if scrolllock + self.scrollLock = true; + clearTimeout($.data(this, 'timer')); + $.data(this, 'timer', setTimeout(function () { + self.scrollLock = false; + //do something + }, 250)); + + var theEvent = e.originalEvent.deltaY || e.originalEvent.detail * -1; + + //this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30; + // e.preventDefault(); + + e.stopImmediatePropagation(); + e.stopPropagation(); + e.preventDefault(); + + if (theEvent == 0) { + // fixes last event inversion bug + return false; + } + + if (theEvent / 120 > 0) { + var nextZoomLevel = parseFloat(self.currentZoomLevel) - self.options.scrollZoomIncrement; + //scrolling up + if (nextZoomLevel >= parseFloat(self.minZoomLevel)) { + self.changeZoomLevel(nextZoomLevel); + } + } + else { + //scrolling down + + //Check if it has to maintain original zoom window aspect ratio or not + if ((!self.fullheight && !self.fullwidth) || !self.options.mantainZoomAspectRatio) { + var nextZoomLevel = parseFloat(self.currentZoomLevel) + self.options.scrollZoomIncrement; + + if (self.options.maxZoomLevel) { + if (nextZoomLevel <= self.options.maxZoomLevel) { + self.changeZoomLevel(nextZoomLevel); + } + } + else { + //andy + self.changeZoomLevel(nextZoomLevel); + } + } + } + return false; + }); + } + }, + destroy: function () { + var self = this; + self.$elem.unbind('ezpspace'); + $(self.zoomContainer).remove(); + if (self.options.loadingIcon && !!self.spinner && !!self.spinner.length) { + self.spinner.remove(); + delete self.spinner; + } + }, + getIdentifier: function () { + var self = this; + return self.options.zoomId; + }, + setElements: function (type) { + var self = this; + if (!self.options.zoomEnabled) { + return false; + } + if (type === 'show') { + if (self.isWindowSet) { + if (self.options.zoomType === 'inner') { + self.showHideWindow('show'); + } + if (self.options.zoomType === 'window') { + self.showHideWindow('show'); + } + if (self.options.showLens) { + self.showHideLens('show'); + } + if (self.options.tint && self.options.zoomType !== 'inner') { + self.showHideTint('show'); + } + } + } + + if (type === 'hide') { + if (self.options.zoomType === 'window') { + self.showHideWindow('hide'); + } + if (!self.options.tint) { + self.showHideWindow('hide'); + } + if (self.options.showLens) { + self.showHideLens('hide'); + } + if (self.options.tint) { + self.showHideTint('hide'); + } + } + }, + setPosition: function (e) { + + var self = this; + + if (!self.options.zoomEnabled) { + return false; + } + + //recaclc offset each time in case the image moves + //this can be caused by other on page elements + self.nzHeight = self.$elem.height(); + self.nzWidth = self.$elem.width(); + self.nzOffset = self.$elem.offset(); + + if (self.options.tint && self.options.zoomType !== 'inner') { + self.zoomTint.css({ + top: 0, + left: 0 + }); + } + //set responsive + //will checking if the image needs changing before running this code work faster? + if (self.options.responsive && !self.options.scrollZoom) { + if (self.options.showLens) { + var lensHeight, lensWidth; + if (self.nzHeight < self.options.zoomWindowWidth / self.widthRatio) { + self.lensHeight = self.nzHeight; + } + else { + self.lensHeight = String((self.options.zoomWindowHeight / self.heightRatio)); + } + if (self.largeWidth < self.options.zoomWindowWidth) { + self.lensWidth = self.nzWidth; + } + else { + self.lensWidth = (self.options.zoomWindowWidth / self.widthRatio); + } + self.widthRatio = self.largeWidth / self.nzWidth; + self.heightRatio = self.largeHeight / self.nzHeight; + if (self.options.zoomType !== 'lens') { + //possibly dont need to keep recalcalculating + //if the lens is heigher than the image, then set lens size to image size + if (self.nzHeight < self.options.zoomWindowWidth / self.widthRatio) { + self.lensHeight = self.nzHeight; + + } + else { + self.lensHeight = String((self.options.zoomWindowHeight / self.heightRatio)); + } + + if (self.nzWidth < self.options.zoomWindowHeight / self.heightRatio) { + self.lensWidth = self.nzWidth; + } + else { + self.lensWidth = String((self.options.zoomWindowWidth / self.widthRatio)); + } + + self.zoomLens.css({ + 'width': self.lensWidth, + 'height': self.lensHeight + }); + + if (self.options.tint) { + self.zoomTintImage.css({ + 'width': self.nzWidth, + 'height': self.nzHeight + }); + } + + } + if (self.options.zoomType === 'lens') { + self.zoomLens.css({ + width: String(self.options.lensSize) + 'px', + height: String(self.options.lensSize) + 'px' + }); + } + //end responsive image change + } + } + + //container fix + self.zoomContainer.css({ + top: self.nzOffset.top, + left: self.nzOffset.left, + width: self.nzWidth, // new code + height: self.nzHeight // new code + }); + self.mouseLeft = parseInt(e.pageX - self.nzOffset.left); + self.mouseTop = parseInt(e.pageY - self.nzOffset.top); + //calculate the Location of the Lens + + //calculate the bound regions - but only if zoom window + if (self.options.zoomType === 'window') { + var zoomLensHeight = self.zoomLens.height() / 2; + var zoomLensWidth = self.zoomLens.width() / 2; + self.Etoppos = (self.mouseTop < 0 + zoomLensHeight); + self.Eboppos = (self.mouseTop > self.nzHeight - zoomLensHeight - (self.options.lensBorderSize * 2)); + self.Eloppos = (self.mouseLeft < 0 + zoomLensWidth); + self.Eroppos = (self.mouseLeft > (self.nzWidth - zoomLensWidth - (self.options.lensBorderSize * 2))); + } + //calculate the bound regions - but only for inner zoom + if (self.options.zoomType === 'inner') { + self.Etoppos = (self.mouseTop < ((self.nzHeight / 2) / self.heightRatio)); + self.Eboppos = (self.mouseTop > (self.nzHeight - ((self.nzHeight / 2) / self.heightRatio))); + self.Eloppos = (self.mouseLeft < 0 + (((self.nzWidth / 2) / self.widthRatio))); + self.Eroppos = (self.mouseLeft > (self.nzWidth - (self.nzWidth / 2) / self.widthRatio - (self.options.lensBorderSize * 2))); + } + + // if the mouse position of the slider is one of the outerbounds, then hide window and lens + if (self.mouseLeft < 0 || self.mouseTop < 0 || self.mouseLeft > self.nzWidth || self.mouseTop > self.nzHeight) { + self.setElements('hide'); + return; + } + //else continue with operations + else { + //lens options + if (self.options.showLens) { + // self.showHideLens('show'); + //set background position of lens + self.lensLeftPos = String(Math.floor(self.mouseLeft - self.zoomLens.width() / 2)); + self.lensTopPos = String(Math.floor(self.mouseTop - self.zoomLens.height() / 2)); + } + //adjust the background position if the mouse is in one of the outer regions + + //Top region + if (self.Etoppos) { + self.lensTopPos = 0; + } + //Left Region + if (self.Eloppos) { + self.windowLeftPos = 0; + self.lensLeftPos = 0; + self.tintpos = 0; + } + //Set bottom and right region for window mode + if (self.options.zoomType === 'window') { + if (self.Eboppos) { + self.lensTopPos = Math.max((self.nzHeight) - self.zoomLens.height() - (self.options.lensBorderSize * 2), 0); + } + if (self.Eroppos) { + self.lensLeftPos = (self.nzWidth - (self.zoomLens.width()) - (self.options.lensBorderSize * 2)); + } + } + //Set bottom and right region for inner mode + if (self.options.zoomType === 'inner') { + if (self.Eboppos) { + self.lensTopPos = Math.max(((self.nzHeight) - (self.options.lensBorderSize * 2)), 0); + } + if (self.Eroppos) { + self.lensLeftPos = (self.nzWidth - (self.nzWidth) - (self.options.lensBorderSize * 2)); + } + } + //if lens zoom + if (self.options.zoomType === 'lens') { + + self.windowLeftPos = String(((e.pageX - self.nzOffset.left) * self.widthRatio - self.zoomLens.width() / 2) * (-1)); + self.windowTopPos = String(((e.pageY - self.nzOffset.top) * self.heightRatio - self.zoomLens.height() / 2) * (-1)); + self.zoomLens.css('background-position', self.windowLeftPos + 'px ' + self.windowTopPos + 'px'); + + if (self.changeBgSize) { + if (self.nzHeight > self.nzWidth) { + if (self.options.zoomType === 'lens') { + self.zoomLens.css('background-size', + self.largeWidth / self.newvalueheight + 'px ' + + self.largeHeight / self.newvalueheight + 'px'); + } + + self.zoomWindow.css('background-size', + self.largeWidth / self.newvalueheight + 'px ' + + self.largeHeight / self.newvalueheight + 'px'); + } + else { + if (self.options.zoomType === 'lens') { + self.zoomLens.css('background-size', + self.largeWidth / self.newvaluewidth + 'px ' + + self.largeHeight / self.newvaluewidth + 'px'); + } + self.zoomWindow.css('background-size', + self.largeWidth / self.newvaluewidth + 'px ' + + self.largeHeight / self.newvaluewidth + 'px'); + } + self.changeBgSize = false; + } + + self.setWindowPosition(e); + } + //if tint zoom + if (self.options.tint && self.options.zoomType !== 'inner') { + self.setTintPosition(e); + } + //set the css background position + if (self.options.zoomType === 'window') { + self.setWindowPosition(e); + } + if (self.options.zoomType === 'inner') { + self.setWindowPosition(e); + } + if (self.options.showLens) { + if (self.fullwidth && self.options.zoomType !== 'lens') { + self.lensLeftPos = 0; + } + self.zoomLens.css({ + left: self.lensLeftPos + 'px', + top: self.lensTopPos + 'px' + }); + } + + } //end else + }, + showHideZoomContainer: function (change) { + var self = this; + if (change === 'show') { + if (self.zoomContainer) { + self.zoomContainer.show(); + } + } + if (change === 'hide') { + if (self.zoomContainer) { + self.zoomContainer.hide(); + } + } + }, + showHideWindow: function (change) { + var self = this; + if (change === 'show') { + if (!self.isWindowActive && self.zoomWindow) { + self.options.onShow(self); + if (self.options.zoomWindowFadeIn) { + self.zoomWindow.stop(true, true, false).fadeIn(self.options.zoomWindowFadeIn); + } + else { + self.zoomWindow.show(); + } + self.isWindowActive = true; + } + } + if (change === 'hide') { + if (self.isWindowActive) { + if (self.options.zoomWindowFadeOut) { + self.zoomWindow.stop(true, true).fadeOut(self.options.zoomWindowFadeOut, function () { + if (self.loop) { + //stop moving the zoom window when zoom window is faded out + clearInterval(self.loop); + self.loop = false; + } + }); + } + else { + self.zoomWindow.hide(); + } + self.isWindowActive = false; + } + } + }, + showHideLens: function (change) { + var self = this; + if (change === 'show') { + if (!self.isLensActive) { + if (self.zoomLens) { + if (self.options.lensFadeIn) { + self.zoomLens.stop(true, true, false).fadeIn(self.options.lensFadeIn); + } + else { + self.zoomLens.show(); + } + } + self.isLensActive = true; + } + } + if (change === 'hide') { + if (self.isLensActive) { + if (self.zoomLens) { + if (self.options.lensFadeOut) { + self.zoomLens.stop(true, true).fadeOut(self.options.lensFadeOut); + } + else { + self.zoomLens.hide(); + } + } + self.isLensActive = false; + } + } + }, + showHideTint: function (change) { + var self = this; + if (change === 'show') { + if (!self.isTintActive && self.zoomTint) { + + if (self.options.zoomTintFadeIn) { + self.zoomTint.css('opacity', self.options.tintOpacity).animate().stop(true, true).fadeIn('slow'); + } + else { + self.zoomTint.css('opacity', self.options.tintOpacity).animate(); + self.zoomTint.show(); + } + self.isTintActive = true; + } + } + if (change === 'hide') { + if (self.isTintActive) { + + if (self.options.zoomTintFadeOut) { + self.zoomTint.stop(true, true).fadeOut(self.options.zoomTintFadeOut); + } + else { + self.zoomTint.hide(); + } + self.isTintActive = false; + } + } + }, + + setLensPosition: function (e) { + }, + + setWindowPosition: function (e) { + //return obj.slice( 0, count ); + var self = this; + + if (!isNaN(self.options.zoomWindowPosition)) { + + switch (self.options.zoomWindowPosition) { + case 1: //done + self.windowOffsetTop = (self.options.zoomWindowOffsetY);//DONE - 1 + self.windowOffsetLeft = (+self.nzWidth); //DONE 1, 2, 3, 4, 16 + break; + case 2: + if (self.options.zoomWindowHeight > self.nzHeight) { //positive margin + + self.windowOffsetTop = ((self.options.zoomWindowHeight / 2) - (self.nzHeight / 2)) * (-1); + self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16 + } + else { //negative margin + $.noop(); + } + break; + case 3: //done + self.windowOffsetTop = (self.nzHeight - self.zoomWindow.height() - (self.options.borderSize * 2)); //DONE 3,9 + self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16 + break; + case 4: //done + self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8 + self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16 + break; + case 5: //done + self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8 + self.windowOffsetLeft = (self.nzWidth - self.zoomWindow.width() - (self.options.borderSize * 2)); //DONE - 5,15 + break; + case 6: + if (self.options.zoomWindowHeight > self.nzHeight) { //positive margin + self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8 + + self.windowOffsetLeft = ((self.options.zoomWindowWidth / 2) - (self.nzWidth / 2) + (self.options.borderSize * 2)) * (-1); + } + else { //negative margin + $.noop(); + } + + break; + case 7: //done + self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8 + self.windowOffsetLeft = 0; //DONE 7, 13 + break; + case 8: //done + self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8 + self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1); //DONE 8,9,10,11,12 + break; + case 9: //done + self.windowOffsetTop = (self.nzHeight - self.zoomWindow.height() - (self.options.borderSize * 2)); //DONE 3,9 + self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1); //DONE 8,9,10,11,12 + break; + case 10: + if (self.options.zoomWindowHeight > self.nzHeight) { //positive margin + + self.windowOffsetTop = ((self.options.zoomWindowHeight / 2) - (self.nzHeight / 2)) * (-1); + self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1); //DONE 8,9,10,11,12 + } + else { //negative margin + $.noop(); + } + break; + case 11: + self.windowOffsetTop = (self.options.zoomWindowOffsetY); + self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1); //DONE 8,9,10,11,12 + break; + case 12: //done + self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16 + self.windowOffsetLeft = (self.zoomWindow.width() + (self.options.borderSize * 2)) * (-1); //DONE 8,9,10,11,12 + break; + case 13: //done + self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16 + self.windowOffsetLeft = (0); //DONE 7, 13 + break; + case 14: + if (self.options.zoomWindowHeight > self.nzHeight) { //positive margin + self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16 + + self.windowOffsetLeft = ((self.options.zoomWindowWidth / 2) - (self.nzWidth / 2) + (self.options.borderSize * 2)) * (-1); + } + else { //negative margin + $.noop(); + } + break; + case 15://done + self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16 + self.windowOffsetLeft = (self.nzWidth - self.zoomWindow.width() - (self.options.borderSize * 2)); //DONE - 5,15 + break; + case 16: //done + self.windowOffsetTop = (self.zoomWindow.height() + (self.options.borderSize * 2)) * (-1); //DONE 12,13,14,15,16 + self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16 + break; + default: //done + self.windowOffsetTop = (self.options.zoomWindowOffsetY);//DONE - 1 + self.windowOffsetLeft = (self.nzWidth); //DONE 1, 2, 3, 4, 16 + } + } //end isNAN + else { + // For BC purposes, treat passed element as ID if element not found + self.externalContainer = $(self.options.zoomWindowPosition); + if (!self.externalContainer.length) { + self.externalContainer = $('#' + self.options.zoomWindowPosition); + } + + self.externalContainerWidth = self.externalContainer.width(); + self.externalContainerHeight = self.externalContainer.height(); + self.externalContainerOffset = self.externalContainer.offset(); + + self.windowOffsetTop = self.externalContainerOffset.top;//DONE - 1 + self.windowOffsetLeft = self.externalContainerOffset.left; //DONE 1, 2, 3, 4, 16 + + } + self.isWindowSet = true; + self.windowOffsetTop = self.windowOffsetTop + self.options.zoomWindowOffsetY; + self.windowOffsetLeft = self.windowOffsetLeft + self.options.zoomWindowOffsetX; + + self.zoomWindow.css({ + top: self.windowOffsetTop, + left: self.windowOffsetLeft + }); + + if (self.options.zoomType === 'inner') { + self.zoomWindow.css({ + top: 0, + left: 0 + }); + + } + + self.windowLeftPos = String(((e.pageX - self.nzOffset.left) * self.widthRatio - self.zoomWindow.width() / 2) * (-1)); + self.windowTopPos = String(((e.pageY - self.nzOffset.top) * self.heightRatio - self.zoomWindow.height() / 2) * (-1)); + if (self.Etoppos) { + self.windowTopPos = 0; + } + if (self.Eloppos) { + self.windowLeftPos = 0; + } + if (self.Eboppos) { + self.windowTopPos = (self.largeHeight / self.currentZoomLevel - self.zoomWindow.height()) * (-1); + } + if (self.Eroppos) { + self.windowLeftPos = ((self.largeWidth / self.currentZoomLevel - self.zoomWindow.width()) * (-1)); + } + + //stops micro movements + if (self.fullheight) { + self.windowTopPos = 0; + } + if (self.fullwidth) { + self.windowLeftPos = 0; + } + + //set the css background position + if (self.options.zoomType === 'window' || self.options.zoomType === 'inner') { + + if (self.zoomLock === 1) { + //overrides for images not zoomable + if (self.widthRatio <= 1) { + self.windowLeftPos = 0; + } + if (self.heightRatio <= 1) { + self.windowTopPos = 0; + } + } + // adjust images less than the window height + + if (self.options.zoomType === 'window') { + if (self.largeHeight < self.options.zoomWindowHeight) { + self.windowTopPos = 0; + } + if (self.largeWidth < self.options.zoomWindowWidth) { + self.windowLeftPos = 0; + } + } + //set the zoomwindow background position + if (self.options.easing) { + + // if(self.changeZoom){ + // clearInterval(self.loop); + // self.changeZoom = false; + // self.loop = false; + + // } + //set the pos to 0 if not set + if (!self.xp) { + self.xp = 0; + } + if (!self.yp) { + self.yp = 0; + } + var interval = 16; + if (Number.isInteger(parseInt(self.options.easing))) { + interval = parseInt(self.options.easing); + } + //if loop not already started, then run it + if (!self.loop) { + self.loop = setInterval(function () { + //using zeno's paradox + + self.xp += (self.windowLeftPos - self.xp) / self.options.easingAmount; + self.yp += (self.windowTopPos - self.yp) / self.options.easingAmount; + if (self.scrollingLock) { + + clearInterval(self.loop); + self.xp = self.windowLeftPos; + self.yp = self.windowTopPos; + + self.xp = ((e.pageX - self.nzOffset.left) * self.widthRatio - self.zoomWindow.width() / 2) * (-1); + self.yp = (((e.pageY - self.nzOffset.top) * self.heightRatio - self.zoomWindow.height() / 2) * (-1)); + + if (self.changeBgSize) { + if (self.nzHeight > self.nzWidth) { + if (self.options.zoomType === 'lens') { + self.zoomLens.css('background-size', + self.largeWidth / self.newvalueheight + 'px ' + + self.largeHeight / self.newvalueheight + 'px'); + } + self.zoomWindow.css('background-size', + self.largeWidth / self.newvalueheight + 'px ' + + self.largeHeight / self.newvalueheight + 'px'); + } + else { + if (self.options.zoomType !== 'lens') { + self.zoomLens.css('background-size', + self.largeWidth / self.newvaluewidth + 'px ' + + self.largeHeight / self.newvalueheight + 'px'); + } + self.zoomWindow.css('background-size', + self.largeWidth / self.newvaluewidth + 'px ' + + self.largeHeight / self.newvaluewidth + 'px'); + } + + /* + if(!self.bgxp){self.bgxp = self.largeWidth/self.newvalue;} + if(!self.bgyp){self.bgyp = self.largeHeight/self.newvalue ;} + if (!self.bgloop){ + self.bgloop = setInterval(function(){ + + self.bgxp += (self.largeWidth/self.newvalue - self.bgxp) / self.options.easingAmount; + self.bgyp += (self.largeHeight/self.newvalue - self.bgyp) / self.options.easingAmount; + + self.zoomWindow.css('background-size', self.bgxp + 'px ' + self.bgyp + 'px' ); + + + }, 16); + + } + */ + self.changeBgSize = false; + } + + self.zoomWindow.css('background-position', self.windowLeftPos + 'px ' + self.windowTopPos + 'px'); + self.scrollingLock = false; + self.loop = false; + + } + else if (Math.round(Math.abs(self.xp - self.windowLeftPos) + Math.abs(self.yp - self.windowTopPos)) < 1) { + //stops micro movements + clearInterval(self.loop); + self.zoomWindow.css('background-position', self.windowLeftPos + 'px ' + self.windowTopPos + 'px'); + self.loop = false; + } + else { + if (self.changeBgSize) { + if (self.nzHeight > self.nzWidth) { + if (self.options.zoomType === 'lens') { + self.zoomLens.css('background-size', + self.largeWidth / self.newvalueheight + 'px ' + + self.largeHeight / self.newvalueheight + 'px'); + } + self.zoomWindow.css('background-size', + self.largeWidth / self.newvalueheight + 'px ' + + self.largeHeight / self.newvalueheight + 'px'); + } + else { + if (self.options.zoomType !== 'lens') { + self.zoomLens.css('background-size', + self.largeWidth / self.newvaluewidth + 'px ' + + self.largeHeight / self.newvaluewidth + 'px'); + } + self.zoomWindow.css('background-size', + self.largeWidth / self.newvaluewidth + 'px ' + + self.largeHeight / self.newvaluewidth + 'px'); + } + self.changeBgSize = false; + } + + self.zoomWindow.css('background-position', self.xp + 'px ' + self.yp + 'px'); + } + }, interval); + } + } + else { + if (self.changeBgSize) { + if (self.nzHeight > self.nzWidth) { + if (self.options.zoomType === 'lens') { + self.zoomLens.css('background-size', + self.largeWidth / self.newvalueheight + 'px ' + + self.largeHeight / self.newvalueheight + 'px'); + } + + self.zoomWindow.css('background-size', + self.largeWidth / self.newvalueheight + 'px ' + + self.largeHeight / self.newvalueheight + 'px'); + } + else { + if (self.options.zoomType === 'lens') { + self.zoomLens.css('background-size', + self.largeWidth / self.newvaluewidth + 'px ' + + self.largeHeight / self.newvaluewidth + 'px'); + } + if ((self.largeHeight / self.newvaluewidth) < self.options.zoomWindowHeight) { + + self.zoomWindow.css('background-size', + self.largeWidth / self.newvaluewidth + 'px ' + + self.largeHeight / self.newvaluewidth + 'px'); + } + else { + + self.zoomWindow.css('background-size', + self.largeWidth / self.newvalueheight + 'px ' + + self.largeHeight / self.newvalueheight + 'px'); + } + + } + self.changeBgSize = false; + } + + self.zoomWindow.css('background-position', + self.windowLeftPos + 'px ' + + self.windowTopPos + 'px'); + } + } + }, + + setTintPosition: function (e) { + var self = this; + var zoomLensWidth = self.zoomLens.width(); + var zoomLensHeight = self.zoomLens.height(); + self.nzOffset = self.$elem.offset(); + self.tintpos = String(((e.pageX - self.nzOffset.left) - (zoomLensWidth / 2)) * (-1)); + self.tintposy = String(((e.pageY - self.nzOffset.top) - zoomLensHeight / 2) * (-1)); + if (self.Etoppos) { + self.tintposy = 0; + } + if (self.Eloppos) { + self.tintpos = 0; + } + if (self.Eboppos) { + self.tintposy = (self.nzHeight - zoomLensHeight - (self.options.lensBorderSize * 2)) * (-1); + } + if (self.Eroppos) { + self.tintpos = ((self.nzWidth - zoomLensWidth - (self.options.lensBorderSize * 2)) * (-1)); + } + if (self.options.tint) { + //stops micro movements + if (self.fullheight) { + self.tintposy = 0; + + } + if (self.fullwidth) { + self.tintpos = 0; + + } + self.zoomTintImage.css({ + 'left': self.tintpos + 'px', + 'top': self.tintposy + 'px' + }); + } + }, + + swaptheimage: function (smallimage, largeimage) { + var self = this; + var newImg = new Image(); + + if (self.options.loadingIcon && !self.spinner) { + var styleAttr = 'background: url(\'' + self.options.loadingIcon + '\') no-repeat center;' + + 'height:' + self.nzHeight + 'px;' + + 'width:' + self.nzWidth + 'px;' + + 'z-index: 2000;' + + 'position: absolute; ' + + 'background-position: center center;'; + if (self.options.zoomType === 'inner') { + styleAttr += 'top: 0px;'; + } + self.spinner = $('
'); + self.$elem.after(self.spinner); + } else if (self.spinner) { + self.spinner.show(); + } + + self.options.onImageSwap(self.$elem); + + newImg.onload = function () { + self.largeWidth = newImg.width; + self.largeHeight = newImg.height; + self.zoomImage = largeimage; + self.zoomWindow.css('background-size', self.largeWidth + 'px ' + self.largeHeight + 'px'); + + self.swapAction(smallimage, largeimage); + return; + }; + self.setImageSource(newImg, largeimage); // this must be done AFTER setting onload + }, + + swapAction: function (smallimage, largeimage) { + var self = this; + var elemWidth = self.$elem.width(); + var elemHeight = self.$elem.height(); + var newImg2 = new Image(); + newImg2.onload = function () { + //re-calculate values + self.nzHeight = newImg2.height; + self.nzWidth = newImg2.width; + self.options.onImageSwapComplete(self.$elem); + + self.doneCallback(); + return; + }; + self.setImageSource(newImg2, smallimage); + + //reset the zoomlevel to that initially set in options + self.currentZoomLevel = self.options.zoomLevel; + self.options.maxZoomLevel = false; + + //swaps the main image + //self.$elem.attr('src',smallimage); + //swaps the zoom image + if (self.options.zoomType === 'lens') { + self.zoomLens.css('background-image', 'url("' + largeimage + '")'); + } + if (self.options.zoomType === 'window') { + self.zoomWindow.css('background-image', 'url("' + largeimage + '")'); + } + if (self.options.zoomType === 'inner') { + self.zoomWindow.css('background-image', 'url("' + largeimage + '")'); + } + + self.currentImage = largeimage; + + if (self.options.imageCrossfade) { + var oldImg = self.$elem; + var newImg = oldImg.clone(); + self.$elem.attr('src', smallimage); + self.$elem.after(newImg); + newImg.stop(true).fadeOut(self.options.imageCrossfade, function () { + $(this).remove(); + }); + + // if(self.options.zoomType === 'inner'){ + //remove any attributes on the cloned image so we can resize later + self.$elem.width('auto').removeAttr('width'); + self.$elem.height('auto').removeAttr('height'); + // } + + oldImg.fadeIn(self.options.imageCrossfade); + + if (self.options.tint && self.options.zoomType !== 'inner') { + + var oldImgTint = self.zoomTintImage; + var newImgTint = oldImgTint.clone(); + self.zoomTintImage.attr('src', largeimage); + self.zoomTintImage.after(newImgTint); + newImgTint.stop(true).fadeOut(self.options.imageCrossfade, function () { + $(this).remove(); + }); + + oldImgTint.fadeIn(self.options.imageCrossfade); + + //self.zoomTintImage.attr('width',elem.data('image')); + + //resize the tint window + self.zoomTint.css({ + height: elemHeight, + width: elemWidth + }); + } + + self.zoomContainer.css({ + 'height': elemHeight, + 'width': elemWidth + }); + + if (self.options.zoomType === 'inner') { + if (!self.options.constrainType) { + self.zoomWrap.parent().css({ + 'height': elemHeight, + 'width': elemWidth + }); + + self.zoomWindow.css({ + 'height': elemHeight, + 'width': elemWidth + }); + } + } + + if (self.options.imageCrossfade) { + self.zoomWrap.css({ + 'height': elemHeight, + 'width': elemWidth + }); + } + } + else { + self.$elem.attr('src', smallimage); + if (self.options.tint) { + self.zoomTintImage.attr('src', largeimage); + //self.zoomTintImage.attr('width',elem.data('image')); + self.zoomTintImage.attr('height', elemHeight); + //self.zoomTintImage.attr('src') = elem.data('image'); + self.zoomTintImage.css('height', elemHeight); + self.zoomTint.css('height', elemHeight); + + } + self.zoomContainer.css({ + 'height': elemHeight, + 'width': elemWidth + }); + + if (self.options.imageCrossfade) { + self.zoomWrap.css({ + 'height': elemHeight, + 'width': elemWidth + }); + } + } + if (self.options.constrainType) { + + //This will contrain the image proportions + if (self.options.constrainType === 'height') { + + var autoWDimension = { + 'height': self.options.constrainSize, + 'width': 'auto' + }; + self.zoomContainer.css(autoWDimension); + + if (self.options.imageCrossfade) { + self.zoomWrap.css(autoWDimension); + self.constwidth = self.zoomWrap.width(); + } + else { + self.$elem.css(autoWDimension); + self.constwidth = elemWidth; + } + + var constWDim = { + 'height': self.options.constrainSize, + 'width': self.constwidth + }; + if (self.options.zoomType === 'inner') { + + self.zoomWrap.parent().css(constWDim); + self.zoomWindow.css(constWDim); + } + if (self.options.tint) { + self.tintContainer.css(constWDim); + self.zoomTint.css(constWDim); + self.zoomTintImage.css(constWDim); + } + + } + if (self.options.constrainType === 'width') { + var autoHDimension = { + 'height': 'auto', + 'width': self.options.constrainSize + }; + self.zoomContainer.css(autoHDimension); + + if (self.options.imageCrossfade) { + self.zoomWrap.css(autoHDimension); + self.constheight = self.zoomWrap.height(); + } + else { + self.$elem.css(autoHDimension); + self.constheight = elemHeight; + } + + var constHDim = { + 'height': self.constheight, + 'width': self.options.constrainSize + }; + if (self.options.zoomType === 'inner') { + self.zoomWrap.parent().css(constHDim); + self.zoomWindow.css(constHDim); + } + if (self.options.tint) { + self.tintContainer.css(constHDim); + self.zoomTint.css(constHDim); + self.zoomTintImage.css(constHDim); + } + } + } + }, + + doneCallback: function () { + var self = this; + if (self.options.loadingIcon && !!self.spinner && !!self.spinner.length) { + self.spinner.hide(); + } + + self.nzOffset = self.$elem.offset(); + self.nzWidth = self.$elem.width(); + self.nzHeight = self.$elem.height(); + + // reset the zoomlevel back to default + self.currentZoomLevel = self.options.zoomLevel; + + //ratio of the large to small image + self.widthRatio = self.largeWidth / self.nzWidth; + self.heightRatio = self.largeHeight / self.nzHeight; + + //NEED TO ADD THE LENS SIZE FOR ROUND + // adjust images less than the window height + if (self.options.zoomType === 'window') { + + if (self.nzHeight < self.options.zoomWindowHeight / self.heightRatio) { + self.lensHeight = self.nzHeight; + + } + else { + self.lensHeight = String((self.options.zoomWindowHeight / self.heightRatio)); + } + + if (self.nzWidth < self.options.zoomWindowWidth) { + self.lensWidth = self.nzWidth; + } + else { + self.lensWidth = (self.options.zoomWindowWidth / self.widthRatio); + } + + if (self.zoomLens) { + self.zoomLens.css({ + 'width': self.lensWidth, + 'height': self.lensHeight + }); + } + } + }, + + getCurrentImage: function () { + var self = this; + return self.zoomImage; + }, + + getGalleryList: function () { + var self = this; + //loop through the gallery options and set them in list for fancybox + self.gallerylist = []; + if (self.options.gallery) { + $('#' + self.options.gallery + ' a').each(function () { + + var imgSrc = ''; + if ($(this).data(self.options.attrImageZoomSrc)) { + imgSrc = $(this).data(self.options.attrImageZoomSrc); + } + else if ($(this).data('image')) { + imgSrc = $(this).data('image'); + } + //put the current image at the start + if (imgSrc === self.zoomImage) { + self.gallerylist.unshift({ + href: '' + imgSrc + '', + title: $(this).find('img').attr('title') + }); + } + else { + self.gallerylist.push({ + href: '' + imgSrc + '', + title: $(this).find('img').attr('title') + }); + } + }); + } + //if no gallery - return current image + else { + self.gallerylist.push({ + href: '' + self.zoomImage + '', + title: $(this).find('img').attr('title') + }); + } + return self.gallerylist; + }, + + changeZoomLevel: function (value) { + var self = this; + + //flag a zoom, so can adjust the easing during setPosition + self.scrollingLock = true; + + //round to two decimal places + self.newvalue = parseFloat(value).toFixed(2); + var newvalue = self.newvalue; + + //maxwidth & Maxheight of the image + var maxheightnewvalue = self.largeHeight / ((self.options.zoomWindowHeight / self.nzHeight) * self.nzHeight); + var maxwidthtnewvalue = self.largeWidth / ((self.options.zoomWindowWidth / self.nzWidth) * self.nzWidth); + + //calculate new heightratio + if (self.options.zoomType !== 'inner') { + if (maxheightnewvalue <= newvalue) { + self.heightRatio = (self.largeHeight / maxheightnewvalue) / self.nzHeight; + self.newvalueheight = maxheightnewvalue; + self.fullheight = true; + } + else { + self.heightRatio = (self.largeHeight / newvalue) / self.nzHeight; + self.newvalueheight = newvalue; + self.fullheight = false; + } + + // calculate new width ratio + + if (maxwidthtnewvalue <= newvalue) { + self.widthRatio = (self.largeWidth / maxwidthtnewvalue) / self.nzWidth; + self.newvaluewidth = maxwidthtnewvalue; + self.fullwidth = true; + } + else { + self.widthRatio = (self.largeWidth / newvalue) / self.nzWidth; + self.newvaluewidth = newvalue; + self.fullwidth = false; + } + if (self.options.zoomType === 'lens') { + if (maxheightnewvalue <= newvalue) { + self.fullwidth = true; + self.newvaluewidth = maxheightnewvalue; + } else { + self.widthRatio = (self.largeWidth / newvalue) / self.nzWidth; + self.newvaluewidth = newvalue; + + self.fullwidth = false; + } + } + } + + if (self.options.zoomType === 'inner') { + maxheightnewvalue = parseFloat(self.largeHeight / self.nzHeight).toFixed(2); + maxwidthtnewvalue = parseFloat(self.largeWidth / self.nzWidth).toFixed(2); + if (newvalue > maxheightnewvalue) { + newvalue = maxheightnewvalue; + } + if (newvalue > maxwidthtnewvalue) { + newvalue = maxwidthtnewvalue; + } + + if (maxheightnewvalue <= newvalue) { + self.heightRatio = (self.largeHeight / newvalue) / self.nzHeight; + if (newvalue > maxheightnewvalue) { + self.newvalueheight = maxheightnewvalue; + } else { + self.newvalueheight = newvalue; + } + self.fullheight = true; + } + else { + self.heightRatio = (self.largeHeight / newvalue) / self.nzHeight; + + if (newvalue > maxheightnewvalue) { + + self.newvalueheight = maxheightnewvalue; + } else { + self.newvalueheight = newvalue; + } + self.fullheight = false; + } + + if (maxwidthtnewvalue <= newvalue) { + + self.widthRatio = (self.largeWidth / newvalue) / self.nzWidth; + if (newvalue > maxwidthtnewvalue) { + + self.newvaluewidth = maxwidthtnewvalue; + } else { + self.newvaluewidth = newvalue; + } + + self.fullwidth = true; + } + else { + self.widthRatio = (self.largeWidth / newvalue) / self.nzWidth; + self.newvaluewidth = newvalue; + self.fullwidth = false; + } + } //end inner + var scrcontinue = false; + + if (self.options.zoomType === 'inner') { + if (self.nzWidth >= self.nzHeight) { + if (self.newvaluewidth <= maxwidthtnewvalue) { + scrcontinue = true; + } + else { + scrcontinue = false; + self.fullheight = true; + self.fullwidth = true; + } + } + if (self.nzHeight > self.nzWidth) { + if (self.newvaluewidth <= maxwidthtnewvalue) { + scrcontinue = true; + } + else { + scrcontinue = false; + self.fullheight = true; + self.fullwidth = true; + } + } + } + + if (self.options.zoomType !== 'inner') { + scrcontinue = true; + } + + if (scrcontinue) { + self.zoomLock = 0; + self.changeZoom = true; + + //if lens height is less than image height + if (((self.options.zoomWindowHeight) / self.heightRatio) <= self.nzHeight) { + self.currentZoomLevel = self.newvalueheight; + if (self.options.zoomType !== 'lens' && self.options.zoomType !== 'inner') { + self.changeBgSize = true; + self.zoomLens.css('height', String(self.options.zoomWindowHeight / self.heightRatio) + 'px'); + } + if (self.options.zoomType === 'lens' || self.options.zoomType === 'inner') { + self.changeBgSize = true; + } + } + + if ((self.options.zoomWindowWidth / self.widthRatio) <= self.nzWidth) { + if (self.options.zoomType !== 'inner') { + if (self.newvaluewidth > self.newvalueheight) { + self.currentZoomLevel = self.newvaluewidth; + } + } + + if (self.options.zoomType !== 'lens' && self.options.zoomType !== 'inner') { + self.changeBgSize = true; + + self.zoomLens.css('width', String(self.options.zoomWindowWidth / self.widthRatio) + 'px'); + } + if (self.options.zoomType === 'lens' || self.options.zoomType === 'inner') { + self.changeBgSize = true; + } + + } + if (self.options.zoomType === 'inner') { + self.changeBgSize = true; + + if (self.nzWidth > self.nzHeight) { + self.currentZoomLevel = self.newvaluewidth; + } + else if (self.nzHeight >= self.nzWidth) { + self.currentZoomLevel = self.newvaluewidth; + } + } + } //under + + //sets the boundry change, called in setWindowPos + self.setPosition(self.currentLoc); + // + }, + + closeAll: function () { + var self = this; + if (self.zoomWindow) { + self.zoomWindow.hide(); + } + if (self.zoomLens) { + self.zoomLens.hide(); + } + if (self.zoomTint) { + self.zoomTint.hide(); + } + }, + + changeState: function (value) { + var self = this; + if (value === 'enable') { + self.options.zoomEnabled = true; + } + if (value === 'disable') { + self.options.zoomEnabled = false; + } + }, + + responsiveConfig: function (options) { + if (options.respond && options.respond.length > 0) { + return $.extend({}, options, this.configByScreenWidth(options)); + } + return options; + }, + + configByScreenWidth: function (options) { + var screenWidth = $(window).width(); + + var config = $.grep(options.respond, function (item) { + var range = item.range.split('-'); + return (screenWidth >= range[0]) && (screenWidth <= range[1]); + }); + + if (config.length > 0) { + return config[0]; + } else { + return options; + } + } + }; + + $.fn.ezPlus = function (options) { + return this.each(function () { + var elevate = Object.create(EZP); + + elevate.init(options, this); + + $.data(this, 'ezPlus', elevate); + + }); + }; + + $.fn.ezPlus.options = { + attrImageZoomSrc: 'zoom-image', // attribute to plugin use for zoom + borderColour: '#888', + borderSize: 4, + constrainSize: false, //in pixels the dimensions you want to constrain on + constrainType: false, //width or height + containLensZoom: false, + cursor: 'inherit', // user should set to what they want the cursor as, if they have set a click function + debug: false, + easing: false, + easingAmount: 12, + enabled: true, + + gallery: false, + galleryActiveClass: 'zoomGalleryActive', + gallerySelector: false, + galleryItem: 'a', + + imageCrossfade: false, + + lensBorderColour: '#000', + lensBorderSize: 1, + lensColour: 'white', //colour of the lens background + lensFadeIn: false, + lensFadeOut: false, + lensOpacity: 0.4, //opacity of the lens + lensShape: 'square', //can be 'round' + lensSize: 200, + lenszoom: false, + + loadingIcon: false, //http://www.example.com/spinner.gif + + // This change will allow to decide if you want to decrease + // zoom of one of the dimensions once the other reached it's top value, + // or keep the aspect ratio, default behaviour still being as always, + // allow to continue zooming out, so it keeps retrocompatibility. + mantainZoomAspectRatio: false, + maxZoomLevel: false, + minZoomLevel: 1.01, + + onComplete: $.noop, + onDestroy: $.noop, + onImageClick: $.noop, + onImageSwap: $.noop, + onImageSwapComplete: $.noop, + onShow: $.noop, + onZoomedImageLoaded: $.noop, + + preloading: 1, //by default, load all the images, if 0, then only load images after activated (PLACEHOLDER FOR NEXT VERSION) + respond: [], + responsive: true, + scrollZoom: false, //allow zoom on mousewheel, true to activate + scrollZoomIncrement: 0.1, //steps of the scrollzoom + showLens: true, + tint: false, //enable the tinting + tintColour: '#333', //default tint color, can be anything, red, #ccc, rgb(0,0,0) + tintOpacity: 0.4, //opacity of the tint + touchEnabled: true, + + zoomActivation: 'hover', // Can also be click (PLACEHOLDER FOR NEXT VERSION) + zoomContainerAppendTo: 'body', //zoom container parent selector + zoomId: -1, // identifier for the zoom container + zoomLevel: 1, //default zoom level of image + zoomTintFadeIn: false, + zoomTintFadeOut: false, + zoomType: 'window', //window is default, also 'lens' available - + zoomWindowAlwaysShow: false, + zoomWindowBgColour: '#fff', + zoomWindowFadeIn: false, + zoomWindowFadeOut: false, + zoomWindowHeight: 400, + zoomWindowOffsetX: 0, + zoomWindowOffsetY: 0, + zoomWindowPosition: 1, //Possible values: 1-16, but we can also position with a selector string. + zoomWindowWidth: 400, + zoomEnabled: true, //false disables zoomwindow from showing + zIndex: 999 + }; + +})(jQuery, window, document); diff --git a/topologie/templates/topologie/aff_switch.html b/topologie/templates/topologie/aff_switch.html index a8547243..799225f0 100644 --- a/topologie/templates/topologie/aff_switch.html +++ b/topologie/templates/topologie/aff_switch.html @@ -24,11 +24,12 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load acl %} +
{% if switch_list.paginator %} {% include "pagination.html" with list=switch_list %} {% endif %} -
+ @@ -72,8 +73,9 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endfor %}
-
{% if switch_list.paginator %} {% include "pagination.html" with list=switch_list %} {% endif %} + +
diff --git a/topologie/templates/topologie/index.html b/topologie/templates/topologie/index.html index 9838499a..6e140251 100644 --- a/topologie/templates/topologie/index.html +++ b/topologie/templates/topologie/index.html @@ -29,7 +29,19 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block title %}Switchs{% endblock %} {% block content %} -

Switchs

+ + + + + + +

Switchs

{% can_create Switch %} Ajouter un switch
@@ -38,4 +50,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,


+ + {% endblock %} diff --git a/topologie/views.py b/topologie/views.py index 6c18721f..82d945e5 100644 --- a/topologie/views.py +++ b/topologie/views.py @@ -43,6 +43,7 @@ from django.db import IntegrityError from django.db import transaction from django.db.models import ProtectedError, Prefetch from django.core.exceptions import ValidationError +from django.contrib.staticfiles.storage import staticfiles_storage from topologie.models import ( Switch, @@ -88,6 +89,8 @@ from machines.views import generate_ipv4_mbf_param from machines.models import Interface from preferences.models import AssoOption, GeneralOption +from subprocess import Popen,PIPE + @login_required @can_view_all(Switch) @@ -785,3 +788,99 @@ def del_constructor_switch(request, constructor_switch, constructorswitchid): 'objet': constructor_switch, 'objet_name': 'Constructeur de switch' }, 'topologie/delete.html', request) + + +def make_machine_graph(): + """ + Crée le fichier dot et l'image du graph des Switchs + """ + #Syntaxe DOT temporaire, A mettre dans un template: + lignes=['''digraph Switchs { +node [ +fontname=Helvetica +fontsize=8 +shape=plaintext] +edge[arrowhead=odot,arrowtail=dot]'''] + node_fixe='''node [label=< + + + + + +''' + node_ports=''' +''' + cluster='''subgraph cluster_{} {{ +color=blue; +label="Batiment {}";''' + end_table='''
+ +{} +
+{} + +{} +
+{} + +{} +
+{} + +{} +
+>] \"{}_{}\" ;''' + switch_alone='''{} [label=< + + +
+ +{} +
+>]''' + missing=[] + detected=[] + for sw in Switch.objects.all(): + if(sw not in detected): + missing.append(sw) + for building in Building.objects.all(): + lignes.append(cluster.format(len(lignes),building)) + for switch in Switch.objects.filter(switchbay__building=building): + lignes.append(node_fixe.format(switch.main_interface().domain.name,"Modèle",switch.model,"Nombre de ports",switch.number)) + for p in switch.ports.all().filter(related__isnull=False): + lignes.append(node_ports.format(p.port,p.related.switch.main_interface().domain.name)) + lignes.append(end_table.format(building.id,switch.id)) + lignes.append("}") + while(missing!=[]): + lignes,new_detected=recursive_switchs(missing[0].ports.all().filter(related=None).first(),None,lignes,[missing[0]]) + missing=[i for i in missing if i not in new_detected] + detected+=new_detected + for switch in Switch.objects.all().filter(switchbay__isnull=True).exclude(ports__related__isnull=False): + lignes.append(switch_alone.format(switch.id,switch.main_interface().domain.name)) + lignes.append("}") + fichier = open("media/images/switchs.dot","w") + for ligne in lignes: + fichier.write(ligne+"\n") + fichier.close() + unflatten = Popen(["unflatten","-l", "3", "media/images/switchs.dot"], stdout=PIPE) + image = Popen(["dot", "-Tpng", "-o", "media/images/switchs.png"], stdin=unflatten.stdout, stdout=PIPE) + + +def recursive_switchs(port_start, switch_before, lignes,detected): + """ + Parcour récursivement le switchs auquel appartient port_start pour trouver les ports suivants liés + """ + l_ports=port_start.switch.ports.filter(related__isnull=False) + for port in l_ports: + if port.related.switch!=switch_before and port.related.switch!=port.switch: + links=[] + for sw in [switch for switch in [port_start.switch,port.related.switch]]: + if(sw not in detected): + detected.append(sw) + if(sw.switchbay.building): + links.append("\"{}_{}\"".format(sw.switchbay.building.id,sw.id)) + else: + links.append("\"{}\"".format(sw.id)) + lignes.append(links[0]+" -> "+links[1]) + lignes, detected = recursive_switchs(port.related, port_start.switch, lignes, detected) + return (lignes, detected) \ No newline at end of file