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

Photoswipe 5 without defining image width and height? #1988

Open carlo-fontanos opened 1 year ago

carlo-fontanos commented 1 year ago

In v4 I was able to achieve it like this:

gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options);

gallery.listen('gettingData', (index, item) => {
    if (!item.w || !item.h) {
        const innerImgEl = item.el.getElementsByTagName('img')[0]
        if (innerImgEl) {
            item.w = innerImgEl.width * 10;
            item.h = innerImgEl.height * 10;
        }

        const img = new Image()
        img.onload = function () {
            item.w = this.width;
            item.h = this.height;
            gallery.updateSize(true);
        }
        img.src = item.src
    }
});

Is there an equivalent solution that we can use on v5?

dimsemenov commented 1 year ago

The PhotoSwipe is designed around having pre-defined dimensions, so there is no such option. Technically you may preload the image and only then open the gallery (or append the slide).

carlo-fontanos commented 1 year ago

Thanks for your reply, I'll try your suggestion. Is there a method in v5 similar to:

gallery.listen('gettingData', (index, item) => {})

that can used to achieve this? Or can you share a code showing your approach on preloading image?

dimsemenov commented 1 year ago

You may check itemData filter, there are some examples with it in docs - https://photoswipe.com/data-sources/#dynamically-generated-data Just be careful with async requests in it, as it's called each time the gallery requests data about a slide, including lazy-loading.

carlo-fontanos commented 1 year ago

Thanks for your reply. I tried the itemData filter as follows:

lightbox.addFilter('itemData', (itemData, index) => {
    const img = new Image()
    img.onload = function () {
        return {
            src: itemData.src,
            width: this.width,
            height: this.height
        };
    }
    img.src = itemData.src;
});

But I'm getting an error. I think PhotoSwipe is expecting the return right away, but the img.onload() blocks it. Please kindly advice.

dimsemenov commented 1 year ago

Async response of itemData filter is not supported, you'll need to do something similar to your old code. As I mentioned previously, The PhotoSwipe is designed around having pre-defined dimensions.

mohamad68 commented 1 year ago

The PhotoSwipe is designed around having pre-defined dimensions.

this is really annoying developers because they don't know the dimensions of images that are uploaded by the admin

spoitler commented 1 year ago

i had the same requirement. i have edited source files, rebuild it and then i think it's working now without pre-defined dimensions.

it's the first time i'm contributing to an open source project. Do i need to do a PR or do i need to ask to the creator if he wants this way of working for his lib ?

Screenshot 2023-04-26 194549

https://user-images.githubusercontent.com/20995631/234661115-ccff8ef5-36aa-46f7-90e8-d62973757763.mp4

brianjenkins94 commented 1 year ago

@spoitler What did you change?

poonasor commented 1 year ago

i had the same requirement. i have edited source files, rebuild it and then i think it's working now without pre-defined dimensions.

it's the first time i'm contributing to an open source project. Do i need to do a PR or do i need to ask to the creator if he wants this way of working for his lib ?

Screenshot 2023-04-26 194549

2023-04-26.19-46-30.mp4

would also like to know how you did this

spoitler commented 1 year ago

I set by default the width and height with the naturalWidth and naturalHeight HTMLImageElement properties. Then i check whether data-pswp-width and data-pswp-height params exist, if so, i replace the naturalWidth and naturalHeight with the defined values. @brianjenkins94

otary commented 1 year ago

I think setting the default width and height is a good idea. Once the width and height preview is not set, there will be problems. Setting the default width and height can be used as a compatibility solution

pbender87 commented 1 year ago

Any updates here? I pass in an array of items via dataSource option and do not have any dimensions as the editor is uploading the images via a cms. I have tried difference thinks but i have no good solution, yet.

It's a bad practice to preload all "large" images to find out the naturalWidth and naturalHeight. As PhotoSwipe is already loading the image and is listening to the onload event of the HTMLImageElement, its much more efficient to handle it inside.

So i have no good idea to solve this in combination with the dataSource option.

krystofbe commented 1 year ago

I want to echo the concerns raised by others here. It's a significant limitation to require developers to know the image dimensions ahead of time. In many real-world applications, images are managed and uploaded via CMS where the developers might not have direct access to, or knowledge of, the image dimensions.

A common use case is wanting to display images in a centered manner with a height of 100%. This doesn't necessitate knowing the dimensions ahead of time - the goal is to have the image take up the full height of the container while maintaining its aspect ratio. This is a standard requirement and should be accommodated in a modern, versatile lightbox solution like PhotoSwipe.

arnowelzel commented 11 months ago

Eventough I understand the need to add images without knowing their exact size: one of the major features of PhotoSwipe is to zoom into images and to support this in a proper way, it must know the image size. If you just need a image slider, there are many other solutions out there which make sure, the image is either using 100% of the viewports width or height, depending on what dimension fits best.

Maybe determining the real image size once an image is loaded, is enough - then you can still click on it to zoom when it is bigger than the current viewport.