Search code examples
polymerpolymer-1.0photoswipe

PhotoSwipe with Polymer misalignment


I'm trying to make a small web-app using Polymer, based on the Nav + List + Detail-layout example they have provided. For part of my web-app I want to make a photo gallery. Luckily, there's an element for that. Unfortunately, there's no element for that. So I set myself upon the task of making my own custom-element that provides this functionality, based on PhotoSwipe.

So I decided to start simple by just implementing the code they provided as an example (see this CodePen). I simply copied this code into a custom element to see how it works, but unfortunately it doesn't work 100%. Here is the CodePen of the custom element.

For small displays the photo's display correctly, but when the screen is tall the 3rd and 4th photo don't align to the center anymore, but slide to the bottom right corner. The easiest way to see this is by pressing the full screen button when viewing an image. Below is an image where you can clearly see the offset to the bottom-right.

Misalignment of picture

I rechecked and this isn't an issue in their own CodePen, but I can't seem to find if there are overlapping styles or something else is breaking it up. Any ides?

<dom-module id="photo-album">
  <link rel="import" type="css" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.0/photoswipe.css"> <!-- photoswipe/photoswipe.css -->
  <link rel="import" type="css" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.0/default-skin/default-skin.css"> <!-- photoswipe/default-skin/default-skin.css -->
  <template>
    <style>
      :host {
        display: block;
      }
      .my-gallery {
        width: 100%;
        float: left;
      }
      .my-gallery img {
        width: 100%;
        height: auto;
      }
      .my-gallery figure {
        display: block;
        float: left;
        margin: 0 5px 5px 0;
        width: 150px;
      }
      .my-gallery figcaption {
        display: none;
      }
    </style>
    <iron-ajax url="" params="" handle-as="json" last-response="{{photos}}"></iron-ajax>
    <!--<template is="dom-repeat" items="{{photos}}">
      <iron-image style="width:400px; height:400px; background-color: lightgray;" sizing="cover" preload fade src="{{item}}"></iron-image>
    </template>-->

    <div class="my-gallery" id="gallery" itemscope itemtype="http://schema.org/ImageGallery">

      <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
        <a href="https://farm3.staticflickr.com/2567/5697107145_a4c2eaa0cd_o.jpg" itemprop="contentUrl" data-size="1024x1024">
            <img src="https://farm3.staticflickr.com/2567/5697107145_3c27ff3cd1_m.jpg" itemprop="thumbnail" alt="Image description" />
        </a>
      </figure>

      <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
        <a href="https://farm2.staticflickr.com/1043/5186867718_06b2e9e551_b.jpg" itemprop="contentUrl" data-size="964x1024">
            <img src="https://farm2.staticflickr.com/1043/5186867718_06b2e9e551_m.jpg" itemprop="thumbnail" alt="Image description" />
        </a>
      </figure>

      <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
        <a href="https://farm7.staticflickr.com/6175/6176698785_7dee72237e_b.jpg" itemprop="contentUrl" data-size="1024x683">
            <img src="https://farm7.staticflickr.com/6175/6176698785_7dee72237e_m.jpg" itemprop="thumbnail" alt="Image description" />
        </a>
      </figure>

      <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
        <a href="https://farm6.staticflickr.com/5023/5578283926_822e5e5791_b.jpg" itemprop="contentUrl" data-size="1024x768">
            <img src="https://farm6.staticflickr.com/5023/5578283926_822e5e5791_m.jpg" itemprop="thumbnail" alt="Image description" />
        </a>
      </figure>

    </div>


    <div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
      <div class="pswp__bg"></div>
      <div class="pswp__scroll-wrap">
          <div class="pswp__container">
              <div class="pswp__item"></div>
              <div class="pswp__item"></div>
              <div class="pswp__item"></div>
          </div>
          <div class="pswp__ui pswp__ui--hidden">

              <div class="pswp__top-bar">
                  <div class="pswp__counter"></div>
                  <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
                  <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>
  </template>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.0/photoswipe.min.js"></script> <!-- photoswipe/photoswipe.min.js -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.0/photoswipe-ui-default.min.js"></script> <!-- photoswipe/photoswipe-ui-default.min.js -->
  <script>
    Polymer({
      is: 'photo-album',
      properties: {
        items: {
          type: Array,
          notify: true,
        }
      },
      ready: function() {
        this.initPhotoSwipeFromDOM();
      },
      initPhotoSwipeFromDOM: function(){
        var gallerySelector = this.$.gallery;
        var parseThumbnailElements = function(el) {
            var thumbElements = el.childNodes,
                numNodes = thumbElements.length,
                items = [],
                figureEl,
                linkEl,
                size,
                item;

            for(var i = 0; i < numNodes; i++) {

                figureEl = thumbElements[i]; // <figure> element

                // include only element nodes 
                if(figureEl.nodeType !== 1) {
                    continue;
                }

                linkEl = figureEl.children[0]; // <a> element

                size = linkEl.getAttribute('data-size').split('x');

                // create slide object
                item = {
                    src: linkEl.getAttribute('href'),
                    w: parseInt(size[0], 10),
                    h: parseInt(size[1], 10)
                };



                if(figureEl.children.length > 1) {
                    // <figcaption> content
                    item.title = figureEl.children[1].innerHTML; 
                }

                if(linkEl.children.length > 0) {
                    // <img> thumbnail element, retrieving thumbnail url
                    item.msrc = linkEl.children[0].getAttribute('src');
                } 

                item.el = figureEl; // save link to element for getThumbBoundsFn
                items.push(item);
            }

            return items;
        };

        // find nearest parent element
        var closest = function closest(el, fn) {
            return el && ( fn(el) ? el : closest(el.parentNode, fn) );
        };

        // triggers when user clicks on thumbnail
        var onThumbnailsClick = function(e) {
            e = e || window.event;
            e.preventDefault ? e.preventDefault() : e.returnValue = false;

            var eTarget = e.target || e.srcElement;

            // find root element of slide
            var clickedListItem = closest(eTarget, function(el) {
                return (el.tagName && el.tagName.toUpperCase() === 'FIGURE');
            });

            if(!clickedListItem) {
                return;
            }

            // find index of clicked item by looping through all child nodes
            // alternatively, you may define index via data- attribute
            var clickedGallery = clickedListItem.parentNode,
                childNodes = clickedListItem.parentNode.childNodes,
                numChildNodes = childNodes.length,
                nodeIndex = 0,
                index;

            for (var i = 0; i < numChildNodes; i++) {
                if(childNodes[i].nodeType !== 1) { 
                    continue; 
                }

                if(childNodes[i] === clickedListItem) {
                    index = nodeIndex;
                    break;
                }
                nodeIndex++;
            }



            if(index >= 0) {
                // open PhotoSwipe if valid index found
                openPhotoSwipe( index, clickedGallery );
            }
            return false;
        };

        // parse picture index and gallery index from URL (#&pid=1&gid=2)
        var photoswipeParseHash = function() {
            var hash = window.location.hash.substring(1),
            params = {};

            if(hash.length < 5) {
                return params;
            }

            var vars = hash.split('&');
            for (var i = 0; i < vars.length; i++) {
                if(!vars[i]) {
                    continue;
                }
                var pair = vars[i].split('=');  
                if(pair.length < 2) {
                    continue;
                }           
                params[pair[0]] = pair[1];
            }

            if(params.gid) {
                params.gid = parseInt(params.gid, 10);
            }

            return params;
        };

        var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) {
            var pswpElement = document.querySelectorAll('.pswp')[0],
                gallery,
                options,
                items;

            items = parseThumbnailElements(galleryElement);

            // define options (if needed)
            options = {

                // define gallery index (for URL)
                galleryUID: galleryElement.getAttribute('data-pswp-uid'),

                getThumbBoundsFn: function(index) {
                    // See Options -> getThumbBoundsFn section of documentation for more info
                    var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail
                        pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
                        rect = thumbnail.getBoundingClientRect(); 

                    return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
                }

            };

            // PhotoSwipe opened from URL
            if(fromURL) {
                if(options.galleryPIDs) {
                    // parse real index when custom PIDs are used 
                    // http://photoswipe.com/documentation/faq.html#custom-pid-in-url
                    for(var j = 0; j < items.length; j++) {
                        if(items[j].pid == index) {
                            options.index = j;
                            break;
                        }
                    }
                } else {
                    // in URL indexes start from 1
                    options.index = parseInt(index, 10) - 1;
                }
            } else {
                options.index = parseInt(index, 10);
            }

            // exit if index not found
            if( isNaN(options.index) ) {
                return;
            }

            options.showAnimationDuration = 0;
            options.hideAnimationDuration = 0;

            // Pass data to PhotoSwipe and initialize it
            gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options);
            gallery.init();
        };

        // loop through all gallery elements and bind events
        var galleryElements = this.$.gallery;

        galleryElements.setAttribute('data-pswp-uid', 1);
        galleryElements.onclick = onThumbnailsClick;

        // Parse URL and open gallery if it contains #&pid=3&gid=1
        var hashData = photoswipeParseHash();
        if(hashData.pid && hashData.gid) {
            openPhotoSwipe( hashData.pid ,  galleryElements[ hashData.gid - 1 ], true, true );
        }
      }
    });
  </script>

</dom-module>

Solution

  • It seems you're missing styles from photoswipe.css.