1 2/* 3 By Osvaldas Valutis, www.osvaldas.info 4 Available for use under the MIT License 5*/ 6 7;( function( $, window, document, undefined ) 8{ 9 'use strict'; 10 11 var cssTransitionSupport = function() 12 { 13 var s = document.body || document.documentElement, s = s.style; 14 if( s.WebkitTransition == '' ) return '-webkit-'; 15 if( s.MozTransition == '' ) return '-moz-'; 16 if( s.OTransition == '' ) return '-o-'; 17 if( s.transition == '' ) return ''; 18 return false; 19 }, 20 21 isCssTransitionSupport = cssTransitionSupport() === false ? false : true, 22 23 cssTransitionTranslateX = function( element, positionX, speed ) 24 { 25 var options = {}, prefix = cssTransitionSupport(); 26 options[ prefix + 'transform' ] = 'translateX(' + positionX + ')'; 27 options[ prefix + 'transition' ] = prefix + 'transform ' + speed + 's linear'; 28 element.css( options ); 29 }, 30 31 hasTouch = ( 'ontouchstart' in window ), 32 hasPointers = window.navigator.pointerEnabled || window.navigator.msPointerEnabled, 33 wasTouched = function( event ) 34 { 35 if( hasTouch ) 36 return true; 37 38 if( !hasPointers || typeof event === 'undefined' || typeof event.pointerType === 'undefined' ) 39 return false; 40 41 if( typeof event.MSPOINTER_TYPE_MOUSE !== 'undefined' ) 42 { 43 if( event.MSPOINTER_TYPE_MOUSE != event.pointerType ) 44 return true; 45 } 46 else 47 if( event.pointerType != 'mouse' ) 48 return true; 49 50 return false; 51 }; 52 53 $.fn.imageLightbox = function( options ) 54 { 55 var options = $.extend( 56 { 57 selector: 'id="imagelightbox"', 58 animationSpeed: 250, 59 preloadNext: true, 60 enableKeyboard: true, 61 quitOnEnd: false, 62 quitOnImgClick: false, 63 quitOnDocClick: true, 64 onStart: false, 65 onEnd: false, 66 onLoadStart: false, 67 onLoadEnd: false 68 }, 69 options ), 70 71 targets = $([]), 72 target = $(), 73 image = $(), 74 imageWidth = 0, 75 imageHeight = 0, 76 swipeDiff = 0, 77 inProgress = false, 78 79 setImage = function() 80 { 81 if( !image.length ) return true; 82 83 var screenWidth = $( window ).width() * 0.8, 84 screenHeight = $( window ).height() * 0.9, 85 tmpImage = new Image(); 86 87 tmpImage.src = image.attr( 'src' ); 88 tmpImage.onload = function() 89 { 90 imageWidth = tmpImage.width; 91 imageHeight = tmpImage.height; 92 93 if( imageWidth > screenWidth || imageHeight > screenHeight ) 94 { 95 var ratio = imageWidth / imageHeight > screenWidth / screenHeight ? imageWidth / screenWidth : imageHeight / screenHeight; 96 imageWidth /= ratio; 97 imageHeight /= ratio; 98 } 99 100 image.css( 101 { 102 'width': imageWidth + 'px', 103 'height': imageHeight + 'px', 104 'top': ( $( window ).height() - imageHeight ) / 2 + 'px', 105 'left': ( $( window ).width() - imageWidth ) / 2 + 'px' 106 }); 107 }; 108 }, 109 110 loadImage = function( direction ) 111 { 112 if( inProgress ) return false; 113 114 direction = typeof direction === 'undefined' ? false : direction == 'left' ? 1 : -1; 115 116 if( image.length ) 117 { 118 if( direction !== false && ( targets.length < 2 || ( options.quitOnEnd === true && ( ( direction === -1 && targets.index( target ) == 0 ) || ( direction === 1 && targets.index( target ) == targets.length - 1 ) ) ) ) ) 119 { 120 quitLightbox(); 121 return false; 122 } 123 var params = { 'opacity': 0 }; 124 if( isCssTransitionSupport ) cssTransitionTranslateX( image, ( 100 * direction ) - swipeDiff + 'px', options.animationSpeed / 1000 ); 125 else params.left = parseInt( image.css( 'left' ) ) + 100 * direction + 'px'; 126 image.animate( params, options.animationSpeed, function(){ removeImage(); }); 127 swipeDiff = 0; 128 } 129 130 inProgress = true; 131 if( options.onLoadStart !== false ) options.onLoadStart(); 132 133 setTimeout( function() 134 { 135 image = $( '<img ' + options.selector + ' />' ) 136 .attr( 'src', target.attr( 'href' ) ) 137 .on( 'load', function() 138 { 139 image.appendTo( 'body' ); 140 setImage(); 141 142 var params = { 'opacity': 1 }; 143 144 image.css( 'opacity', 0 ); 145 if( isCssTransitionSupport ) 146 { 147 cssTransitionTranslateX( image, -100 * direction + 'px', 0 ); 148 setTimeout( function(){ cssTransitionTranslateX( image, 0 + 'px', options.animationSpeed / 1000 ) }, 50 ); 149 } 150 else 151 { 152 var imagePosLeft = parseInt( image.css( 'left' ) ); 153 params.left = imagePosLeft + 'px'; 154 image.css( 'left', imagePosLeft - 100 * direction + 'px' ); 155 } 156 157 image.animate( params, options.animationSpeed, function() 158 { 159 inProgress = false;
160 if( options.onLoadEnd !== false ) options.onLoadEnd(); 161 }); 162 if( options.preloadNext ) 163 { 164 var nextTarget = targets.eq( targets.index( target ) + 1 ); 165 if( !nextTarget.length ) nextTarget = targets.eq( 0 ); 166 $( '<img />' ).attr( 'src', nextTarget.attr( 'href' ) ); 167 } 168 }) 169 .on( 'error', function() 170 { 171 if( options.onLoadEnd !== false ) options.onLoadEnd(); 172 }); 173 174 var swipeStart = 0, 175 swipeEnd = 0, 176 imagePosLeft = 0; 177 178 image.on( hasPointers ? 'pointerup MSPointerUp' : 'click', function( e ) 179 { 180 e.preventDefault(); 181 if( options.quitOnImgClick ) 182 { 183 quitLightbox(); 184 return false; 185 } 186 if( wasTouched( e.originalEvent ) ) return true; 187 var posX = ( e.pageX || e.originalEvent.pageX ) - e.target.offsetLeft; 188 target = targets.eq( targets.index( target ) - ( imageWidth / 2 > posX ? 1 : -1 ) ); 189 if( !target.length ) target = targets.eq( imageWidth / 2 > posX ? targets.length : 0 ); 190 loadImage( imageWidth / 2 > posX ? 'left' : 'right' ); 191 }) 192 .on( 'touchstart pointerdown MSPointerDown', function( e ) 193 { 194 if( !wasTouched( e.originalEvent ) || options.quitOnImgClick ) return true; 195 if( isCssTransitionSupport ) imagePosLeft = parseInt( image.css( 'left' ) ); 196 swipeStart = e.originalEvent.pageX || e.originalEvent.touches[ 0 ].pageX; 197 }) 198 .on( 'touchmove pointermove MSPointerMove', function( e ) 199 { 200 if( !wasTouched( e.originalEvent ) || options.quitOnImgClick ) return true; 201 e.preventDefault(); 202 swipeEnd = e.originalEvent.pageX || e.originalEvent.touches[ 0 ].pageX; 203 swipeDiff = swipeStart - swipeEnd; 204 if( isCssTransitionSupport ) cssTransitionTranslateX( image, -swipeDiff + 'px', 0 ); 205 else image.css( 'left', imagePosLeft - swipeDiff + 'px' ); 206 }) 207 .on( 'touchend touchcancel pointerup pointercancel MSPointerUp MSPointerCancel', function( e ) 208 { 209 if( !wasTouched( e.originalEvent ) || options.quitOnImgClick ) return true; 210 if( Math.abs( swipeDiff ) > 50 ) 211 { 212 target = targets.eq( targets.index( target ) - ( swipeDiff < 0 ? 1 : -1 ) ); 213 if( !target.length ) target = targets.eq( swipeDiff < 0 ? targets.length : 0 ); 214 loadImage( swipeDiff > 0 ? 'right' : 'left' ); 215 } 216 else 217 { 218 if( isCssTransitionSupport ) cssTransitionTranslateX( image, 0 + 'px', options.animationSpeed / 1000 ); 219 else image.animate({ 'left': imagePosLeft + 'px' }, options.animationSpeed / 2 ); 220 } 221 }); 222 223 }, options.animationSpeed + 100 ); 224 }, 225 226 removeImage = function() 227 { 228 if( !image.length ) return false; 229 image.remove(); 230 image = $(); 231 }, 232 233 quitLightbox = function() 234 { 235 if( !image.length ) return false; 236 image.animate({ 'opacity': 0 }, options.animationSpeed, function() 237 { 238 removeImage(); 239 inProgress = false; 240 if( options.onEnd !== false ) options.onEnd(); 241 }); 242 }, 243 244 addTargets = function( newTargets ) 245 { 246 newTargets.each( function() 247 { 248 targets = targets.add( $( this ) ); 249 }); 250 251 newTargets.on( 'click.imageLightbox', function( e ) 252 { 253 e.preventDefault(); 254 if( inProgress ) return false; 255 inProgress = false; 256 if( options.onStart !== false ) options.onStart(); 257 target = $( this ); 258 loadImage(); 259 }); 260 }; 261 262 $( window ).on( 'resize', setImage ); 263 264 if( options.quitOnDocClick ) 265 { 266 $( document ).on( hasTouch ? 'touchend' : 'click', function( e ) 267 { 268 if( image.length && !$( e.target ).is( image ) ) quitLightbox(); 269 }); 270 } 271 272 if( options.enableKeyboard ) 273 { 274 $( document ).on( 'keyup', function( e ) 275 { 276 if( !image.length ) return true; 277 e.preventDefault(); 278 if( e.keyCode == 27 ) quitLightbox(); 279 if( e.keyCode == 37 || e.keyCode == 39 ) 280 { 281 target = targets.eq( targets.index( target ) - ( e.keyCode == 37 ? 1 : -1 ) ); 282 if( !target.length ) target = targets.eq( e.keyCode == 37 ? targets.length : 0 ); 283 loadImage( e.keyCode == 37 ? 'left' : 'right' ); 284 } 285 }); 286 } 287 288 addTargets( $( this ) ); 289 290 this.switchImageLightbox = function( index ) 291 { 292 var tmpTarget = targets.eq( index ); 293 if( tmpTarget.length ) 294 { 295 var currentIndex = targets.index( target ); 296 target = tmpTarget; 297 loadImage( index < currentIndex ? 'left' : 'right' ); 298 } 299 return this; 300 }; 301 302 this.addToImageLightbox = function( newTargets ) 303 { 304 addTargets( newTargets ); 305 }; 306 307 this.quitImageLightbox = function() 308 { 309 quitLightbox(); 310 return this; 311 }; 312 313 return this; 314 }; 315})( jQuery, window, document );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.