/*
* jQuery elevateZoom 3.0.8
* Demo's and documentation:
* www.elevateweb.co.uk/image-zoom
*
* Copyright (c) 2012 Andrew Eades
* www.elevateweb.co.uk
*
* Dual licensed under the GPL and MIT licenses.
* http://en.wikipedia.org/wiki/MIT_License
* http://en.wikipedia.org/wiki/GNU_General_Public_License
*
/*
* jQuery elevateZoom 3.0.3
* Demo's and documentation:
* www.elevateweb.co.uk/image-zoom
*
* Copyright (c) 2012 Andrew Eades
* www.elevateweb.co.uk
*
* Dual licensed under the GPL and MIT licenses.
* http://en.wikipedia.org/wiki/MIT_License
* http://en.wikipedia.org/wiki/GNU_General_Public_License
*/
if ( typeof Object.create !== 'function' ) {
Object.create = function( obj ) {
function F() {};
F.prototype = obj;
return new F();
};
}
(function( $, window, document, undefined ) {
var ElevateZoom = {
init: function( options, elem ) {
var self = this;
self.elem = elem;
self.$elem = $( elem );
self.imageSrc = self.$elem.data("zoom-image") ? self.$elem.data("zoom-image") : self.$elem.attr("src");
self.options = $.extend( {}, $.fn.elevateZoom.options, options );
//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;}
//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
$('#'+self.options.gallery + ' a').click( function(e) {
// TOBI specific code to disable clicking on a product detail image and zooming in even more
if($(this).closest('div').hasClass('product-detail-images')) {
e.preventDefault();
return false;
}
//Set a class on the currently active gallery image
if(self.options.galleryActiveClass){
$('#'+self.options.gallery + ' a').removeClass(self.options.galleryActiveClass);
$(this).addClass(self.options.galleryActiveClass);
}
//stop any link on the a tag from working
e.preventDefault();
//call the swap image function
if($(this).data("zoom-image")){self.zoomImagePre = $(this).data("zoom-image")}
else{self.zoomImagePre = $(this).data("image");}
self.swaptheimage($(this).data("image"), self.zoomImagePre);
return false;
});
},
refresh: function( length ) {
var self = this;
setTimeout(function() {
self.fetch(self.imageSrc);
}, length || self.options.refresh );
},
fetch: function(imgsrc) {
//get the image
var self = this;
var newImg = new Image();
newImg.onload = function() {
//set the large image dimensions - used to calculte ratio's
self.largeWidth = newImg.width;
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);
}
newImg.src = imgsrc; // this must be done AFTER setting onload
return;
},
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 Wrappe
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;
//if window zoom
if(self.options.zoomType == "window") {
self.zoomWindowStyle = "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 inner zoom
if(self.options.zoomType == "inner") {
//has a border been put on the image? Lets cater for this
var borderWidth = self.$elem.css("border-left-width");
self.zoomWindowStyle = "overflow: hidden;"
+ "margin-left: " + String(borderWidth) + ";"
+ "margin-top: " + String(borderWidth) + ";"
+ "background-position: 0px 0px;"
+ "width: " + String(self.nzWidth) + "px;"
+ "height: " + String(self.nzHeight) + "px;"
+ "px;float: left;"
+ "display: none;"
+ "cursor:"+(self.options.cursor)+";"
+ "px solid " + self.options.borderColour
+ ";background-repeat: no-repeat;"
+ "position: absolute;";
}
//lens style for window zoom
if(self.options.zoomType == "window") {
// adjust images less than the window height
if(self.nzHeight < self.options.zoomWindowWidth/self.widthRatio){
lensHeight = self.nzHeight;
}
else{
lensHeight = String((self.options.zoomWindowHeight/self.heightRatio))
}
if(self.largeWidth < self.options.zoomWindowWidth){
lensWidth = self.nzWidth;
}
else{
lensWidth = (self.options.zoomWindowWidth/self.widthRatio);
}
self.lensStyle = "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;"
+ "-webkit-transform: translateZ(0);"
+ "opacity:"+(self.options.lensOpacity)+";filter: alpha(opacity = "+(self.options.lensOpacity*100)+"); zoom:1;"
+ "width:"+lensWidth+"px;"
+ "height:"+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;";
}
//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 = $('');
$('body').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');
});
}
}
//create zoom window
if(isNaN(self.options.zoomWindowPosition)){
self.zoomWindow = $("
")
.appendTo('body')
.click(function () {
self.$elem.trigger('click');
});
}else{
self.zoomWindow = $("
")
.appendTo(self.zoomContainer)
.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({ backgroundImage: "url('" + self.imageSrc + "')" });
}
if(self.options.zoomType == "window") {
self.zoomWindow.css({ backgroundImage: "url('" + self.imageSrc + "')" });
}
if(self.options.zoomType == "inner") {
self.zoomWindow.css({ backgroundImage: "url('" + self.imageSrc + "')" });
}
/*-------------------END THE ZOOM WINDOW AND LENS----------------------------------*/
//touch events
self.$elem.bind('touchmove', function(e){
e.preventDefault();
var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
self.setPosition(touch);
});
self.zoomContainer.bind('touchmove', 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', 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', 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', function(e){
e.preventDefault();
var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
self.setPosition(touch);
});
self.zoomLens.bind('touchend', 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', 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('mousemove', 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;
});
if(self.options.zoomType != "inner") {
self.zoomLens.bind('mousemove', function(e){
//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;
});
}
if(self.options.tint && self.options.zoomType != "inner") {
self.zoomTint.bind('mousemove', function(e){
//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;
});
}
if(self.options.zoomType == "inner") {
self.zoomWindow.bind('mousemove', function(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;
});
}
// 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){
self.zoomContainer.add(self.$elem).bind('mousewheel 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.wheelDelta || e.originalEvent.detail*-1
//this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;
// e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
e.preventDefault();
if(theEvent /120 > 0) {
//scrolling up
if(self.currentZoomLevel >= self.minZoomLevel){
self.changeZoomLevel(self.currentZoomLevel-self.options.scrollZoomIncrement);
}
}
else{
//scrolling down
if(self.options.maxZoomLevel){
if(self.currentZoomLevel <= self.options.maxZoomLevel){
self.changeZoomLevel(parseFloat(self.currentZoomLevel)+self.options.scrollZoomIncrement);
}
}
else{
//andy
self.changeZoomLevel(parseFloat(self.currentZoomLevel)+self.options.scrollZoomIncrement);
}
}
return false;
});
}
},
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});
self.zoomTint.css({ 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){
if(self.nzHeight < self.options.zoomWindowWidth/self.widthRatio){
lensHeight = self.nzHeight;
}
else{
lensHeight = String((self.options.zoomWindowHeight/self.heightRatio))
}
if(self.largeWidth < self.options.zoomWindowWidth){
lensWidth = self.nzWidth;
}
else{
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){
lensHeight = self.nzHeight;
}
else{
lensHeight = String((self.options.zoomWindowHeight/self.heightRatio))
}
if(self.nzWidth < self.options.zoomWindowHeight/self.heightRatio){
lensWidth = self.nzWidth;
}
else{
lensWidth = String((self.options.zoomWindowWidth/self.widthRatio));
}
self.zoomLens.css('width', lensWidth);
self.zoomLens.css('height', lensHeight);
if(self.options.tint){
self.zoomTintImage.css('width', self.nzWidth);
self.zoomTintImage.css('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});
self.zoomContainer.css({ left: self.nzOffset.left});
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") {
self.Etoppos = (self.mouseTop < (self.zoomLens.height()/2));
self.Eboppos = (self.mouseTop > self.nzHeight - (self.zoomLens.height()/2)-(self.options.lensBorderSize*2));
self.Eloppos = (self.mouseLeft < 0+((self.zoomLens.width()/2)));
self.Eroppos = (self.mouseLeft > (self.nzWidth - (self.zoomLens.width()/2)-(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({ backgroundPosition: 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.setWindowPostition(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.setWindowPostition(e);
}
if(self.options.zoomType == "inner") {
self.setWindowPostition(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
},
showHideWindow: function(change) {
var self = this;
if(change == "show"){
if(!self.isWindowActive){
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.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.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){
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;
}
}
},
setLensPostition: function( e ) {
},
setWindowPostition: 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.zoomWindowOffety);//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
}
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
}
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
}
break;
case 11:
self.windowOffsetTop = (self.options.zoomWindowOffety);
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
}
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.zoomWindowOffety);//DONE - 1
self.windowOffsetLeft =(self.nzWidth); //DONE 1, 2, 3, 4, 16
}
} //end isNAN
else{
//WE CAN POSITION IN A CLASS - ASSUME THAT ANY STRING PASSED IS
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.zoomWindowOffety;
self.windowOffsetLeft = self.windowOffsetLeft + self.options.zoomWindowOffetx;
self.zoomWindow.css({ top: self.windowOffsetTop});
self.zoomWindow.css({ left: self.windowOffsetLeft});
if(self.options.zoomType == "inner") {
self.zoomWindow.css({ top: 0});
self.zoomWindow.css({ 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;}
//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({ backgroundPosition: 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({ backgroundPosition: 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({ backgroundPosition: self.xp + 'px ' + self.yp + 'px' });
}
}, 16);
}
}
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({ backgroundPosition: self.windowLeftPos + 'px ' + self.windowTopPos + 'px' });
}
}
},
setTintPosition: function(e){
var self = this;
self.nzOffset = self.$elem.offset();
self.tintpos = String(((e.pageX - self.nzOffset.left)-(self.zoomLens.width() / 2)) * (-1));
self.tintposy = String(((e.pageY - self.nzOffset.top) - self.zoomLens.height() / 2) * (-1));
if(self.Etoppos){
self.tintposy = 0;
}
if(self.Eloppos){
self.tintpos=0;
}
if(self.Eboppos){
self.tintposy = (self.nzHeight-self.zoomLens.height()-(self.options.lensBorderSize*2))*(-1);
}
if(self.Eroppos){
self.tintpos = ((self.nzWidth-self.zoomLens.width()-(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'});
self.zoomTintImage.css({'top': self.tintposy+'px'});
}
},
swaptheimage: function(smallimage, largeimage){
var self = this;
var newImg = new Image();
if(self.options.loadingIcon){
self.spinner = $('');
self.$elem.after(self.spinner);
}
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;
}
newImg.src = largeimage; // this must be done AFTER setting onload
},
swapAction: function(smallimage, largeimage){
var self = this;
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;
}
newImg2.src = 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({ backgroundImage: "url('" + largeimage + "')" });
}
if(self.options.zoomType == "window") {
self.zoomWindow.css({ backgroundImage: "url('" + largeimage + "')" });
}
if(self.options.zoomType == "inner") {
self.zoomWindow.css({ backgroundImage: "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: self.$elem.height()});
self.zoomTint.css({ width: self.$elem.width()});
}
self.zoomContainer.css("height", self.$elem.height());
self.zoomContainer.css("width", self.$elem.width());
if(self.options.zoomType == "inner"){
if(!self.options.constrainType){
self.zoomWrap.parent().css("height", self.$elem.height());
self.zoomWrap.parent().css("width", self.$elem.width());
self.zoomWindow.css("height", self.$elem.height());
self.zoomWindow.css("width", self.$elem.width());
}
}
if(self.options.imageCrossfade){
self.zoomWrap.css("height", self.$elem.height());
self.zoomWrap.css("width", self.$elem.width());
}
}
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",self.$elem.height());
//self.zoomTintImage.attr('src') = elem.data("image");
self.zoomTintImage.css({ height: self.$elem.height()});
self.zoomTint.css({ height: self.$elem.height()});
}
self.zoomContainer.css("height", self.$elem.height());
self.zoomContainer.css("width", self.$elem.width());
if(self.options.imageCrossfade){
self.zoomWrap.css("height", self.$elem.height());
self.zoomWrap.css("width", self.$elem.width());
}
}
if(self.options.constrainType){
//This will contrain the image proportions
if(self.options.constrainType == "height"){
self.zoomContainer.css("height", self.options.constrainSize);
self.zoomContainer.css("width", "auto");
if(self.options.imageCrossfade){
self.zoomWrap.css("height", self.options.constrainSize);
self.zoomWrap.css("width", "auto");
self.constwidth = self.zoomWrap.width();
}
else{
self.$elem.css("height", self.options.constrainSize);
self.$elem.css("width", "auto");
self.constwidth = self.$elem.width();
}
if(self.options.zoomType == "inner"){
self.zoomWrap.parent().css("height", self.options.constrainSize);
self.zoomWrap.parent().css("width", self.constwidth);
self.zoomWindow.css("height", self.options.constrainSize);
self.zoomWindow.css("width", self.constwidth);
}
if(self.options.tint){
self.tintContainer.css("height", self.options.constrainSize);
self.tintContainer.css("width", self.constwidth);
self.zoomTint.css("height", self.options.constrainSize);
self.zoomTint.css("width", self.constwidth);
self.zoomTintImage.css("height", self.options.constrainSize);
self.zoomTintImage.css("width", self.constwidth);
}
}
if(self.options.constrainType == "width"){
self.zoomContainer.css("height", "auto");
self.zoomContainer.css("width", self.options.constrainSize);
if(self.options.imageCrossfade){
self.zoomWrap.css("height", "auto");
self.zoomWrap.css("width", self.options.constrainSize);
self.constheight = self.zoomWrap.height();
}
else{
self.$elem.css("height", "auto");
self.$elem.css("width", self.options.constrainSize);
self.constheight = self.$elem.height();
}
if(self.options.zoomType == "inner"){
self.zoomWrap.parent().css("height", self.constheight);
self.zoomWrap.parent().css("width", self.options.constrainSize);
self.zoomWindow.css("height", self.constheight);
self.zoomWindow.css("width", self.options.constrainSize);
}
if(self.options.tint){
self.tintContainer.css("height", self.constheight);
self.tintContainer.css("width", self.options.constrainSize);
self.zoomTint.css("height", self.constheight);
self.zoomTint.css("width", self.options.constrainSize);
self.zoomTintImage.css("height", self.constheight);
self.zoomTintImage.css("width", self.options.constrainSize);
}
}
}
},
doneCallback: function(){
var self = this;
if(self.options.loadingIcon){
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.zoomWindowWidth/self.widthRatio){
lensHeight = self.nzHeight;
}
else{
lensHeight = String((self.options.zoomWindowHeight/self.heightRatio))
}
if(self.options.zoomWindowWidth < self.options.zoomWindowWidth){
lensWidth = self.nzWidth;
}
else{
lensWidth = (self.options.zoomWindowWidth/self.widthRatio);
}
if(self.zoomLens){
self.zoomLens.css('width', lensWidth);
self.zoomLens.css('height', 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 img_src = '';
if($(this).data("zoom-image")){
img_src = $(this).data("zoom-image");
}
else if($(this).data("image")){
img_src = $(this).data("image");
}
//put the current image at the start
if(img_src == self.zoomImage){
self.gallerylist.unshift({
href: ''+img_src+'',
title: $(this).find('img').attr("title")
});
}
else{
self.gallerylist.push({
href: ''+img_src+'',
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);
newvalue = parseFloat(value).toFixed(2);
//maxwidth & Maxheight of the image
maxheightnewvalue = self.largeHeight/((self.options.zoomWindowHeight / self.nzHeight) * self.nzHeight);
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
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;
}
if(self.nzHeight > self.nzWidth){
self.currentZoomLevel = self.newvaluewidth;
}
}
} //under
//sets the boundry change, called in setWindowPos
self.setPosition(self.currentLoc);
//
},
closeAll: function(){
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;}
}
};
$.fn.elevateZoom = function( options ) {
return this.each(function() {
var elevate = Object.create( ElevateZoom );
elevate.init( options, this );
$.data( this, 'elevateZoom', elevate );
});
};
$.fn.elevateZoom.options = {
zoomActivation: "hover", // Can also be click (PLACEHOLDER FOR NEXT VERSION)
zoomEnabled: true, //false disables zoomwindow from showing
preloading: 1, //by default, load all the images, if 0, then only load images after activated (PLACEHOLDER FOR NEXT VERSION)
zoomLevel: 1, //default zoom level of image
scrollZoom: false, //allow zoom on mousewheel, true to activate
scrollZoomIncrement: 0.1, //steps of the scrollzoom
minZoomLevel: false,
maxZoomLevel: false,
easing: false,
easingAmount: 12,
lensSize: 200,
zoomWindowWidth: 400,
zoomWindowHeight: 400,
zoomWindowOffetx: 0,
zoomWindowOffety: 0,
zoomWindowPosition: 1,
zoomWindowBgColour: "#fff",
lensFadeIn: false,
lensFadeOut: false,
debug: false,
zoomWindowFadeIn: false,
zoomWindowFadeOut: false,
zoomWindowAlwaysShow: false,
zoomTintFadeIn: false,
zoomTintFadeOut: false,
borderSize: 4,
showLens: true,
borderColour: "#888",
lensBorderSize: 1,
lensBorderColour: "#000",
lensShape: "square", //can be "round"
zoomType: "window", //window is default, also "lens" available -
containLensZoom: false,
lensColour: "white", //colour of the lens background
lensOpacity: 0.4, //opacity of the lens
lenszoom: false,
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
gallery: false,
galleryActiveClass: "zoomGalleryActive",
imageCrossfade: false,
constrainType: false, //width or height
constrainSize: false, //in pixels the dimensions you want to constrain on
loadingIcon: false, //http://www.example.com/spinner.gif
cursor:"default", // user should set to what they want the cursor as, if they have set a click function
responsive:true,
onComplete: $.noop,
onDestroy: function() {},
onZoomedImageLoaded: function() {},
onImageSwap: $.noop,
onImageSwapComplete: $.noop
};
})( jQuery, window, document );
/*
_ _ _ _
___| (_) ___| | __ (_)___
/ __| | |/ __| |/ / | / __|
\__ \ | | (__| < _ | \__ \
|___/_|_|\___|_|\_(_)/ |___/
|__/
Version: 1.8.1
Author: Ken Wheeler
Website: http://kenwheeler.github.io
Docs: http://kenwheeler.github.io/slick
Repo: http://github.com/kenwheeler/slick
Issues: http://github.com/kenwheeler/slick/issues
*/
/* global window, document, define, jQuery, setInterval, clearInterval */
;(function(factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else if (typeof exports !== 'undefined') {
module.exports = factory(require('jquery'));
} else {
factory(jQuery);
}
}(function($) {
'use strict';
var Slick = window.Slick || {};
Slick = (function() {
var instanceUid = 0;
function Slick(element, settings) {
var _ = this, dataSettings;
_.defaults = {
accessibility: true,
adaptiveHeight: false,
appendArrows: $(element),
appendDots: $(element),
arrows: true,
asNavFor: null,
prevArrow: '',
nextArrow: '',
autoplay: false,
autoplaySpeed: 3000,
centerMode: false,
centerPadding: '50px',
cssEase: 'ease',
customPaging: function(slider, i) {
return $('').text(i + 1);
},
dots: false,
dotsClass: 'slick-dots',
draggable: true,
easing: 'linear',
edgeFriction: 0.35,
fade: false,
focusOnSelect: false,
focusOnChange: false,
infinite: true,
initialSlide: 0,
lazyLoad: 'ondemand',
mobileFirst: false,
pauseOnHover: true,
pauseOnFocus: true,
pauseOnDotsHover: false,
respondTo: 'window',
responsive: null,
rows: 1,
rtl: false,
slide: '',
slidesPerRow: 1,
slidesToShow: 1,
slidesToScroll: 1,
speed: 500,
swipe: true,
swipeToSlide: false,
touchMove: true,
touchThreshold: 5,
useCSS: true,
useTransform: true,
variableWidth: false,
vertical: false,
verticalSwiping: false,
waitForAnimate: true,
zIndex: 1000,
verticalSwipeLengthLimit: 15
};
_.initials = {
animating: false,
dragging: false,
autoPlayTimer: null,
currentDirection: 0,
currentLeft: null,
currentSlide: 0,
direction: 1,
$dots: null,
listWidth: null,
listHeight: null,
loadIndex: 0,
$nextArrow: null,
$prevArrow: null,
scrolling: false,
slideCount: null,
slideWidth: null,
$slideTrack: null,
$slides: null,
sliding: false,
slideOffset: 0,
swipeLeft: null,
swiping: false,
$list: null,
touchObject: {},
transformsEnabled: false,
unslicked: false
};
$.extend(_, _.initials);
_.activeBreakpoint = null;
_.animType = null;
_.animProp = null;
_.breakpoints = [];
_.breakpointSettings = [];
_.cssTransitions = false;
_.focussed = false;
_.interrupted = false;
_.hidden = 'hidden';
_.paused = true;
_.positionProp = null;
_.respondTo = null;
_.rowCount = 1;
_.shouldClick = true;
_.$slider = $(element);
_.$slidesCache = null;
_.transformType = null;
_.transitionType = null;
_.visibilityChange = 'visibilitychange';
_.windowWidth = 0;
_.windowTimer = null;
dataSettings = $(element).data('slick') || {};
_.options = $.extend({}, _.defaults, settings, dataSettings);
_.currentSlide = _.options.initialSlide;
_.originalSettings = _.options;
if (typeof document.mozHidden !== 'undefined') {
_.hidden = 'mozHidden';
_.visibilityChange = 'mozvisibilitychange';
} else if (typeof document.webkitHidden !== 'undefined') {
_.hidden = 'webkitHidden';
_.visibilityChange = 'webkitvisibilitychange';
}
_.autoPlay = $.proxy(_.autoPlay, _);
_.autoPlayClear = $.proxy(_.autoPlayClear, _);
_.autoPlayIterator = $.proxy(_.autoPlayIterator, _);
_.changeSlide = $.proxy(_.changeSlide, _);
_.clickHandler = $.proxy(_.clickHandler, _);
_.selectHandler = $.proxy(_.selectHandler, _);
_.setPosition = $.proxy(_.setPosition, _);
_.swipeHandler = $.proxy(_.swipeHandler, _);
_.dragHandler = $.proxy(_.dragHandler, _);
_.keyHandler = $.proxy(_.keyHandler, _);
_.instanceUid = instanceUid++;
// A simple way to check for HTML strings
// Strict HTML recognition (must start with <)
// Extracted from jQuery v1.11 source
_.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/;
_.registerBreakpoints();
_.init(true);
}
return Slick;
}());
Slick.prototype.activateADA = function() {
var _ = this;
_.$slideTrack.find('.slick-active').attr({
'aria-hidden': 'false'
}).find('a, input, button, select').attr({
'tabindex': '0'
});
};
Slick.prototype.addSlide = Slick.prototype.slickAdd = function(markup, index, addBefore) {
var _ = this;
if (typeof(index) === 'boolean') {
addBefore = index;
index = null;
} else if (index < 0 || (index >= _.slideCount)) {
return false;
}
_.unload();
if (typeof(index) === 'number') {
if (index === 0 && _.$slides.length === 0) {
$(markup).appendTo(_.$slideTrack);
} else if (addBefore) {
$(markup).insertBefore(_.$slides.eq(index));
} else {
$(markup).insertAfter(_.$slides.eq(index));
}
} else {
if (addBefore === true) {
$(markup).prependTo(_.$slideTrack);
} else {
$(markup).appendTo(_.$slideTrack);
}
}
_.$slides = _.$slideTrack.children(this.options.slide);
_.$slideTrack.children(this.options.slide).detach();
_.$slideTrack.append(_.$slides);
_.$slides.each(function(index, element) {
$(element).attr('data-slick-index', index);
});
_.$slidesCache = _.$slides;
_.reinit();
};
Slick.prototype.animateHeight = function() {
var _ = this;
if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
_.$list.animate({
height: targetHeight
}, _.options.speed);
}
};
Slick.prototype.animateSlide = function(targetLeft, callback) {
var animProps = {},
_ = this;
_.animateHeight();
if (_.options.rtl === true && _.options.vertical === false) {
targetLeft = -targetLeft;
}
if (_.transformsEnabled === false) {
if (_.options.vertical === false) {
_.$slideTrack.animate({
left: targetLeft
}, _.options.speed, _.options.easing, callback);
} else {
_.$slideTrack.animate({
top: targetLeft
}, _.options.speed, _.options.easing, callback);
}
} else {
if (_.cssTransitions === false) {
if (_.options.rtl === true) {
_.currentLeft = -(_.currentLeft);
}
$({
animStart: _.currentLeft
}).animate({
animStart: targetLeft
}, {
duration: _.options.speed,
easing: _.options.easing,
step: function(now) {
now = Math.ceil(now);
if (_.options.vertical === false) {
animProps[_.animType] = 'translate(' +
now + 'px, 0px)';
_.$slideTrack.css(animProps);
} else {
animProps[_.animType] = 'translate(0px,' +
now + 'px)';
_.$slideTrack.css(animProps);
}
},
complete: function() {
if (callback) {
callback.call();
}
}
});
} else {
_.applyTransition();
targetLeft = Math.ceil(targetLeft);
if (_.options.vertical === false) {
animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)';
} else {
animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)';
}
_.$slideTrack.css(animProps);
if (callback) {
setTimeout(function() {
_.disableTransition();
callback.call();
}, _.options.speed);
}
}
}
};
Slick.prototype.getNavTarget = function() {
var _ = this,
asNavFor = _.options.asNavFor;
if ( asNavFor && asNavFor !== null ) {
asNavFor = $(asNavFor).not(_.$slider);
}
return asNavFor;
};
Slick.prototype.asNavFor = function(index) {
var _ = this,
asNavFor = _.getNavTarget();
if ( asNavFor !== null && typeof asNavFor === 'object' ) {
asNavFor.each(function() {
var target = $(this).slick('getSlick');
if(!target.unslicked) {
target.slideHandler(index, true);
}
});
}
};
Slick.prototype.applyTransition = function(slide) {
var _ = this,
transition = {};
if (_.options.fade === false) {
transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase;
} else {
transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase;
}
if (_.options.fade === false) {
_.$slideTrack.css(transition);
} else {
_.$slides.eq(slide).css(transition);
}
};
Slick.prototype.autoPlay = function() {
var _ = this;
_.autoPlayClear();
if ( _.slideCount > _.options.slidesToShow ) {
_.autoPlayTimer = setInterval( _.autoPlayIterator, _.options.autoplaySpeed );
}
};
Slick.prototype.autoPlayClear = function() {
var _ = this;
if (_.autoPlayTimer) {
clearInterval(_.autoPlayTimer);
}
};
Slick.prototype.autoPlayIterator = function() {
var _ = this,
slideTo = _.currentSlide + _.options.slidesToScroll;
if ( !_.paused && !_.interrupted && !_.focussed ) {
if ( _.options.infinite === false ) {
if ( _.direction === 1 && ( _.currentSlide + 1 ) === ( _.slideCount - 1 )) {
_.direction = 0;
}
else if ( _.direction === 0 ) {
slideTo = _.currentSlide - _.options.slidesToScroll;
if ( _.currentSlide - 1 === 0 ) {
_.direction = 1;
}
}
}
_.slideHandler( slideTo );
}
};
Slick.prototype.buildArrows = function() {
var _ = this;
if (_.options.arrows === true ) {
_.$prevArrow = $(_.options.prevArrow).addClass('slick-arrow');
_.$nextArrow = $(_.options.nextArrow).addClass('slick-arrow');
if( _.slideCount > _.options.slidesToShow ) {
_.$prevArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
_.$nextArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
if (_.htmlExpr.test(_.options.prevArrow)) {
_.$prevArrow.prependTo(_.options.appendArrows);
}
if (_.htmlExpr.test(_.options.nextArrow)) {
_.$nextArrow.appendTo(_.options.appendArrows);
}
if (_.options.infinite !== true) {
_.$prevArrow
.addClass('slick-disabled')
.attr('aria-disabled', 'true');
}
} else {
_.$prevArrow.add( _.$nextArrow )
.addClass('slick-hidden')
.attr({
'aria-disabled': 'true',
'tabindex': '-1'
});
}
}
};
Slick.prototype.buildDots = function() {
var _ = this,
i, dot;
if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
_.$slider.addClass('slick-dotted');
dot = $('').addClass(_.options.dotsClass);
for (i = 0; i <= _.getDotCount(); i += 1) {
dot.append($('').append(_.options.customPaging.call(this, _, i)));
}
_.$dots = dot.appendTo(_.options.appendDots);
_.$dots.find('li').first().addClass('slick-active');
}
};
Slick.prototype.buildOut = function() {
var _ = this;
_.$slides =
_.$slider
.children( _.options.slide + ':not(.slick-cloned)')
.addClass('slick-slide');
_.slideCount = _.$slides.length;
_.$slides.each(function(index, element) {
$(element)
.attr('data-slick-index', index)
.data('originalStyling', $(element).attr('style') || '');
});
_.$slider.addClass('slick-slider');
_.$slideTrack = (_.slideCount === 0) ?
$('').appendTo(_.$slider) :
_.$slides.wrapAll('').parent();
_.$list = _.$slideTrack.wrap(
'').parent();
_.$slideTrack.css('opacity', 0);
if (_.options.centerMode === true || _.options.swipeToSlide === true) {
_.options.slidesToScroll = 1;
}
$('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading');
_.setupInfinite();
_.buildArrows();
_.buildDots();
_.updateDots();
_.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
if (_.options.draggable === true) {
_.$list.addClass('draggable');
}
};
Slick.prototype.buildRows = function() {
var _ = this, a, b, c, newSlides, numOfSlides, originalSlides,slidesPerSection;
newSlides = document.createDocumentFragment();
originalSlides = _.$slider.children();
if(_.options.rows > 0) {
slidesPerSection = _.options.slidesPerRow * _.options.rows;
numOfSlides = Math.ceil(
originalSlides.length / slidesPerSection
);
for(a = 0; a < numOfSlides; a++){
var slide = document.createElement('div');
for(b = 0; b < _.options.rows; b++) {
var row = document.createElement('div');
for(c = 0; c < _.options.slidesPerRow; c++) {
var target = (a * slidesPerSection + ((b * _.options.slidesPerRow) + c));
if (originalSlides.get(target)) {
row.appendChild(originalSlides.get(target));
}
}
slide.appendChild(row);
}
newSlides.appendChild(slide);
}
_.$slider.empty().append(newSlides);
_.$slider.children().children().children()
.css({
'width':(100 / _.options.slidesPerRow) + '%',
'display': 'inline-block'
});
}
};
Slick.prototype.checkResponsive = function(initial, forceUpdate) {
var _ = this,
breakpoint, targetBreakpoint, respondToWidth, triggerBreakpoint = false;
var sliderWidth = _.$slider.actual('width');
var windowWidth = window.innerWidth || $(window).width();
if (_.respondTo === 'window') {
respondToWidth = windowWidth;
} else if (_.respondTo === 'slider') {
respondToWidth = sliderWidth;
} else if (_.respondTo === 'min') {
respondToWidth = Math.min(windowWidth, sliderWidth);
}
if ( _.options.responsive &&
_.options.responsive.length &&
_.options.responsive !== null) {
targetBreakpoint = null;
for (breakpoint in _.breakpoints) {
if (_.breakpoints.hasOwnProperty(breakpoint)) {
if (_.originalSettings.mobileFirst === false) {
if (respondToWidth < _.breakpoints[breakpoint]) {
targetBreakpoint = _.breakpoints[breakpoint];
}
} else {
if (respondToWidth > _.breakpoints[breakpoint]) {
targetBreakpoint = _.breakpoints[breakpoint];
}
}
}
}
if (targetBreakpoint !== null) {
if (_.activeBreakpoint !== null) {
if (targetBreakpoint !== _.activeBreakpoint || forceUpdate) {
_.activeBreakpoint =
targetBreakpoint;
if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
_.unslick(targetBreakpoint);
} else {
_.options = $.extend({}, _.originalSettings,
_.breakpointSettings[
targetBreakpoint]);
if (initial === true) {
_.currentSlide = _.options.initialSlide;
}
_.refresh(initial);
}
triggerBreakpoint = targetBreakpoint;
}
} else {
_.activeBreakpoint = targetBreakpoint;
if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
_.unslick(targetBreakpoint);
} else {
_.options = $.extend({}, _.originalSettings,
_.breakpointSettings[
targetBreakpoint]);
if (initial === true) {
_.currentSlide = _.options.initialSlide;
}
_.refresh(initial);
}
triggerBreakpoint = targetBreakpoint;
}
} else {
if (_.activeBreakpoint !== null) {
_.activeBreakpoint = null;
_.options = _.originalSettings;
if (initial === true) {
_.currentSlide = _.options.initialSlide;
}
_.refresh(initial);
triggerBreakpoint = targetBreakpoint;
}
}
// only trigger breakpoints during an actual break. not on initialize.
if( !initial && triggerBreakpoint !== false ) {
_.$slider.trigger('breakpoint', [_, triggerBreakpoint]);
}
}
};
Slick.prototype.changeSlide = function(event, dontAnimate) {
var _ = this,
$target = $(event.currentTarget),
indexOffset, slideOffset, unevenOffset;
// If target is a link, prevent default action.
if($target.is('a')) {
event.preventDefault();
}
// If target is not the element (ie: a child), find the .
if(!$target.is('li')) {
$target = $target.closest('li');
}
unevenOffset = (_.slideCount % _.options.slidesToScroll !== 0);
indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll;
switch (event.data.message) {
case 'previous':
slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset;
if (_.slideCount > _.options.slidesToShow) {
_.slideHandler(_.currentSlide - slideOffset, false, dontAnimate);
}
break;
case 'next':
slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset;
if (_.slideCount > _.options.slidesToShow) {
_.slideHandler(_.currentSlide + slideOffset, false, dontAnimate);
}
break;
case 'index':
var index = event.data.index === 0 ? 0 :
event.data.index || $target.index() * _.options.slidesToScroll;
_.slideHandler(_.checkNavigable(index), false, dontAnimate);
$target.children().trigger('focus');
break;
default:
return;
}
};
Slick.prototype.checkNavigable = function(index) {
var _ = this,
navigables, prevNavigable;
navigables = _.getNavigableIndexes();
prevNavigable = 0;
if (index > navigables[navigables.length - 1]) {
index = navigables[navigables.length - 1];
} else {
for (var n in navigables) {
if (index < navigables[n]) {
index = prevNavigable;
break;
}
prevNavigable = navigables[n];
}
}
return index;
};
Slick.prototype.cleanUpEvents = function() {
var _ = this;
if (_.options.dots && _.$dots !== null) {
$('li', _.$dots)
.off('click.slick', _.changeSlide)
.off('mouseenter.slick', $.proxy(_.interrupt, _, true))
.off('mouseleave.slick', $.proxy(_.interrupt, _, false));
if (_.options.accessibility === true) {
_.$dots.off('keydown.slick', _.keyHandler);
}
}
_.$slider.off('focus.slick blur.slick');
if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
_.$prevArrow && _.$prevArrow.off('click.slick', _.changeSlide);
_.$nextArrow && _.$nextArrow.off('click.slick', _.changeSlide);
if (_.options.accessibility === true) {
_.$prevArrow && _.$prevArrow.off('keydown.slick', _.keyHandler);
_.$nextArrow && _.$nextArrow.off('keydown.slick', _.keyHandler);
}
}
_.$list.off('touchstart.slick mousedown.slick', _.swipeHandler);
_.$list.off('touchmove.slick mousemove.slick', _.swipeHandler);
_.$list.off('touchend.slick mouseup.slick', _.swipeHandler);
_.$list.off('touchcancel.slick mouseleave.slick', _.swipeHandler);
_.$list.off('click.slick', _.clickHandler);
$(document).off(_.visibilityChange, _.visibility);
_.cleanUpSlideEvents();
if (_.options.accessibility === true) {
_.$list.off('keydown.slick', _.keyHandler);
}
if (_.options.focusOnSelect === true) {
$(_.$slideTrack).children().off('click.slick', _.selectHandler);
}
$(window).off('orientationchange.slick.slick-' + _.instanceUid, _.orientationChange);
$(window).off('resize.slick.slick-' + _.instanceUid, _.resize);
$('[draggable!=true]', _.$slideTrack).off('dragstart', _.preventDefault);
$(window).off('load.slick.slick-' + _.instanceUid, _.setPosition);
};
Slick.prototype.cleanUpSlideEvents = function() {
var _ = this;
_.$list.off('mouseenter.slick', $.proxy(_.interrupt, _, true));
_.$list.off('mouseleave.slick', $.proxy(_.interrupt, _, false));
};
Slick.prototype.cleanUpRows = function() {
var _ = this, originalSlides;
if(_.options.rows > 0) {
originalSlides = _.$slides.children().children();
originalSlides.removeAttr('style');
_.$slider.empty().append(originalSlides);
}
};
Slick.prototype.clickHandler = function(event) {
var _ = this;
if (_.shouldClick === false) {
event.stopImmediatePropagation();
event.stopPropagation();
event.preventDefault();
}
};
Slick.prototype.destroy = function(refresh) {
var _ = this;
_.autoPlayClear();
_.touchObject = {};
_.cleanUpEvents();
$('.slick-cloned', _.$slider).detach();
if (_.$dots) {
_.$dots.remove();
}
if ( _.$prevArrow && _.$prevArrow.length ) {
_.$prevArrow
.removeClass('slick-disabled slick-arrow slick-hidden')
.removeAttr('aria-hidden aria-disabled tabindex')
.css('display','');
if ( _.htmlExpr.test( _.options.prevArrow )) {
_.$prevArrow.remove();
}
}
if ( _.$nextArrow && _.$nextArrow.length ) {
_.$nextArrow
.removeClass('slick-disabled slick-arrow slick-hidden')
.removeAttr('aria-hidden aria-disabled tabindex')
.css('display','');
if ( _.htmlExpr.test( _.options.nextArrow )) {
_.$nextArrow.remove();
}
}
if (_.$slides) {
_.$slides
.removeClass('slick-slide slick-active slick-center slick-visible slick-current')
.removeAttr('aria-hidden')
.removeAttr('data-slick-index')
.each(function(){
$(this).attr('style', $(this).data('originalStyling'));
});
_.$slideTrack.children(this.options.slide).detach();
_.$slideTrack.detach();
_.$list.detach();
_.$slider.append(_.$slides);
}
_.cleanUpRows();
_.$slider.removeClass('slick-slider');
_.$slider.removeClass('slick-initialized');
_.$slider.removeClass('slick-dotted');
_.unslicked = true;
if(!refresh) {
_.$slider.trigger('destroy', [_]);
}
};
Slick.prototype.disableTransition = function(slide) {
var _ = this,
transition = {};
transition[_.transitionType] = '';
if (_.options.fade === false) {
_.$slideTrack.css(transition);
} else {
_.$slides.eq(slide).css(transition);
}
};
Slick.prototype.fadeSlide = function(slideIndex, callback) {
var _ = this;
if (_.cssTransitions === false) {
_.$slides.eq(slideIndex).css({
zIndex: _.options.zIndex
});
_.$slides.eq(slideIndex).animate({
opacity: 1
}, _.options.speed, _.options.easing, callback);
} else {
_.applyTransition(slideIndex);
_.$slides.eq(slideIndex).css({
opacity: 1,
zIndex: _.options.zIndex
});
if (callback) {
setTimeout(function() {
_.disableTransition(slideIndex);
callback.call();
}, _.options.speed);
}
}
};
Slick.prototype.fadeSlideOut = function(slideIndex) {
var _ = this;
if (_.cssTransitions === false) {
_.$slides.eq(slideIndex).animate({
opacity: 0,
zIndex: _.options.zIndex - 2
}, _.options.speed, _.options.easing);
} else {
_.applyTransition(slideIndex);
_.$slides.eq(slideIndex).css({
opacity: 0,
zIndex: _.options.zIndex - 2
});
}
};
Slick.prototype.filterSlides = Slick.prototype.slickFilter = function(filter) {
var _ = this;
if (filter !== null) {
_.$slidesCache = _.$slides;
_.unload();
_.$slideTrack.children(this.options.slide).detach();
_.$slidesCache.filter(filter).appendTo(_.$slideTrack);
_.reinit();
}
};
Slick.prototype.focusHandler = function() {
var _ = this;
_.$slider
.off('focus.slick blur.slick')
.on('focus.slick blur.slick', '*', function(event) {
event.stopImmediatePropagation();
var $sf = $(this);
setTimeout(function() {
if( _.options.pauseOnFocus ) {
_.focussed = $sf.is(':focus');
_.autoPlay();
}
}, 0);
});
};
Slick.prototype.getCurrent = Slick.prototype.slickCurrentSlide = function() {
var _ = this;
return _.currentSlide;
};
Slick.prototype.getDotCount = function() {
var _ = this;
var breakPoint = 0;
var counter = 0;
var pagerQty = 0;
if (_.options.infinite === true) {
if (_.slideCount <= _.options.slidesToShow) {
++pagerQty;
} else {
while (breakPoint < _.slideCount) {
++pagerQty;
breakPoint = counter + _.options.slidesToScroll;
counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
}
}
} else if (_.options.centerMode === true) {
pagerQty = _.slideCount;
} else if(!_.options.asNavFor) {
pagerQty = 1 + Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll);
}else {
while (breakPoint < _.slideCount) {
++pagerQty;
breakPoint = counter + _.options.slidesToScroll;
counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
}
}
return pagerQty - 1;
};
Slick.prototype.getLeft = function(slideIndex) {
var _ = this,
targetLeft,
verticalHeight,
verticalOffset = 0,
targetSlide,
coef;
_.slideOffset = 0;
verticalHeight = _.$slides.first().outerHeight(true);
if (_.options.infinite === true) {
if (_.slideCount > _.options.slidesToShow) {
_.slideOffset = (_.slideWidth * _.options.slidesToShow) * -1;
coef = -1
if (_.options.vertical === true && _.options.centerMode === true) {
if (_.options.slidesToShow === 2) {
coef = -1.5;
} else if (_.options.slidesToShow === 1) {
coef = -2
}
}
verticalOffset = (verticalHeight * _.options.slidesToShow) * coef;
}
if (_.slideCount % _.options.slidesToScroll !== 0) {
if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) {
if (slideIndex > _.slideCount) {
_.slideOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth) * -1;
verticalOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight) * -1;
} else {
_.slideOffset = ((_.slideCount % _.options.slidesToScroll) * _.slideWidth) * -1;
verticalOffset = ((_.slideCount % _.options.slidesToScroll) * verticalHeight) * -1;
}
}
}
} else {
if (slideIndex + _.options.slidesToShow > _.slideCount) {
_.slideOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * _.slideWidth;
verticalOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * verticalHeight;
}
}
if (_.slideCount <= _.options.slidesToShow) {
_.slideOffset = 0;
verticalOffset = 0;
}
if (_.options.centerMode === true && _.slideCount <= _.options.slidesToShow) {
_.slideOffset = ((_.slideWidth * Math.floor(_.options.slidesToShow)) / 2) - ((_.slideWidth * _.slideCount) / 2);
} else if (_.options.centerMode === true && _.options.infinite === true) {
_.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth;
} else if (_.options.centerMode === true) {
_.slideOffset = 0;
_.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2);
}
if (_.options.vertical === false) {
targetLeft = ((slideIndex * _.slideWidth) * -1) + _.slideOffset;
} else {
targetLeft = ((slideIndex * verticalHeight) * -1) + verticalOffset;
}
if (_.options.variableWidth === true) {
if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
} else {
targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow);
}
if (_.options.rtl === true) {
if (targetSlide[0]) {
targetLeft = (_.$slideTrack.actual('width') - targetSlide[0].offsetLeft - targetSlide.actual('width')) * -1;
} else {
targetLeft = 0;
}
} else {
targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
}
if (_.options.centerMode === true) {
if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
} else {
targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1);
}
if (_.options.rtl === true) {
if (targetSlide[0]) {
targetLeft = (_.$slideTrack.actual('width') - targetSlide[0].offsetLeft - targetSlide.actual('width')) * -1;
} else {
targetLeft = 0;
}
} else {
targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
}
targetLeft += (_.$list.actual('width') - targetSlide.outerWidth()) / 2;
}
}
return targetLeft;
};
Slick.prototype.getOption = Slick.prototype.slickGetOption = function(option) {
var _ = this;
return _.options[option];
};
Slick.prototype.getNavigableIndexes = function() {
var _ = this,
breakPoint = 0,
counter = 0,
indexes = [],
max;
if (_.options.infinite === false) {
max = _.slideCount;
} else {
breakPoint = _.options.slidesToScroll * -1;
counter = _.options.slidesToScroll * -1;
max = _.slideCount * 2;
}
while (breakPoint < max) {
indexes.push(breakPoint);
breakPoint = counter + _.options.slidesToScroll;
counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
}
return indexes;
};
Slick.prototype.getSlick = function() {
return this;
};
Slick.prototype.getSlideCount = function() {
var _ = this,
slidesTraversed, swipedSlide, centerOffset;
centerOffset = _.options.centerMode === true ? _.slideWidth * Math.floor(_.options.slidesToShow / 2) : 0;
if (_.options.swipeToSlide === true) {
_.$slideTrack.find('.slick-slide').each(function(index, slide) {
if (slide.offsetLeft - centerOffset + ($(slide).outerWidth() / 2) > (_.swipeLeft * -1)) {
swipedSlide = slide;
return false;
}
});
slidesTraversed = Math.abs($(swipedSlide).attr('data-slick-index') - _.currentSlide) || 1;
return slidesTraversed;
} else {
return _.options.slidesToScroll;
}
};
Slick.prototype.goTo = Slick.prototype.slickGoTo = function(slide, dontAnimate) {
var _ = this;
_.changeSlide({
data: {
message: 'index',
index: parseInt(slide)
}
}, dontAnimate);
};
Slick.prototype.init = function(creation) {
var _ = this;
if (!$(_.$slider).hasClass('slick-initialized')) {
$(_.$slider).addClass('slick-initialized');
_.buildRows();
_.buildOut();
_.setProps();
_.startLoad();
_.loadSlider();
_.initializeEvents();
_.updateArrows();
_.updateDots();
_.checkResponsive(true);
_.focusHandler();
}
if (creation) {
_.$slider.trigger('init', [_]);
}
if (_.options.accessibility === true) {
_.initADA();
}
if ( _.options.autoplay ) {
_.paused = false;
_.autoPlay();
}
};
Slick.prototype.initADA = function() {
var _ = this,
numDotGroups = Math.ceil(_.slideCount / _.options.slidesToShow),
tabControlIndexes = _.getNavigableIndexes().filter(function(val) {
return (val >= 0) && (val < _.slideCount);
});
_.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({
'aria-hidden': 'true',
'tabindex': '-1'
}).find('a, input, button, select').attr({
'tabindex': '-1'
});
if (_.$dots !== null) {
_.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function(i) {
var slideControlIndex = tabControlIndexes.indexOf(i);
$(this).attr({
'role': 'tabpanel',
'id': 'slick-slide' + _.instanceUid + i,
'tabindex': -1
});
if (slideControlIndex !== -1) {
var ariaButtonControl = 'slick-slide-control' + _.instanceUid + slideControlIndex
if ($('#' + ariaButtonControl).length) {
$(this).attr({
'aria-describedby': ariaButtonControl
});
}
}
});
_.$dots.attr('role', 'tablist').find('li').each(function(i) {
var mappedSlideIndex = tabControlIndexes[i];
$(this).attr({
'role': 'presentation'
});
$(this).find('button').first().attr({
'role': 'tab',
'id': 'slick-slide-control' + _.instanceUid + i,
'aria-controls': 'slick-slide' + _.instanceUid + mappedSlideIndex,
'aria-label': (i + 1) + ' of ' + numDotGroups,
'aria-selected': null,
'tabindex': '-1'
});
}).eq(_.currentSlide).find('button').attr({
'aria-selected': 'true',
'tabindex': '0'
}).end();
}
for (var i=_.currentSlide, max=i+_.options.slidesToShow; i < max; i++) {
if (_.options.focusOnChange) {
_.$slides.eq(i).attr({'tabindex': '0'});
} else {
_.$slides.eq(i).removeAttr('tabindex');
}
}
_.activateADA();
};
Slick.prototype.initArrowEvents = function() {
var _ = this;
if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
_.$prevArrow
.off('click.slick')
.on('click.slick', {
message: 'previous'
}, _.changeSlide);
_.$nextArrow
.off('click.slick')
.on('click.slick', {
message: 'next'
}, _.changeSlide);
if (_.options.accessibility === true) {
_.$prevArrow.on('keydown.slick', _.keyHandler);
_.$nextArrow.on('keydown.slick', _.keyHandler);
}
}
};
Slick.prototype.initDotEvents = function() {
var _ = this;
if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
$('li', _.$dots).on('click.slick', {
message: 'index'
}, _.changeSlide);
if (_.options.accessibility === true) {
_.$dots.on('keydown.slick', _.keyHandler);
}
}
if (_.options.dots === true && _.options.pauseOnDotsHover === true && _.slideCount > _.options.slidesToShow) {
$('li', _.$dots)
.on('mouseenter.slick', $.proxy(_.interrupt, _, true))
.on('mouseleave.slick', $.proxy(_.interrupt, _, false));
}
};
Slick.prototype.initSlideEvents = function() {
var _ = this;
if ( _.options.pauseOnHover ) {
_.$list.on('mouseenter.slick', $.proxy(_.interrupt, _, true));
_.$list.on('mouseleave.slick', $.proxy(_.interrupt, _, false));
}
};
Slick.prototype.initializeEvents = function() {
var _ = this;
_.initArrowEvents();
_.initDotEvents();
_.initSlideEvents();
_.$list.on('touchstart.slick mousedown.slick', {
action: 'start'
}, _.swipeHandler);
_.$list.on('touchmove.slick mousemove.slick', {
action: 'move'
}, _.swipeHandler);
_.$list.on('touchend.slick mouseup.slick', {
action: 'end'
}, _.swipeHandler);
_.$list.on('touchcancel.slick mouseleave.slick', {
action: 'end'
}, _.swipeHandler);
_.$list.on('click.slick', _.clickHandler);
$(document).on(_.visibilityChange, $.proxy(_.visibility, _));
if (_.options.accessibility === true) {
_.$list.on('keydown.slick', _.keyHandler);
}
if (_.options.focusOnSelect === true) {
$(_.$slideTrack).children().on('click.slick', _.selectHandler);
}
$(window).on('orientationchange.slick.slick-' + _.instanceUid, $.proxy(_.orientationChange, _));
$(window).on('resize.slick.slick-' + _.instanceUid, $.proxy(_.resize, _));
$('[draggable!=true]', _.$slideTrack).on('dragstart', _.preventDefault);
$(window).on('load.slick.slick-' + _.instanceUid, _.setPosition);
$(_.setPosition);
};
Slick.prototype.initUI = function() {
var _ = this;
if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
_.$prevArrow.show();
_.$nextArrow.show();
}
if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
_.$dots.show();
}
};
Slick.prototype.keyHandler = function(event) {
var _ = this;
//Dont slide if the cursor is inside the form fields and arrow keys are pressed
if(!event.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
if (event.keyCode === 37 && _.options.accessibility === true) {
_.changeSlide({
data: {
message: _.options.rtl === true ? 'next' : 'previous'
}
});
} else if (event.keyCode === 39 && _.options.accessibility === true) {
_.changeSlide({
data: {
message: _.options.rtl === true ? 'previous' : 'next'
}
});
}
}
};
Slick.prototype.lazyLoad = function() {
var _ = this,
loadRange, cloneRange, rangeStart, rangeEnd;
function loadImages(imagesScope) {
$('img[data-lazy]', imagesScope).each(function() {
var image = $(this),
imageSource = $(this).attr('data-lazy'),
imageSrcSet = $(this).attr('data-srcset'),
imageSizes = $(this).attr('data-sizes') || _.$slider.attr('data-sizes'),
imageToLoad = document.createElement('img');
imageToLoad.onload = function() {
image
.animate({ opacity: 0 }, 100, function() {
if (imageSrcSet) {
image
.attr('srcset', imageSrcSet );
if (imageSizes) {
image
.attr('sizes', imageSizes );
}
}
image
.attr('src', imageSource)
.animate({ opacity: 1 }, 200, function() {
image
.removeAttr('data-lazy data-srcset data-sizes')
.removeClass('slick-loading');
});
_.$slider.trigger('lazyLoaded', [_, image, imageSource]);
});
};
imageToLoad.onerror = function() {
image
.removeAttr( 'data-lazy' )
.removeClass( 'slick-loading' )
.addClass( 'slick-lazyload-error' );
_.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
};
imageToLoad.src = imageSource;
});
}
if (_.options.centerMode === true) {
if (_.options.infinite === true) {
rangeStart = _.currentSlide + (_.options.slidesToShow / 2 + 1);
rangeEnd = rangeStart + _.options.slidesToShow + 2;
} else {
rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow / 2 + 1));
rangeEnd = 2 + (_.options.slidesToShow / 2 + 1) + _.currentSlide;
}
} else {
rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide;
rangeEnd = Math.ceil(rangeStart + _.options.slidesToShow);
if (_.options.fade === true) {
if (rangeStart > 0) rangeStart--;
if (rangeEnd <= _.slideCount) rangeEnd++;
}
}
loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd);
if (_.options.lazyLoad === 'anticipated') {
var prevSlide = rangeStart - 1,
nextSlide = rangeEnd,
$slides = _.$slider.find('.slick-slide');
for (var i = 0; i < _.options.slidesToScroll; i++) {
if (prevSlide < 0) prevSlide = _.slideCount - 1;
loadRange = loadRange.add($slides.eq(prevSlide));
loadRange = loadRange.add($slides.eq(nextSlide));
prevSlide--;
nextSlide++;
}
}
loadImages(loadRange);
if (_.slideCount <= _.options.slidesToShow) {
cloneRange = _.$slider.find('.slick-slide');
loadImages(cloneRange);
} else
if (_.currentSlide >= _.slideCount - _.options.slidesToShow) {
cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow);
loadImages(cloneRange);
} else if (_.currentSlide === 0) {
cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1);
loadImages(cloneRange);
}
};
Slick.prototype.loadSlider = function() {
var _ = this;
_.setPosition();
_.$slideTrack.css({
opacity: 1
});
_.$slider.removeClass('slick-loading');
_.initUI();
if (_.options.lazyLoad === 'progressive') {
_.progressiveLazyLoad();
}
};
Slick.prototype.next = Slick.prototype.slickNext = function() {
var _ = this;
_.changeSlide({
data: {
message: 'next'
}
});
};
Slick.prototype.orientationChange = function() {
var _ = this;
_.checkResponsive();
_.setPosition();
};
Slick.prototype.pause = Slick.prototype.slickPause = function() {
var _ = this;
_.autoPlayClear();
_.paused = true;
};
Slick.prototype.play = Slick.prototype.slickPlay = function() {
var _ = this;
_.autoPlay();
_.options.autoplay = true;
_.paused = false;
_.focussed = false;
_.interrupted = false;
};
Slick.prototype.postSlide = function(index) {
var _ = this;
if( !_.unslicked ) {
_.$slider.trigger('afterChange', [_, index]);
_.animating = false;
if (_.slideCount > _.options.slidesToShow) {
_.setPosition();
}
_.swipeLeft = null;
if ( _.options.autoplay ) {
_.autoPlay();
}
if (_.options.accessibility === true) {
_.initADA();
if (_.options.focusOnChange) {
var $currentSlide = $(_.$slides.get(_.currentSlide));
$currentSlide.attr('tabindex', 0).focus();
}
}
}
};
Slick.prototype.prev = Slick.prototype.slickPrev = function() {
var _ = this;
_.changeSlide({
data: {
message: 'previous'
}
});
};
Slick.prototype.preventDefault = function(event) {
event.preventDefault();
};
Slick.prototype.progressiveLazyLoad = function( tryCount ) {
tryCount = tryCount || 1;
var _ = this,
$imgsToLoad = $( 'img[data-lazy]', _.$slider ),
image,
imageSource,
imageSrcSet,
imageSizes,
imageToLoad;
if ( $imgsToLoad.length ) {
image = $imgsToLoad.first();
imageSource = image.attr('data-lazy');
imageSrcSet = image.attr('data-srcset');
imageSizes = image.attr('data-sizes') || _.$slider.attr('data-sizes');
imageToLoad = document.createElement('img');
imageToLoad.onload = function() {
if (imageSrcSet) {
image
.attr('srcset', imageSrcSet );
if (imageSizes) {
image
.attr('sizes', imageSizes );
}
}
image
.attr( 'src', imageSource )
.removeAttr('data-lazy data-srcset data-sizes')
.removeClass('slick-loading');
if ( _.options.adaptiveHeight === true ) {
_.setPosition();
}
_.$slider.trigger('lazyLoaded', [ _, image, imageSource ]);
_.progressiveLazyLoad();
};
imageToLoad.onerror = function() {
if ( tryCount < 3 ) {
/**
* try to load the image 3 times,
* leave a slight delay so we don't get
* servers blocking the request.
*/
setTimeout( function() {
_.progressiveLazyLoad( tryCount + 1 );
}, 500 );
} else {
image
.removeAttr( 'data-lazy' )
.removeClass( 'slick-loading' )
.addClass( 'slick-lazyload-error' );
_.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
_.progressiveLazyLoad();
}
};
imageToLoad.src = imageSource;
} else {
_.$slider.trigger('allImagesLoaded', [ _ ]);
}
};
Slick.prototype.refresh = function( initializing ) {
var _ = this, currentSlide, lastVisibleIndex;
lastVisibleIndex = _.slideCount - _.options.slidesToShow;
// in non-infinite sliders, we don't want to go past the
// last visible index.
if( !_.options.infinite && ( _.currentSlide > lastVisibleIndex )) {
_.currentSlide = lastVisibleIndex;
}
// if less slides than to show, go to start.
if ( _.slideCount <= _.options.slidesToShow ) {
_.currentSlide = 0;
}
currentSlide = _.currentSlide;
_.destroy(true);
$.extend(_, _.initials, { currentSlide: currentSlide });
_.init();
if( !initializing ) {
_.changeSlide({
data: {
message: 'index',
index: currentSlide
}
}, false);
}
};
Slick.prototype.registerBreakpoints = function() {
var _ = this, breakpoint, currentBreakpoint, l,
responsiveSettings = _.options.responsive || null;
if ( $.type(responsiveSettings) === 'array' && responsiveSettings.length ) {
_.respondTo = _.options.respondTo || 'window';
for ( breakpoint in responsiveSettings ) {
l = _.breakpoints.length-1;
if (responsiveSettings.hasOwnProperty(breakpoint)) {
currentBreakpoint = responsiveSettings[breakpoint].breakpoint;
// loop through the breakpoints and cut out any existing
// ones with the same breakpoint number, we don't want dupes.
while( l >= 0 ) {
if( _.breakpoints[l] && _.breakpoints[l] === currentBreakpoint ) {
_.breakpoints.splice(l,1);
}
l--;
}
_.breakpoints.push(currentBreakpoint);
_.breakpointSettings[currentBreakpoint] = responsiveSettings[breakpoint].settings;
}
}
_.breakpoints.sort(function(a, b) {
return ( _.options.mobileFirst ) ? a-b : b-a;
});
}
};
Slick.prototype.reinit = function() {
var _ = this;
_.$slides =
_.$slideTrack
.children(_.options.slide)
.addClass('slick-slide');
_.slideCount = _.$slides.length;
if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) {
_.currentSlide = _.currentSlide - _.options.slidesToScroll;
}
if (_.slideCount <= _.options.slidesToShow) {
_.currentSlide = 0;
}
_.registerBreakpoints();
_.setProps();
_.setupInfinite();
_.buildArrows();
_.updateArrows();
_.initArrowEvents();
_.buildDots();
_.updateDots();
_.initDotEvents();
_.cleanUpSlideEvents();
_.initSlideEvents();
_.checkResponsive(false, true);
if (_.options.focusOnSelect === true) {
$(_.$slideTrack).children().on('click.slick', _.selectHandler);
}
_.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
_.setPosition();
_.focusHandler();
_.paused = !_.options.autoplay;
_.autoPlay();
_.$slider.trigger('reInit', [_]);
};
Slick.prototype.resize = function() {
var _ = this;
if ($(window).width() !== _.windowWidth) {
clearTimeout(_.windowDelay);
_.windowDelay = window.setTimeout(function() {
_.windowWidth = $(window).width();
_.checkResponsive();
if( !_.unslicked ) { _.setPosition(); }
}, 50);
}
};
Slick.prototype.removeSlide = Slick.prototype.slickRemove = function(index, removeBefore, removeAll) {
var _ = this;
if (typeof(index) === 'boolean') {
removeBefore = index;
index = removeBefore === true ? 0 : _.slideCount - 1;
} else {
index = removeBefore === true ? --index : index;
}
if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) {
return false;
}
_.unload();
if (removeAll === true) {
_.$slideTrack.children().remove();
} else {
_.$slideTrack.children(this.options.slide).eq(index).remove();
}
_.$slides = _.$slideTrack.children(this.options.slide);
_.$slideTrack.children(this.options.slide).detach();
_.$slideTrack.append(_.$slides);
_.$slidesCache = _.$slides;
_.reinit();
};
Slick.prototype.setCSS = function(position) {
var _ = this,
positionProps = {},
x, y;
if (_.options.rtl === true) {
position = -position;
}
x = _.positionProp == 'left' ? Math.ceil(position) + 'px' : '0px';
y = _.positionProp == 'top' ? Math.ceil(position) + 'px' : '0px';
positionProps[_.positionProp] = position;
if (_.transformsEnabled === false) {
_.$slideTrack.css(positionProps);
} else {
positionProps = {};
if (_.cssTransitions === false) {
positionProps[_.animType] = 'translate(' + x + ', ' + y + ')';
_.$slideTrack.css(positionProps);
} else {
positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)';
_.$slideTrack.css(positionProps);
}
}
};
Slick.prototype.setDimensions = function() {
var _ = this;
if (_.options.vertical === false) {
if (_.options.centerMode === true) {
_.$list.css({
padding: ('0px ' + _.options.centerPadding)
});
}
} else {
_.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow);
if (_.options.centerMode === true) {
_.$list.css({
padding: (_.options.centerPadding + ' 0px')
});
}
}
_.listWidth = _.$list.actual('width');
_.listHeight = _.$list.height();
if (_.options.vertical === false && _.options.variableWidth === false) {
_.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
_.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length)));
} else if (_.options.variableWidth === true) {
_.$slideTrack.width(5000 * _.slideCount);
} else {
_.slideWidth = Math.ceil(_.listWidth);
_.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length)));
}
var offset = _.$slides.first().outerWidth(true) - _.$slides.first().actual('width');
if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset);
};
Slick.prototype.setFade = function() {
var _ = this,
targetLeft;
_.$slides.each(function(index, element) {
targetLeft = (_.slideWidth * index) * -1;
if (_.options.rtl === true) {
$(element).css({
position: 'relative',
right: targetLeft,
top: 0,
zIndex: _.options.zIndex - 2,
opacity: 0
});
} else {
$(element).css({
position: 'relative',
left: targetLeft,
top: 0,
zIndex: _.options.zIndex - 2,
opacity: 0
});
}
});
_.$slides.eq(_.currentSlide).css({
zIndex: _.options.zIndex - 1,
opacity: 1
});
};
Slick.prototype.setHeight = function() {
var _ = this;
if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
_.$list.css('height', targetHeight);
}
};
Slick.prototype.setOption =
Slick.prototype.slickSetOption = function() {
/**
* accepts arguments in format of:
*
* - for changing a single option's value:
* .slick("setOption", option, value, refresh )
*
* - for changing a set of responsive options:
* .slick("setOption", 'responsive', [{}, ...], refresh )
*
* - for updating multiple values at once (not responsive)
* .slick("setOption", { 'option': value, ... }, refresh )
*/
var _ = this, l, item, option, value, refresh = false, type;
if( $.type( arguments[0] ) === 'object' ) {
option = arguments[0];
refresh = arguments[1];
type = 'multiple';
} else if ( $.type( arguments[0] ) === 'string' ) {
option = arguments[0];
value = arguments[1];
refresh = arguments[2];
if ( arguments[0] === 'responsive' && $.type( arguments[1] ) === 'array' ) {
type = 'responsive';
} else if ( typeof arguments[1] !== 'undefined' ) {
type = 'single';
}
}
if ( type === 'single' ) {
_.options[option] = value;
} else if ( type === 'multiple' ) {
$.each( option , function( opt, val ) {
_.options[opt] = val;
});
} else if ( type === 'responsive' ) {
for ( item in value ) {
if( $.type( _.options.responsive ) !== 'array' ) {
_.options.responsive = [ value[item] ];
} else {
l = _.options.responsive.length-1;
// loop through the responsive object and splice out duplicates.
while( l >= 0 ) {
if( _.options.responsive[l].breakpoint === value[item].breakpoint ) {
_.options.responsive.splice(l,1);
}
l--;
}
_.options.responsive.push( value[item] );
}
}
}
if ( refresh ) {
_.unload();
_.reinit();
}
};
Slick.prototype.setPosition = function() {
var _ = this;
_.setDimensions();
_.setHeight();
if (_.options.fade === false) {
_.setCSS(_.getLeft(_.currentSlide));
} else {
_.setFade();
}
_.$slider.trigger('setPosition', [_]);
};
Slick.prototype.setProps = function() {
var _ = this,
bodyStyle = document.body.style;
_.positionProp = _.options.vertical === true ? 'top' : 'left';
if (_.positionProp === 'top') {
_.$slider.addClass('slick-vertical');
} else {
_.$slider.removeClass('slick-vertical');
}
if (bodyStyle.WebkitTransition !== undefined ||
bodyStyle.MozTransition !== undefined ||
bodyStyle.msTransition !== undefined) {
if (_.options.useCSS === true) {
_.cssTransitions = true;
}
}
if ( _.options.fade ) {
if ( typeof _.options.zIndex === 'number' ) {
if( _.options.zIndex < 3 ) {
_.options.zIndex = 3;
}
} else {
_.options.zIndex = _.defaults.zIndex;
}
}
if (bodyStyle.OTransform !== undefined) {
_.animType = 'OTransform';
_.transformType = '-o-transform';
_.transitionType = 'OTransition';
if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
}
if (bodyStyle.MozTransform !== undefined) {
_.animType = 'MozTransform';
_.transformType = '-moz-transform';
_.transitionType = 'MozTransition';
if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false;
}
if (bodyStyle.webkitTransform !== undefined) {
_.animType = 'webkitTransform';
_.transformType = '-webkit-transform';
_.transitionType = 'webkitTransition';
if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
}
if (bodyStyle.msTransform !== undefined) {
_.animType = 'msTransform';
_.transformType = '-ms-transform';
_.transitionType = 'msTransition';
if (bodyStyle.msTransform === undefined) _.animType = false;
}
if (bodyStyle.transform !== undefined && _.animType !== false) {
_.animType = 'transform';
_.transformType = 'transform';
_.transitionType = 'transition';
}
_.transformsEnabled = _.options.useTransform && (_.animType !== null && _.animType !== false);
};
Slick.prototype.setSlideClasses = function(index) {
var _ = this,
centerOffset, allSlides, indexOffset, remainder;
allSlides = _.$slider
.find('.slick-slide')
.removeClass('slick-active slick-center slick-current')
.attr('aria-hidden', 'true');
_.$slides
.eq(index)
.addClass('slick-current');
if (_.options.centerMode === true) {
var evenCoef = _.options.slidesToShow % 2 === 0 ? 1 : 0;
centerOffset = Math.floor(_.options.slidesToShow / 2);
if (_.options.infinite === true) {
if (index >= centerOffset && index <= (_.slideCount - 1) - centerOffset) {
_.$slides
.slice(index - centerOffset + evenCoef, index + centerOffset + 1)
.addClass('slick-active')
.attr('aria-hidden', 'false');
} else {
indexOffset = _.options.slidesToShow + index;
allSlides
.slice(indexOffset - centerOffset + 1 + evenCoef, indexOffset + centerOffset + 2)
.addClass('slick-active')
.attr('aria-hidden', 'false');
}
if (index === 0) {
allSlides
.eq(allSlides.length - 1 - _.options.slidesToShow)
.addClass('slick-center');
} else if (index === _.slideCount - 1) {
allSlides
.eq(_.options.slidesToShow)
.addClass('slick-center');
}
}
_.$slides
.eq(index)
.addClass('slick-center');
} else {
if (index >= 0 && index <= (_.slideCount - _.options.slidesToShow)) {
_.$slides
.slice(index, index + _.options.slidesToShow)
.addClass('slick-active')
.attr('aria-hidden', 'false');
} else if (allSlides.length <= _.options.slidesToShow) {
allSlides
.addClass('slick-active')
.attr('aria-hidden', 'false');
} else {
remainder = _.slideCount % _.options.slidesToShow;
indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index;
if (_.options.slidesToShow == _.options.slidesToScroll && (_.slideCount - index) < _.options.slidesToShow) {
allSlides
.slice(indexOffset - (_.options.slidesToShow - remainder), indexOffset + remainder)
.addClass('slick-active')
.attr('aria-hidden', 'false');
} else {
allSlides
.slice(indexOffset, indexOffset + _.options.slidesToShow)
.addClass('slick-active')
.attr('aria-hidden', 'false');
}
}
}
if (_.options.lazyLoad === 'ondemand' || _.options.lazyLoad === 'anticipated') {
_.lazyLoad();
}
};
Slick.prototype.setupInfinite = function() {
var _ = this,
i, slideIndex, infiniteCount;
if (_.options.fade === true) {
_.options.centerMode = false;
}
if (_.options.infinite === true && _.options.fade === false) {
slideIndex = null;
if (_.slideCount > _.options.slidesToShow) {
if (_.options.centerMode === true) {
infiniteCount = _.options.slidesToShow + 1;
} else {
infiniteCount = _.options.slidesToShow;
}
for (i = _.slideCount; i > (_.slideCount -
infiniteCount); i -= 1) {
slideIndex = i - 1;
$(_.$slides[slideIndex]).clone(true).attr('id', '')
.attr('data-slick-index', slideIndex - _.slideCount)
.prependTo(_.$slideTrack).addClass('slick-cloned');
}
for (i = 0; i < infiniteCount + _.slideCount; i += 1) {
slideIndex = i;
$(_.$slides[slideIndex]).clone(true).attr('id', '')
.attr('data-slick-index', slideIndex + _.slideCount)
.appendTo(_.$slideTrack).addClass('slick-cloned');
}
_.$slideTrack.find('.slick-cloned').find('[id]').each(function() {
$(this).attr('id', '');
});
}
}
};
Slick.prototype.interrupt = function( toggle ) {
var _ = this;
if( !toggle ) {
_.autoPlay();
}
_.interrupted = toggle;
};
Slick.prototype.selectHandler = function(event) {
var _ = this;
var targetElement =
$(event.target).is('.slick-slide') ?
$(event.target) :
$(event.target).parents('.slick-slide');
var index = parseInt(targetElement.attr('data-slick-index'));
if (!index) index = 0;
if (_.slideCount <= _.options.slidesToShow) {
_.slideHandler(index, false, true);
return;
}
_.slideHandler(index);
};
Slick.prototype.slideHandler = function(index, sync, dontAnimate) {
var targetSlide, animSlide, oldSlide, slideLeft, targetLeft = null,
_ = this, navTarget;
sync = sync || false;
if (_.animating === true && _.options.waitForAnimate === true) {
return;
}
if (_.options.fade === true && _.currentSlide === index) {
return;
}
if (sync === false) {
_.asNavFor(index);
}
targetSlide = index;
targetLeft = _.getLeft(targetSlide);
slideLeft = _.getLeft(_.currentSlide);
_.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft;
if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) {
if (_.options.fade === false) {
targetSlide = _.currentSlide;
if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) {
_.animateSlide(slideLeft, function() {
_.postSlide(targetSlide);
});
} else {
_.postSlide(targetSlide);
}
}
return;
} else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > (_.slideCount - _.options.slidesToScroll))) {
if (_.options.fade === false) {
targetSlide = _.currentSlide;
if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) {
_.animateSlide(slideLeft, function() {
_.postSlide(targetSlide);
});
} else {
_.postSlide(targetSlide);
}
}
return;
}
if ( _.options.autoplay ) {
clearInterval(_.autoPlayTimer);
}
if (targetSlide < 0) {
if (_.slideCount % _.options.slidesToScroll !== 0) {
animSlide = _.slideCount - (_.slideCount % _.options.slidesToScroll);
} else {
animSlide = _.slideCount + targetSlide;
}
} else if (targetSlide >= _.slideCount) {
if (_.slideCount % _.options.slidesToScroll !== 0) {
animSlide = 0;
} else {
animSlide = targetSlide - _.slideCount;
}
} else {
animSlide = targetSlide;
}
_.animating = true;
_.$slider.trigger('beforeChange', [_, _.currentSlide, animSlide]);
oldSlide = _.currentSlide;
_.currentSlide = animSlide;
_.setSlideClasses(_.currentSlide);
if ( _.options.asNavFor ) {
navTarget = _.getNavTarget();
navTarget = navTarget.slick('getSlick');
if ( navTarget.slideCount <= navTarget.options.slidesToShow ) {
navTarget.setSlideClasses(_.currentSlide);
}
}
_.updateDots();
_.updateArrows();
if (_.options.fade === true) {
if (dontAnimate !== true) {
_.fadeSlideOut(oldSlide);
_.fadeSlide(animSlide, function() {
_.postSlide(animSlide);
});
} else {
_.postSlide(animSlide);
}
_.animateHeight();
return;
}
if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) {
_.animateSlide(targetLeft, function() {
_.postSlide(animSlide);
});
} else {
_.postSlide(animSlide);
}
};
Slick.prototype.startLoad = function() {
var _ = this;
if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
_.$prevArrow.hide();
_.$nextArrow.hide();
}
if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
_.$dots.hide();
}
_.$slider.addClass('slick-loading');
};
Slick.prototype.swipeDirection = function() {
var xDist, yDist, r, swipeAngle, _ = this;
xDist = _.touchObject.startX - _.touchObject.curX;
yDist = _.touchObject.startY - _.touchObject.curY;
r = Math.atan2(yDist, xDist);
swipeAngle = Math.round(r * 180 / Math.PI);
if (swipeAngle < 0) {
swipeAngle = 360 - Math.abs(swipeAngle);
}
if ((swipeAngle <= 45) && (swipeAngle >= 0)) {
return (_.options.rtl === false ? 'left' : 'right');
}
if ((swipeAngle <= 360) && (swipeAngle >= 315)) {
return (_.options.rtl === false ? 'left' : 'right');
}
if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
return (_.options.rtl === false ? 'right' : 'left');
}
if (_.options.verticalSwiping === true) {
if ((swipeAngle >= 35) && (swipeAngle <= 135)) {
return 'down';
} else {
return 'up';
}
}
return 'vertical';
};
Slick.prototype.swipeEnd = function(event) {
var _ = this,
slideCount,
direction;
_.dragging = false;
_.swiping = false;
if (_.scrolling) {
_.scrolling = false;
return false;
}
_.interrupted = false;
_.shouldClick = ( _.touchObject.swipeLength > 10 ) ? false : true;
if ( _.touchObject.curX === undefined ) {
return false;
}
if ( _.touchObject.edgeHit === true ) {
_.$slider.trigger('edge', [_, _.swipeDirection() ]);
}
if ( _.touchObject.swipeLength >= _.touchObject.minSwipe ) {
direction = _.swipeDirection();
switch ( direction ) {
case 'left':
case 'down':
slideCount =
_.options.swipeToSlide ?
_.checkNavigable( _.currentSlide + _.getSlideCount() ) :
_.currentSlide + _.getSlideCount();
_.currentDirection = 0;
break;
case 'right':
case 'up':
slideCount =
_.options.swipeToSlide ?
_.checkNavigable( _.currentSlide - _.getSlideCount() ) :
_.currentSlide - _.getSlideCount();
_.currentDirection = 1;
break;
default:
}
if( direction != 'vertical' ) {
_.slideHandler( slideCount );
_.touchObject = {};
_.$slider.trigger('swipe', [_, direction ]);
}
} else {
if ( _.touchObject.startX !== _.touchObject.curX ) {
_.slideHandler( _.currentSlide );
_.touchObject = {};
}
}
};
Slick.prototype.swipeHandler = function(event) {
var _ = this;
if ((_.options.swipe === false) || ('ontouchend' in document && _.options.swipe === false)) {
return;
} else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) {
return;
}
_.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ?
event.originalEvent.touches.length : 1;
_.touchObject.minSwipe = _.listWidth / _.options
.touchThreshold;
if (_.options.verticalSwiping === true) {
_.touchObject.minSwipe = _.listHeight / _.options
.touchThreshold;
}
switch (event.data.action) {
case 'start':
_.swipeStart(event);
break;
case 'move':
_.swipeMove(event);
break;
case 'end':
_.swipeEnd(event);
break;
}
};
Slick.prototype.swipeMove = function(event) {
var _ = this,
edgeWasHit = false,
curLeft, swipeDirection, swipeLength, positionOffset, touches, verticalSwipeLength;
touches = event.originalEvent !== undefined ? event.originalEvent.touches : null;
if (!_.dragging || _.scrolling || touches && touches.length !== 1) {
return false;
}
curLeft = _.getLeft(_.currentSlide);
_.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX;
_.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY;
_.touchObject.swipeLength = Math.round(Math.sqrt(
Math.pow(_.touchObject.curX - _.touchObject.startX, 2)));
verticalSwipeLength = Math.round(Math.sqrt(
Math.pow(_.touchObject.curY - _.touchObject.startY, 2)));
if (!_.options.verticalSwiping && !_.swiping && verticalSwipeLength > _.options.verticalSwipeLengthLimit) {
_.scrolling = true;
return false;
}
if (_.options.verticalSwiping === true) {
_.touchObject.swipeLength = verticalSwipeLength;
}
swipeDirection = _.swipeDirection();
if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) {
_.swiping = true;
event.preventDefault();
}
positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1);
if (_.options.verticalSwiping === true) {
positionOffset = _.touchObject.curY > _.touchObject.startY ? 1 : -1;
}
swipeLength = _.touchObject.swipeLength;
_.touchObject.edgeHit = false;
if (_.options.infinite === false) {
if ((_.currentSlide === 0 && swipeDirection === 'right') || (_.currentSlide >= _.getDotCount() && swipeDirection === 'left')) {
swipeLength = _.touchObject.swipeLength * _.options.edgeFriction;
_.touchObject.edgeHit = true;
}
}
if (_.options.vertical === false) {
_.swipeLeft = curLeft + swipeLength * positionOffset;
} else {
_.swipeLeft = curLeft + (swipeLength * (_.$list.height() / _.listWidth)) * positionOffset;
}
if (_.options.verticalSwiping === true) {
_.swipeLeft = curLeft + swipeLength * positionOffset;
}
if (_.options.fade === true || _.options.touchMove === false) {
return false;
}
if (_.animating === true) {
_.swipeLeft = null;
return false;
}
_.setCSS(_.swipeLeft);
};
Slick.prototype.swipeStart = function(event) {
var _ = this,
touches;
_.interrupted = true;
if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) {
_.touchObject = {};
return false;
}
if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) {
touches = event.originalEvent.touches[0];
}
_.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX;
_.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY;
_.dragging = true;
};
Slick.prototype.unfilterSlides = Slick.prototype.slickUnfilter = function() {
var _ = this;
if (_.$slidesCache !== null) {
_.unload();
_.$slideTrack.children(this.options.slide).detach();
_.$slidesCache.appendTo(_.$slideTrack);
_.reinit();
}
};
Slick.prototype.unload = function() {
var _ = this;
$('.slick-cloned', _.$slider).remove();
if (_.$dots) {
_.$dots.remove();
}
if (_.$prevArrow && _.htmlExpr.test(_.options.prevArrow)) {
_.$prevArrow.remove();
}
if (_.$nextArrow && _.htmlExpr.test(_.options.nextArrow)) {
_.$nextArrow.remove();
}
_.$slides
.removeClass('slick-slide slick-active slick-visible slick-current')
.attr('aria-hidden', 'true')
.css('width', '');
};
Slick.prototype.unslick = function(fromBreakpoint) {
var _ = this;
_.$slider.trigger('unslick', [_, fromBreakpoint]);
_.destroy();
};
Slick.prototype.updateArrows = function() {
var _ = this,
centerOffset;
centerOffset = Math.floor(_.options.slidesToShow / 2);
if ( _.options.arrows === true &&
_.slideCount > _.options.slidesToShow &&
!_.options.infinite ) {
_.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
_.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
if (_.currentSlide === 0) {
_.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
_.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
} else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) {
_.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
_.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
} else if (_.currentSlide >= _.slideCount - 1 && _.options.centerMode === true) {
_.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
_.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
}
}
};
Slick.prototype.updateDots = function() {
var _ = this;
if (_.$dots !== null) {
_.$dots
.find('li')
.removeClass('slick-active')
.end();
_.$dots
.find('li')
.eq(Math.floor(_.currentSlide / _.options.slidesToScroll))
.addClass('slick-active');
}
};
Slick.prototype.visibility = function() {
var _ = this;
if ( _.options.autoplay ) {
if ( document[_.hidden] ) {
_.interrupted = true;
} else {
_.interrupted = false;
}
}
};
$.fn.slick = function() {
var _ = this,
opt = arguments[0],
args = Array.prototype.slice.call(arguments, 1),
l = _.length,
i,
ret;
for (i = 0; i < l; i++) {
if (typeof opt == 'object' || typeof opt == 'undefined')
_[i].slick = new Slick(_[i], opt);
else
ret = _[i].slick[opt].apply(_[i].slick, args);
if (typeof ret != 'undefined') return ret;
}
return _;
};
}));
jQuery(function ($) {
'use strict';
function PDPTouchZoomer() {
var
$imageContainer,
$image,
zoomContainerSelector,
zoomValue = 2.5,
newPos = {},
originalPos = {},
startPinch = {},
hasTouchMoved = false,
zoomInitiated = false,
isSwipeOn = true,
initialZoom = true,
pinchConcluded = false,
xPosStart,
yPosStart,
container,
startDistance;
function init() {
zoomContainerSelector = $.TOBI.Device.isMobile ? ".mobile-product-container" : ".product-detail-image-link-main";
$imageContainer = $(zoomContainerSelector);
if($imageContainer.length) {
setupListeners();
if(isTouchDevice()) showDoubleTapNotice();
setTimeout(fadeOutDoubleTapNotice, 4000);
}
}
function setupListeners() {
if(!$.TOBI.Device.isDesktop()) {
$('.product-detail-page').on("doubletap dblclick", zoomContainerSelector, initZoom);
$imageContainer[0].addEventListener('touchstart', pinchStart);
$imageContainer[0].addEventListener('touchmove', pinchMove);
}
}
//mobile/tablet zoom feature
function initZoom(e) {
if(e) {
e.preventDefault();
e.stopPropagation();
}
if(zoomInitiated) {
destroyZoom();
zoomInitiated = false;
return;
}
fadeOutDoubleTapNotice();
$imageContainer = $(this);
$image = $.TOBI.Device.isMobile ? $(this).find('.slick-current img') : $(this).find('img');
if($image.is("img") === false || !isTouchDevice()) return;
zoomInitiated = true;
initialZoom = true;
sliderTouchEvents(false);
loadLargerImage();
if(e && e.type==="doubletap") {
imageZoomIn(e);
} else {
imageZoomInCenter();
}
enableMoveZoomListeners();
}
function resetZoomFeature(colorId) {
if(
$.TOBI.Device.isTouchScreen &&
!$.TOBI.Device.isDesktop() &&
zoomInitiated
) {
destroyZoom();
}
}
function destroyZoom(animate) {
zoomInitiated = false;
var animate = typeof animate === 'undefined' ? true : animate;
disableZoomListeners();
zoomOutToOriginal(animate);
sliderTouchEvents(true);
}
function isZoomed() {
return zoomInitiated;
}
function loadLargerImage() {
var zoomSrc = $image.attr("data-zoom");
if($image.data("zoomLoaded") == false || $image.data("zoomLoaded") == undefined) {
//dont load the larger image if already in the browser memory
if($.TOBI.Detail.imageIsLoaded(zoomSrc)) {
largerImageLoaded(zoomSrc);
return;
}
var $tempImage = $('', {
'src': zoomSrc,
'class': 'u-hide-important',
});
$tempImage.appendTo($('body'));
$tempImage.one("load", function() {
largerImageLoaded(zoomSrc);
}).each(function() {
if(this.complete) largerImageLoaded(zoomSrc);
});
} else {
largerImageLoaded(zoomSrc);
}
}
function largerImageLoaded(imageURL) {
$image.attr("src", imageURL);
$image.attr("data-zoom-loaded", true);
$.TOBI.Detail.addLoadedImage(imageURL);
}
function imageZoomIn(e) {
container = {
width: $imageContainer.outerWidth(),
height: $imageContainer.outerHeight(),
centerWidth: $imageContainer.outerWidth() / 2,
centerHeight: $imageContainer.outerHeight() / 2,
offsetLeft: $image.offset().left,
offsetTop: $image.offset().top
};
var xClickedPos = (e.pageX - container.offsetLeft) * zoomValue;
var yClickedPos = (e.pageY - container.offsetTop) * zoomValue;
// Centers image and offset with clicked position base on image
originalPos.x = container.centerWidth - xClickedPos;
originalPos.y = container.centerHeight - yClickedPos;
originalPos = restrictImagePosition(originalPos.x, originalPos.y);
updateImagePosition(originalPos.x, originalPos.y, zoomValue, true);
}
function imageZoomInCenter() {
container = {
width: $imageContainer.outerWidth(),
height: $imageContainer.outerHeight(),
centerWidth: $imageContainer.outerWidth() / 2,
centerHeight: $imageContainer.outerHeight() / 2,
offsetLeft: $image.offset().left,
offsetTop: $image.offset().top
};
var xClickedPos = (container.centerWidth - container.offsetLeft) * zoomValue;
var yClickedPos = (container.centerHeight - container.offsetTop) * zoomValue;
// Centers image and offset with clicked position base on image
originalPos.x = container.centerWidth - xClickedPos;
originalPos.y = container.centerHeight - yClickedPos;
originalPos = restrictImagePosition(originalPos.x, originalPos.y);
updateImagePosition(originalPos.x, originalPos.y, zoomValue, true);
}
function zoomOutToOriginal(animate) {
var animate = typeof animate === 'undefined' ? true : animate;
updateImagePosition(0, 0, 1, animate);
}
function enableMoveZoomListeners() {
$imageContainer[0].addEventListener('touchstart', zoomTouchStart);
$imageContainer[0].addEventListener('touchmove', zoomTouchMove);
$imageContainer[0].addEventListener('touchend', zoomTouchEnd);
}
function disableZoomListeners() {
$imageContainer[0].removeEventListener('touchstart', zoomTouchStart);
$imageContainer[0].removeEventListener('touchmove', zoomTouchMove);
$imageContainer[0].removeEventListener('touchend', zoomTouchEnd);
}
function zoomTouchStart(e) {
var evt = e;
var numTouches = evt.touches.length;
hasTouchMoved = false;
if(numTouches === 1) {
initialZoom = false;
hasTouchMoved = false;
xPosStart = evt.touches[0].pageX * -1;
yPosStart = evt.touches[0].pageY * -1;
}
}
function zoomTouchMove(e) {
if(xPosStart == false) return;
if(initialZoom == true) return;
var evt = e;
var numTouches = evt.touches.length;
if(numTouches === 2) return;
if(numTouches === 1) {
e.preventDefault();
hasTouchMoved = true;
var xPos = evt.touches[0].pageX * -1;
var yPos = evt.touches[0].pageY * -1;
newPos.x = (xPosStart - xPos) + originalPos.x;
newPos.y = (yPosStart - yPos) + originalPos.y;
newPos = restrictImagePosition(newPos.x, newPos.y)
updateImagePosition(newPos.x, newPos.y, zoomValue);
}
}
function zoomTouchEnd(e) {
if(hasTouchMoved === false) return;
var evt = e;
var numTouches = evt.touches.length;
if(numTouches === 1) return;
if(numTouches === 0) {
initialZoom = false;
newPos = restrictImagePosition(newPos.x, newPos.y);
originalPos.x = newPos.x;
originalPos.y = newPos.y;
updateImagePosition(newPos.x, newPos.y, zoomValue, true);
}
}
function updateImagePosition(x, y, scale, animation) {
var animation = animation ? "transform 200ms ease-out" : "none" ;
var animate = {
"WebkitTransition": animation,
"MozTransition": animation,
"MsTransition": animation,
"transition": animation
}
var defaults = {
"transform-origin": container.offsetLeft + "px 0px 0px",
"transform": "translate3d(" + x + "px, " + y + "px, 0px) scale(" + scale + ")"
}
$.extend(defaults, animate);
$image.css(defaults);
}
function restrictImagePosition(touchX, touchY) {
// top boundary
touchX = (touchX > 0) ? 0 : touchX;
// left boundary
touchY = (touchY > 0) ? 0 : touchY;
var height = container.height;
var width = $image.actual('width');
var rightBoundaryZoomFactor = $.TOBI.Device.isPhone ? (zoomValue - 0.2) : (zoomValue - 0.5);
var bottomBoundaryZoomFactor = $.TOBI.Device.isPhone ? (zoomValue - 0.2) : zoomValue;
// right boundary
var rightBoundary = width * -rightBoundaryZoomFactor + container.width;
touchX = (touchX < rightBoundary) ? rightBoundary : touchX;
//bottom boundary
var bottomBoundary = height * -bottomBoundaryZoomFactor + height;
touchY = (touchY < bottomBoundary) ? bottomBoundary : touchY;
return {x: touchX, y: touchY}
}
function isTouchDevice() {
return ('ontouchstart' in window // works on most browsers
|| navigator.maxTouchPoints) && !$.TOBI.Device.isDesktop(); // works on IE10/11 and Surface
};
function pinchStart(e) {
if(e.touches.length == 2) {
pinchConcluded = false;
isSwipeOn = false;
$imageContainer.unbind('swipeleft');
$imageContainer.unbind('swiperight');
startPinch = { point1 : e.touches[0], point2 : e.touches[1] };
startDistance = getDistanceOfTwoPoints(startPinch);
}
}
function pinchMove(e) {
if(e.touches.length != 2) return;
if(pinchConcluded) return;
var touchPositions = { point1 : e.touches[0], point2 : e.touches[1] };
var touchDistance = getDistanceOfTwoPoints(touchPositions);
if(startDistance - touchDistance < -40) {
if(zoomInitiated) return;
initZoom(e);
pinchConcluded = true;
} else if (startDistance - touchDistance > 40) {
pinchConcluded = true;
destroyZoom();
}
}
function getDistanceOfTwoPoints(point) {
return Math.sqrt(
(point.point1.clientX-point.point2.clientX) * (point.point1.clientX-point.point2.clientX) +
(point.point1.clientY-point.point2.clientY) * (point.point1.clientY-point.point2.clientY));
}
function showDoubleTapNotice() {
$('.double-tap-zoom').fadeIn();
}
function fadeOutDoubleTapNotice() {
$('.double-tap-zoom').fadeOut();
}
/**
Set mobile slider touch events
**/
function sliderTouchEvents(option) {
if($.TOBI.Device.isMobile) {
$('.product-detail .mobile-thumbs .slick-slider').slick('slickSetOption', 'draggable', option, true);
$('.product-detail .mobile-thumbs .slick-slider').slick('slickSetOption', 'swipe', option, true);
$('.product-detail .mobile-thumbs .slick-slider').slick('slickSetOption', 'touchMove', option, true);
}
}
return {
init: init,
initZoom: initZoom,
resetZoomFeature: resetZoomFeature,
isZoomed: isZoomed,
isTouchDevice: isTouchDevice
}
}
$.TOBI.PDPTouchZoomer = PDPTouchZoomer();
$.TOBI.PDPTouchZoomer.init();
});
jQuery(function ($) {
'use strict';
function ProductDetail() {
// set up global vars.
var initialized = false,
cache,
colorId = 0,
sizeId = 0,
preloadedImgs = [],
twitterBaseUrl = 'https://twitter.com/intent/tweet?',
googlePlusBaseUrl = 'https://plus.google.com/share?',
pinterestBaseUrl = 'https://pinterest.com/pin/create/button/?',
facebookBaseUrl = 'https://www.facebook.com/sharer/sharer.php?source=facebook&medium=smm&campaign=pageshare&content=button',
relatedProductsCache = {},
zoomOptions = {
cursor: "default",
zoomType: "inner",
galleryActiveClass: 'active',
loadingIcon: '/images/ring-loader.svg',
zoomWindowFadeIn: 100,
zoomWindowFadeOut: 50,
// lensFadeIn: 100,
// lensFadeOut: 100,
easing : true,
easingAmount: 2
};
/**
Initialize the whole product detail page.
@public
**/
function init() {
// cache jquery objects of elements we use often
cache = {
addToCartMsg: $('.add-to-cart-confirmation'),
addToCartBtn: $('.btn-add-to-cart'),
soldOutBtn: $('.btn-sold-out')
};
setupListeners();
if($.TOBI.Device.isMobile) {
initMobileSlider();
} else {
// init tooltips for non-touch screen devices
$('.product-detail-tooltip').tooltip();
if(!$.TOBI.PDPTouchZoomer.isTouchDevice()) {
initDesktopZoom();
} else {
$('.product-detail').on('click', '.product-detail-image-link', handleProductImageModalLink);
}
}
updateShareInfo();
initialized = true;
$.publish('Detail.init');
}
/**
Setup the appropriate listeners for clicking.
@private
**/
function setupListeners() {
var productDetail = $('.product-detail'),
detailInfo = $('.grid-detail-info');
// listeners for color/size swatches
detailInfo.on('click', '.size', handleSizeClick);
detailInfo.on('click', '.color-swatch', handleColorClick);
// initial calls on selected color/size swatches
handleSelectedColor();
// listen for adding to cart! {self: self} passes the parent (this)
// object into the event so we can use it to trigger other internal functions
detailInfo.on('click', '.btn-add-to-cart', handleAddToCartClick);
// allow the alert to be closed.
cache.addToCartMsg.on('click', resetAddToCartMessage);
$('body').on('click', '.social-icon .twitter', function(event) {
event.preventDefault();
})
if ($.TOBI.Device.isDesktop()) {
$(window).resize($.TOBI.throttle(initDesktopZoom, 150));
// keyup listener
$(document).on('keyup', handleKeyup);
handleMainProductImageHover();
}
if($.TOBI.Device.isMobile) {
$('body').on('click', '.slick-current img', function(event) {
event.preventDefault();
return;
});
// On swipe event
$('.product-detail .mobile-thumbs .slick-slider').on('swipe', function(event, slick, direction){
if($.TOBI.PDPTouchZoomer.isZoomed()) {
event.preventDefault();
event.stopPropagation();
return;
}
});
// On edge hit
$('.product-detail .mobile-thumbs .slick-slider').on('edge', function(event, slick, direction){
if($.TOBI.PDPTouchZoomer.isZoomed()) {
event.preventDefault();
event.stopPropagation();
return;
}
});
// On before slide change
$('.product-detail .mobile-thumbs .slick-slider').on('beforeChange', function(event, slick, currentSlide, nextSlide){
if($.TOBI.PDPTouchZoomer.isZoomed()) {
event.preventDefault();
event.stopPropagation();
return;
}
});
}
$('body').on('click', '.product-detail-image-link-main, .product-detail-image-link', function(event) {
event.preventDefault();
});
$.subscribe('Like.unlikeItem', handleUnlikeItem);
$.subscribe('Like.likeItem', handleLikeItem);
}
function getColorId() {
return colorId;
}
function getSizeId() {
return sizeId;
}
/**
Check to see if the detailed info is in the featured product modal
@public
**/
function featuredProductPage() {
return ($('.featured-product:not(.product-detail-page)').length > 0)
}
/**
Update the See Details link on the featured product modal
@param colorId {Integer} the color to change link to
@private
**/
function updateSeeMorelink(colorId) {
if($('.see-more a').length && colorId) {
var url = $('.see-more a').attr('href').split("=")[0];
$('.see-more a').attr('href', url + "=" + colorId);
}
}
/**
Switch the page to display another color.
@param colorId {Integer} the color to switch to
@param soldOut {String} whether color is sold out or not
@public
**/
function switchColor(id, soldOut, haltGtmEvent) {
if (!id) return;
// save new color id
colorId = id;
fetchRelatedProducts(colorId);
var newColorSizeElem = getSizeElement(colorId, sizeId);
var colorSwitcherSel = '.product-detail .color-switching.color-'+colorId;
// show/hide images, sizes, and price for each color based on selected color
$('.product-detail .color-switching').addClass('hide');
$(colorSwitcherSel).removeClass('hide');
if ($.TOBI.Like.likeCount($('.color-' + colorId)) > 0){
$('.likes-count-'+colorId).removeClass('hide');
}
// change meta fields based on color
if ($('.product-list-container').length == 0) {
var titles = JSON.parse($('#hidden_title').html());
document.title = titles[colorId]
}
if($.TOBI.Device.isMobile) {
bLazy.load($(colorSwitcherSel+' .mobile-thumbs img'), true);
} else {
bLazy.load($(colorSwitcherSel+' .desktop-thumbs img'), true);
bLazy.load($(colorSwitcherSel+' .product-detail-image-large'), true);
if($.TOBI.Device.isDesktop() && initialized) initDesktopZoom();
}
// Select an appropriate size since the colors have changed.
if (newColorSizeElem) handleSizeClick({ currentTarget: newColorSizeElem });
// hide the add to cart confirmation
resetAddToCartMessage();
// set the add to cart / out of stock button
if (soldOut) {
cache.soldOutBtn.removeClass('hide');
cache.addToCartBtn.addClass('hide');
} else {
cache.soldOutBtn.addClass('hide');
cache.addToCartBtn.removeClass('hide');
}
// check if client supports history API
if(window.history && history.pushState) {
// replace current history state with new color id in the url
if(!featuredProductPage()) {
history.replaceState(
{ colorId: colorId },
'',
window.location.protocol + '//' + window.location.host + window.location.pathname + '?' + $.param($.extend($.TOBI.urlParams, { color_id: colorId }))
);
}
}
if(featuredProductPage()) {
updateSeeMorelink(colorId);
}
if(!haltGtmEvent) $.TOBI.Detail.publishProductView(colorId);
// track the color loading, either from a color change, or from the initial page load.
$.publish('Detail.switchColor', {
'page_type':'p',
'color_id':colorId
});
updateShareInfo();
if(typeof $(colorSwitcherSel+' .mobile-thumbs .slider')[0].slick !== 'undefined') {
$(colorSwitcherSel+' .mobile-thumbs .slider')[0].slick.refresh();
}
var $mainImage = $(colorSwitcherSel+' .product-detail-image-large');
$mainImage.attr('data-zoom', $mainImage.data('zoom-image'))
$.TOBI.PDPTouchZoomer.resetZoomFeature();
}
/**
Gets the needed size element
@param colorId {Integer} the color to switch to
@param sizeId {Integer} the size id
@public
**/
function getSizeElement(color, size) {
var sizeElem = $('.color-' + color + '-size-' + size);
if (sizeElem.length===0) {
sizeElem = $('.sizes-' + color + ' .size')[0];
}
return sizeElem;
}
/**
show the add to cart confirmation message or alert.
@public
**/
function addToCartMessage(result) {
var fsfr = $('.add-to-cart-wrapper .fsfr'),
confirm = cache.addToCartMsg,
result_type = result.success ? 'success' : 'danger';
fsfr.hide();
confirm
.text(result.message)
.addClass('alert-' + result_type)
.removeClass('hide')
.delay(3500)
.fadeOut(200, function() {
// set style to blank to remove display: none; from fadeOut()
$(this).addClass('hide').attr('style', '');
$('.add-to-cart-wrapper .fsfr').show();
});
}
/**
Hide the add-to-cart confirmation on submit.
@public
**/
function resetAddToCartMessage() {
cache.addToCartMsg.addClass('hide').stop();
$('.add-to-cart-wrapper .fsfr').show();
}
/**
Update the Main Share Image, Titles, and Urls for social button interactions
@public
**/
function updateShareInfo() {
var imgUrl = $(".product-detail-images:not(.hide)").find('.product-detail-image-link img').attr('data-image-large');
var price = $("meta[property='og:price:amount']").attr('content');
var description = $("meta[property='og:description']").attr('content');
var name = $('.product-detail').data('product-name');
var productDescription = $('.product-detail').data('product-description');
var titlePrefix = "Check out Tobi's ";
$("meta[property='og:image']").attr('content', imgUrl);
$("meta[property='twitter:image']").attr('content', imgUrl);
$("img[itemprop='image']").attr('src', imgUrl);
$("meta[property='og:url']").attr('content', window.location.href);
//update pinterest links
$('.social-icon .pinterest, img.pinterest').closest('a').attr('href',
pinterestBaseUrl +
'url=' + encodeURIComponent(window.location.href) +
'&description=' + encodeURIComponent(productDescription + ' #shoptobi') +
'&media=' + imgUrl
);
//update twitter links
$('.social-icon .twitter').closest('a').attr('href',
twitterBaseUrl +
'url=' + encodeURIComponent(window.location.href) +
'&text=' + encodeURIComponent(name) +
'&via=shoptobi'
);
//update google plus links
$('.social-icon .gplus').closest('a').attr('href',
googlePlusBaseUrl +
'url=' + encodeURIComponent(window.location.href)
);
//update facebook links
$('.social-icon .facebook').closest('a').attr('href',
facebookBaseUrl +
'&u=' + encodeURIComponent(window.location.href)
);
}
/**
Setup Hover event on main product image to show social icons
@private
**/
function handleMainProductImageHover() {
$('body').on('mouseenter mouseleave', ".grid-detail-images, .zoomContainer", function(event) {
if(event.type == 'mouseenter') {
$('.featured-images').find('.pinterest.action').show();
} else if(event.type == 'mouseleave') {
$('.featured-images').find('.pinterest.action').hide();
}
});
}
/**
Handle the event for clicking on a size.
@param e {Event} the form submission event
@private
**/
function handleSizeClick(event) {
var sizeEl = $(event.currentTarget),
size = sizeEl.data('sizeid');
// manage the selected class
$('.product-detail .size').removeClass('is-selected');
sizeEl.addClass('is-selected');
// reset the form and save the size
resetAddToCartMessage();
sizeId = size;
}
/**
Handle clicking on the color, and indirectly switching colors.
@param e {Event} the color clicking event
@private
**/
function handleColorClick(event, haltGtmEvent) {
var swatchEl = $(event.currentTarget),
soldOut = swatchEl.data('soldout');
colorId = swatchEl.data('colorid');
// manage the selected class
$('.product-detail .color-swatch').removeClass('is-selected');
swatchEl.addClass('is-selected');
// actually switch the color
switchColor(colorId, soldOut, haltGtmEvent);
}
/**
Handle keypresses.
@param {Event} the event
@private
**/
function handleKeyup(event) {
var keyCode = event.keyCode;
switch(event.keyCode) {
// arrow left
case 37:
selectPrevImage();
break;
// arrow right
case 39:
selectNextImage();
break;
// c
case 67:
cycleThroughColors();
break;
// s
case 83:
cycleThroughSizes();
break;
}
}
/**
Select next preview image
@private
**/
function selectNextImage() {
$('.product-detail-image-link-selected')
.first()
.next()
.trigger('click');
}
/**
Select previous preview image
@private
**/
function selectPrevImage() {
$('.product-detail-image-link-selected')
.first()
.prev('.product-detail-image-link')
.trigger('click');
}
/**
Cycle through the colors available.
@private
**/
function cycleThroughColors() {
var el = $('.color-swatch.is-selected'),
nextEl = el.next().length > 0 ? el.next() : $('.color-swatch').first();
nextEl.trigger('click');
}
/**
Cycle through the sizes available.
@private
**/
function cycleThroughSizes() {
var el = $('.size.is-selected'),
nextEl = el.next().length > 0 ? el.next() : el.parent().find('.size').first();
nextEl.trigger('click');
}
/**
Preload image and place it in provided element when loaded.
@param {Element} the jquery selected element to replace img src
@param {String} the path of the new image
@private
**/
function preloadImage(el, path, colorId, imgZoom) {
$.TOBI.PDPTouchZoomer.resetZoomFeature(colorId);
// check if we've already preloaded image
if($.inArray(path, preloadedImgs) > -1) {
el.attr('src', path);
}
else {
var tempImage = new Image();
addLoadedImage(path);
tempImage.onload = function() {
el.attr('src', path);
};
// we set path after to ensure the onload gets triggered
tempImage.src = path;
}
}
/**
Add to Cart onclick handler
@param ev {Event} click event.
@private
**/
function handleAddToCartClick(event) {
event.preventDefault();
var itemData = {
color_id: colorId,
size_id: sizeId,
click_type: 'c'
};
$.TOBI.Cart.addItem(itemData).done( function(response, status) {
$.publish('tobi_criteo.cart_changed', response.cart);
$.publish('data_layer.add_to_cart', colorId);
$.publish('adwords.add_to_cart', {
color_id: colorId,
cart: response.cart
});
// highlight the cart summary in the header
if (response.cart && response.cart.quantity) {
$.TOBI.Cart.updateQuantity(response.cart.quantity);
}
// list page messaging
if (response.result) {
addToCartMessage(response.result);
}
});
}
/**
Handle clicking on the sizing guide
@param e {Event} the sizing guide event
@public
**/
function handleSizingGuide(event) {
event.preventDefault();
window.open($(this).data('url'),'','width=800,height=600,toolbar=0,scrollbars=1');
}
function handleUnlikeItem(event, data) {
var $el = data.$el,
colorId = data.colorId;
if( $el.closest('.product-detail').length ) {
$el.closest('.product-detail').find('.product-detail-like-btn[data-colorid="' + colorId + '"]').each(function() {
var $btn = $(this);
if( $btn.hasClass('featured-product-like') ) {
$btn.removeClass( 'is-liked');
} else {
$btn.text('Like');
}
});
}
}
function handleLikeItem(event, data) {
var $el = data.$el,
colorId = data.colorId;
if( $el.closest('.product-detail').length ) {
$el.closest('.product-detail').find('.product-detail-like-btn[data-colorid="' + colorId + '"]').each(function() {
var $btn = $(this);
if( $btn.hasClass('featured-product-like') ) {
$btn.addClass( 'is-liked');
} else {
$btn.text('Unlike');
}
});
}
if(data.colorId === $.TOBI.Detail.colorId()) {
$('.likes-count-' + colorId).removeClass('hide');
}
}
function handleSelectedColor() {
$.publish('Detail.trackRecentlyViewed', {
color_id: $('.product-detail .color-swatch.is-selected').data('colorid')
});
handleColorClick({ currentTarget: $('.product-detail .color-swatch.is-selected') });
handleSizeClick({ currentTarget: $('.product-detail .size.is-selected') });
}
//Desktop zoom feature
function initDesktopZoom() {
$('.zoomContainer').remove();
var zoomImage = $('.product-detail-images:not(.hide) .product-detail-image-large');
var gallery = $(".product-detail-images:not(.hide)").attr('id');
zoomImage.removeData('elevateZoom');
if(gallery) {
zoomOptions.gallery = gallery;
$(".product-detail-images:not(.hide) .zoom_img").elevateZoom(zoomOptions);
}
}
function initMobileSlider() {
$('.product-detail .mobile-thumbs .slick-slider').each(function() {
$(this).slick({
dots: true,
infinite: true,
speed: 300,
slidesToShow: 1,
adaptiveHeight: false,
waitForAnimate: false,
touchThreshold: 10,
init: function() {
bLazy.revalidate();
},
beforeChange: function() {
bLazy.revalidate();
}
});
});
}
/**
* Initializes slick widget slider
* @param {number} desktopCount
* @param {number} tabletCount
* @param {number} phoneCount
* @return {undefined}
*/
function initSlickWidgetSlider(desktopCount, tabletCount, phoneCount) {
if($('.pdp-widget-slider').length) {
var desktopCount = desktopCount || 7;
var tabletCount = tabletCount || 5;
var phoneCount = phoneCount || 4;
$('.pdp-widget-slider .slider:not(.slick-initialized)').each(function() {
$(this).slick({
dots: false,
infinite: true,
speed: 450,
slidesToShow: desktopCount,
adaptiveHeight: false,
useCSS: false,
// useTransform: true,
easing: 'easeOutQuint',
slidesToScroll: desktopCount,
nextArrow: '',
prevArrow: '',
responsive: [
{
breakpoint: 1180,
settings: {
slidesToShow: tabletCount,
slidesToScroll: tabletCount,
arrows: true,
infinite: true
}
},
{
breakpoint: 800,
settings: {
slidesToShow: phoneCount,
slidesToScroll: phoneCount,
arrows: true,
infinite: true
}
}
],
init: function() {
bLazy.revalidate();
},
beforeChange: function() {
bLazy.revalidate();
}
});
});
}
}
/**
Handle the event for clicking on the large image preview to open modal.
@private
**/
function handleProductImageModalLink(event) {
event.preventDefault();
var thisEl = $(this),
imgPath = thisEl.attr('href'),
zoomPath = thisEl.attr('data-zoom');
if($.TOBI.Device.isMobile) {
// set src of modal main image after preload
$('.responsive-image-selected').removeClass('responsive-image-selected');
thisEl.addClass('responsive-image-selected');
}
else {
// set src of modal main image to new img path
$('.product-detail-image-large').attr('data-zoom', zoomPath);
$('.product-detail-image-large').attr('data-zoom-image', zoomPath);
$('.product-detail-image-large').attr('src', imgPath);
}
$.TOBI.PDPTouchZoomer.resetZoomFeature();
}
function imageIsLoaded(path) {
return preloadedImgs.includes(path);
}
function addLoadedImage(path) {
return preloadedImgs.push(path);
}
function fetchRelatedProducts(colorId) {
if(colorId in relatedProductsCache) {
$('.js-related-products-container').html(relatedProductsCache[colorId]);
initSlickWidgetSlider();
$('.related-products').show();
return;
}
var country = $('meta[name="country"]').attr('content');
if(country == 'US') {
country = '';
} else {
country = '/' + country;
}
$.ajax({
url: country + '/related_products/' + colorId,
type: 'GET'
})
.done(function(response) {
try {
if(response.html) {
$('.js-mini-list-container').hide();
relatedProductsCache[colorId] = response.html;
$('.js-related-products-container').html(response.html);
initSlickWidgetSlider();
} else {
$('.js-mini-list-container').show();
bLazy.revalidate();
}
} catch (e) {}
$('.related-products').show();
});
}
function publishProductView(colorId) {
$.publish('data_layer.product_view', colorId);
}
return {
init: init,
colorId: getColorId,
sizeId: getSizeId,
featuredProductPage: featuredProductPage,
handleSelectedColor: handleSelectedColor,
imageIsLoaded: imageIsLoaded,
addLoadedImage: addLoadedImage,
publishProductView: publishProductView,
initSlickWidgetSlider: initSlickWidgetSlider
}
}
$.TOBI.Detail = ProductDetail();
});
jQuery(function ($) {
'use strict';
/**
Main Like Class
**/
var TobiLike = {
likedColors: null,
/**
Initialize the abilities to like and unlike products on both the
product detail and product list pages.
@public
**/
init: function() {
if($.TOBI.Device.isMobile && !$('.product-detail-page').length) return;
this.likedColors = [];
// set up listeners for the detail page
this._setupListeners();
// load the user's likes via json
this._loadCurrentLikes();
},
/**
one-stop lookup of whether or not an item is liked.
@param el {Element} the element of the item that could be liked.
@return {Boolean}
@public
**/
isLiked: function(el) {
if (!el) {
return false;
}
var colorId = el.data('colorid');
return ($.inArray(colorId, this.likedColors) !== -1);
},
/**
processing to like an item in the current browser view;
the ajax call is handled by the _handleLikeClick function
@param el {Element} the element of the item that is to be liked.
@public
**/
likeItem: function($el) {
var colorId = $el.data('colorid');
// fake the count.
if (this._isDetailItem($el)) {
this._fakeCount($el, 1);
}
// push the new color onto the array.
this.likedColors.push(colorId);
// notify Trialfire
if (typeof Trialfire !== 'undefined'){
Trialfire.track('Product Like', {
colorId: $el.data('color-id'),
productId: $el.data('product-id'),
name: $el.data('product-name'),
price: $el.data('product-price'),
currency: 'USD'
});
}
// add liked class
$el.addClass('is-liked');
$.publish('Like.likeItem', { colorId: colorId, $el: $el });
},
/**
processing to unlike an item in the current browser view;
the ajax call is handled by the _handleLikeClick function
@param el {Element} the element of the item that is to be unliked.
@public
**/
unlikeItem: function($el) {
var colorId = $el.data('colorid'),
textEl = $el.children('.like-text');
// fake the count.
this._fakeCount($el, -1);
// push the new color onto the array.
this.likedColors = $.grep(this.likedColors, function(value) {
return value != colorId;
});
$.publish('Like.unlikeItem', { $el: $el, colorId: colorId });
},
/**
get the like count from the close-by element, returning a integer
@param el {Element} the element of the item that is to be liked.
@return {Integer} # of likes
@public
**/
likeCount: function(el) {
return parseInt(el.find('.like-count').html(), 10);
},
/**
Setup the appropriate listeners for clicking & mouseovers
@param sizeData {Array/Object} either an array of objects or an object of color data
@private
**/
_setupListeners: function() {
var likeLists = $('#product-list, .product-list, .product-detail, .featured-product');
// listener for just like button on list page
if (likeLists.length > 0) {
$('body').on('click', '.btn-like', this._handleLikeClick);
$('body').on('mouseleave', '.just-liked', this._handleJustLiked);
}
},
_handleJustLiked: function(ev) {
$(ev.currentTarget).removeClass('just-liked');
},
/**
load the current likes via ajax.
@private
**/
_loadCurrentLikes: function() {
var self = this;
$.getJSON('/likes_service/current_likes', function(likedColors) {
self.likedColors = likedColors;
self.syncLikeButtons();
});
},
/**
sync the page's display to match what it should be.
@public
**/
syncLikeButtons: function(selectorOverride) {
var self = this;
var selector = selectorOverride || '.btn-like';
$(selector).each(function() {
var $el = $(this);
if (self.isLiked($el) && !$el.hasClass('btn')) {
self.likeItem($el);
}
});
},
/**
click event for liking an item, fires off the ajax request to process
the like in our system.
@param ev {Event} mouseEnter / mouseLeave event.
@private
**/
_handleLikeClick: function(ev) {
var self = TobiLike,
el = $(ev.currentTarget);
ev.preventDefault();
$.get(el.attr('href'));
el.addClass('just-liked');
if (self.isLiked(el)) {
self.unlikeItem(el);
} else {
self.likeItem(el);
}
},
/**
increment the count for likes, if the current user liked it. This could
make the appearance of an extra like after the caches are reset, but
we're willing to live with that for now.
@param el {Element} the element of the item that is to be liked.
@private
**/
_fakeCount: function(el, diff) {
var colorId = el.data('colorid'),
likesContainerEl = el.closest('.grid-detail-info'),
likesCountEl = likesContainerEl.find('.likes-count-'+colorId+' .like-count'),
oldCount = parseInt(likesCountEl.html(),10),
newCount = oldCount + diff,
newLabel;
// set the new count
likesCountEl.html(newCount + ' Likes');
newLabel = ' ';
likesContainerEl.find('.like-label').html(newLabel);
likesContainerEl.find('.like-label').html(newLabel);
if (this._isDetailItem(el)) {
var iconHeartClass = diff > 0 ? 'fa fa-heart' : 'fa fa-heart-o',
likesButtonText = diff > 0 ? 'Remove from Likes' : 'Add To Likes',
iconHeartTooltip = diff > 0 ? 'You liked this item.' : 'You haven\'t liked this item.';
likesContainerEl.find('.js-like-button-'+ colorId +' i').attr('class', iconHeartClass);
likesContainerEl.find('.js-track-like[data-colorid="'+ colorId +'"] i').attr('class', iconHeartClass);
likesCountEl.closest('.likes-count-list').attr('title', iconHeartTooltip).tooltip('fixTitle');
el.find('.like-title').html(likesButtonText);
}
},
/**
see if this item is an element in a list of items or not.
@param el {Element} the element of the item in question
@return {Boolean}
@private
**/
_isListItem: function(el) {
return (el.parents('.product-list').length > 0);
},
/**
see if this item is an element in the detail page or not.
@param el {Element} the element of the item in question
@return {Boolean}
@private
**/
_isDetailItem: function(el) {
return (el.parents('.product-detail').length > 0);
}
}; // end Likes
// add Likes to the new $.TOBI obj.
$.TOBI.Like = TobiLike;
});
jQuery(function($) {
'use strict';
/**
* Size Guide
*
* @classdesc
* @requires
* Jquery
*/
function SizeGuide(){
function init() {
setupListeners();
}
/**
* Setup Event Listeners
*/
function setupListeners() {
$('body').on('click', '.size-guide .size-guide-size-changer .btn', switchSize);
$('body').on('click', '.js-size-guide', initModal);
}
function switchSize(event) {
if($(this).hasClass('btn-primary')) return;
var $container = $(this).closest('.size-guide-size-changer');
$container.find('.btn').removeClass('btn-primary');
$(this).addClass('btn-primary');
$('.size-switch span').toggleClass('hide');
}
function initModal(event) {
var modalConfig = $.TOBI.modalConfig(true);
$('.modal-size-guide').modal(modalConfig);
}
return {
init: init,
}
}
$.TOBI = $.TOBI || {};
$.TOBI.SizeGuide = SizeGuide();
})
;
jQuery(function($) {
'use strict';
/**
* RecentlyViewed
*/
function RecentlyViewed() {
var $recentlyViewedItems,
$recentlyViewedProducts,
$STASHED_PRODUCTS;
/**
* Initialize RecentlyViewed
* @return {undefined}
*/
function init() {
_setupSelectors();
_setupListeners();
}
/**
* Private methods
*/
/**
* Define RecentlyViewed selectors
* @return {undefined}
*/
function _setupSelectors() {
$recentlyViewedItems = $('.recently-viewed-products .recently-viewed-items');
$recentlyViewedProducts = $('.recently-viewed-products');
$STASHED_PRODUCTS = 7;
}
/**
* Defines RecentlyViewed listeners
* @return {undefined}
*/
function _setupListeners() {
$.subscribe('Detail.trackRecentlyViewed', _initOrUpdateCookie);
if ($recentlyViewedProducts.length) $.subscribe('Detail.trackRecentlyViewed', _getAndDisplay);
}
/**
* Initializes or updates recently viewed cookie
* @return {undefined}
*/
function _initOrUpdateCookie(event, data) {
if(typeof dataLayerHelper === 'undefined') return;
var colorId = data.color_id;
var $viewedProduct = {};
var $clonedColorData = $.extend(true, {}, dataLayerHelper.colors[colorId]); // Clone data into new object
var $colorData = _sliceObject.call($clonedColorData, ['display_name', 'image', 'url']);
// Merge timestamp as ordinal for sorting
$viewedProduct[colorId] = $.extend($colorData, { ordinal: Date.now() });
if ($.cookie('recently_viewed')) {
var $recentlyViewed = JSON.parse($.cookie('recently_viewed'));
var $sortedArray = _sortByOrdinal.call($.extend($recentlyViewed, $viewedProduct)).slice(0, $STASHED_PRODUCTS);
var $recentlyViewedProducts = _viewedProducts.call($sortedArray);
$.cookie('recently_viewed', JSON.stringify($recentlyViewedProducts), { path: '/' });
} else {
$.cookie('recently_viewed', JSON.stringify($viewedProduct), { path: '/' });
}
}
/**
* Gets and displays recently viewed products
* @return {undefined}
*/
function _getAndDisplay() {
$.ajax({
type: 'GET',
url: '/store/widgets/recently_viewed_products'
})
.done(function (response) {
$recentlyViewedItems.html(response);
if ($recentlyViewedProducts.hasClass('hide') && _numberProductsViewed() > 1) $recentlyViewedProducts.removeClass('hide');
if (bLazy) bLazy.revalidate();
$.TOBI.Detail.initSlickWidgetSlider(6, 5, 4);
})
.fail(function (response, textStatus, errorThrown) {
console.log(textStatus + ': ' + errorThrown);
});
}
/**
* Sorts Hash by ordinal
* @return {jQuery Object} Sorted array of hash objects
*/
function _sortByOrdinal() {
var $sortArray = [];
for (var key in this) {
$sortArray.push({ key: key, value: this[key] });
}
$sortArray.sort(function (a, b) {
return b.value.ordinal - a.value.ordinal; // Sort by ordinal DESC
});
return $sortArray;
}
/**
* Return Hash of viewed products
* @return {jQuery Object}
*/
function _viewedProducts() {
var $viewedProducts = {};
this.forEach(function (item) {
var $initHash = {};
$initHash[item.key] = item.value;
$.extend($viewedProducts, $initHash);
});
return $viewedProducts;
}
/**
* Returns the number of products viewed
* @return {number}
*/
function _numberProductsViewed() {
if ($.cookie('recently_viewed')) {
var recently_viewed = JSON.parse($.cookie('recently_viewed'));
return Object.keys(recently_viewed).length;
} else {
return 0;
}
}
/**
* Returns jQuery Object containing specified keys
* @param {Array} keys
* @return {jQuery Object}
*/
function _sliceObject(keys) {
var sliced = {};
for (var i in keys) {
sliced[keys[i]] = this[keys[i]];
}
return sliced;
}
return {
init: init
}
}
$.TOBI = $.TOBI || {};
$.TOBI.RecentlyViewed = RecentlyViewed();
$.TOBI.RecentlyViewed.init();
});
// TOBI Product Detail Page Assets
// TOBI
;