function slideShowAnimator(options,$){
//Optional options object thinger
this.Options = {
'animationDelay': 3000,
'transitionTime': 3000,
'touchTransitionTime': 500,
'animationType' : 'opacity',
'tweenType' : 'easeOutQuint',
'touchTweenType' : 'easeOutSine',
'outerWrapperName' : 'sm_slideshow-wrapper',
'innerWrapperName' : 'sm_inner-wrapper',
'slideshowID' : '',
'nonNumberedChoosers' : false,
'numberedChoosers' : false,
'chooserType' : 'none',
'arrowChoosers' : false,
'chooserPlacement' : 1,
'hideChoosers' : false,
'useResponsiveLayout': false,
'enableEventBroadcasting': false
};
//assign Options with custom or default values
if ( options != null ) {
for( var index in this.Options ) {
this.Options[index] = (typeof options[index] != "undefined") ? options[index] : this.Options[index];
}
}
//initial slideShow vars
var enableEventBroadcasting = this.Options.enableEventBroadcasting;
var wrapper = $('.' + this.Options.outerWrapperName + '.' + this.Options.slideshowID);
var wrapperInsert = '.' + this.Options.outerWrapperName + '.' + this.Options.slideshowID;
var slideHolder = wrapper.find('#' + this.Options.innerWrapperName);
var slideChooser;
var animationSlides = slideHolder.find('li.sm_slide-wrapper');
var slideCount = animationSlides.length;
var slideWidth = wrapper.width();
var slideHeight = wrapper.height();
var permaWidth = wrapper.data('slideshowwidth');
var permaHeight = wrapper.data('slideshowheight');
var widthPercentageDiff;
var heightPercentageDiff;
//arrow elements
var arrowHolder;
var leftArrow;
var rightArrow;
//slide trackers
var currAnimateIn = 1;
var currAnimateOut = 0;
var currClickForward = 1;
var currClickBack = slideCount - 1;
//animation trackers
var isAnimating = true;
var showPaused = false;
var animationTimeout;
//touch pos trackers for touch events
var isTouch = false;
var isTouchSliding = false;
var touchStartX = 0;
var touchMoveX = 0;
var initResized = false;
//slide holder
var slideArray = new Array();
//constant for global 'this'
var self = this;
var isIE8 = false;
var isIE10 = false;
//test for IE 8 to compensate for opacity browser issues
if($.browser.msie && parseInt($.browser.version, 10) == 8) {
isIE8 = true;
}
if($.browser.msie && parseInt($.browser.version, 10) == 10) {
isIE10 = true;
}
this.init = function(){
//if user has requested choosers of any kind create the necessary dom elements to house them
//set the placment of the slidechoosers
if(self.Options.chooserType == 'basic' || self.Options.chooserType == 'numbers' || self.Options.arrowChoosers == true){
switch(self.Options.chooserPlacement){
case 2:
placementClass = 'top-right';
break;
case 3:
placementClass = 'bottom-left';
break;
case 4:
placementClass = 'bottom-right';
break;
default:
placementClass = 'top-left';
}
$('
').appendTo(wrapper);
slideChooser = $('#fade-chooser-block_' + this.Options.slideshowID);
}
animationSlides.each(function(i,e){
if(enableEventBroadcasting){
if(i==0){
window.EventManager.dispatchEvent({EventType: 'SlideshowSlideImpression', Slide: $(this)});
}
$(this).click(function() {
window.EventManager.dispatchEvent({EventType: 'SlideshowSlideClick', Slide: $(this)});
});
}
//for crossbrower purposes! hide the initial slides with opacity
//they are hidden in the DOM with display (as this is more crossbrowser compatible)
//using both prevents an initial 'flash' if page loads are delayed
if(i!=0){
if(self.Options.animationType == 'opacity'){
//set all slides besides the first index (0) to opacity:0
if(isIE8){
$(this).hide();
} else {
$(this).css({opacity:0});
}
//set all slides beside the first under the first
$(this).css({'z-index':1});
}else if(self.Options.animationType == 'slideLeft'){
$(this).css({'left':slideWidth+'px'});
}else if(self.Options.animationType == 'slideRight'){
$(this).css({'left':-slideWidth+'px'});
}else if(self.Options.animationType == 'slideDown'){
$(this).css({'top':-slideHeight+'px'});
}else if(self.Options.animationType == 'slideUp'){
$(this).css({'top':slideHeight+'px'});
}
}else if(i == 0 && self.Options.animationType == 'opacity'){
//set the first slide on top of the other slides
$(this).css({'z-index':2});
}
//add the slides to the slideArray
slideArray.push($(this));
//add necessary slide choosers
if(self.Options.chooserType == 'basic' ){
$('').data({'arrIndex':i}).appendTo(slideChooser);
}else if(self.Options.chooserType == 'numbers' ){
$('' + (i+1) + '
').data({'arrIndex':i}).appendTo(slideChooser);
}
});
//click event for the slide choosers
$(document).on('click',wrapperInsert + ' .clicker',function(){
//get the current slide
var currSlide = $(this).data('arrIndex');
self.showSlideInstant(currSlide);
});
//play / pause click handlers
$(document).on('click',wrapperInsert + ' #play-pause',function(){
isTouch = false;
//clear the animation timeout
clearTimeout(animationTimeout);
//show is paused
if(showPaused == true){
//update the global pause booleans and classes
isAnimating = true;
showPaused = false;
wrapper.find('#play-pause').attr('class','pauseNow');
self.animateCurrSlides();
//show is playing
}else{
//update the global pause booleans and classes
isAnimating = false;
showPaused = true;
wrapper.find('#play-pause').attr('class','playNow');
}
});
if(self.Options.arrowChoosers == true){
//create a left arrow clicker
$('').appendTo(slideChooser);
leftArrow = $('#left-arrow');
//create a right arrow clicker
$('').appendTo(slideChooser);
rightArrow = $('#right-arrow');
}
//arrow click event handlers
$(document).on('click',wrapperInsert + ' #left-arrow',function(evt){
if(currAnimateOut != 0){
self.showSlideInstant(currAnimateOut-1);
}else{
self.showSlideInstant(slideCount-1);
}
});
//arrow click event handlers
$(document).on('click',wrapperInsert + ' #right-arrow',function(){
if(currAnimateOut == slideCount - 1){
self.showSlideInstant(self.getAnimationOrder(-1));
}else{
self.showSlideInstant(self.getAnimationOrder(currAnimateOut));
}
});
//start the initial fade animation
setTimeout(self.animateCurrSlides,self.Options.animationDelay);
//shows the correct slide instantly when an arrow or chooser is clicked
this.showSlideInstant = function(currSlide){
isAnimating = false;
//hide the unclicked slides, show the clicked slide
//based on the transition type
for(var i =0; i < slideArray.length; i++){
if(self.Options.animationType == 'opacity'){
//ie8 conditional for opcaity "bug"
if(isIE8){
if(currSlide == i){
slideArray[currSlide].show();
slideArray[i].css({'z-index':2});
}else{
slideArray[i].hide();
slideArray[i].css({'z-index':1});
}
} else {
if(currSlide == i){
slideArray[currSlide].css({opacity:1,'top':'0px','left':'0px'});
slideArray[i].css({'z-index':2});
}else{
slideArray[i].css({opacity:0});
slideArray[i].css({'z-index':1});
}
}
}else if(self.Options.animationType == 'slideLeft'){
if(currSlide == i){
slideArray[currSlide].css({left:0+'px'});
}else{
slideArray[i].css({left: slideWidth + 'px'});
}
}else if(self.Options.animationType == 'slideRight'){
if(currSlide == i){
slideArray[currSlide].css({left:0+'px'});
}else{
slideArray[i].css({left: -slideWidth + 'px'});
}
}else if(self.Options.animationType == 'slideDown'){
if(currSlide == i){
slideArray[currSlide].css({top:0+'px','left':'0px'});
}else{
slideArray[i].css({top: -slideHeight + 'px','left':'0px'});
}
}else if(self.Options.animationType == 'slideUp'){
if(currSlide == i){
slideArray[currSlide].css({top:0+'px','left':'0px'});
}else{
slideArray[i].css({top: slideHeight + 'px','left':'0px'});
}
}
}
//pause the slideshow
self.pauseSlides(currSlide);
//update the clicked clicker
self.manageClickChoosers(currSlide);
if (enableEventBroadcasting){
window.EventManager.dispatchEvent({EventType: 'SlideshowSlideImpression', Slide: $(this)});
}
}
//pauses the slideshow
this.pauseSlides = function(currSlide){
//stop all animating animation
slideArray[currAnimateOut].stop();
slideArray[currAnimateIn].stop();
//clear the animation timeout
clearTimeout(animationTimeout);
//update the slide order
currAnimateOut = self.getAnimationOrder(currSlide-1);
currAnimateIn = self.getAnimationOrder(currSlide);
//update the global pause booleans and classes
showPaused = true;
wrapper.find('#play-pause').attr('class','playNow');
}
self.manageClickChoosers(0);
//resize the slideshow initially IF the site is set
//to use the 'Use Responsive Assets' bSetting
if(this.Options.useResponsiveLayout){
setTimeout(self.resizeOuterSlideshow,1000);
//this is for a timing bug where in a small
//percentage of loads the slideshow does not resize correctly
self.manualWindowResize();
}
}
//does the actual slide animation.
this.animateCurrSlides = function(){
if(isAnimating && isTouch == false){
//slide opacity animation
if(self.Options.animationType == 'opacity' && showPaused == false){
//ie8 conditional for opcaity "bug"
slideArray[currAnimateOut].css({'left':'0px','top':'0px'});
slideArray[currAnimateIn].css({'left':'0px','top':'0px'});
//reset any z-indexs that may have been displaced by touch events
for(var i = 0; i < slideArray.length; i++){
if(i == currAnimateIn){
slideArray[i].css({'z-index':'3'});
}else if(i == currAnimateOut){
slideArray[i].css({'z-index':'2'});
}else{
slideArray[i].css({'z-index':'1','left':slideWidth + 'px'});
}
}
if(isIE8){
slideArray[currAnimateOut].fadeOut(self.Options.transitionTime, function() {
self.resetAnimation();
});
slideArray[currAnimateIn].fadeIn(self.Options.transitionTime);
} else {
slideArray[currAnimateOut].css({opacity:1}).animate({opacity: 0}, self.Options.transitionTime, function() {
self.resetAnimation();
});
slideArray[currAnimateIn].css({opacity:0}).animate({opacity: 1}, self.Options.transitionTime);
}
//animates slides to the left
}else if(self.Options.animationType == 'slideLeft'){
//reset any slides that may have been displaced by touch events
for(var i = 0; i < slideArray.length; i++){
if(i != currAnimateOut){
slideArray[i].css({'left':slideWidth + 'px'});
}
}
slideArray[currAnimateOut].animate({'left': -slideWidth + 'px'},self.Options.transitionTime,self.Options.tweenType,function(){
self.resetAnimation();
//reset the current slide to it's starting slide position
$(this).css({'left':slideWidth + 'px'});
});
slideArray[currAnimateIn].animate({'left': '0px'},self.Options.transitionTime,self.Options.tweenType);
//animates slides to the right
}else if(self.Options.animationType == 'slideRight'){
//reset any slides that may have been displaced by touch events
for(var i = 0; i < slideArray.length; i++){
if(i != currAnimateOut){
slideArray[i].css({'left':-slideWidth + 'px'});
}
}
slideArray[currAnimateOut].animate({'left': slideWidth + 'px'},self.Options.transitionTime,self.Options.tweenType,function(){
self.resetAnimation();
//reset the current slide to it's starting slide position
$(this).css({'left':-slideWidth + 'px'});
});
slideArray[currAnimateIn].animate({'left': '0px'},self.Options.transitionTime,self.Options.tweenType);
//animates slides from the top
}else if(self.Options.animationType == 'slideDown'){
//reset any slides that may have been displaced by touch events
for(var i = 0; i < slideArray.length; i++){
if(i != currAnimateOut){
slideArray[i].css({'left':'0px','top':-slideHeight+'px'});
}
}
slideArray[currAnimateOut].animate({'top': slideHeight + 'px'},self.Options.transitionTime,self.Options.tweenType,function(){
self.resetAnimation();
//reset the current slide to it's starting slide position
$(this).css({'top':-slideHeight + 'px'});
});
slideArray[currAnimateIn].animate({'top': '0px'},self.Options.transitionTime,self.Options.tweenType);
//animates slides from the bottom
}else if(self.Options.animationType == 'slideUp'){
//reset any slides that may have been displaced by touch events
for(var i = 0; i < slideArray.length; i++){
if(i != currAnimateOut){
slideArray[i].css({'left':'0px','top':slideHeight+'px'});
}
}
slideArray[currAnimateOut].animate({'top': -slideHeight + 'px'},self.Options.transitionTime,self.Options.tweenType,function(){
self.resetAnimation();
//reset the current slide to it's starting slide position
$(this).css({'top':slideHeight + 'px'});
});
slideArray[currAnimateIn].animate({'top': '0px'},self.Options.transitionTime,self.Options.tweenType);
}
self.manageClickChoosers(currAnimateIn);
if (enableEventBroadcasting){
window.EventManager.dispatchEvent({EventType: 'SlideshowSlideImpression', Slide: $(slideArray[currAnimateIn])});
}
}
}
//sets up the slide show for the next animation
this.resetAnimation = function(){
//reset the z-index of all slides for IE z-index issues
if(self.Options.animationType == 'opacity'){
for(var i = 0; i < slideArray.length; i++){
if(i == currAnimateIn){
slideArray[i].css({'z-index':2});
}else{
slideArray[i].css({'z-index':1});
}
}
}
currAnimateOut = self.getAnimationOrder(currAnimateOut);
currAnimateIn = self.getAnimationOrder(currAnimateIn);
animationTimeout = setTimeout(self.animateCurrSlides, self.Options.animationDelay);
}
//updates counters to set correct fade order
this.getAnimationOrder = function(currSlide){
currSlide < slideCount - 1 ? currSlide++ : currSlide = 0;
return currSlide;
}
this.manageClickChoosers = function(currClick){
if(self.Options.chooserType == 'basic' || self.Options.chooserType == 'numbers'){
wrapper.find('.clicker').removeClass('clicked');
$('#clicker_'+ currClick + '_' + self.Options.slideshowID).addClass('clicked');
}
}
this.resizeOuterSlideshow = function(){
// IF THE BROWSER IS INTERNET EXPLORER 10
/*
if(isIE10 == true){
var currHeight = wrapper.find('li img').get(0).naturalHeight;
}else{
}
*/
var currHeight = wrapper.find('li img').height();
slideHolder.css({'height':currHeight+'px'});
slideHeight = currHeight;
wrapper.css('height',currHeight+'px');
self.updateWidthDifference();
slideArray.each(function(e,i){
if(i != currAnimateOut){
if(self.Options.animationType == 'slideDown'){
slideArray[i].css({'top':-slideHeight+'px'});
}else if(self.Options.animationType == 'slideUp'){
slideArray[i].css({'top':slideHeight+'px'});
}
}
});
}
//this function and testInitResize test at a regular interval to
//make sure the slideshow is actually resizing correctly onload
this.manualWindowResize = function(){
if(self.testInitResize() == true){
setTimeout(function(){
self.resizeOuterSlideshow();
},500);
}else{
setTimeout(function(){
self.manualWindowResize();
},500);
}
}
this.testInitResize = function(){
if(slideHolder.height() == wrapper.find('li img').eq(0).height()){
initResized = true;
}else{
initResized = false;
}
return initResized;
}
this.updateWidthDifference = function(){
widthPercentageDiff = wrapper.find('li img').eq(0).width() / permaWidth;
self.updateButtonTextPosition(widthPercentageDiff);
}
this.updateButtonTextPosition = function(percentageDiff){
wrapper.find('.cta-button').each(function(){
var currFontSize = parseInt($(this).data('buttonfontsize'));
var updatedFontSize = Math.floor(currFontSize * percentageDiff);
var currWidth = parseInt($(this).data('buttonwidth'));
var updatedWidth = Math.floor(currWidth * percentageDiff);
var currHeight = parseInt($(this).data('buttonheight'));
var updatedHeight = Math.floor(currHeight * percentageDiff);
var currLeftPos = parseInt($(this).data('buttonleft'));
var updatedLeftPos = Math.floor(currLeftPos * percentageDiff);
var currTopPos = parseInt($(this).data('buttontop'));
var updatedTopPos = Math.floor(currTopPos * percentageDiff);
$(this).css({'font-size':updatedFontSize+'px','width':updatedWidth+'px','height':updatedHeight+'px','left':updatedLeftPos+'px','top':updatedTopPos+'px','line-height':updatedHeight+'px'});
});
$('.slide-text-box').each(function(){
//if the slide is less than 100% of it's native size
if(percentageDiff < 1){
var currFontSize = parseInt($(this).data('textfontsize'));
var updatedFontSize = Math.floor(currFontSize * percentageDiff);
var currLeftPos = parseInt($(this).data('textleft'));
var updatedLeftPos = Math.floor(currLeftPos * percentageDiff);
var currTopPos = parseInt($(this).data('texttop'));
var updatedTopPos = Math.floor(currTopPos * percentageDiff);
}else{
//else set the button size and positioning to its default
var updatedFontSize = parseInt($(this).data('textfontsize'));
var updatedLeftPos = parseInt($(this).data('textleft'));
var updatedTopPos = parseInt($(this).data('texttop'));
}
$(this).css({'font-size':updatedFontSize+'px','left':updatedLeftPos+'px','top':updatedTopPos+'px'});
});
}
/*----- touch events -----*/
$('#sm_show-wrapper').bind('touchstart',function(event){
touchStartX = event.originalEvent.changedTouches[0].pageX;
//set touch boolean to true
isTouch = true;
//set all slides' opacity to 1
slideArray.each(function(v,i){
slideArray[i].css({opacity:1});
});
//event.preventDefault();
}).bind('touchend',function(event){
touchMoveX = event.originalEvent.changedTouches[0].pageX;
isTouch = true;
var touchDiff = touchMoveX - touchStartX;
//if user moves touch to right
if(touchDiff > 50){
self.touchSlideRight();
event.preventDefault();
//if user moves touch to left
}else if(touchDiff < -50){
self.touchSlideLeft();
event.preventDefault();
}
});
this.touchSlideRight = function(){
var cachedAnimationType = self.Options.animationType;
if(isTouchSliding == false){
isTouchSliding = true;
self.Options.animationType = 'slideRight';
slideArray.each(function(v,i){
if(i != currAnimateOut){
slideArray[i].css({'left':-slideWidth + 'px','top':'0px','opacity':1});
}
});
if(currAnimateOut > 0){
currAnimateIn = currAnimateOut - 1;
}else{
currAnimateIn = slideCount - 1;
}
slideArray[currAnimateOut].animate({'left': slideWidth + 'px'},self.Options.touchTransitionTime,self.Options.touchTweenType,function(){
//reset the current slide to it's starting slide position
$(this).css({'left':-slideWidth + 'px'});
isTouchSliding = false;
self.pauseSlides(currAnimateIn);
});
slideArray[currAnimateIn].animate({'left': '0px'},self.Options.touchTransitionTime,self.Options.touchTweenType);
}
self.Options.animationType = cachedAnimationType;
self.manageClickChoosers(currAnimateIn);
}
this.touchSlideLeft = function(){
var cachedAnimationType = self.Options.animationType;
if(isTouchSliding == false){
isTouchSliding = true;
self.Options.animationType = 'slideLeft';
slideArray.each(function(v,i){
if(i != currAnimateOut){
slideArray[i].css({'left':slideWidth + 'px','top':'0px','opacity':1});
}
});
if(currAnimateOut < slideCount - 1){
currAnimateIn = currAnimateOut + 1;
}else{
currAnimateIn = 0;
}
slideArray[currAnimateOut].animate({'left': -slideWidth + 'px'},self.Options.touchTransitionTime,self.Options.touchTweenType,function(){
//reset the current slide to it's starting slide position
$(this).css({'left':slideWidth + 'px'});
isTouchSliding = false;
self.pauseSlides(currAnimateIn);
});
slideArray[currAnimateIn].animate({'left': '0px'},self.Options.touchTransitionTime,self.Options.touchTweenType);
}
self.Options.animationType = cachedAnimationType;
self.manageClickChoosers(currAnimateIn);
}
//initialize the slideshow if there is more than one slide
if(slideCount > 1){
self.init();
}else if(slideCount == 1 && self.Options.useResponsiveLayout){
//if responsiveLayout is used and there is just one slide set the height
//of the inner wrapper
slideHolder.css({'height':wrapper.find('li img').eq(0).height()+'px'});
if(permaWidth != wrapper.find('li img').eq(0).width()){
self.updateWidthDifference();
}
var oneTo = setTimeout(function(){
slideHolder.css({'height':wrapper.find('li img').eq(0).height()+'px'});
},3000);
}
}