Skip to content

Instantly share code, notes, and snippets.

@cescoferraro
Created November 10, 2015 02:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cescoferraro/63e0d96b6e3f396d8347 to your computer and use it in GitHub Desktop.
Save cescoferraro/63e0d96b6e3f396d8347 to your computer and use it in GitHub Desktop.
Photoswipe
<h1>PhotoSwipe using jQuery for responsive images</h1>
<h2>First gallery:</h2>
<div class="lightbox clearfix">
<figure>
<a alt-src="http://placehold.it/1024x1024" data-large="http://placehold.it/1024x1024" data-large-size="1024x1024" data-medium="http://placehold.it/400x400" data-medium-size="400x400" data-small="http://placehold.it/200x200" data-small-size="200x200">
<img src="http://placehold.it/200x200" alt="" />
<figcaption>This is dummy figcaption 1.</figcaption>
</a>
</figure>
<figure>
<a alt-src="http://placehold.it/1024x768" data-large="http://placehold.it/1024x768" data-large-size="1024x768" data-medium="http://placehold.it/400x300" data-medium-size="400x300" data-small="http://placehold.it/200x150" data-small-size="200x150">
<img src="http://placehold.it/200x150" alt="" />
<figcaption>This is dummy figcaption 2.</figcaption>
</a>
</figure>
<figure>
<a alt-src="http://placehold.it/768x1024" data-large="http://placehold.it/768x1024" data-large-size="768x1024" data-medium="http://placehold.it/300x400" data-medium-size="300x400" data-small="http://placehold.it/150x200" data-small-size="150x200">
<img src="http://placehold.it/150x200" alt="" />
<figcaption>This is dummy figcaption 3.</figcaption>
</a>
</figure>
</div>
<h2>Second gallery:</h2>
<div class="lightbox clearfix">
<figure>
<a alt-src="http://placehold.it/1024x1024/eee" data-large="http://placehold.it/1024x1024/eee" data-large-size="1024x1024" data-medium="http://placehold.it/400x400/eee" data-medium-size="400x400" data-small="http://placehold.it/200x200/eee" data-small-size="200x200">
<img src="http://placehold.it/200x200/eee" alt="" />
<figcaption>This is dummy figcaption 1.</figcaption>
</a>
</figure>
<figure>
<a alt-src="http://placehold.it/1024x768/eee" data-large="http://placehold.it/1024x768/eee" data-large-size="1024x768" data-medium="http://placehold.it/400x300/eee" data-medium-size="400x300" data-small="http://placehold.it/200x150/eee" data-small-size="200x150">
<img src="http://placehold.it/200x150/eee" alt="" />
<figcaption>This is dummy figcaption 2.</figcaption>
</a>
</figure>
<figure>
<a alt-src="http://placehold.it/768x1024/eee" data-large="http://placehold.it/768x1024/eee" data-large-size="768x1024" data-medium="http://placehold.it/300x400/eee" data-medium-size="300x400" data-small="http://placehold.it/150x200/eee" data-small-size="150x200">
<img src="http://placehold.it/150x200/eee" alt="" />
<figcaption>This is dummy figcaption 3.</figcaption>
</a>
</figure>
</div>
<a href="http://photoswipe.com">PhotoSwipe homepage</a>
<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
<!-- Background of PhotoSwipe. It's a separate element, as animating opacity is faster than rgba(). -->
<div class="pswp__bg"></div>
<!-- Slides wrapper with overflow:hidden. -->
<div class="pswp__scroll-wrap">
<!-- Container that holds slides. PhotoSwipe keeps only 3 slides in DOM to save memory. -->
<div class="pswp__container">
<!-- don't modify these 3 pswp__item elements, data is added later on -->
<div class="pswp__item"></div>
<div class="pswp__item"></div>
<div class="pswp__item"></div>
</div>
<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
<div class="pswp__ui pswp__ui--hidden">
<div class="pswp__top-bar">
<!-- Controls are self-explanatory. Order can be changed. -->
<div class="pswp__counter"></div>
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
<button class="pswp__button pswp__button--share" title="Share"></button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
<!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
<!-- element will get class pswp__preloader--active when preloader is running -->
<div class="pswp__preloader">
<div class="pswp__preloader__icn">
<div class="pswp__preloader__cut">
<div class="pswp__preloader__donut"></div>
</div>
</div>
</div>
</div>
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class="pswp__share-tooltip"></div>
</div>
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)"> </button>
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)"> </button>
<div class="pswp__caption">
<div class="pswp__caption__center"></div>
</div>
</div>
</div>
</div>
// PhotoSwipe (http://photoswipe.com) using Jquery to handle responsive images.
// This pen is "as is" and experimental, and probably still needs some work, so feel free to suggest edits.
// Original jquery version code by @kshnurov - https://gist.github.com/kshnurov/8b175b8798d4a907e47b
// See https://github.com/dimsemenov/PhotoSwipe/issues/771 for issue.
// Help from Paulius Friedt to handle responsive images.
(function($) {
$.fn.photoswipe = function(options) {
var galleries = [],
_options = options;
var parseImage = function($link, size) {
var sizeItem;
if ($link.attr('data-' + size) != 'undefined' && $link.attr('data-' + size + '-size') != 'undefined') {
var imageSize = $link.data(size + '-size').split('x');
if (imageSize.length != 2) {
throw SyntaxError("Missing data-size attribute.");
}
sizeItem = {
src: $link.data(size),
w: parseInt(imageSize[0], 10),
h: parseInt(imageSize[1], 10)
}
} else {
throw SyntaxError("Missing data-* attributes for " + size);
}
return sizeItem;
}
var init = function($this) {
galleries = [];
$this.each(function(i, gallery) {
galleries.push({
id: i,
items: []
});
$(gallery).find('a').each(function(k, link) {
var $link = $(link);
$link.data('gallery-id', i + 1);
$link.data('photo-id', k);
var item = {
src: link.href,
msrc: link.children[0].getAttribute('alt-src'),
// title: $link.data('title'), // for captions using data-title attribute, add data-title="The caption", uncomment this line and comment line below
title: $link.children('figcaption').text(),
el: link,
smallImage: parseImage($link, 'small'),
mediumImage: parseImage($link, 'medium'),
largeImage: parseImage($link, 'large')
}
galleries[i].items.push(item);
});
$(gallery).on('click', 'a', function(e) {
e.preventDefault();
var gid = $(this).data('gallery-id'),
pid = $(this).data('photo-id');
openGallery(gid, pid);
});
});
}
var parseHash = function() {
var hash = window.location.hash.substring(1),
params = {};
if (hash.length < 5) {
return params;
}
var vars = hash.split('&');
for (var i = 0; i < vars.length; i++) {
if (!vars[i]) {
continue;
}
var pair = vars[i].split('=');
if (pair.length < 2) {
continue;
}
params[pair[0]] = pair[1];
}
if (params.gid) {
params.gid = parseInt(params.gid, 10);
}
if (!params.hasOwnProperty('pid')) {
return params;
}
params.pid = parseInt(params.pid, 10);
return params;
};
var openGallery = function(gid, pid) {
var pswpElement = document.querySelectorAll('.pswp')[0],
items = galleries[gid - 1].items,
options = {
index: pid,
galleryUID: gid,
getThumbBoundsFn: function(index) {
var thumbnail = items[index].el.children[0],
pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
rect = thumbnail.getBoundingClientRect();
return {
x: rect.left,
y: rect.top + pageYScroll,
w: rect.width
};
}
};
$.extend(options, _options);
var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options);
// create variable that will store real size of viewport
var realViewportWidth,
useImageSize = 'large',
firstResize = true,
imageSrcWillChange;
// beforeResize event fires each time size of gallery viewport updates
gallery.listen('beforeResize', function() {
// calculate real pixels when size changes
// realViewportWidth = gallery.viewportSize.x * window.devicePixelRatio;
realViewportWidth = gallery.viewportSize.x;
// Code below is needed if you want image to switch dynamically on window.resize
// Find out if current images need to be changed
if (useImageSize != 'small' && realViewportWidth < gallery.options.breakpoints.medium) {
useImageSize = 'small';
imageSrcWillChange = true;
} else if (useImageSize != 'medium' && (realViewportWidth >= gallery.options.breakpoints.medium && realViewportWidth < gallery.options.breakpoints.large)) {
useImageSize = 'medium';
imageSrcWillChange = true;
} else if (useImageSize != 'large' && realViewportWidth >= gallery.options.breakpoints.large) {
useImageSize = 'large';
imageSrcWillChange = true;
}
// Invalidate items only when source is changed and when it's not the first update
if (imageSrcWillChange && !firstResize) {
// invalidateCurrItems sets a flag on slides that are in DOM, which will force update of content (image) on window.resize.
gallery.invalidateCurrItems();
}
if (firstResize) {
firstResize = false;
}
imageSrcWillChange = false;
});
// gettingData event fires each time PhotoSwipe retrieves image source & size
gallery.listen('gettingData', function(index, item) {
// Set image source & size based on real viewport width
if (useImageSize == 'large') {
item.src = item.largeImage.src;
item.w = item.largeImage.w;
item.h = item.largeImage.h;
} else if (useImageSize == 'medium') {
item.src = item.mediumImage.src;
item.w = item.mediumImage.w;
item.h = item.mediumImage.h;
} else if (useImageSize == 'small') {
item.src = item.smallImage.src;
item.w = item.smallImage.w;
item.h = item.smallImage.h;
}
// It doesn't really matter what will you do here, as long as item.src, item.w and item.h have valid values. Just avoid http requests in this listener, as it fires quite often
});
gallery.init();
}
// initialize
init(this);
// Parse URL and open gallery if it contains #&pid=3&gid=1
var hashData = parseHash();
if (hashData.pid > 0 && hashData.gid > 0) {
openGallery(hashData.gid, hashData.pid);
}
return this;
};
}(jQuery));
// init
$('.lightbox').photoswipe({
// image breakpoint options
breakpoints: { // small images are below the medium breakpoint
medium: 480, // medium sizes above this
large: 767 // large sizes above this
},
// options
bgOpacity: 0.9,
loop: true,
history: false
});
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="http://photoswipe.s3-eu-west-1.amazonaws.com/pswp/dist/photoswipe.min.js"></script>
<script src="http://photoswipe.s3-eu-west-1.amazonaws.com/pswp/dist/photoswipe-ui-default.min.js"></script>
figure {
float: left;
margin: 10px;
}
.clearfix:before,
.clearfix:after { content: " "; display: table; }
.clearfix:after { clear: both; }
.clearfix { *zoom: 1; }
<link href="http://photoswipe.s3.amazonaws.com/pswp/dist/photoswipe.css" rel="stylesheet" />
<link href="http://photoswipe.s3.amazonaws.com/pswp/dist/default-skin/default-skin.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment