diff options
author | JT <jeffreytse.mail@gmail.com> | 2023-06-25 23:20:01 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-25 23:20:01 +0800 |
commit | 9b14d7b963fd912310b054e91c10cfe789491aff (patch) | |
tree | 49deb7d8ce08a21b5f266c8819e957055f7a2f97 /_includes/extensions | |
parent | 54b30d735523c31237ab94959c983b0eeb5c4ebe (diff) |
feat: photo previewer support (#113)
Diffstat (limited to '_includes/extensions')
-rw-r--r-- | _includes/extensions/photo-swipe.html | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/_includes/extensions/photo-swipe.html b/_includes/extensions/photo-swipe.html new file mode 100644 index 0000000..ea93674 --- /dev/null +++ b/_includes/extensions/photo-swipe.html @@ -0,0 +1,161 @@ +<script src="//cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe.min.js"></script> +<script src="//cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe-ui-default.min.js"></script> +<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" +/> +<style> + .pswp .pswp__container .pswp__img { + background-color: white; + } +</style> + +<script> + function initPhotoSwipe() { + var mainEl = document.querySelector("section.main"); + + var imgEls = mainEl.querySelectorAll("img:not(.emoji)"); + imgEls.forEach((imgEl) => { + imgEl.outerHTML = ` + <a class="photo-swipe" + href="${imgEl.src}" + data-width="${imgEl.getAttribute("width") || imgEl.width * 2}" + data-height="${imgEl.getAttribute("height") || imgEl.height * 2}" + data-caption="${imgEl.getAttribute("caption") || imgEl.alt}" + target="_blank"> + ${imgEl.outerHTML} + </a>`; + }); + + // Init empty gallery array + var container = []; + + // Loop over gallery items and push it to the array + var linkEls = mainEl.querySelectorAll("a.photo-swipe"); + linkEls.forEach((link) => { + var item = { + src: link.getAttribute("href"), + w: link.dataset.width, + h: link.dataset.height, + title: link.dataset.caption || "", + }; + container.push(item); + }); + + // Define click event on gallery item + linkEls.forEach((link, index) => { + link.addEventListener("click", (event) => { + // Prevent location change + event.preventDefault(); + + // Define object and gallery options + var pswp = document.querySelector(".pswp"); + + var zoomLevel = 1; + + // Define object and gallery options + var options = { + index: index, + bgOpacity: 0.85, + showHideOpacity: true, + closeOnScroll: true, + maxSpreadZoom: 1, + getDoubleTapZoom: (isMouseClick, item) => { + if (item.detail) { + zoomLevel += item.detail.origEvent.shiftKey ? -1 : 1; + item.detail = undefined; + } else { + zoomLevel = zoomLevel === 1 ? 2 : 1; + } + if (zoomLevel <= 1) { + zoomLevel = 1; + setTimeout(() => pswp.classList.remove("pswp--zoomed-in"), 0); + } + return item.initialZoomLevel * zoomLevel; + }, + }; + + // Initialize PhotoSwipe + var gallery = new PhotoSwipe( + pswp, + PhotoSwipeUI_Default, + container, + options + ); + + gallery.init(); + + // Custom zoom event + gallery.container.addEventListener("pswpTap", (e) => { + gallery.currItem.detail = e.detail; + }); + }); + }); + } + + window.addEventListener("load", initPhotoSwipe); +</script> + +<!-- 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> + <!-- 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> |