JavaScript Image Gallery With Thumbnails and Control Buttons

javascript image gallery with thumbnails and control buttons
Project: PhotoSwipe Vanilla Javascript Demo
Author: Kyle Smith
Edit Online: View on CodePen
License: MIT

An image gallery is a useful feature to organize and display images on a website. Whether it’s a personal portfolio, photography website, or e-commerce store, an image gallery is one of the must-have components. If you’re developing a website template/theme or just want to integrate an image gallery into your custom website, this gallery project might be helpful to you. This project uses the JavaScript Photo Swipe library to create an image gallery with thumbnails and control buttons.

How to Create Javascript Image Gallery with Thumbnails and Control Buttons

1. First of all, load the Bootstrap CSS, Photo Swipe CSS, and Google Fonts CSS by adding the following CDN links into the head tag of your website.

<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css'>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.0/photoswipe.css'>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.0/default-skin/default-skin.css'>
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Bitter:400,700,400italic'>

2. After that, create the HTML structure for the image gallery as follows:

<div class="container">
  <div class="row">
    <div class="col-sm-8 col-sm-offset-2">

      <h1 class="text-center">
          Iceland<br>
          <small><em>a PhotoSwipe Demo</em></small>
        </h1>

      <!-- Galley wrapper that contains all items -->
      <div id="gallery" class="gallery" itemscope itemtype="http://schema.org/ImageGallery">

        <!-- Use figure for a more semantic html -->
        <!-- Set an index through a dataset to retrieve figure's index -->
        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject" data-index="0">
          <!-- Link to the big image, not mandatory, but usefull when there is no JS -->
          <a href="https://unsplash.it/1200/900/?image=702" data-caption="Sea side, south shore<br><em class='text-muted'>© Dominik Schröder</em>" data-width="1200" data-height="900" itemprop="contentUrl">
            <!-- Thumbnail -->
            <img src="https://unsplash.it/400/300/?image=702" itemprop="thumbnail" alt="Image description">
          </a>
        </figure>

        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject" data-index="1">
          <a href="https://unsplash.it/1200/900/?image=695" data-caption="Sunset in the wheat field<br><em class='text-muted'>© Jordan McQueen</em>" data-width="1200" data-height="900" itemprop="contentUrl">
            <img src="https://unsplash.it/400/300/?image=695" itemprop="thumbnail" alt="Image description">
          </a>
        </figure>
        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject" data-index="2">
          <a href="https://unsplash.it/1200/900/?image=675" data-caption="Mysterious ocean<br><em class='text-muted'>© Barn Images</em>" data-width="1200" data-height="900" itemprop="contentUrl">
            <img src="https://unsplash.it/400/300/?image=675" itemprop="thumbnail" alt="Image description">
          </a>
        </figure>
        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject" data-index="3">
          <a href="https://unsplash.it/1200/900/?image=651" data-caption="Cloud over the mountains<br><em class='text-muted'>© James Pritchett</em>" data-width="1200" data-height="900" itemprop="contentUrl">
            <img src="https://unsplash.it/400/300/?image=651" itemprop="thumbnail" alt="Image description">
          </a>
        </figure>
        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject" data-index="4">
          <a href="https://unsplash.it/1200/900/?image=584" data-caption="Icelandic horses<br><em class='text-muted'>© Bethany Legg</em>" data-width="1200" data-height="900" itemprop="contentUrl">
            <img src="https://unsplash.it/400/300/?image=584" itemprop="thumbnail" alt="Image description">
          </a>
        </figure>
        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject" data-index="5">
          <a href="https://unsplash.it/1200/900/?image=574" data-caption="Sea side, south shore<br><em class='text-muted'>© Julien Lavallée</em>" data-width="1200" data-height="900" itemprop="contentUrl">
            <img src="https://unsplash.it/400/300/?image=574" itemprop="thumbnail" alt="Image description">
          </a>
        </figure>
        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject" data-index="6">
          <a href="https://unsplash.it/1200/900/?image=551" data-caption="Sunset on the highland road<br><em class='text-muted'>© Forrest Cavale</em>" data-width="1200" data-height="900" itemprop="contentUrl">
            <img src="https://unsplash.it/400/300/?image=551" itemprop="thumbnail" alt="Image description">
          </a>
        </figure>
        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject" data-index="7">
          <a href="https://unsplash.it/1200/900/?image=509" data-caption="Seljalandsfoss waterfall<br><em class='text-muted'>© Jeff Sheldon</em>" data-width="1200" data-height="900" itemprop="contentUrl">
            <img src="https://unsplash.it/400/300/?image=509" itemprop="thumbnail" alt="Image description">
          </a>
        </figure>
        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject" data-index="8">
          <a href="https://unsplash.it/1200/900/?image=511" data-caption="Fjadrarglufur canyon, south shore<br><em class='text-muted'>© Jeff Sheldon</em>" data-width="1200" data-height="900" itemprop="contentUrl">
            <img src="https://unsplash.it/400/300/?image=511" itemprop="thumbnail" alt="Image description">
          </a>
        </figure>
        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject" data-index="9">
          <a href="https://unsplash.it/1200/900/?image=515" data-caption="Eerie wreckage of a crashed U.S. Navy aircraft<br><em class='text-muted'>© Jeff Sheldon</em>" data-width="1200" data-height="900" itemprop="contentUrl">
            <img src="https://unsplash.it/400/300/?image=515" itemprop="thumbnail" alt="Image description">
          </a>
        </figure>
        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject" data-index="10">
          <a href="https://unsplash.it/1200/900/?image=512" data-caption="Blue Lagoon<br><em class='text-muted'>© Jeff Sheldon</em>" data-width="1200" data-height="900" itemprop="contentUrl">
            <img src="https://unsplash.it/400/300/?image=512" itemprop="thumbnail" alt="Image description">
          </a>
        </figure>
        <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject" data-index="11">
          <a href="https://unsplash.it/1200/900/?image=514" data-caption="Sunny Reykjavik street<br><em class='text-muted'>© Jeff Sheldon</em>" data-width="1200" data-height="900" itemprop="contentUrl">
            <img src="https://unsplash.it/400/300/?image=514" itemprop="thumbnail" alt="Image description">
          </a>
        </figure>
      </div>

    </div>
  </div>
</div>

<!-- Some spacing 😉 -->
<div class="spacer"></div>


<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
  <!-- Background of PhotoSwipe. 
           It's a separate element as animating opacity is faster than rgba(). -->
  <div class="pswp__bg"></div>
  <!-- Slides wrapper with overflow:hidden. -->
  <div class="pswp__scroll-wrap">
    <!-- Container that holds slides. 
              PhotoSwipe keeps only 3 of them in the DOM to save memory.
              Don't modify these 3 pswp__item elements, data is added later on. -->
    <div class="pswp__container">
      <div class="pswp__item"></div>
      <div class="pswp__item"></div>
      <div class="pswp__item"></div>
    </div>
    <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
    <div class="pswp__ui pswp__ui--hidden">
      <div class="pswp__top-bar">
        <!--  Controls are self-explanatory. Order can be changed. -->
        <div class="pswp__counter"></div>
        <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
        <button class="pswp__button pswp__button--share" title="Share"></button>
        <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
        <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
        <!-- Preloader demo https://codepen.io/dimsemenov/pen/yyBWoR -->
        <!-- element will get class pswp__preloader--active when preloader is running -->
        <div class="pswp__preloader">
          <div class="pswp__preloader__icn">
            <div class="pswp__preloader__cut">
              <div class="pswp__preloader__donut"></div>
            </div>
          </div>
        </div>
      </div>
      <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
        <div class="pswp__share-tooltip"></div>
      </div>
      <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
      </button>
      <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
      </button>
      <div class="pswp__caption">
        <div class="pswp__caption__center"></div>
      </div>
    </div>
  </div>
</div>

3. Style the image gallery using the following CSS styles:

body {
  font-family: "Bitter", Georgia, Times, sans-serif;
}

h1 {
  margin: 2em;
}

.pswp__caption__center {
  text-align: center;
}

figure {
  display: inline-block;
  width: 33.333%;
  float: left;
}

img {
  width: 100%;
}

.spacer {
  height: 5em;
}

4. Load the Photo Swipe JS by adding the following CDN link before closing the body tag.

<script src='//cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.0/photoswipe.min.js'></script>
<script src='//cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.0/photoswipe-ui-default.min.js'></script>

5. Finally, initialize the photo swipe with the following configuration options. You can set the custom values for its options to get the desired output.

const photoswipe = () => {
  let container = [];
  const gallery = document.querySelector("#gallery");
  const galleryFigures = document.querySelectorAll("#gallery figure");
  
  galleryFigures.forEach(figure => {
    const link = figure.querySelector('a')
    const item = {
      src: link.getAttribute("href"),
      w: link.dataset.width,
      h: link.dataset.height,
      title: link.dataset.caption,
    }
    container.push(item)
  })
  console.log(container)
  
  const galleryLinks = document.querySelectorAll("#gallery figure a")
  galleryLinks.forEach(link => {
    link.addEventListener("click", e => {
      e.preventDefault();
      
      const figure = link.parentElement;
      const figureIndex = figure.dataset.index;
      
      // Define object and gallery options
      const pswp = document.querySelector('.pswp')
      const options = {
        index: figureIndex,
        showHideOpacity: true,
        
        history: false,
        tapToClose: true,
        tapToToggleControls: false,
        barsSize: { top: 0, bottom: 0 },
        captionEl: false,
        fullscreenEl: false,
        zoomEl: false,
        shareEl: false,
        counterEl: false,
        bgOpacity: 0.95,
        closeOnScroll: false,
        closeOnVerticalDrag: false,
        pinchToClose: false,
        // maxSpreadZoom: 1,
        // clickToCloseNonZoomable: true,
        getDoubleTapZoom: function(isMouseClick, item) {
          gallery.close();
        },
      };
      
      // Initialize PhotoSwipe
      const gallery = new PhotoSwipe(pswp, PhotoSwipeUI_Default, container, options);
      console.log(gallery)
      gallery.init();
      
    })
  })
}

photoswipe();

That’s all! hopefully, you have successfully integrated the image gallery into your project. If you have any questions or suggestions, feel free to comment below.

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply