Yesterday, and for about an hour today, I worked on using a responsive, zoomable, mobile-friendly solution for displaying photos without constantly loading all the photos from the DB every time a single photo is shown.
It was actually done yesterday at 8 in the evening, but it had one bug – when you shared a page with, say, pid (Photo ID) 1 and someone clicked on it, the photo with pid 0 loaded automatically – in other words, the previous one.
That is fixed now. But another problem remains – I couldn’t get it to work so that when a user closes a photo and picks another one, it opens in the same tab. It simply opens a new tab.
That’s not all, though. When the user closes the photo in the new tab, the gid and pid hash parameters don’t disappear from the address – so if they don’t notice and send this link to someone, the recipient sees the photo they last viewed in this album.
I tried, but I couldn’t come up with a better solution. And now for how to use this photo gallery. We’ll be using TypeScript, so you first need to create a definition for the .js file.
In the options object you can specify that, among other things, the following elements are displayed – I have all of them set to false, because clicking any of these elements causes the first image to load, no matter which one you’re on – I know how to get around it, and I’ll get to that later:
closeEl:false,
fullscreenEl: false,
zoomEl: false,
shareEl: false,- closeEl – simply not needed; on a PC the gallery closes when you click outside the photo or press
esc. On mobile, just swipe any photo up or down. - fullscreenEl – This is quite a nice thing on mobile, but all the controls are hidden by default and zooming works just as well without it.
- zoomEl – You can do without this too – on mobile you can pinch to zoom, and on a PC you use the mouse button.
- shareEl – sharing to Pinterest, Twitter, Facebook and the option to download the photo.
Please don’t ask me too much why things are written one way or another. I don’t know myself, and I set it up using my traditional method – that is, trial and error, because with the sheer abundance and tangle of settings this gallery has, and since I don’t really read the documentation either, it gets hard.
On to the code – here, finally, is the TypeScript definition in the file PhotoSwipe.d.ts with the methods and constructor we’ll need:
declare class PhotoSwipe {
constructor(pswpElement, PhotoSwipeUI_Default, items, options);
listen(ev : string, fn : any) : void;
init(): void;
next(): void;
}The PhotoSwipe.ts file itself, which we then import into the page where we want to display the photo gallery, looks like this:
/// <reference path="../swf.ts"></reference>
/// <reference path="../PhotoSwipe.d.ts"></reference>
/// <reference path="../jquery.d.ts"></reference>
function photoSwipe(nameAlbum: string) {
var pswpElement = document.querySelectorAll('.pswp')[0];
var pid = getHashValue('pid');
var options = {
galleryUID: nameAlbum,
backButtonHideEnabled: false,
loop: true,
escKey: true,
arrowKeys: true,
history: true,
captionEl: true,
closeEl: false,
fullscreenEl: false,
zoomEl: false,
shareEl: false,
counterEl: true,
arrowEl: true,
preloaderEl: true,
tapToClose: false,
tapToToggleControls: true,
mouseUsed: false,
closeOnScroll: false,
pinchToClose: false,
};
var gallery = new PhotoSwipe(pswpElement, window['PhotoSwipeUI_Default'], items, options);
gallery.listen('gettingData', setAAnchorImage);
gallery.listen('close', function () {
history.replaceState('', document.title, window.location.pathname);
});
gallery.init();
if (pid != undefined) {
gallery.next();
}
}
function setAAnchorImage(index, item) {
var a = document.getElementById('aAnchorImage');
a.setAttribute('href', item.src);
a.setAttribute('data-size', item.w + 'x' + item.h);
a.setAttribute('pid', item.id);
if (items[index + 1]) {
var nextAnchorElement = document.getElementById('aAnchorImage2');
nextAnchorElement.setAttribute('href', items[index + 1].src);
nextAnchorElement.setAttribute('data-size', items[index + 1].w + 'x' + items[index + 1].h);
nextAnchorElement.setAttribute('pid', items[index + 1].id);
}
}I don’t think I need to show what this file looks like in JavaScript here – just compile it or adapt it yourself.
In the *.aspx.cs file you now only need to do 2 things. First, insert the JavaScript/jQuery code that calls the photoSwipe method in PhotoSwipe.js; the jQuery code can look something like this:
$(document).ready(function () { photoSwipe('" + "A" + idAlbum.ToString() + @"'); });So, for example, I pass A1 to the photoSwipe method, which PhotoSwipe remembers, and when someone sends a link to a photo to someone else, it opens in the correct album. But that’s only for those who don’t yet have the album identifier in the URI itself – for me it’s just there to keep things “tidy”.
The second thing is to call a method that inserts a JS array with the individual photos into the page – each object must have 3 variables – src, w, h – if any of them is missing, the application won’t display the image. You can also add pid so that PhotoSwipe knows the image’s ID – I strongly recommend it.
The whole JS object can then look something like this:
var items = [{src:'http://sunamo.cz/i/Photos/A-2147482952/uwHWhz2WGO/-2147474835_DSC_0001.JPG',w:1024,h:576,pid:0},{src:'http://sunamo.cz/i/Photos/A-2147482952/eIUz56x2IH/-2147474834_DSC_0002.JPG',w:1024,h:576,pid:1}, ...];And that’s all. You can see how it looks in practice in, for example, this album: 👻 Server unplugged, cable coiled up, keys handed back..