Skip to content

Commit

Permalink
feat: upgrade photo previewer to PhotoSwipe 5 (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffreytse committed Jun 30, 2023
1 parent a8c9de3 commit 03ea171
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 169 deletions.
14 changes: 10 additions & 4 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
203 changes: 38 additions & 165 deletions _includes/extensions/photo-swipe.html
Original file line number Diff line number Diff line change
@@ -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>
Expand All @@ -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>

0 comments on commit 03ea171

Please sign in to comment.