-
-
Save Grawl/e67aeffbe5e3c09c5ca1acc95765df61 to your computer and use it in GitHub Desktop.
import PhotoSwipe from 'photoswipe/dist/photoswipe' | |
import PhotoSwipeUI_Default from 'photoswipe/dist/photoswipe-ui-default' | |
import { photoswipePreviews } from './previews' | |
const holder = document.querySelector('.pswp') | |
// initializing code | |
const openPhotoSwipe = ({ items }) => { | |
// opening code | |
const gallery = new PhotoSwipe(holder, PhotoSwipeUI_Default, items, { /* options */ }) | |
photoswipePreviews(gallery) // <- add this | |
gallery.init() | |
} |
// Root element of PhotoSwipe. Must have class pswp. | |
.pswp(tabindex='-1' role='dialog' aria-hidden='true') | |
// | |
Background of PhotoSwipe. | |
It's a separate element as animating opacity is faster than rgba(). | |
.pswp__bg | |
// Slides wrapper with overflow:hidden. | |
.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. | |
.pswp__container | |
.pswp__item | |
.pswp__item | |
.pswp__item | |
// Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. | |
.pswp__ui.pswp__ui--hidden | |
.pswp__top-bar | |
// Controls are self-explanatory. Order can be changed. | |
.pswp__counter | |
button.pswp__button.pswp__button--close(title='Close (Esc)') | |
button.pswp__button.pswp__button--share(title='Share') | |
button.pswp__button.pswp__button--fs(title='Toggle fullscreen') | |
button.pswp__button.pswp__button--zoom(title='Zoom in/out') | |
// Preloader demo https://codepen.io/dimsemenov/pen/yyBWoR | |
// element will get class pswp__preloader--active when preloader is running | |
.pswp__preloader | |
.pswp__preloader__icn | |
.pswp__preloader__cut | |
.pswp__preloader__donut | |
.pswp__share-modal.pswp__share-modal--hidden.pswp__single-tap | |
.pswp__share-tooltip | |
button.pswp__button.pswp__button--arrow--left(title='Previous (arrow left)') | |
button.pswp__button.pswp__button--arrow--right(title='Next (arrow right)') | |
.pswp__previews(data-previews) | |
.pswp__caption | |
.pswp__caption__center |
module.exports = { | |
plugins: { | |
'postcss-momentum-scrolling': [ | |
'scroll', | |
'auto', | |
], | |
'postcss-position-alt': {}, | |
'postcss-short': {}, | |
'postcss-axis': {}, | |
'postcss-single-charset': {}, | |
'postcss-font-family-system-ui': {}, | |
'autoprefixer': {}, | |
}, | |
} |
/** | |
* @param {object} gallery | |
*/ | |
export const photoswipePreviews = gallery => { | |
let added = false | |
const props = { | |
gallery, | |
selector: '[data-previews]', | |
} | |
gallery.listen('gettingData', () => { | |
if (added) return | |
added = true | |
addPreviews(props) | |
}) | |
gallery.listen('close', () => { | |
removePreviews(props) | |
}) | |
gallery.listen('afterChange', () => { | |
setActivePreview(props) | |
}) | |
} | |
/** | |
* @typedef photoSwipePreviewsMethodProps | |
* @prop {object} gallery | |
* @prop {string} selector | |
*/ | |
/** | |
* @param {photoSwipePreviewsMethodProps} props | |
*/ | |
const addPreviews = ({ gallery, selector }) => { | |
const { scrollWrap, items } = gallery | |
const place = scrollWrap.querySelector(selector) | |
for (const item of items) { | |
const { msrc: preview } = item | |
const element = document.createElement('img') | |
element.setAttribute('src', preview) | |
element.addEventListener('click', () => { | |
gallery.goTo(items.indexOf(item)) | |
}) | |
place.appendChild(element) | |
} | |
} | |
/** | |
* @param {photoSwipePreviewsMethodProps} props | |
*/ | |
const removePreviews = ({ gallery, selector }) => { | |
const { scrollWrap } = gallery | |
const place = scrollWrap.querySelector(selector) | |
place.innerHTML = '' | |
} | |
/** | |
* @param {photoSwipePreviewsMethodProps} props | |
*/ | |
const setActivePreview = ({ gallery, selector }) => { | |
const { scrollWrap, currItem } = gallery | |
const { msrc: preview } = currItem | |
const place = scrollWrap.querySelector(selector) | |
const previewElements = place.querySelectorAll('img') | |
for (const element of previewElements) { | |
const src = element.getAttribute('src') | |
const className = 'is-active' | |
// Warning: collision possible if image not unique | |
if (src === preview) { | |
element.classList.add(className) | |
element.scrollIntoView({ behavior: 'smooth' }) | |
} | |
else element.classList.remove(className) | |
} | |
} |
.pswp | |
&__caption | |
bottom: 3em | |
&__previews | |
absolute: bottom left | |
width: 100% | |
display: flex | |
flex-flow: row | |
justify-content: center | |
background-color: rgba(black, 0.3) | |
overflow: auto | |
// Hide scrollbar in Quantum (Firefox) | |
scrollbar-width: none | |
// Hide scrollbar in Blink (Chrome) | |
&::-webkit-scrollbar | |
display: none | |
img | |
size: 3em | |
object-fit: cover | |
opacity: 0.3 | |
transition: opacity 0.3s | |
cursor: pointer | |
&:hover | |
opacity: 0.8 | |
&.is-active | |
opacity: 1 | |
cursor: default |
works good thank you but if you have A LOT thumbnails, you get problems with scrolling horizontal thru the thumbnails.
what problems?
with justify-content:center it looks good on large screens and when you just have a few thumbnails but with many thumbnails you are unable to scroll to the beginning of the thumbnails. and if you try you will leave the lightbox because it responses on scroll events with an exit. i will try to fix this on my side with more html/css code for the thumbnails.
oh I see. I just added some images to my codepen and see this flexbox problem https://codepen.io/Grawl/pen/PoZBMPg
oh cool! can you update that codepen with your fixes? so anyone can use Photoswipe with good working previews.
Clicking on the thumbnails in https://codepen.io/Grawl/pen/ExPpXeW is not working
working for me
https://codepen.io/Grawl/pen/PoZBMPg