Skip to content

Instantly share code, notes, and snippets.

@Grawl
Last active April 18, 2023 14:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Grawl/e67aeffbe5e3c09c5ca1acc95765df61 to your computer and use it in GitHub Desktop.
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
@Grawl
Copy link
Author

Grawl commented Jul 14, 2020

@nicmare
Copy link

nicmare commented Dec 15, 2020

works good thank you but if you have A LOT thumbnails, you get problems with scrolling horizontal thru the thumbnails.

@Grawl
Copy link
Author

Grawl commented Dec 16, 2020

what problems?

@nicmare
Copy link

nicmare commented Dec 16, 2020

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.
image

@Grawl
Copy link
Author

Grawl commented Dec 16, 2020

oh I see. I just added some images to my codepen and see this flexbox problem https://codepen.io/Grawl/pen/PoZBMPg

@Grawl
Copy link
Author

Grawl commented Dec 17, 2020

oh cool! can you update that codepen with your fixes? so anyone can use Photoswipe with good working previews.

@888ba8
Copy link

888ba8 commented Jan 8, 2021

Clicking on the thumbnails in https://codepen.io/Grawl/pen/ExPpXeW is not working

@Grawl
Copy link
Author

Grawl commented Jan 12, 2021

working for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment