blog-banner

Adding Next and Previous Images To Either Sides of Galleria Slideshow & Adding Responsiveness

    JQuery has made our lives easier with its vast plugin repository (so is Drupal). The popular jQuery plugins make their way into Drupal with easy-to-configure modules. One such is galleria, which integrates well with views to quickly create an image slideshow.

    We recently had a requirement to show the next and previous images attached to either side of the currently visible galleria slideshow image, which isn't supported by galleria out of the box. Understandably, addressing the needs of people all over the globe may not be possible for these open-source projects, but they do catch up by exposing an API that we could use to tailor the functionality of our application.

    We also wanted the galleria slideshow to be responsive (again, which is not supported out of the box as of this writing). To be precise: we want the galleria to occupy the full width of the screen if the display port width is below a threshold limit (say 900px) and want it to be back to its original width if the display port width goes above the threshold. Here is how we achieved both functionalities:

    /* It is assumed that the threshold width is also the standard width of the Galleria slideshow.. Which means, on a display of width 1024px, the galleria would take the center stage with a width of 900px and previous/next images on either sides. On responsive mode [when browser width reduced below threshold], galleria will take a 100% width, with NO previous or next images visible */

    var _window_threshold_width = 900;

    jQuery(window).ready(function() {
    /* Tweak to load previous & next images on the left/right of current image */
    Galleria.ready(function() {
    _responsive_galleria_resize(); /* Call this on page-load, so that if width is < threshold on load, galleria adapts */

        /* We will bind to the loadfinish API event, that is triggered just before the active image being shown is going to be replaced with another image with a slide effect. It is called every time the slide transition is about to occur. */

    this.bind('loadfinish', function(e) {
    var _galleria = this;
    setTimeout(function() {
    /* cleanup old tags added by us (if any); we will re-add it */

    jQuery('#gallery-img-pre').remove();
    jQuery('#gallery-img-post').remove();
    jQuery('#gallery-img-pre-overlay').remove(); /* The overlay part is optional -- we added this over the prev/next image for a transculent effect over the images appearing on either sides */
    jQuery('#gallery-img-post-overlay').remove();
    var previous_image = _galleria.getData(_galleria.getPrev());
    var next_image = _galleria.getData(_galleria.getNext());
    if (jQuery(e.imageTarget).position()) { /* e.imageTarget is the tag, that is visible currently on galleria */
    jQuery(e.imageTarget).before('');
    jQuery('#gallery-img-pre').css('margin-left', '-' + (_window_threshold_width - jQuery(e.imageTarget).position().left) + 'px');
    jQuery(e.imageTarget).after('');
    jQuery('#gallery-img-post').css('margin-left', (jQuery(e.imageTarget).position().left + _window_threshold_width) + 'px');
    /* The overlay part is optional -- we added this over the prev/next image for a transculent effect over the images appearing on either sides */ 
    jQuery(e.imageTarget).before('

    ');
    jQuery('#gallery-img-pre-overlay').css('margin-left', '-' + (_window_threshold_width - jQuery(e.imageTarget).position().left) + 'px');
    jQuery(e.imageTarget).after('

     

    ');
    jQuery('#gallery-img-post-overlay').css('margin-left', (jQuery(e.imageTarget).position().left + _window_threshold_width) + 'px');
    }
    }, (jQuery(window).width() - _window_threshold_width)/2); /* This timeout is essential to make a "seamless" transition effect & makes illusion that the images on either sides are actually attached to the left & right of current image */
    } /* ends .bind('loadfinish'); */
    }); /* ends Galleria.ready() */
    }); /* ends jQuery(window).ready() */

    /* Function to make the Galleria responsive (full width) & to reset it back to normal state */
    function _responsive_galleria_resize() {
    var ref_width = 900; /* Feed in your Galleria's width */
    var ref_height = 414; /* Feed in your Galleria's height */
    var ht = ref_height;
    if ((jQuery(window).width() < _window_threshold_width) {     /* If you have reached here, it means.. current window viewport width is < threshold. So, find the reduced height of the galleria w.r.t current window width, maintaining the aspect ratio */
    ht = jQuery('.galleria-stage').width();
    ht = parseInt(ht * (ref_height / ref_width));
    }
    jQuery('.galleria-images').style('height', ht + 'px', 'important'); /* .style (!important) is not supported out of the box - refer to http://stackoverflow.com/a/8894528 to implement it */
    jQuery('.galleria-images > .galleria-image').style('height', ht + 'px', 'important');
    jQuery('.galleria-container').style('height', ht + 'px', 'important');
    jQuery('.galleria-image img').style('height', ht + 'px', 'important');
    jQuery('.galleria-info').style('height', ht + 'px', 'important');
    }

    /* Responsiveness: Trick to auto-center & reload galleria on window resize */
    var _window_width = jQuery(window).width();
    jQuery(window).resize(function() {
    if (jQuery(window).width() != _window_width) {
    _window_width = jQuery(window).width();
    var g = jQuery('#galleria-1').data('galleria'); /* Note: this may not be very reliable, but it works for us */
          /* The trick we'll employ is that: we will alter the styling of galleria, which would be in effect after next slideshow image has loaded.. But, without waiting, we're going to force reload with some timeouts */
    if (g) {
    g.setOptions('transition', 'flash').setOptions('transitionSpeed', '20').resize(); /* Change the transition style temporarily to quickly reload galleria */
    setTimeout(function() {
    g.show(g.getIndex()); /* Actual reload-galleria call */
    }, 100);
    setTimeout(function() {
    g.setOptions('transition', 'slide').setOptions('transitionSpeed', '400');
    }, 600); /* Reset transition after all the reloading/redrawing is done */
    _responsive_galleria_resize(); /* The resize function */
    }
    }
    });

    As you could notice, most of the functionality is explained with inline comments wherever required. Let us know if this works for you or if you want to suggest a better approach to achieve the functionality. See it in action here.