Skip to content

Instantly share code, notes, and snippets.

@Grawl
Last active March 27, 2025 05:49
Show Gist options
  • Select an option

  • Save Grawl/e67aeffbe5e3c09c5ca1acc95765df61 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown
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