dimsemenov / PhotoSwipe

JavaScript image gallery for mobile and desktop, modular, framework independent
http://photoswipe.com
MIT License
24.18k stars 3.31k forks source link

*v5-beta* How to make gallery responsive without knowing width and height of images #1752

Open pihomeserver opened 3 years ago

pihomeserver commented 3 years ago

Hi Using the beta, i would like to build multiple galleries dynamically (code is not optimized !):

const galleryCount = 10;

let optionsGallery = Array.from({length: galleryCount}, (_, i) => {
    let galleryId = i + 1;
    let options = {
        // Suppose 2 images per gallery
        dataSource: new Array(2),
        showHideAnimationType: "none",
        pswpModule: "./assets/photoswipe/photoswipe.esm.js",
        pswpCSS: "./assets/photoswipe/photoswipe.css"
    }
    return options
})
const gallery01 = new PhotoSwipeLightbox(optionsGallery[0]);
gallery01.init();
gallery01.on('itemData', (e) => {
    e.itemData = {
        src: 'images/01/art-0' + (e.index + 1) + '.jpg',
        w: '100%',
        h: '100%'
    };
});

How can i get width and height of the image using a preload promise to set 'w' and 'h' to make the image responsive with correct ratio ?

I tried to use with no success

function loadImage(url) {
  return new Promise(resolve => {
    const image = new Image();
    image.addEventListener('load', () => {
      resolve(image);
    });
    image.src = url;
  });
}

Thanks

pihomeserver commented 3 years ago

I tried something different for the event :

function waitForImageToLoad(imageElement){
  return new Promise(resolve=>{imageElement.onload = resolve})
}

gallery01.on('itemData', (e) => {
  const image = new Image();
  image.src = 'images/01/art-01.jpg';
  waitForImageToLoad(image).then(()=>{
    console.log('Loaded')
    e.itemData = {
      src: 'images/01/art-01.jpg',
      w: 2000,
      h: 2000
    };
  });
});

Here is the error :

Loaded
opener.js:211 Uncaught (in promise) TypeError: Cannot read property 'style' of undefined
    at Opener._initiate (opener.js:211)
    at Opener._start (opener.js:199)
    at Opener.open (opener.js:32)
    at PhotoSwipe.init (photoswipe.js:177)
    at PhotoSwipeLightbox._openPhotoswipe (lightbox.js:232)
    at lightbox.js:187
_initiate @ opener.js:211
_start @ opener.js:199
open @ opener.js:32
init @ photoswipe.js:177
_openPhotoswipe @ lightbox.js:232
(anonymous) @ lightbox.js:187
Promise.then (async)
preload @ lightbox.js:178
loadAndOpen @ lightbox.js:129
document.querySelector.onclick @ main.js:187
2main.js:177 Loaded

Same if i set the function async with await in front of the waitForImageToLoad function call

twojtylak commented 3 years ago

@pihomeserver Not sure if this helps you but, I tried it with setting the height via loadComplete callback:

lightbox.on('loadComplete', (data) => {
    if (null !== data.slide.image) {
      lightbox.pswp.currSlide.width = data.slide.image.width;
      lightbox.pswp.currSlide.height = data.slide.image.height;
      lightbox.pswp.currSlide.resize();
    }
  });