photoswipe

ui-component carousel animation

PhotoSwipe는 간단하면서도 강력한 JavaScript 갤러리 라이브러리로, 모바일과 데스크탑 모두에서 터치 제스처를 지원하는 이미지 갤러리를 구현할 수 있습니다. 이 라이브러리는 성능을 최적화하기 위해 CSS3를 활용하며, 모듈러 구조로 되어 있어 필요한 기능만 선택적으로 사용할 수 있습니다.

Latest Ver 5.4.4
Homepage
Github
0
24,596
📢 PhotoSwipe는 모바일과 데스크탑에서 사용할 수 있는 터치 제스처 지원 이미지 갤러리 라이브러리입니다.
License: MIT
https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe-lightbox.esm.js
https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe-lightbox.esm.min.js
https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe.esm.js
https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe.esm.min.js
https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/umd/photoswipe-lightbox.umd.min.js
https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/umd/photoswipe.umd.min.js
https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe.css
https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe.min.css
https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe-lightbox.esm.js.map
https://cdnjs.cloudflare.com/ajax/libs/photoswipe/5.4.4/photoswipe.esm.js.map

Sample Code

⚠️ import 문을 포함한 일부 코드는 jsFiddle에서 정상 실행되지 않을 수 있습니다. 실행 오류가 발생할 경우 코드 복사 후 직접 실행해보세요.
📄 HTML
<div class='my-gallery' itemscope itemtype='http://schema.org/ImageGallery'>
  <figure itemprop='associatedMedia' itemscope itemtype='http://schema.org/ImageObject'>
    <a href='https://placekitten.com/800/600' itemprop='contentUrl' data-size='800x600'>
      <img src='https://placekitten.com/200/150' itemprop='thumbnail' alt='Image description' />
    </a>
    <figcaption itemprop='caption description'>Sample image 1</figcaption>
  </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>
        <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>
        <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>

🎨 External CSS
<link href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/default-skin/default-skin.css" rel="stylesheet">

🧩 External JS
<script src="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe-ui-default.min.js"></script>

⚙️ JavaScript
document.addEventListener('DOMContentLoaded', function() {
  var initPhotoSwipeFromDOM = function(gallerySelector) {
    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];
        if(figureEl.nodeType !== 1) {
          continue;
        }
        linkEl = figureEl.children[0];
        size = linkEl.getAttribute('data-size').split('x');
        item = {
          src: linkEl.getAttribute('href'),
          w: parseInt(size[0], 10),
          h: parseInt(size[1], 10)
        };
        if(figureEl.children.length > 1) {
          item.title = figureEl.children[1].innerHTML;
        }
        if(linkEl.children.length > 0) {
          item.msrc = linkEl.children[0].getAttribute('src');
        }
        item.el = figureEl;
        items.push(item);
      }
      return items;
    };
    var closest = function closest(el, fn) {
      return el && (fn(el) ? el : closest(el.parentNode, fn));
    };
    var onThumbnailsClick = function(e) {
      e = e || window.event;
      e.preventDefault ? e.preventDefault() : e.returnValue = false;
      var eTarget = e.target || e.srcElement;
      var clickedListItem = closest(eTarget, function(el) {
        return (el.tagName && el.tagName.toUpperCase() === 'FIGURE');
      });
      if(!clickedListItem) {
        return;
      }
      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) {
        openPhotoSwipe(index, clickedGallery);
      }
      return false;
    };
    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);
      options = {
        galleryUID: galleryElement.getAttribute('data-pswp-uid'),
        getThumbBoundsFn: function(index) {
          var thumbnail = items[index].el.getElementsByTagName('img')[0],
              pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
              rect = thumbnail.getBoundingClientRect(); 
          return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
        }
      };
      if(fromURL) {
        if(options.galleryPIDs) {
          for(var j = 0; j < items.length; j++) {
            if(items[j].pid == index) {
              options.index = j;
              break;
            }
          }
        } else {
          options.index = parseInt(index, 10) - 1;
        }
      } else {
        options.index = parseInt(index, 10);
      }
      if( isNaN(options.index) ) {
        return;
      }
      if(disableAnimation) {
        options.showAnimationDuration = 0;
      }
      gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options);
      gallery.init();
    };
    var galleryElements = document.querySelectorAll(gallerySelector);
    for(var i = 0, l = galleryElements.length; i < l; i++) {
      galleryElements[i].setAttribute('data-pswp-uid', i+1);
      galleryElements[i].onclick = onThumbnailsClick;
    }
    var hashData = photoswipeParseHash();
    if(hashData.pid && hashData.gid) {
      openPhotoSwipe( hashData.pid ,  galleryElements[ hashData.gid - 1], true, true);
    }
  };
  initPhotoSwipeFromDOM('.my-gallery');
});
⚡ Top Tools for Developers
Text Compare

텍스트 비교

두 텍스트의 차이점을 한눈에 확인하세요.

Favicon Generator

Favicon 생성기

파비콘을 쉽고 빠르게 생성하세요.

Lorem Ipsum Generator

Lorem Ipsum 생성기

디자인을 위한 더미 텍스트를 생성하세요.

Character Counter

글자수 세기

글자 수와 단어 수를 실시간으로 확인하세요.

SRT ↔ SMI

SRT ↔ SMI 변환기

자막 형식을 간편하게 변환합니다.

Text Extract(OCR)

이미지 텍스트 추출

이미지 속 텍스트 자동 추출