Gatsby: Lightbox plugin that utilizes Gatsby-Image

Created on 4 Aug 2018  Â·  8Comments  Â·  Source: gatsbyjs/gatsby

Summary

Gatsby-Image opens up a myriad of possibilities when working with images on the web. Having additional lightbox functionality, similar to React-Images would really take it to the next level.

Basic example

The examples on the React-Images site showcase desired functionality.

Motivation

  1. Why are we doing this?
  2. Expands the already fantastic Gatsby-Image functionality.
  3. What use cases does it support?
  4. Image galleries, detail views, product views, etc.
  5. What is the expected outcome?
  6. Plugin should be source agnostic in Gatsby. If an image is loaded using Gatsby-Image, users should be allowed to set a flag that enables a lightbox for that image. It should be possible to viewers to progress to the next image in a gallery set through thumbnails/keyboard interaction/on-screen navigation.

Most helpful comment

Maybe a plugin is not needed actually. An example in the docs could suffice.

Here's an extracted code

class Gallery extends Component {
  constructor(props) {
    super(props);
    this.state = {
      shareOpen: false,
      anchorEl: null,
      lightbox: false,
      photos: props.photos.map(photo => Object.assign({ srcSet: photo.childImageSharp.fluid.srcSet })),
    };
  }

  gotoPrevLightboxImage() {
    const { photo } = this.state;
    this.setState({ photo: photo - 1 });
  }

  gotoNextLightboxImage() {
    const { photo } = this.state;
    this.setState({ photo: photo + 1 });
  }

  openLightbox(photo, event) {
    event.preventDefault();
    this.setState({ lightbox: true, photo });
  }

  closeLightbox() {
    this.setState({ lightbox: false });
  }

  render() {
    const { photos } = this.props;
    return (
      <div>
        <div>
          {photos.map((photo, i) => (
            <a href={photo.childImageSharp.fluid.src} onClick={e => this.openLightbox(i, e)}>
              <Img key={i} className={classes.spacer} fluid={photo.childImageSharp.fluid} />
            </a>
          ))}
        </div>
        <Lightbox
          backdropClosesModal
          images={this.state.photos}
          currentImage={this.state.photo}
          isOpen={this.state.lightbox}
          onClickPrev={() => this.gotoPrevLightboxImage()}
          onClickNext={() => this.gotoNextLightboxImage()}
          onClose={() => this.closeLightbox()}
        />
      </div>
    );
  }
}

All 8 comments

@iammatthias I am not smart enough to create a plugin that adds a lightbox flag to images but I created a small example using gatsby-image and built a custom lightbox that has on screen controls and listens to keyboard events.

Github: https://github.com/416serg/gatsby-starter-lightbox
Demo: https://gatsby-lightbox.416serg.me/

Instead of creating a new plugin for this, it might be a good idea to modify react-images to allow replacing their image component.

Maybe a plugin is not needed actually. An example in the docs could suffice.

Here's an extracted code

class Gallery extends Component {
  constructor(props) {
    super(props);
    this.state = {
      shareOpen: false,
      anchorEl: null,
      lightbox: false,
      photos: props.photos.map(photo => Object.assign({ srcSet: photo.childImageSharp.fluid.srcSet })),
    };
  }

  gotoPrevLightboxImage() {
    const { photo } = this.state;
    this.setState({ photo: photo - 1 });
  }

  gotoNextLightboxImage() {
    const { photo } = this.state;
    this.setState({ photo: photo + 1 });
  }

  openLightbox(photo, event) {
    event.preventDefault();
    this.setState({ lightbox: true, photo });
  }

  closeLightbox() {
    this.setState({ lightbox: false });
  }

  render() {
    const { photos } = this.props;
    return (
      <div>
        <div>
          {photos.map((photo, i) => (
            <a href={photo.childImageSharp.fluid.src} onClick={e => this.openLightbox(i, e)}>
              <Img key={i} className={classes.spacer} fluid={photo.childImageSharp.fluid} />
            </a>
          ))}
        </div>
        <Lightbox
          backdropClosesModal
          images={this.state.photos}
          currentImage={this.state.photo}
          isOpen={this.state.lightbox}
          onClickPrev={() => this.gotoPrevLightboxImage()}
          onClickNext={() => this.gotoNextLightboxImage()}
          onClose={() => this.closeLightbox()}
        />
      </div>
    );
  }
}

Thanks, @oorestisime. I'll give that a shot!

Thanks for the help, @oorestisime. I was able to get the Lightbox working using the code you provided.

Thanks for the help, @oorestisime. I was able to get the Lightbox working using the code you provided.

@iammatthias is your working code posted somewhere? I'm new to react and have never used react-images before so I'm a little lost on how to get oorestisime's code working.

@moxdev my gallery code is here: https://github.com/iammatthias/net/blob/master/src/templates/gallery.js

That’s the template, it passes the images from the GraphQL query down to a component that renders the lightbox. Component is here: https://github.com/iammatthias/net/blob/master/src/components/Gallery/GalleryGrid.js

I’m in the process of cleaning up the codebase. It’s kinda a mess, and has some redundencies right now.

@iammatthias your example was very helpful for me to get graphql data of local photos, 'gatsby-image', and the lightbox from 'react-images' working together. Thank you 🙌

Was this page helpful?
0 / 5 - 0 ratings