ui icon indicating copy to clipboard operation
ui copied to clipboard

Infinite gallery

Open zub0r opened this issue 4 years ago • 5 comments
trafficstars

First of all, thanks for this great plugin!

The example from the docs shows single images in the gallery instead of two listed images. https://fancyapps.com/docs/ui/fancybox/api#initialization

<div id="gallery">
  <a href="https://lipsum.app/id/1/800x600">
    <img src="https://lipsum.app/id/1/300x225" />
  </a>

  <a href="https://lipsum.app/id/2/800x600">
    <img src="https://lipsum.app/id/2/300x225" />
  </a>
</div>

<script>
  Fancybox.bind("#gallery a", {
    on : {
      ready : (fancybox) => {
        console.log(`fancybox #${fancybox.id} is ready!`);
      }
    }
  });
</script>

I'd like to use the bind method to observe the container for elements and add slides dynamically (I use infinite scroll in the grid).

zub0r avatar Aug 18 '21 18:08 zub0r

Hi,

Unfortunately, there is so much to do, and I have not yet updated the documentation to reflect recent changes. So, either use the groupAll option to group them all, or add data-fancybox attribute to your links, see this demo for different uses - https://fancyapps.com/playground/w6

fancyapps avatar Aug 19 '21 11:08 fancyapps

Thanks for the fast reply, that's what I was looking for. Is there a way to dynamically add new slides to an opened gallery from the DOM? Something like a reload? Thanks

zub0r avatar Aug 19 '21 14:08 zub0r

Sorry, it is currently not possible to add / remove slides from an already open instance. You could do something like this to destroy and reinitialize Carousel, but it is not optimized and there can be glitches:

Fancybox.getInstance().items.push({src : "https://lipsum.app/id/99/300x200/", type : "image"});
Fancybox.getInstance().Carousel.destroy();
Fancybox.getInstance().initCarousel();

Anyway, your goal is to create something like infinite gallery? Sometimes people ask for it, but I think it's useless. I believe it would be best to display maximum 20 or 25 images on the page, but include all images in the Fancybox. Unless you really have infinite number images, you can easily use Fancybox to display hundreds of images. Fancybox (and thumbnail carousel) will load visible images and next/prev items (you can configure that).

fancyapps avatar Aug 19 '21 18:08 fancyapps

Thanks. My use case is that I'm loading hundreds of items to the grid with infinite scroll in sets of 20-30 (imagine like a photo bank). When someone opens the gallery and reaches the final gallery item from the first set, it looks like there are no more items.

I've added the logic to fetch next set of items (html) when last slide is displayed, but can't load them in opened gallery. The user would have to close the gallery and reopen it for every set of new images.

zub0r avatar Aug 21 '21 18:08 zub0r

@fancyapps: I'm also interested in the same feature. As @zub0r, I have a page with some image thumbnail, and if the user scrolls down, more are loaded. However, I would like that when the user opens the Fancybox gallery view, and reaches the last image, more images are loaded with AJAX and appended to the current Fancybox instance.

Is there a way to achieve this? Thanks!

siovene avatar Mar 11 '22 17:03 siovene

Good idea, waiting for this feature too :)

fhnb16 avatar Apr 09 '23 22:04 fhnb16

Hi,

Starting from v5, you can add new slides like this:

Fancybox.getInstance().carousel.appendSlide({ src : "https://lipsum.app/id/1/800x600", type: "image"});

However, currently the thumbnails are not synchronized, but this is planned to be implemented.

fancyapps avatar Apr 10 '23 06:04 fancyapps

你好,

从 v5 开始,您可以像这样添加新幻灯片:

Fancybox.getInstance().carousel.appendSlide({ src : "https://lipsum.app/id/1/800x600", type: "image"});

不过,目前缩略图尚未同步,但计划实施。

Looking forward to adding thumbnail synchronization function.

Container-Zero avatar Jul 10 '23 19:07 Container-Zero

As of v5.0.25, it is possible to create a gallery with an infinite number of items, and thumbnails are synchronized.

Here are two possible solutions.

1. Solution

Add new slides as the user nears the end of the gallery while navigating.

const addSlides = () => {
  const carousel = Fancybox.getInstance()?.carousel;
  const totalSlides = carousel?.slides.length || 0;
  const requiredSlides = Math.ceil(window.innerWidth / 96);

  if (carousel && carousel.page >= totalSlides - requiredSlides) {
    carousel.appendSlide({
      src: `https://lipsum.app/id/${totalSlides + 1}/1024x768/`,
      thumb: `https://lipsum.app/id/${totalSlides + 1}/300x225/`,
      caption: `#${totalSlides + 1}`,
    });

    addSlides(carousel);
  }
};

Fancybox.bind('[data-fancybox="gallery"]', {
  Carousel: {
    infinite: false,
  },

  on: {
    "Carousel.ready": () => {
      addSlides();
    },
    "Carousel.change": () => {
      addSlides();
    },
  },
});    

https://jsfiddle.net/d17qftax/

2. Solution

In the previous solution, you'll notice that even though the main carousel is infinite, the user can reach the end of the row of thumbnails. The solution would be to add new slides when the thumbnail carousel position is changed.

const addSlide = () => {
  const carousel = Fancybox.getInstance()?.carousel;

  if (carousel) {
    const totalSlides = carousel.slides.length;

    carousel.appendSlide({
      src: `https://lipsum.app/id/${totalSlides + 1}/1024x768/`,
      thumb: `https://lipsum.app/id/${totalSlides + 1}/300x225/`,
      caption: `#${totalSlides + 1}`,
    });
  }
};

Fancybox.bind('[data-fancybox="gallery"]', {
  Carousel: {
    infinite: false,
  },

  Thumbs: {
    Carousel: {
      on: {
        "refresh Panzoom.afterTransform": (carousel) => {
          const { viewportDim, contentDim, panzoom } = carousel;
          const currentPos = (panzoom?.current.e || 0) * -1;

          if (contentDim - viewportDim - currentPos < viewportDim * 0.5) {
            addSlide();
          }
        },
      },
    },
  },
});   

https://jsfiddle.net/nom5p2u7/

fancyapps avatar Nov 05 '23 09:11 fancyapps