Open thriveweb opened 8 years ago
Thanks for looking into this. I plan on doing some plugin updates over Christmas!
no probs... I've hacked a version that works for me, in the theme adding a psgal class to the body for the post types where I want to enable this feature and a new version of photoswipe-masonry.js (dequeueing the plugin version and queuing a theme version).
In this case I allow swipe-through of all linked images and galleries on the page, which might not be what everyone wants - to add to the plugin it should tie in with some options that could be set on the plug-in to control the behaviour.
If you've got any thoughts on how that should be done I'll take a quick look, otherwise I'll post the revise js up here when I've soak-tested it a bit more.
Hi, I put this live over the weekend on a chinese art website, it seems to be working fine. There were a few more issues and ideas on the way which I will report separately.
Note, in this implementation:
Steps taken were: 1) in the theme:
2) one tiny hack to the plugin detailed on https://github.com/thriveweb/photoswipe-masonry/issues/13
3) the new .js, which is somewhat some fault tolerant, so it only applies to links which contain both an image and an href to an image, and also assume the zoomed image will be the same ratio as the small image if no size detail is set...
jQuery(function($) {
photoswipe_masonry($);
});
var photoswipe_masonry = function($){
var $pswp = $('.pswp')[0];
var image = [];
/////////////////////////////////////////////////////////////////////////////////////////////
// Gallery
//in this case the psgal class is actually on the <body>
//so only the first gallery is used to swipe through all the images
//If you want separate galleries within article gallery of images in the text,
//then you need to decide how to handle nested galleries and image index numbers
var $psgal = $('.psgal').first();
$galleryUID = $psgal.attr('id');
if (undefined===$galleryUID) {
$psgal.attr('id', 'psgalmain');
$galleryUID = 'psgalmain';
}
getItems = function() {
var items = [];
$psgal.find('a').each(function() {
//only if the link actually contains an image
var $img = $(this).find('img').first();
if ($img.length){
var $href = $(this).attr('href');
var $ext = $href.split('.').pop();
switch($ext) {
case "jpg":
case "png":
case "jpeg":
//default src width and height: TODO: alternative way of getting real dimensions if size missing
var $width = 1800;
var $height = 1800;
var $size = $(this).attr('data-size');
if ($size){
$size=$size.split('x');
if ($size.length>1){
$width = $size[0];
$height = $size[1];
}
}
else{
//if no saved size, use the ratio of the small image as basis for calculation..
//..works great for images within an article
var $imgWidth = $img.attr('width');
var $imgHeight = $img.attr('height');
try {
$height=$width*$imgHeight/$imgWidth;
}
catch(e){}
}
//ADDED: set item photoswipe index to avoid recalculating it later
$(this).attr('data-psindex', items.length);
var item = {
src : $href,
w : $width,
h : $height,
el : $(this),
msrc : $img.attr('src'),
title : $(this).attr('data-caption')
}
items.push(item);
break;
default:
//If the link is to a separate document, don't use the photoswipe
//(unless the photoswipe supports popup pages not just images
// - actually http://photoswipe.com/ does support html in the gallery,
// that could be a cool enhancement late..)
}
}
});
return items;
}
var items = getItems();
$.each(items, function(index, value) {
image[index] = new Image();
image[index].src = value['src'];
});
$psgal.on('click', 'a[data-psindex]', function(event) {
event.preventDefault();
var $index = 0;
try{
$index=Number($(this).attr('data-psindex'));
}
catch(e){
}
var options = {
index: $index,
bgOpacity: 0.9,
showHideOpacity: false,
galleryUID: $galleryUID,
getThumbBoundsFn: function(index) {
var image = items[index].el.find('img'),
offset = image.offset();
return {x:offset.left, y:offset.top, w:image.width()};
}
}
var lightBox = new PhotoSwipe($pswp, PhotoSwipeUI_Default, items, options);
lightBox.init();
});
/////////////////////////////////////////////////////////////////////////////////////////////
// Parse URL and open gallery if it contains #&pid=3&gid=1
var hashData = parseHash();
if(hashData.gid) {
$('#' + hashData.gid).each( function() {
$index=Number(hashData.pid);
try{
}
catch(e){
}
var options = {
index: $index,
bgOpacity: 0.9,
showHideOpacity: false,
galleryUID: hashData.gid,
getThumbBoundsFn: function(index) {
var image = items[index].el.find('img'),
offset = image.offset();
return {x:offset.left, y:offset.top, w:image.width()};
}
}
var lightBox = new PhotoSwipe($pswp, PhotoSwipeUI_Default, items, options);
lightBox.init();
});
}
};
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];
}
params.pid = parseInt(params.pid, 10);
return params;
};
Disclaimer: this isn't perfect and might not suit everyone but it does work and I'm out of time for further improvements for now.
Thanks for posting this, I will try it out soon!
Following up on my disclaimer, a specific limitation on not setting the size attributes is that if your small image is square but your full size image is a different shape you will get distortions... typically this doesn't happen with medium sized images, as the shape of the thumbnail is the same as the large image, and with shops that use square images not a problem. Even then there could be a solution, to unset the height once the large image has loaded so the browser can resize the image to the correct proportional height for the current width.
Actually it seems about there with almost no code changes, e.g. the photoswipe will work on any images and text inside a container element of class="psgal" Testing both this and an actual image gallery, it supports both on the same page.
However at the moment the relevant code section: $('.psgal').each( function() { [in photoswipe-masonry.js] isn’t error tolerant and will fail if there is any link which doesn’t include a data attribute with a size element as per <a data-size="1280x1280" [These attributes are added by the plugin at save-time but obviously don’t apply to links which don’t contain images for example, or posts that were saved when the plugin was not activated.]
So to make the Photoswipe more flexible we could do the following:
check for existence of image
use image width and height if available rather than relying on data-size property
skip links with a picture which do not link TO an image (a weakness in the current single_photoswipe: if the picture has been added as a link to custom url, photowipe zooms in and then shows an error as the custom url is not a picture “The image could not be loaded.” (thankfully it does include the link to the image).
the coding for single_photoswipe would then not be necessary, since all image links will get the photoswipe. Perhaps an option could be enabled for those who really want the single photo with no-swipe photoswipe..