// developed by codeinn.co // released under mit license (https://opensource.org/licenses/mit) // //the mit license (mit) //copyright (c) 2016 codeinn.co //permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated //documentation files (the "software"), to deal in the software without restriction, including without limitation //the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, //and to permit persons to whom the software is furnished to do so, subject to the following conditions: // //the above copyright notice and this permission notice shall be included in all copies or substantial portions of the software. //the software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties //of merchantability, fitness for a particular purpose and noninfringement. in no event shall the authors or copyright holders be //liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or //in connection with the software or the use or other dealings in the software. ( function ( $ ) { var defaults = { // auto navbar: false, auto: false, pause: 5000 }; $.fn.hslider = function( options ) { if ( this.length === 0 ) { return this; } // if there are more than one elements being used if ( this.length > 1 ) { this.each( function() { $( this ).hslider( options ); }); return this; } var settings = {}; if ( $( thisslider ).data( 'hslider' ) ) { return; } // if already initialized, return settings = $.extend( {}, defaults, options ); //merge the default settings and the specified settings var thisslider = this; var leftx = 0, windowwidth = 0, gallerywidth = 0, gallerywidthspace = 0, $responsiveheight = 0; var nextchildnum, prevchildnum, resizetimer, windowwidthtimer; var autointerval; var windowwidthaddedpadding = 1; var $container = thisslider; //var $imagecontainer = $container.find( 'img' ).parent().addclass( 'hsldr-image-container' ); var $imagecontainer; $imagecontainer = $container.find( 'figure' ); if( $imagecontainer.length > 0 ){ $imagecontainer.addclass( 'hsldr-image-container' ); $imagecontainer.wrapall( "" ); } else{ $imagecontainer = $container.find( 'li' ); if( $imagecontainer.length > 0 ){ $imagecontainer.addclass( 'hsldr-image-container' ); $imagecontainer.closest('ul').wrapall( "" ); } } //var $imagecontainer = $container.find( 'figure, li' ).addclass( 'hsldr-image-container' ); //$imagecontainer.wrapall( "" ); var $gallerycontainer = $container.find( '.hsldr-gallery-container' ); var $allimages = $imagecontainer.find( 'img' ); var $figcaption = $imagecontainer.find( 'figcaption, .caption' ); if ( $figcaption.length > 0 ) { $figcaption.parent().append( '' ); } var $allinfo = $container.find( '.info' ); var $imagenumber = $allimages.length; var $imagewidths = array.apply( null, array( $imagenumber ) ).map( number.prototype.valueof, 0 ); // initialize to all zeros var $activeindex = 0; // current active image index if(settings.navbar){ $container.addclass("hsldr-has-nav-bar"); var $dotstring = '
'; $dotstring += '
'; $container.append( '
' + $dotstring + '
' ); // store pointers to all the dot elements var $allnavdots = $container.find( '.hsldr-nav-marker' ); var $allnavdotswrapper = $container.find( '.hsldr-nav-wrapper' ); var $navregion = $container.find( '.hsldr-nav-region' ); } $container.append( '
' ); var $nextbutton = $container.find( '.hsldr-next' ); var $prevbutton = $container.find( '.hsldr-prev' ); var computecacheimagewidths = function() { // computes the current image widths and stores as a n array so that it can be retrieved fast later var loopcounter = 0; $imagecontainer.each( function() { $imagewidths[loopcounter] = math.floor( $( this ).width() ); loopcounter++; }); } var compsetwidths = function() { windowwidth = $( window ).width(); $responsiveheight = windowwidth/1.7; if( windowwidth < 600 * 1.7 ) { $container.css( 'max-height', ( 180 + 30 ) + 'px' ); $allimages.css( 'max-height', 180 + 'px' ); } else { $container.css( 'max-height', '184px' ); $allimages.css( 'max-height', '184px' ); } windowwidth += windowwidthaddedpadding; /* add up image widths to determine the gallery container width */ computecacheimagewidths(); gallerywidth = 0; for( var i = 0; i < $imagewidths.length; i++ ) { gallerywidth += $imagewidths[i]; } // set gallery container width gallerywidthspace = gallerywidth + 4; $gallerycontainer.width( gallerywidthspace ); } var discouragewhitespace = function() { // try to remove the white space on either sides by adjusting the leftx. if white space is not avoidable, center the gallery. //if gallerywidth is smaller than windowwidth, jsut center the gallery if( gallerywidth <= windowwidth ) { leftx = ( gallerywidth - windowwidth)/2; } else if( leftx <= 0 ) { // white space on left side leftx = 0; } else if( (gallerywidth - leftx) <= windowwidth ) { // white space on right side leftx = gallerywidth - windowwidth; } if(settings.navbar){ updatevisibledots(); } } var updatevisibledots = function() { // find which of the images are visible var startindex = 0; var endindex = 0; var widthsum = 0; var isstartset = false; var isendset = false; for( var i = 0; i < $imagewidths.length; i++ ) { widthsum += $imagewidths[i]; if( ! isstartset ) { if( widthsum > leftx ){ startindex = i; isstartset = true; } } if( ! isendset ) { if( widthsum > ( leftx + windowwidth ) ) { endindex = i; isendset = true; } } } if(!isstartset)startindex = 0; if(!isendset)endindex = ( $imagewidths.length - 1 ); if( startindex < 0 ) startindex = 0; if( startindex > ( $imagewidths.length - 1 ) ) startindex = ( $imagewidths.length - 1 ); if( endindex < 0 )endindex = 0; if( endindex > ( $imagewidths.length - 1 ) ) endindex = ( $imagewidths.length - 1 ); if( endindex < startindex )endindex = startindex; var bgwidth = ( windowwidth / 450 ) * 200; if( bgwidth > 200 )bgwidth = 200; var barwidth = ( windowwidth / gallerywidth ) * bgwidth; var barleft = leftx * ( bgwidth - barwidth ) / ( gallerywidth - windowwidth ); if( barleft > ( bgwidth - barwidth) ) barleft = ( bgwidth - barwidth); bgwidth = math.floor( bgwidth ); barwidth = math.floor( barwidth ); if( barwidth > bgwidth ) barwidth = bgwidth; if( barwidth < 1 ) barwidth =1; barleft = math.floor( barleft ); if( barleft < 0 )barleft=0; $allnavdots.css({'width' : bgwidth + 'px'}); $navregion.animate({ left: barleft, width: barwidth }); } var makecentral = function() { // all previous images total width console.log('calling makecentral'); var previmgwidth = 0; for( var i = 0; i < $activeindex; i++ ) { previmgwidth += $imagewidths[i]; } leftx = ( previmgwidth + $imagewidths[$activeindex] / 2 ) - windowwidth / 2; discouragewhitespace(); $gallerycontainer.css( 'left', -leftx + 'px' ); //position the caption 'i' icon properly var thisimagewidth; var hiddenwidth; for( var i = 0; i < $imagewidths.length; i++ ) { thisimagewidth = $imagewidths[i]; hiddenwidth = ( thisimagewidth - windowwidth ) / 2; if ( hiddenwidth < 0 ) hiddenwidth = 0; var $curinfo = $allimages.eq( i ).closest('.hsldr-image-container').children('.info'); $curinfo.css( 'right', ( math.ceil(hiddenwidth) + 10 ) + 'px' ); } } $( window ).on( 'resize', function( e ) { $gallerycontainer.width( '99999px' ); cleartimeout(resizetimer); resizetimer = settimeout(function() { // run code here, resizing has "stopped" compsetwidths(); makecentral(); }, 250); // if scroll bar hides due to resize, the old window width becomes incorrect cleartimeout(windowwidthtimer); windowwidthtimer = settimeout(function() { windowwidth = $( window ).width() + windowwidthaddedpadding; makecentral(); }, 1000); // the delay shoudld be sufficiently bigger than the one use above }); var shownextslide = function() { if( (leftx == ( gallerywidth - windowwidth)) || ( $activeindex == $imagenumber - 1 ) ) { // no images left. the expression inside the if clause should be identical to the one in discouragewhitespace() //scroll to the begining $activeindex = 0; $(thisslider).find( '.active-slide' ).removeclass( 'active-slide' ); $(thisslider).find( '.hsldr-image-container:first-child' ).addclass( 'active-slide' ); makecentral(); } else { //fidn the image just past the center point var targetvalue = leftx + windowwidth/2; var cursum = 0; var childnum = 0; var curwidth = 0; for( var i = 0; i < $imagewidths.length; i++ ) { curwidth = $imagewidths[i]; cursum += curwidth; if( cursum >= targetvalue ) { break; // break out of the loop } childnum++; } // if subtracting half the width of the cur child is past the middle, then cur image otherwise next image if( ( cursum - curwidth/2 ) >= (targetvalue + 5 ) ) { // number 5 to avoid any ambiguity nextchildnum = childnum; } else{ nextchildnum = childnum +1; } // remove old active slide and add new active slide $activeindex = nextchildnum; $( thisslider ).find( '.active-slide' ).removeclass( 'active-slide' ); $gallerycontainer.children( '.hsldr-image-container' ).eq( nextchildnum ).addclass( 'active-slide' ); makecentral(); } } var showprevslide = function() { if( ( leftx == 0 ) || ( $activeindex == 0 ) ) { // no images left. $activeindex = $imagenumber - 1; $(thisslider).find( '.active-slide' ).removeclass( 'active-slide' ); $(thisslider).find( '.hsldr-image-container:last-child' ).addclass( 'active-slide' ); makecentral(); } else { //find the image just before the center point var targetvalue = leftx + windowwidth/2; var cursum = 0; var childnum = 0; var curwidth = 0; for( var i = 0; i < $imagewidths.length; i++ ) { curwidth = $imagewidths[i]; cursum += curwidth; if( cursum >= targetvalue ) { break; // break out of the loop } childnum++; } // if subtracting half the width of the cur child is past the middle, then cur image otherwise next image if( ( cursum - curwidth/2 ) >= (targetvalue - 5 ) ) { // number 5 to avoid any ambiguity prevchildnum = childnum -1 ; } else{ prevchildnum = childnum; } // remove old active slide and add new active slide $activeindex = prevchildnum; $(thisslider).find( '.active-slide' ).removeclass( 'active-slide' ); $gallerycontainer.children( '.hsldr-image-container' ).eq(prevchildnum).addclass( 'active-slide' ); makecentral(); } } var initslider = function() { $gallerycontainer.imagesloaded( function() { compsetwidths(); $container.addclass( 'fade-in' ); makecentral(); }); $imagecontainer.on( 'click', '.info', function() { $( this ).parent().toggleclass( 'showcaption' ).siblings().removeclass( 'showcaption' ); }); // next button $nextbutton.on( 'click', function( e ) { e.preventdefault(); abortslidetimer(); // disable auto play if navigation buttons are pressed shownextslide(); }); // previous button $prevbutton.on('click', function( e ) { e.preventdefault(); abortslidetimer(); // disable auto play if navigation buttons are pressed showprevslide(); }); if(settings.auto){ var delayval = settings.delay; if( delayval < 1000)delayval = 1000; var autointerval = setinterval(shownextslide, delayval); } var abortslidetimer = function() { clearinterval(autointerval); } // if scroll bar hides due to resize, the old window width becomes incorrect cleartimeout(windowwidthtimer); windowwidthtimer = settimeout(function() { windowwidth = $( window ).width() + windowwidthaddedpadding; }, 1000); // the delay shoudld be sufficiently bigger than the one use above }; initslider(); $( thisslider ).data( 'hslider', this ); // store for later use return this; }; } ( jquery ) );