Skip to content

Instantly share code, notes, and snippets.

@alrnz
Last active May 8, 2019 08:46
Show Gist options
  • Save alrnz/1999802ce08db87ab01b to your computer and use it in GitHub Desktop.
Save alrnz/1999802ce08db87ab01b to your computer and use it in GitHub Desktop.
Responsive Touch Lightbox #JS #Lightbox
/*
By Osvaldas Valutis, www.osvaldas.info
Available for use under the MIT License
*/
;(function(e,t,n,r){"use strict";var i=function(){var e=n.body||n.documentElement,e=e.style;if(e.WebkitTransition=="")return"-webkit-";if(e.MozTransition=="")return"-moz-";if(e.OTransition=="")return"-o-";if(e.transition=="")return"";return false},s=i()===false?false:true,o=function(e,t,n){var r={},s=i();r[s+"transform"]="translateX("+t+")";r[s+"transition"]=s+"transform "+n+"s linear";e.css(r)},u="ontouchstart"in t,a=t.navigator.pointerEnabled||t.navigator.msPointerEnabled,f=function(e){if(u)return true;if(!a||typeof e==="undefined"||typeof e.pointerType==="undefined")return false;if(typeof e.MSPOINTER_TYPE_MOUSE!=="undefined"){if(e.MSPOINTER_TYPE_MOUSE!=e.pointerType)return true}else if(e.pointerType!="mouse")return true;return false};e.fn.imageLightbox=function(r){var r=e.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},r),i=e([]),l=e(),c=e(),h=0,p=0,d=0,v=false,m=function(t){return e(t).prop("tagName").toLowerCase()=="a"&&(new RegExp(".("+r.allowedTypes+")$","i")).test(e(t).attr("href"))},g=function(){if(!c.length)return true;var n=e(t).width()*.8,r=e(t).height()*.9,i=new Image;i.src=c.attr("src");i.onload=function(){h=i.width;p=i.height;if(h>n||p>r){var s=h/p>n/r?h/n:p/r;h/=s;p/=s}c.css({width:h+"px",height:p+"px",top:(e(t).height()-p)/2+"px",left:(e(t).width()-h)/2+"px"})}},y=function(t){if(v)return false;t=typeof t==="undefined"?false:t=="left"?1:-1;if(c.length){if(t!==false&&(i.length<2||r.quitOnEnd===true&&(t===-1&&i.index(l)==0||t===1&&i.index(l)==i.length-1))){w();return false}var n={opacity:0};if(s)o(c,100*t-d+"px",r.animationSpeed/1e3);else n.left=parseInt(c.css("left"))+100*t+"px";c.animate(n,r.animationSpeed,function(){b()});d=0}v=true;if(r.onLoadStart!==false)r.onLoadStart();setTimeout(function(){c=e("<img "+r.selector+" />").attr("src",l.attr("href")).load(function(){c.appendTo("body");g();var n={opacity:1};c.css("opacity",0);if(s){o(c,-100*t+"px",0);setTimeout(function(){o(c,0+"px",r.animationSpeed/1e3)},50)}else{var u=parseInt(c.css("left"));n.left=u+"px";c.css("left",u-100*t+"px")}c.animate(n,r.animationSpeed,function(){v=false;if(r.onLoadEnd!==false)r.onLoadEnd()});if(r.preloadNext){var a=i.eq(i.index(l)+1);if(!a.length)a=i.eq(0);e("<img />").attr("src",a.attr("href")).load()}}).error(function(){if(r.onLoadEnd!==false)r.onLoadEnd()});var n=0,u=0,p=0;c.on(a?"pointerup MSPointerUp":"click",function(e){e.preventDefault();if(r.quitOnImgClick){w();return false}if(f(e.originalEvent))return true;var t=(e.pageX||e.originalEvent.pageX)-e.target.offsetLeft;l=i.eq(i.index(l)-(h/2>t?1:-1));if(!l.length)l=i.eq(h/2>t?i.length:0);y(h/2>t?"left":"right")}).on("touchstart pointerdown MSPointerDown",function(e){if(!f(e.originalEvent)||r.quitOnImgClick)return true;if(s)p=parseInt(c.css("left"));n=e.originalEvent.pageX||e.originalEvent.touches[0].pageX}).on("touchmove pointermove MSPointerMove",function(e){if(!f(e.originalEvent)||r.quitOnImgClick)return true;e.preventDefault();u=e.originalEvent.pageX||e.originalEvent.touches[0].pageX;d=n-u;if(s)o(c,-d+"px",0);else c.css("left",p-d+"px")}).on("touchend touchcancel pointerup pointercancel MSPointerUp MSPointerCancel",function(e){if(!f(e.originalEvent)||r.quitOnImgClick)return true;if(Math.abs(d)>50){l=i.eq(i.index(l)-(d<0?1:-1));if(!l.length)l=i.eq(d<0?i.length:0);y(d>0?"right":"left")}else{if(s)o(c,0+"px",r.animationSpeed/1e3);else c.animate({left:p+"px"},r.animationSpeed/2)}})},r.animationSpeed+100)},b=function(){if(!c.length)return false;c.remove();c=e()},w=function(){if(!c.length)return false;c.animate({opacity:0},r.animationSpeed,function(){b();v=false;if(r.onEnd!==false)r.onEnd()})};e(t).on("resize",g);if(r.quitOnDocClick){e(n).on(u?"touchend":"click",function(t){if(c.length&&!e(t.target).is(c))w()})}if(r.enableKeyboard){e(n).on("keyup",function(e){if(!c.length)return true;e.preventDefault();if(e.keyCode==27)w();if(e.keyCode==37||e.keyCode==39){l=i.eq(i.index(l)-(e.keyCode==37?1:-1));if(!l.length)l=i.eq(e.keyCode==37?i.length:0);y(e.keyCode==37?"left":"right")}})}e(n).on("click",this.selector,function(t){if(!m(this))return true;t.preventDefault();if(v)return false;v=false;if(r.onStart!==false)r.onStart();l=e(this);y()});this.each(function(){if(!m(this))return true;i=i.add(e(this))});this.switchImageLightbox=function(e){var t=i.eq(e);if(t.length){var n=i.index(l);l=t;y(e<n?"left":"right")}return this};this.quitImageLightbox=function(){w();return this};return this}})(jQuery,window,document);
HTML
<a href="/img/pic.jpg" class="lightbox">
<ima src="/img/pic.jpg"/>
</a>
HTML with caption
<a href="/img/pic.jpg" class="lightbox withCaption">
<ima src="/img/pic.jpg"/>
</a>
Fluid
<a href="{f:uri.image(src: '{story.file1}' minWidth: 400, maxWidth: 1000)}" class="lightbox">
<f:image src="{story.file1}" alt=""/>
</a>
jQuery(document).ready(function () {
initLightbox();
});
function initLightbox() {
var lightBoxSelector = '.lightbox';
var lightBox = $(lightBoxSelector).imageLightbox({
//selector: 'class="lightbox"', // string;
allowedTypes: 'png|jpg|jpeg|gif', // string;
animationSpeed: 250, // integer;
preloadNext: true, // bool; silently preload the next image
enableKeyboard: true, // bool; enable keyboard shortcuts (arrows Left/Right and Esc)
quitOnEnd: false, // bool; quit after viewing the last image
quitOnImgClick: false, // bool; quit when the viewed image is clicked
quitOnDocClick: true, // bool; quit when anything but the viewed image is clicked
onStart: function () {
arrowsOn(lightBox, lightBoxSelector);
overlayOn();
closeButtonOn( lightBox );
},
onEnd: function () {
arrowsOff();
overlayOff();
closeButtonOff();
activityIndicatorOff();
if(lightBox.hasClass("withCaption")){
captionOff();
}
},
onLoadStart: function () {
activityIndicatorOn();
if(lightBox.hasClass("withCaption")){
captionOff();
}
},
onLoadEnd: function () {
$('.imagelightbox-arrow').css('display', 'block');
activityIndicatorOff();
if(lightBox.hasClass("withCaption")){
captionOn();
}
}
});
// ARROWS
var activityIndicatorOn = function () {
$('<div id="imagelightbox-loading"><div></div></div>').appendTo('body');
},
activityIndicatorOff = function () {
$('#imagelightbox-loading').remove();
},
arrowsOn = function (instance, selector) {
var $arrows = $('<button type="button" class="imagelightbox-arrow imagelightbox-arrow-left"></button><button type="button" class="imagelightbox-arrow imagelightbox-arrow-right"></button>');
$arrows.appendTo('body');
$arrows.on('click touchend', function (e) {
e.preventDefault();
var $this = $(this),
$target = $(selector + '[href="' + $('#imagelightbox').attr('src') + '"]'),
index = $target.index(selector);
if ($this.hasClass('imagelightbox-arrow-left')) {
index = index - 1;
if (!$(selector).eq(index).length) {
index = $(selector).length;
}
} else {
index = index + 1;
if (!$(selector).eq(index).length) {
index = 0;
}
}
instance.switchImageLightbox(index);
return false;
});
},
arrowsOff = function () {
$('.imagelightbox-arrow').remove();
},
// OVERLAY
overlayOn = function () {
$('<div id="imagelightbox-overlay"></div>').appendTo('body');
},
overlayOff = function () {
$('#imagelightbox-overlay').remove();
},
// CLOSE BUTTON
closeButtonOn = function (instance) {
$('<button type="button" id="imagelightbox-close" title="Close"></button>').appendTo('body').on('click touchend', function () {
$(this).remove();
instance.quitImageLightbox();
return false;
});
},
closeButtonOff = function () {
$('#imagelightbox-close').remove();
},
// CAPTION
captionOn = function()
{
var description = $( 'a[href="' + $( '#imagelightbox' ).attr( 'src' ) + '"] img' ).attr( 'alt' );
if( description.length > 0 )
$( '<div id="imagelightbox-caption">' + description + '</div>' ).appendTo( 'body' );
},
captionOff = function()
{
$( '#imagelightbox-caption' ).remove();
};
}
#imagelightbox {
position: fixed;
z-index: 9999;
-ms-touch-action: none;
touch-action: none;
cursor: pointer;
-webkit-box-shadow: 0 0 3.125em rgba(0, 0, 0, 0.75);
box-shadow: 0 0 3.125em rgba(0, 0, 0, 0.75);
background: #fff;
border: 5px solid #fff;
}
/* ARROWS */
.imagelightbox-arrow
{
width: 3.75em; /* 60 */
height: 7.5em; /* 120 */
background-color: #444;
background-color: rgba( 0, 0, 0, .5 );
vertical-align: middle;
display: none;
position: fixed;
z-index: 10001;
top: 50%;
margin-top: -3.75em; /* 60 */
border: none;
}
.imagelightbox-arrow:hover,
.imagelightbox-arrow:focus
{
background-color: #666;
background-color: rgba( 0, 0, 0, .75 );
}
.imagelightbox-arrow:active
{
background-color: #111;
}
.imagelightbox-arrow-left
{
left: 2.5em; /* 40 */
}
.imagelightbox-arrow-right
{
right: 2.5em; /* 40 */
}
.imagelightbox-arrow:before
{
width: 0;
height: 0;
border: 1em solid transparent;
content: '';
display: inline-block;
margin-bottom: -0.125em; /* 2 */
}
.imagelightbox-arrow-left:before
{
border-left: none;
border-right-color: #fff;
margin-left: -0.313em; /* 5 */
}
.imagelightbox-arrow-right:before
{
border-right: none;
border-left-color: #fff;
margin-right: -0.313em; /* 5 */
}
#imagelightbox-loading,
#imagelightbox-overlay,
#imagelightbox-close,
#imagelightbox-caption,
#imagelightbox-nav,
.imagelightbox-arrow
{
-webkit-animation: fade-in .25s linear;
animation: fade-in .25s linear;
}
/* CAPTION */
#imagelightbox-caption
{
text-align: center;
color: #fff;
background-color: #666;
position: fixed;
z-index: 10001;
left: 0;
right: 0;
bottom: 0;
padding: 0.625em; /* 10 */
}
@-webkit-keyframes fade-in
{
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fade-in
{
from { opacity: 0; }
to { opacity: 1; }
}
@media only screen and (max-width: 41.250em) /* 660 */
{
.imagelightbox-arrow
{
width: 2.5em; /* 40 */
height: 3.75em; /* 60 */
margin-top: -2.75em; /* 30 */
}
.imagelightbox-arrow-left
{
left: 1.25em; /* 20 */
}
.imagelightbox-arrow-right
{
right: 1.25em; /* 20 */
}
}
@media only screen and (max-width: 20em) /* 320 */
{
.imagelightbox-arrow-left
{
left: 0;
}
.imagelightbox-arrow-right
{
right: 0;
}
}
/* OVERLAY */
#imagelightbox-overlay
{
background-color: #fff;
background-color: rgba( 255, 255, 255, .9 );
position: fixed;
z-index: 9999;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
/* "CLOSE" BUTTON */
#imagelightbox-close
{
width: 2.5em; /* 40 */
height: 2.5em; /* 40 */
text-align: left;
background-color: #666;
border-radius: 50%;
position: fixed;
z-index: 10003;
top: 2.5em; /* 40 */
right: 2.5em; /* 40 */
-webkit-transition: color .3s ease;
transition: color .3s ease;
}
#imagelightbox-close:hover,
#imagelightbox-close:focus
{
background-color: #111;
}
#imagelightbox-close:before,
#imagelightbox-close:after
{
width: 2px;
background-color: #fff;
content: '';
position: absolute;
top: 20%;
bottom: 20%;
left: 50%;
margin-left: -1px;
}
#imagelightbox-close:before
{
-webkit-transform: rotate( 45deg );
-ms-transform: rotate( 45deg );
transform: rotate( 45deg );
}
#imagelightbox-close:after
{
-webkit-transform: rotate( -45deg );
-ms-transform: rotate( -45deg );
transform: rotate( -45deg );
}
@alrnz
Copy link
Author

alrnz commented Nov 11, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment