314 lines
9.2 KiB
JavaScript
314 lines
9.2 KiB
JavaScript
|
|
/*
|
|
By Osvaldas Valutis, www.osvaldas.info
|
|
Available for use under the MIT License
|
|
*/
|
|
|
|
;( function( $, window, document, undefined )
|
|
{
|
|
'use strict';
|
|
|
|
var cssTransitionSupport = function()
|
|
{
|
|
var s = document.body || document.documentElement, s = s.style;
|
|
if( s.WebkitTransition == '' ) return '-webkit-';
|
|
if( s.MozTransition == '' ) return '-moz-';
|
|
if( s.OTransition == '' ) return '-o-';
|
|
if( s.transition == '' ) return '';
|
|
return false;
|
|
},
|
|
|
|
isCssTransitionSupport = cssTransitionSupport() === false ? false : true,
|
|
|
|
cssTransitionTranslateX = function( element, positionX, speed )
|
|
{
|
|
var options = {}, prefix = cssTransitionSupport();
|
|
options[ prefix + 'transform' ] = 'translateX(' + positionX + ')';
|
|
options[ prefix + 'transition' ] = prefix + 'transform ' + speed + 's linear';
|
|
element.css( options );
|
|
},
|
|
|
|
hasTouch = ( 'ontouchstart' in window ),
|
|
hasPointers = window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
|
|
wasTouched = function( event )
|
|
{
|
|
if( hasTouch )
|
|
return true;
|
|
|
|
if( !hasPointers || typeof event === 'undefined' || typeof event.pointerType === 'undefined' )
|
|
return false;
|
|
|
|
if( typeof event.MSPOINTER_TYPE_MOUSE !== 'undefined' )
|
|
{
|
|
if( event.MSPOINTER_TYPE_MOUSE != event.pointerType )
|
|
return true;
|
|
}
|
|
else
|
|
if( event.pointerType != 'mouse' )
|
|
return true;
|
|
|
|
return false;
|
|
};
|
|
|
|
$.fn.imageLightbox = function( options )
|
|
{
|
|
var options = $.extend(
|
|
{
|
|
selector: 'id="imagelightbox"',
|
|
allowedTypes: 'png|jpg|jpeg|gif',
|
|
animationSpeed: 250,
|
|
preloadNext: true,
|
|
enableKeyboard: true,
|
|
quitOnEnd: false,
|
|
quitOnImgClick: false,
|
|
quitOnDocClick: true,
|
|
onStart: false,
|
|
onEnd: false,
|
|
onLoadStart: false,
|
|
onLoadEnd: false
|
|
},
|
|
options ),
|
|
|
|
targets = $([]),
|
|
target = $(),
|
|
image = $(),
|
|
imageWidth = 0,
|
|
imageHeight = 0,
|
|
swipeDiff = 0,
|
|
inProgress = false,
|
|
|
|
isTargetValid = function( element )
|
|
{
|
|
return $( element ).prop( 'tagName' ).toLowerCase() == 'a' && ( new RegExp( '\.(' + options.allowedTypes + ')$', 'i' ) ).test( $( element ).attr( 'href' ) );
|
|
},
|
|
|
|
setImage = function()
|
|
{
|
|
if( !image.length ) return true;
|
|
|
|
var screenWidth = $( window ).width() * 0.8,
|
|
screenHeight = $( window ).height() * 0.9,
|
|
tmpImage = new Image();
|
|
|
|
tmpImage.src = image.attr( 'src' );
|
|
tmpImage.onload = function()
|
|
{
|
|
imageWidth = tmpImage.width;
|
|
imageHeight = tmpImage.height;
|
|
|
|
if( imageWidth > screenWidth || imageHeight > screenHeight )
|
|
{
|
|
var ratio = imageWidth / imageHeight > screenWidth / screenHeight ? imageWidth / screenWidth : imageHeight / screenHeight;
|
|
imageWidth /= ratio;
|
|
imageHeight /= ratio;
|
|
}
|
|
|
|
image.css(
|
|
{
|
|
'width': imageWidth + 'px',
|
|
'height': imageHeight + 'px',
|
|
'top': ( $( window ).height() - imageHeight ) / 2 + 'px',
|
|
'left': ( $( window ).width() - imageWidth ) / 2 + 'px'
|
|
});
|
|
};
|
|
},
|
|
|
|
loadImage = function( direction )
|
|
{
|
|
if( inProgress ) return false;
|
|
|
|
direction = typeof direction === 'undefined' ? false : direction == 'left' ? 1 : -1;
|
|
|
|
if( image.length )
|
|
{
|
|
if( direction !== false && ( targets.length < 2 || ( options.quitOnEnd === true && ( ( direction === -1 && targets.index( target ) == 0 ) || ( direction === 1 && targets.index( target ) == targets.length - 1 ) ) ) ) )
|
|
{
|
|
quitLightbox();
|
|
return false;
|
|
}
|
|
var params = { 'opacity': 0 };
|
|
if( isCssTransitionSupport ) cssTransitionTranslateX( image, ( 100 * direction ) - swipeDiff + 'px', options.animationSpeed / 1000 );
|
|
else params.left = parseInt( image.css( 'left' ) ) + 100 * direction + 'px';
|
|
image.animate( params, options.animationSpeed, function(){ removeImage(); });
|
|
swipeDiff = 0;
|
|
}
|
|
|
|
inProgress = true;
|
|
if( options.onLoadStart !== false ) options.onLoadStart();
|
|
|
|
setTimeout( function()
|
|
{
|
|
image = $( '<img ' + options.selector + ' />' )
|
|
.attr( 'src', target.attr( 'href' ) )
|
|
.load( function()
|
|
{
|
|
image.appendTo( 'body' );
|
|
setImage();
|
|
|
|
var params = { 'opacity': 1 };
|
|
|
|
image.css( 'opacity', 0 );
|
|
if( isCssTransitionSupport )
|
|
{
|
|
cssTransitionTranslateX( image, -100 * direction + 'px', 0 );
|
|
setTimeout( function(){ cssTransitionTranslateX( image, 0 + 'px', options.animationSpeed / 1000 ) }, 50 );
|
|
}
|
|
else
|
|
{
|
|
var imagePosLeft = parseInt( image.css( 'left' ) );
|
|
params.left = imagePosLeft + 'px';
|
|
image.css( 'left', imagePosLeft - 100 * direction + 'px' );
|
|
}
|
|
|
|
image.animate( params, options.animationSpeed, function()
|
|
{
|
|
inProgress = false;
|
|
if( options.onLoadEnd !== false ) options.onLoadEnd();
|
|
});
|
|
if( options.preloadNext )
|
|
{
|
|
var nextTarget = targets.eq( targets.index( target ) + 1 );
|
|
if( !nextTarget.length ) nextTarget = targets.eq( 0 );
|
|
$( '<img />' ).attr( 'src', nextTarget.attr( 'href' ) ).load();
|
|
}
|
|
})
|
|
.error( function()
|
|
{
|
|
if( options.onLoadEnd !== false ) options.onLoadEnd();
|
|
})
|
|
|
|
var swipeStart = 0,
|
|
swipeEnd = 0,
|
|
imagePosLeft = 0;
|
|
|
|
image.on( hasPointers ? 'pointerup MSPointerUp' : 'click', function( e )
|
|
{
|
|
e.preventDefault();
|
|
if( options.quitOnImgClick )
|
|
{
|
|
quitLightbox();
|
|
return false;
|
|
}
|
|
if( wasTouched( e.originalEvent ) ) return true;
|
|
var posX = ( e.pageX || e.originalEvent.pageX ) - e.target.offsetLeft;
|
|
target = targets.eq( targets.index( target ) - ( imageWidth / 2 > posX ? 1 : -1 ) );
|
|
if( !target.length ) target = targets.eq( imageWidth / 2 > posX ? targets.length : 0 );
|
|
loadImage( imageWidth / 2 > posX ? 'left' : 'right' );
|
|
})
|
|
.on( 'touchstart pointerdown MSPointerDown', function( e )
|
|
{
|
|
if( !wasTouched( e.originalEvent ) || options.quitOnImgClick ) return true;
|
|
if( isCssTransitionSupport ) imagePosLeft = parseInt( image.css( 'left' ) );
|
|
swipeStart = e.originalEvent.pageX || e.originalEvent.touches[ 0 ].pageX;
|
|
})
|
|
.on( 'touchmove pointermove MSPointerMove', function( e )
|
|
{
|
|
if( !wasTouched( e.originalEvent ) || options.quitOnImgClick ) return true;
|
|
e.preventDefault();
|
|
swipeEnd = e.originalEvent.pageX || e.originalEvent.touches[ 0 ].pageX;
|
|
swipeDiff = swipeStart - swipeEnd;
|
|
if( isCssTransitionSupport ) cssTransitionTranslateX( image, -swipeDiff + 'px', 0 );
|
|
else image.css( 'left', imagePosLeft - swipeDiff + 'px' );
|
|
})
|
|
.on( 'touchend touchcancel pointerup pointercancel MSPointerUp MSPointerCancel', function( e )
|
|
{
|
|
if( !wasTouched( e.originalEvent ) || options.quitOnImgClick ) return true;
|
|
if( Math.abs( swipeDiff ) > 50 )
|
|
{
|
|
target = targets.eq( targets.index( target ) - ( swipeDiff < 0 ? 1 : -1 ) );
|
|
if( !target.length ) target = targets.eq( swipeDiff < 0 ? targets.length : 0 );
|
|
loadImage( swipeDiff > 0 ? 'right' : 'left' );
|
|
}
|
|
else
|
|
{
|
|
if( isCssTransitionSupport ) cssTransitionTranslateX( image, 0 + 'px', options.animationSpeed / 1000 );
|
|
else image.animate({ 'left': imagePosLeft + 'px' }, options.animationSpeed / 2 );
|
|
}
|
|
});
|
|
|
|
}, options.animationSpeed + 100 );
|
|
},
|
|
|
|
removeImage = function()
|
|
{
|
|
if( !image.length ) return false;
|
|
image.remove();
|
|
image = $();
|
|
},
|
|
|
|
quitLightbox = function()
|
|
{
|
|
if( !image.length ) return false;
|
|
image.animate({ 'opacity': 0 }, options.animationSpeed, function()
|
|
{
|
|
removeImage();
|
|
inProgress = false;
|
|
if( options.onEnd !== false ) options.onEnd();
|
|
});
|
|
};
|
|
|
|
$( window ).on( 'resize', setImage );
|
|
|
|
if( options.quitOnDocClick )
|
|
{
|
|
$( document ).on( hasTouch ? 'touchend' : 'click', function( e )
|
|
{
|
|
if( image.length && !$( e.target ).is( image ) ) quitLightbox();
|
|
})
|
|
}
|
|
|
|
if( options.enableKeyboard )
|
|
{
|
|
$( document ).on( 'keyup', function( e )
|
|
{
|
|
if( !image.length ) return true;
|
|
e.preventDefault();
|
|
if( e.keyCode == 27 ) quitLightbox();
|
|
if( e.keyCode == 37 || e.keyCode == 39 )
|
|
{
|
|
target = targets.eq( targets.index( target ) - ( e.keyCode == 37 ? 1 : -1 ) );
|
|
if( !target.length ) target = targets.eq( e.keyCode == 37 ? targets.length : 0 );
|
|
loadImage( e.keyCode == 37 ? 'left' : 'right' );
|
|
}
|
|
});
|
|
}
|
|
|
|
$( document ).on( 'click', this.selector, function( e )
|
|
{
|
|
if( !isTargetValid( this ) ) return true;
|
|
e.preventDefault();
|
|
if( inProgress ) return false;
|
|
inProgress = false;
|
|
if( options.onStart !== false ) options.onStart();
|
|
target = $( this );
|
|
loadImage();
|
|
});
|
|
|
|
this.each( function()
|
|
{
|
|
if( !isTargetValid( this ) ) return true;
|
|
targets = targets.add( $( this ) );
|
|
});
|
|
|
|
this.switchImageLightbox = function( index )
|
|
{
|
|
var tmpTarget = targets.eq( index );
|
|
if( tmpTarget.length )
|
|
{
|
|
var currentIndex = targets.index( target );
|
|
target = tmpTarget;
|
|
loadImage( index < currentIndex ? 'left' : 'right' );
|
|
}
|
|
return this;
|
|
};
|
|
|
|
this.quitImageLightbox = function()
|
|
{
|
|
quitLightbox();
|
|
return this;
|
|
};
|
|
|
|
return this;
|
|
};
|
|
})( jQuery, window, document );
|