12
votes

Comment interroger plusieurs images avec gatsby-image?

J'ai 16 images que je souhaite afficher sur un site Web dans un format de grille.

J'utilise les plugins suivants pour cela:

  • gatsby-image
  • gatsby-source-filesystem
  • gatsby-plugin-sharp
  • gatsby-transformer-sharp

J'ai lu la documentation et pour autant que je sache, elle n'a démontré que comment interroger une seule image.

par exemple

export const squareImage = graphql`
  fragment squareImage on File {
    childImageSharp {
      fluid(maxWidth: 200, maxHeight: 200) {
        ...GatsbyImageSharpFluid
      }
    }
  }
`

export const query = graphql`
  query {
    image1: file(relativePath: { eq: "images/image1.jpg" }) {
      ...squareImage
    }

    image2: file(relativePath: { eq: "images/image2.jpg" }) {
      ...squareImage
    }

    image3: file(relativePath: { eq: "images/image3.jpg" }) {
      ...squareImage
    }
  }
`

Mais comment procéderais-je si j'avais 16 images? La rédaction de 16 requêtes distinctes semble assez lourde et serait difficile à lire à l'avenir.

J'ai vu ce code dans la documentation référençant plusieurs images, mais j'ai du mal à essayer d'accéder aux images elles-mêmes.

par exemple

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

export default ({ data }) => (
  <div>
    <h1>Hello gatsby-image</h1>
    <Img fixed={data.file.childImageSharp.fixed} />
  </div>
)

export const query = graphql`
  query {
    file(relativePath: { eq: "blog/avatars/kyle-mathews.jpeg" }) {
      childImageSharp {
        # Specify the image processing specifications right in the query.
        # Makes it trivial to update as your page's design changes.
        fixed(width: 125, height: 125) {
          ...GatsbyImageSharpFixed
        }
      }
    }
  }
`

Ma structure de dossiers est la suivante:

--- package.json

--- src

------images

--------- les 16 images

------ pages

--------- la page où je veux rendre les 16 images dans

etc.

Merci.


2 commentaires

La réponse fournie n'a pas expliqué comment utiliser le code donné dans l'exemple. Je n'ai pas encore compris comment importer image1, image2 et image3. Toute aide serait appréciée.


Salut @ R3N0, "image1:", "image2:", etc. sont des alias, vous les appelleriez donc data.image1.childImageSharp... , etc.


3 Réponses :


9
votes

Avoir un fouet dans GraphiQL devrait vous aider, en particulier l'Explorateur. N'oubliez pas que les fragments Gatsby ne fonctionneront pas dans GraphiQL.

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

const imgGridStyle = {
  display: 'grid',
  gridTemplateColumns: `repeat(auto-fill, 200px)`
};

export default ({ data }) => (
  <div>
    <h1>Hello gatsby-image</h1>
    <div style={imgGridStyle}>
      {data.allImageSharp.edges.map(edge => 
        <Img fluid={edge.node.fluid} />
      )}
    </div>
  </div>
)

export const query = graphql`
  query {
    allImageSharp {
      edges {
        node {
          id
          fluid(maxWidth: 200, maxHeight: 200) {
            ...GatsbyImageSharpFluid
          }
        }
      }
    }
  }
`

Donc , ce qui précède doit être égale à quelque chose comme la requête suivante qui travaillera en GraphiQL

{
  allImageSharp {
    edges {
      node {
        id
        fluid(maxHeight: 200, maxWidth: 200) {
          src
          srcSet
          base64
          aspectRatio
          originalImg
          sizes        
        }
      }
    }
  }
}

Ensuite, votre composant peut utiliser cette même requête et rendre les résultats comme ceci:

{
  allImageSharp {
    edges {
      node {
        id
        fluid(maxWidth: 200, maxHeight: 200) {
            ...GatsbyImageSharpFluid
        }
      }
    }
  }
}

Vous pouvez facilement parcourir le tableau résultant de nœuds imageSharp renvoyés par la requête dans data.allImageSharp.edges.map . gatsby-image ensuite la propriété fluid chaque nœud, comme accessoire fluid à gatsby-image .

Remarque: Cela rend chaque nœud imageSharp de votre projet, ce qui peut être ou non ce que vous souhaitez réaliser.


6 commentaires

Belle solution, a parfaitement fonctionné! Merci. Je voudrais demander un suivi. Puisque les images fluides remplissent automatiquement la largeur du conteneur, comment puis-je m'assurer que maxWidth fonctionne pour les images fluides de sorte que lorsque sa largeur est plus petite que ses conteneurs, la largeur est conservée.


J'ai fait une petite modification au css du conteneur de grille. Mais fondamentalement, vous avez juste besoin de css pour contraindre chaque <Img /> à avoir une largeur maximale de 200 px. Il existe de nombreuses façons de le faire dans CSS (mais elles sont probablement en dehors de la portée de cette question), alors n'hésitez pas à poser une autre question et à me lier ici.


Génial, tu as raison. L'ajout de styles CSS supplémentaires qui correspondent aux styles de la requête fonctionne. Merci. Il semble que même sans utiliser CSS Grid , gatsby-image dispose déjà de flex-wrap pour un design réactif? Je l'ai testé avec des images fixes.


Je pense qu'ils sont configurés pour display: inline-block; , tout comme un HTML classique <img>


Oh vraiment? Cool.


Avec cette solution, comment spécifier le chemin d'accès au dossier avec les images? Comme par exemple, pour une seule image, il y a image1: file(relativePath: { eq: "images/image1.jpg" })



4
votes

Le moyen le plus simple est de créer un fournisseur d'images:

<Image fileName="yourImage.jpg" style={{ width: '100%' }} alt="" />

Et puis, après l'importation, insérez facilement l'image dont vous avez besoin:

import React from 'react'
import { graphql, useStaticQuery } from 'gatsby'
import Img from 'gatsby-image'

const Image = ({ fileName, alt, style }) => {
  const { allImageSharp } = useStaticQuery(graphql`
    query {
      allImageSharp {
        nodes {
          fluid(maxWidth: 1600) {
            originalName
            ...GatsbyImageSharpFluid_withWebp
          }
        }
      }
    }
  `)

  const fluid = allImageSharp.nodes.find(n => n.fluid.originalName === fileName)
    .fluid

  return (
    <figure>
      <Img fluid={fluid} alt={alt} style={style} />
    </figure>
  )
}

export default Image;


1 commentaires

Cela fonctionne, mais la taille du bundle ... Pouvons-nous améliorer cela d'une manière ou d'une autre? Je sais qu'il n'y a aucun argument comme ${name} autorisé dans les requêtes statiques.



0
votes

Voici un exemple simple avec la prise en charge de TypeScript et SVG:

<Image name="logo.svg" alt="compony logo" />
or
<Image name="logo.png" alt="compony logo" />

et utilisez le composant comme

import * as React from 'react';
import { FC } from 'react';
import { graphql, StaticQuery } from 'gatsby';
import Img from 'gatsby-image';

interface IProps {
  name: string;
  alt: string;
  className?: string;
}

const Image: FC<IProps> = ({ name, alt, className }) => (
  <StaticQuery
    query={graphql`
      query {
        allImages: allFile {
          nodes {
            publicURL
            extension
            sharp: childImageSharp {
              fluid {
                originalName
                ...GatsbyImageSharpFluid_withWebp
              }
            }
          }
        }
      }
    `}
    render={({ allImages }) => {
      const image = allImages.nodes.find(
        (node: any) => node.publicURL.indexOf(name) !== -1
      );
      if (!image) {
        return null;
      }
      // svg support
      if (image && image.extension === 'svg') {
        return (
          <img
            className={className}
            src={image.publicURL}
            alt={alt}
            width="100"
            height="100"
          />
        );
      }
      return <Img className={className} fluid={image.sharp.fluid} alt={alt} />;
    }}
  />
);

export { Image };


0 commentaires