diff options
author | Jeffrey Tse <jeffreytse.mail@gmail.com> | 2023-06-30 22:52:04 +0800 |
---|---|---|
committer | Jeffrey Tse <jeffreytse.mail@gmail.com> | 2023-06-30 22:52:04 +0800 |
commit | 03ea17117db4dd00e3dd38984389181c2c0faa2f (patch) | |
tree | 2c04a3cf8edbc8eb51519ff5202d477d703e0e8f | |
parent | a8c9de315d6680f17217dc0abbc135d23092f344 (diff) |
feat: upgrade photo previewer to PhotoSwipe 5 (#115)
-rw-r--r-- | _config.yml | 14 | ||||
-rw-r--r-- | _includes/extensions/photo-swipe.html | 203 |
2 files changed, 48 insertions, 169 deletions
diff --git a/_config.yml b/_config.yml index 981fa59..40d9762 100644 --- a/_config.yml +++ b/_config.yml @@ -183,11 +183,17 @@ yat: # Pagination setting # paginate: 5 -# Photo previewer settings +# Photo previewer settings (PhotoSwipe 5) +# the options please refer to: https://photoswipe.com/options/ # photo_previewer: -# photo_selectors: "section.main" # Preview specified areas of photos by CSS selectors (It also can be an array) -# photo_scale: 2 # Adjust the preview scale of photos -# background_opacity: 0.85 # Background backdrop opacity +# gallery: "section.main" +# children: "a.photo-swipe" +# bgOpacity: 0.8 +# padding: +# top: 20 +# bottom: 40 +# left: 100 +# right: 100 # Disqus comments # disqus: diff --git a/_includes/extensions/photo-swipe.html b/_includes/extensions/photo-swipe.html index ec4b8a2..9a5a51c 100644 --- a/_includes/extensions/photo-swipe.html +++ b/_includes/extensions/photo-swipe.html @@ -1,11 +1,7 @@ -<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> +<script src="//cdnjs.cloudflare.com/ajax/libs/photoswipe/5.3.7/umd/photoswipe-lightbox.umd.min.js"></script> +<script src="//cdnjs.cloudflare.com/ajax/libs/photoswipe/5.3.7/umd/photoswipe.umd.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" + href="//cdnjs.cloudflare.com/ajax/libs/photoswipe/5.3.7/photoswipe.min.css" rel="stylesheet" /> <style> @@ -16,188 +12,65 @@ <script> function initPhotoSwipe() { - const selectors = '{{ site.photo_previewer.photo_selectors || join: "," }}' - .split(",") - .filter((item) => item.length > 0); + let customOptions = {}; - // Default selector - if (selectors.length === 0) { - selectors.push("section.main"); + try { + const data = `{{ site.photo_previewer }}`.replaceAll("=>", ":"); + customOptions = JSON.parse(data); + } catch (e) { + console.error("Invalid custom photo previewer options! " + e.message); } - const areaEls = []; - selectors.forEach((selector) => { - const el = document.querySelector(selector); - if (el) { - areaEls.push(el); - } - }); + // Define object and gallery options + const options = Object.assign( + { + gallery: "section.main", + children: "a.photo-swipe", + photo_scale: 2, + // dynamic import is not supported in UMD version + pswpModule: PhotoSwipe, + }, + customOptions + ); + + const galleryEl = document.querySelector(options.gallery); + if (!galleryEl) { + return; + } const imgEls = []; - - areaEls.forEach((areaEl) => { - var els = areaEl.querySelectorAll("img:not(.emoji)"); - els.forEach((el) => { - if (!imgEls.includes(el)) { - imgEls.push(el); - } - }); + const els = galleryEl.querySelectorAll("img:not(.emoji)"); + els.forEach((el) => { + if (!imgEls.includes(el)) { + imgEls.push(el); + } }); if (imgEls.length === 0) { return; } - const photo_scale = '{{ site.photo_previewer.photo_scale }}'; - const background_opacity = '{{ site.photo_previewer.background_opacity }}'; - const previewer_options = { - photo_scale: photo_scale.length > 0 ? parseFloat(photo_scale) : 2, - background_opacity: background_opacity.length > 0 ? - parseFloat(background_opacity) : 0.85, - }; - imgEls.forEach((imgEl) => { imgEl.outerHTML = ` <a class="photo-swipe" href="${imgEl.src}" - data-width="${ - Math.max(imgEl.naturalWidth, imgEl.width) * - previewer_options.photo_scale + data-pswp-width="${ + Math.max(imgEl.naturalWidth, imgEl.width) * options.photo_scale }" - data-height="${ - Math.max(imgEl.naturalHeight, imgEl.height) * - previewer_options.photo_scale + data-pswp-height="${ + Math.max(imgEl.naturalHeight, imgEl.height) * options.photo_scale }" - data-caption="${imgEl.getAttribute("caption") || imgEl.alt}" + data-pswp-caption="${imgEl.getAttribute("caption") || imgEl.alt}" target="_blank"> ${imgEl.outerHTML} </a>`; }); - // Init empty gallery array - var container = []; + // Initialize PhotoSwipe 5 + var lightbox = new PhotoSwipeLightbox(options); - // Loop over gallery items and push it to the array - var linkEls = document.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: previewer_options.background_opacity, - showHideOpacity: true, - closeOnScroll: true, - 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; - }); - }); - }); + lightbox.init(); } 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> |