React Gatsbyjs добавляет класс к gatsby-image на основе соотношения сторон

gatsby-image оборачивает каждое изображение в div gatsby-image-wrapper, который заполняет 100% доступной ширины области просмотра. Этот div-оболочку можно легко стилизовать с помощью CSS, но невозможно обрабатывать пейзажные, портретные или квадратные изображения по-разному.

React Gatsbyjs добавляет класс к gatsby-image на основе соотношения сторон Что если вы хотите, чтобы горизонтальные изображения заполняли 80-100% доступной ширины, а портретные и квадратные изображения заполняли не более 40-50% ширины области просмотра.

Таким образом, в идеале к каждому div gatsby-image-wrapper добавляется класс в зависимости от его соотношения сторон, что может быть либо; landscape, portrait или square.

Один из способов сделать это — написать некоторый условный оператор, используя соотношение сторон, которое поставляется с childImageSharp:

      edges {
        node {
          name
          childImageSharp {
            fluid(maxWidth: 915, quality: 90) {
              aspectRatio
              ...GatsbyImageSharpFluid_withWebp
            }
          }
        }
      }

Когда я сопоставляю все изображения своей галереи, я могу получить соотношение сторон и добавить его к каждой gatsby-image-wrapper, используя className, но это не очень полезно в необработанном формате, поскольку возвращаемые данные для aspectRatio представляют собой числа, такие как 0.6666666666666666 для портретных изображений или 1.5003750937734435 для пейзажа. Было бы лучше работать с упомянутыми выше классами; landscape, portrait или square.

Вот как я получаю все изображения галереи из текущего поста вместе с их aspectRatio.

export default ({ data }) => {
  return (
    <Layout>
      <article>
        {data.allFile.edges.map(({ node }, index) => (
          <div>
            <Img
              key = {index}
              className = {node.childImageSharp.fluid.aspectRatio}
              alt = {node.name}
              fluid = {node.childImageSharp.fluid}
            />
            <span>{node.childImageSharp.fluid.aspectRatio}</span>
          </div>
        ))}
      </article>
    </Layout>
  );
};

Полный запрос GraphQL, который я использую:

export const query = graphql`
  query($slug: String!, $absolutePathRegex: String!) {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      html
      frontmatter {
        title
        date
        modified
        caption
        description
        cover {
          publicURL
          childImageSharp {
            fluid(maxWidth: 915, quality: 90) {
              ...GatsbyImageSharpFluid_withWebp
            }
          }
        }
      }
      fields {
        slug
      }
    }
    allFile(
      filter: {
        extension: { regex: "/(jpg)|(png)|(tif)|(tiff)|(webp)|(jpeg)/" }
        absolutePath: { regex: $absolutePathRegex }
      }
    ) {
      edges {
        node {
          name
          childImageSharp {
            fluid(maxWidth: 915, quality: 90) {
              aspectRatio
              ...GatsbyImageSharpFluid_withWebp
            }
          }
        }
      }
    }
  }
`;

Для этого должно быть простое решение с использованием условного оператора в React, где вы сопоставляете все свои изображения, берете соотношение сторон а затем преобразовать необработанные данные в нужные классы.

Итак, вместо:

<div class = "1.5003750937734435 gatsby-image-wrapper"></div>
<div class = "0.6666666666666666 gatsby-image-wrapper"></div>
<div class = "0.6666666666666666 gatsby-image-wrapper"></div>
<div class = "1.0000000000000000 gatsby-image-wrapper"></div>
<div class = "1.5003750937734435 gatsby-image-wrapper"></div>

Вы получите:

<div class = "landscape gatsby-image-wrapper"></div>
<div class = "portrait gatsby-image-wrapper"></div>
<div class = "portrait gatsby-image-wrapper"></div>
<div class = "square gatsby-image-wrapper"></div>
<div class = "landscape gatsby-image-wrapper"></div>

Который затем можно было бы легко стилизовать с помощью css.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
5
0
1 782
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если я что-то не упустил, разве вы уже не там на 99%? Вы можете написать условное выражение внутри map или, что еще лучше, написать компонент, который обертывает <Img>:

import React from 'react'
import Img from 'gatsby-image'

// we only care about `aspectRatio`, the rest will be passed directly to `Img`
// also take out `className` so it be merged with our generated `orientation` class name
const ImgWithOrient = ({ aspectRatio, className, ...props }) => {
  let orientation
  if (aspectRatio > 1) orientation = 'landscape'
  if (aspectRatio < 1) orientation = 'portrait'
  else orientation = 'square'

  return <Img className = {`${className} ${orientation}`} {...props} />
}

export default ({ data }) => {
  return (
    <Layout>
      <article>
        {data.allFile.edges.map(({ node }, index) => (
          <div key = {index}>
            <ImgWithOrient
              key = {index}
              aspectRatio = {node.childImageSharp.fluid.aspectRatio}
              className = "other class name"
              alt = {node.name}
              fluid = {node.childImageSharp.fluid}
            />
            <span>{node.childImageSharp.fluid.aspectRatio}</span>
          </div>
        ))}
      </article>
    </Layout>
  )
}

Также обратите внимание, что когда вы перебираете что-то, вам нужно поместить key в самый внешний компонент — в этом случае внешний <div> вместо <Img>.

Спасибо, Дерек, твой ответ заставил это работать. Мне пришлось немного поиграть с операторами меньше/больше, чтобы получить желаемый результат. Вот что у меня есть на основе вашего кода: const ImgWithOrient = ({ aspectRatio, className, ...props }) => { let orientation; if (aspectRatio >= 1.2) orientation = "landscape"; if (aspectRatio <= 0.8) orientation = "portrait"; if (aspectRatio > 0.8 && aspectRatio < 1.2) orientation = "square"; return <Img className = {`${className} ${orientation}`} {...props} />; };

Glen 02.07.2019 23:56

Другие вопросы по теме