dimsemenov / PhotoSwipe

JavaScript image gallery for mobile and desktop, modular, framework independent
http://photoswipe.com
MIT License
24.15k stars 3.31k forks source link

Slideshow (auto next) #753

Open rogerbinns opened 9 years ago

rogerbinns commented 9 years ago

This is a feature request to the ui to add slideshow functionality (essentially automatically next every N seconds) with a button alongside the others to start it. Ideally any user interaction should cancel the auto next. It would also be nice if I could make photoswipe start with the auto next already on.

dimsemenov commented 9 years ago

For now I don't have plans to add this feature, at least until fade transition feature is ready.

It's not that hard to implement it by yourself, use PhotoSwipe public API http://photoswipe.com/documentation/api.html

JimCook57 commented 9 years ago

Following.... I would like this feature too.

JimCook57 commented 9 years ago

Any plans to add this into the core functionality?

JimCook57 commented 8 years ago

Has anyone implemented this?

Plixo commented 8 years ago

it's done in one line, after you create and init your psp, aka: psp = new PhotoSwipe(...); psp.init(); Just do this: setInterval(function(){psp.next();},4000);

rogerbinns commented 8 years ago

That just forces a transition every 4 seconds. It should also be stopped if the user interacts (eg they zoom in a pic to take a closer look, or go back to a previous pic). Plus some sort of toggle for auto next being on/off. Even the timing needs some attention. For example if it takes 3 seconds to display the image (eg slow network) then the timer should really start from when the image is reasonably visible, and not from when the loading started.

Shivang44 commented 8 years ago

I agree with @rogerbinns on this, @Plixo's solution isn't very optimal. Are there any plans to add it now or is it still the same status?

jtbr commented 8 years ago

Here is what I do. 1) Make a button in the photoswipe toolbar: In the photoswipe markup on your page, insert this after the other buttons:

    <!-- custom slideshow button: -->
    <button class="pswp__button pswp__button--playpause" title="Play Slideshow"></button>

In the CSS for your page, insert the following:

/* set play/pause button */
@media (-webkit-min-device-pixel-ratio: 1.1), (-webkit-min-device-pixel-ratio: 1.09375), (min-resolution: 105dpi), (min-resolution: 1.1dppx) { /*serve if resolution high enough & browser supports */
    .pswp--svg .pswp__button--playpause.play, .pswp--svg .pswp__button--playpause.play:before {
        background-image: url('play-wh.svg');
    }
    .pswp--svg .pswp__button--playpause.pause, .pswp--svg .pswp__button--playpause.pause:before {
        background-image: url('pause-wh.svg');
    }
}
.pswp__button--playpause.play, .pswp__button--playpause.play:before {
    background: url('play-wh.png') 12px 12px/20px 20px no-repeat;
}
.pswp__button--playpause.pause, .pswp__button--playpause.pause:before {
    background: url('pause-wh.png') 12px 12px/20px 20px no-repeat;
}
.pswp__button {
    outline: none;
}

These media queries match those used by the other toolbar icons.

Put these PNGs in the directory with your CSS:

pause-wh.png - (pause-wh)

play-wh.png - (play-wh) (they appear invisible on a white background)

Create two SVG files in the same dir with the following contents: pause-wh.svg:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="24" height="24" viewBox="0 0 24 24">
  <path
     d="m 6.4533898,3 c -1.656,0 -3,1.344 -3,3 v 12 c 0,1.656 1.344,3 3,3 1.656,0 3,-1.344 3,-3 V 6 c 0,-1.656 -1.344,-3 -3,-3 z" style="fill:#fff"/>/>
  <path
     d="m 16.95339,3 c -1.656,0 -3,1.344 -3,3 v 12 c 0,1.656 1.344,3 3,3 1.656,0 3,-1.344 3,-3 V 6 c 0,-1.656 -1.344,-3 -3,-3 z" style="fill:#fff"/>/>
</svg>

and play-wh.svg:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="24" height="24" viewBox="0 0 24 24">
  <path
     d="M 9.594,21.6495 C 13.5555,17.7885 19.5,12 19.5,12 19.5,12 13.5555,6.2115 9.594,2.3505 9.0495,1.827 8.3145,1.5 7.5,1.5 c -1.656,0 -3,1.344 -3,3 v 15 c 0,1.656 1.344,3 3,3 0.8145,0 1.5495,-0.327 2.094,-0.8505 z" style="fill:#fff"/>
</svg>

2) Now add some javascript to your page. They assume you called your photoswipe variable lightBox.

// slideshow vars:
var ssRunning = false, 
    ssOnce = false,
    ssDelay = 2500 /*ms*/,
    ssButtonClass = '.pswp__button--playpause';

var lightBox = null;

$('#openPswp').click( function(event) {

    lightBox = new PhotoSwipe( /* your settings ... */ );

    setSlideshowState(ssButtonClass, false /* not running from the start */);

    // start timer for the next slide in slideshow after prior image has loaded
    lightBox.listen('afterChange', function() { 
        if (ssRunning && ssOnce) {
            ssOnce = false;
            setTimeout(gotoNextSlide, ssDelay);
        }
    }); 
    lightBox.listen('destroy', function() { lightBox = null; });

    // ....

    lightBox.init();
});

/* slideshow management */
$(ssButtonClass).on('click', function(e) {
    // toggle slideshow on/off
    setSlideshowState(this, !ssRunning);
});

function setSlideshowState(el, running) {
    if (running) {
        setTimeout(gotoNextSlide, ssDelay / 2.0 /* first time wait less */);
    }
    var title = running ? "Pause Slideshow" : "Play Slideshow";
    $(el).removeClass(running ? "play" : "pause") // change icons defined in css
        .addClass(running ? "pause" : "play")
        .prop('title', title);
    ssRunning = running;
}

function gotoNextSlide() {
    if (ssRunning && !!lightBox) {
        ssOnce = true;
        lightBox.next();
        // start counter for next slide in 'afterChange' listener
    }
}

/* override handling of Esc key to stop slideshow on first esc (note Esc to leave fullscreen never gets here) */
$(document).keydown(function(e) {
    if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) return;
    if ((e.key === "Escape" || e.which == 27 /*esc*/) && !!lightBox) {
        if (e.preventDefault)  e.preventDefault();
        else  e.returnValue = false;
        if (ssRunning) {
            setSlideshowState(ssButtonClass, false);
        } else {
            lightBox.close();
        }
    }
});

It uses jQuery, since my page does, but this wouldn't be hard to remove.

The user toggles the slideshow function on and off by using the play/pause button (which changes depending upon the mode). It can also be aborted by hitting the escape key. Slides change every 2.5 seconds (starting after the prior image loaded).

pwFoo commented 5 years ago

Would be nice to see it merged to PhotoSwipe

daltimus11 commented 5 years ago

Lot's of edits on this comment, but the important take away is that the code provided does function, it just has an issue that occurs if the slideshow is started and paused too quickly.

jtbr commented 5 years ago

You shouldn't need to ever click the start/stop slideshow button repeatedly, as it only begins the process. You don't need to click it again to change slides...

But if you think users will repeatedly click it anyway, you could keep track of the number of outstanding timers pending (increment the variable when calling setTimeout() and decrement it when entering gotoNextSlide()), and don't call setTimeout if this is greater than 0. What's happening is that multiple timeouts are getting created if you click start/stop rapidly enough (within 1.25s by default).

If you do this, please post the code. Good luck

On Fri, Sep 6, 2019 at 10:34 PM Dustyn Altimus notifications@github.com wrote:

@jtbr https://github.com/jtbr Thanks a lot for sharing your slideshow solution. I am trying to implement it, but running into a problem where, if you click click the slideshow button too fast it behaves strangely, such as moving way too fast. It works perfectly if I always wait enough time between presses, but I can't rely on users doing that consistently.

I am trying to figure out a way to fix it on my own, but do you have any ideas about it?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/dimsemenov/PhotoSwipe/issues/753?email_source=notifications&email_token=ADESBN6XBPKIK75TQHVJE53QIK5E5A5CNFSM4A3VGSU2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD6D7RJY#issuecomment-529004711, or mute the thread https://github.com/notifications/unsubscribe-auth/ADESBN737PQFHQDJN6753YLQIK5E5ANCNFSM4A3VGSUQ .

daltimus11 commented 5 years ago

Thank you for explaining, it helped me understand what was happening a lot better.

Edit: I've decided not to implement a slideshow on my gallery.

andi34 commented 4 years ago

Thanks for your shared code @jtbr . You could point me in the right direction to refresh the image database after X seconds and start the slideshow directly with latest image without the need to click on a thumbnail and without another click to start the slideshow again?