How to query full size image using gatsby-image?

I’d need a bit of advice with gatsby-image. I’m building a gallery with a custom lightbox.

Query:

export const getAllPhotos = graphql`
query GetAllPhotos {
    allStrapiPortfolio {
        photos: nodes {
            categories {
                name
            }
            photo {
                childImageSharp {
                    fluid(quality: 100) {
                        ...GatsbyImageSharpFluid
                    }
                }
            }
            strapiId
        }
    }
}
`;

I’m displaying my images in a grid. photos prop contains images from the query above.

Gallery.js

const Gallery = ({ photos }) => {
const [currentPhotoId, setCurrentPhotoId] = useState(null);

const handleClick = (e) => {
    const lightbox = document.getElementById("lightbox");
    const div = parseInt(e.target.parentElement.parentElement.className.split(" ")[0]);
    const imgSelected = e.target.parentElement.parentElement.className.includes("gatsby-image-wrapper");

    if (imgSelected) {
        setCurrentPhotoId(div);
        lightbox.classList.add("lightbox-active");
    } else {
        setCurrentPhotoId(null);
        lightbox.classList.remove("lightbox-active");
    }
};

return (
    <main className="portfolio-gallery" onClick={(e) => handleClick(e)}>
        photos.map((item) => {
                    return (
                        <Image
                            key={item.strapiId}
                            fluid={item.photo.childImageSharp.fluid}
                            data-categories={item.categories[0]}
                            alt={item.categories[0].name}
                            className={`${item.strapiId}`}
                        />
                    );              
              })}
        <Lightbox photos={photos} currentPhotoId={currentPhotoId} />
    </main>
);
};

export default Gallery;

And after an image is clicked I display my lightbox component

lightbox.js

const Lightbox = ({ photos, currentPhotoId }) => {
const currentPhoto = photos.filter((photo) => photo.strapiId === currentPhotoId)[0];

return currentPhotoId === null ? (
    <div id="lightbox" className="lightbox">
        <h4>Nothing to display, this is hidden currently</h4>
    </div>
) : (
    <div id="lightbox" className="lightbox">
        <Image fluid={currentPhoto.photo.childImageSharp.fluid} />
    </div>
);
};

export default Lightbox;

Problem is that when I display my image in the lightbox stretched across the screen it is in a bad quality as the query downloads images in small sizes. However, my original images are 5000px wide. Unfortunately, as gatsby page queries are generated at the build I’m stuck with this quality.

Any idea about a workaround?

Answer

The idea when dealing with multiple images with gatsby-images for your kind of use-case is to query different image resolutions using the art director workaround (breakpoints). The idea, based on the documentation is to:

import React from "react"
import { graphql } from "gatsby"
import Img from "gatsby-image"

export default ({ data }) => {
  // Set up the array of image data and `media` keys.
  // You can have as many entries as you'd like.
  const sources = [
    data.mobileImage.childImageSharp.fluid,
    {
      ...data.desktopImage.childImageSharp.fluid,
      media: `(min-width: 768px)`,
    },
  ]

  return (
    <div>
      <h1>Hello art-directed gatsby-image</h1>
      <Img fluid={sources} />
    </div>
  )
}

export const query = graphql`
  query {
    mobileImage: file(relativePath: { eq: "blog/avatars/kyle-mathews.jpeg" }) {
      childImageSharp {
        fluid(maxWidth: 1000, quality: 100) {
          ...GatsbyImageSharpFluid
        }
      }
    }
    desktopImage: file(
      relativePath: { eq: "blog/avatars/kyle-mathews-desktop.jpeg" }
    ) {
      childImageSharp {
        fluid(maxWidth: 2000, quality: 100) {
          ...GatsbyImageSharpFluid
        }
      }
    }
  }
`

Leave a Reply

Your email address will not be published. Required fields are marked *