3

Plase see title. I would like to achieve the following:

1. On Mobile: In PhotoSwipe, when a swipe to view next image is detected (when already viewing last image), Close PhotoSwipe.

2. On Mobile: Same as the above but when viewing the 1st image. When already viewing 1st image and swipe to show the previous image is detected, Close PhotoSwipe.

3. On Desktop: Using the code below, when the 1st image is viewed, the left arrow PhotoSwipe UI button gets hidden (because there is no previous image to show) and the left arrow key of the keyboard gets disabled.
The goal here is when viewing the first image and the left arrow key on the keyboard is pressed, instead of doing nothing (or looping to the last image), PhotoSwipe gallery to close itself.


Here is a jsfiddle showing the current state of the code:
https://jsfiddle.net/bezq08oc/



Perhaps an approach could be to re-enable loop and in its place to inject code to close the gallery instead of looping it?

loop: false



I am using the code below to:

  • Hide the not needed arrow when viewing first image or last image.
  • Disable left and right arrow keys on the keyboard when viewing first image or last image.
This will hide the left arrow on first image and right arrow on last image.
It will also work when the keyboard left and right keys are used to change the images.

// Initialize PhotoSwipe
    var gallery = new PhotoSwipe($pswp, PhotoSwipeUI_Default, container, options);
    gallery.init();


// disable html-arrows control (Hide left arrow on first image and right arrow on last image)
// Code below works only when PhotoSwipe Gallery loads     
    gallery.getCurrentIndex() === 0 ? $('.pswp__button--arrow--left').hide() : $('.pswp__button--arrow--left').show();
    gallery.getCurrentIndex()+1 === gallery.items.length ? $('.pswp__button--arrow--right').hide() : $('.pswp__button--arrow--right').show();

// disable html-arrows control (Hide left arrow on first image and right arrow on last image)
// Code below works when PhotoSwipe Gallery is already opened
    gallery.listen('beforeChange', function() {
        gallery.getCurrentIndex() === 0 ? $('.pswp__button--arrow--left').hide() : $('.pswp__button--arrow--left').show();
        gallery.getCurrentIndex()+1 === gallery.items.length ? $('.pswp__button--arrow--right').hide() : $('.pswp__button--arrow--right').show();
      }
    );

// disable keys left+right control
    $('body').keydown(function(e) {
        // key left
        if ((e.keyCode || e.which) == 37) {
            if (gallery.getCurrentIndex() === 0) {
                gallery.options.arrowKeys = false;
            } else {
                gallery.options.arrowKeys = true;
            }
        }
        // key right
        if ((e.keyCode || e.which) == 39) {
            if (gallery.getCurrentIndex()+1 === gallery.items.length) {
                gallery.options.arrowKeys = false;
            } else {
                gallery.options.arrowKeys = true;
            }
        }
    });
  • PhotoSwipe looks like it's no longer maintained. The most recent commits and tweets are over a year old. Could you fork it and make the changes you need directly? – Tyler Mumford Jan 17 '20 at 22:30
  • I am just trying to get it to work for my site, but as you can guess by my post, I don’t know what to change. Do you have an idea how to approach this? – user3703618 Jan 18 '20 at 06:40
  • From a UX point of view, I think that users may find this annoying (the photoswipe closing), especially if the person is e.g. on image number 2 and is swiping backward to see image number 12 for instance.. just a thought.. it can be closed manually with the x in the corner, yes? – Rachel Gallen Jan 18 '20 at 10:12
  • In the intended use case I would prefer it to close. The idea is to create few separate PhotoSwipe galleries and each would only contain 3-4 images. So the goal would be to quickly jump between each gallery and sample what’s in them. Would you happen to have an idea how to approach it so the gallery would close unstead of loop? – user3703618 Jan 18 '20 at 11:56

1 Answers1

1

Okay, you can do it, but you're going to have to edit the core photoswipe.js file. Delete the code for your previous attempts to do this such as making the key presses do nothing and leave the loop option turned ON for this to work properly.

Part One: In that file find this code on line 1076:

    next: function() {
        self.goTo( _currentItemIndex + 1);
    },
    prev: function() {
        self.goTo( _currentItemIndex - 1);
    },

This is determining the action whenever a user is changing the slide to previous or next through a click or key press. So we can insert a simple statement here checking if it is the first slide, and moving left, or if it is the last slide, and moving right. Then initiate the close function.

So, change the previously mentioned code to this:

    next: function() {
        if ( (_currentItemIndex + 1) === _getNumItems() ) {
            self.close();
        } else {
            self.goTo( _currentItemIndex + 1);
        }
    },
    prev: function() {
        if ( (_currentItemIndex + 1) === 1) {
            self.close();
        } else {
            self.goTo( _currentItemIndex - 1);
        }
    },

Part Two: We need to also change the mechanism for the swipe gesture, so find this code on line 2306:

        if(gestureType === 'swipe') {
            var totalShiftDist = _currPoint.x - _startPoint.x,
                isFastLastFlick = _releaseAnimData.lastFlickDist.x < 10;

            // if container is shifted for more than MIN_SWIPE_DISTANCE, 
            // and last flick gesture was in right direction
            if(totalShiftDist > MIN_SWIPE_DISTANCE && 
                (isFastLastFlick || _releaseAnimData.lastFlickOffset.x > 20) ) {
                // go to prev item
                itemsDiff = -1;
            } else if(totalShiftDist < -MIN_SWIPE_DISTANCE && 
                (isFastLastFlick || _releaseAnimData.lastFlickOffset.x < -20) ) {
                // go to next item
                itemsDiff = 1;
            }
        }

And, were going to do something similar to this function as in part one. Change the code to the following:

        if(gestureType === 'swipe') {
            var totalShiftDist = _currPoint.x - _startPoint.x,
                isFastLastFlick = _releaseAnimData.lastFlickDist.x < 10;

            // if container is shifted for more than MIN_SWIPE_DISTANCE,
            // and last flick gesture was in right direction
            if(totalShiftDist > MIN_SWIPE_DISTANCE &&
                (isFastLastFlick || _releaseAnimData.lastFlickOffset.x > 20) ) {
                // go to prev item
                if ( (_currentItemIndex + 1) === 1) {
                    self.close();
                } else {
                    itemsDiff = -1;
                }
            } else if(totalShiftDist < -MIN_SWIPE_DISTANCE &&
                (isFastLastFlick || _releaseAnimData.lastFlickOffset.x < -20) ) {
                // go to next item
                if ( (_currentItemIndex + 1) === _getNumItems() ) {
                    self.close();
                } else {
                    itemsDiff = 1;
                }
            }
        }

I have tested on my site and it works correctly.

Enjoy :)

Dustyn Altimus
  • 316
  • 2
  • 11