简体   繁体   English

如何使用 gatsby-image 在不裁剪的情况下显示图像?

[英]How to display images without cropping using gatsby-image?

Live example (images might load slowly): https://suhadolnik-photo.surge.sh/portreti现场示例(图像可能加载缓慢): https : //suhadolnik-photo.surge.sh/portreti

I'm making a photography site with GatsbyJS and using the following template as a base site that I've been changing: https://github.com/LekoArts/gatsby-starter-portfolio-emilia我正在使用 GatsbyJS 制作一个摄影网站,并使用以下模板作为我一直在更改的基本网站: https : //github.com/LekoArts/gatsby-starter-portfolio-emilia

Being really new to graphql I've run into a problem displaying images after a user clicks on the card to show the 'Portraits' subpage.作为graphql的新手,我遇到了在用户单击卡片以显示“肖像”子页面后显示图像的问题。 The images are all displayed with a fixed width and height which I don't want.图像都以我不想要的固定宽度和高度显示。 I need to display them with their native width and height, just resized to fit into the grid.我需要用它们的原始宽度和高度显示它们,只需调整大小以适应网格。

I've tried changing the graphql query in the project.js file, where you set the maxWidth: 1600 to no avail, as well as the resize(width: 800) further down the query.我已经尝试更改project.js文件中的 graphql 查询,在那里您将maxWidth: 1600设置为无效,以及在查询中进一步resize(width: 800) Later I found out that changing the margin on gatsby-image-wrapper through dev tools gave me the expected results, but that required changing the core gatsby-image plugin and having to manually change the margin for every image separately which isn't the solution.后来我发现通过开发工具更改gatsby-image-wrappermargin给了我预期的结果,但这需要更改核心gatsby-image插件并且必须分别手动更改每个图像的margin ,这不是解决方案.

project.js

import React from 'react'
import Img from 'gatsby-image'
import PropTypes from 'prop-types'
import { graphql } from 'gatsby'
import styled from 'styled-components'

import { Layout, ProjectHeader, ProjectPagination, SEO } from '../components'
import config from '../../config/site'

const BG = styled.div`
  background-color: ${props => props.theme.colors.bg};
  position: relative;
  padding: 2rem 0 0 0;
`

const OuterWrapper = styled.div`
  padding: 0 ${props => props.theme.contentPadding};
  margin: -10rem auto 0 auto;
`

const InnerWrapper = styled.div`
  position: relative;
  max-width: ${props => `${props.theme.maxWidths.project}px`};
  margin: 0 auto;
`

const Grid = styled.div`
  display: grid;
  grid-template-columns: repeat(${props => props.theme.gridColumnsProject}, 1fr);
  grid-gap: 20px;

  @media (max-width: 768px) {
    grid-template-columns: 1fr;
  }
`

const Project = ({ pageContext: { slug, prev, next }, data: { project: postNode, images } }) => {
  const project = postNode.frontmatter

  return (
    <Layout customSEO>
      <SEO postPath={slug} postNode={postNode} postSEO />
      <ProjectHeader
        name={config.name}
        date={project.date}
        title={project.title}
        areas={project.areas}
        text={postNode.body}
      />
      <BG>
        <OuterWrapper>
          <InnerWrapper>
            <Grid>
              {images.nodes.map(image => (
                <Img
                  alt={image.name}
                  key={image.childImageSharp.fluid.src}
                  fluid={image.childImageSharp.fluid}
                  style={{ margin: '2rem 0' }}
                />
              ))}
            </Grid>
          </InnerWrapper>
          <ProjectPagination next={next} prev={prev} />
        </OuterWrapper>
      </BG>
    </Layout>
  )
}

export default Project

Project.propTypes = {
  pageContext: PropTypes.shape({
    slug: PropTypes.string.isRequired,
    next: PropTypes.object,
    prev: PropTypes.object,
  }),
  data: PropTypes.shape({
    project: PropTypes.object.isRequired,
    images: PropTypes.object.isRequired,
  }).isRequired,
}

Project.defaultProps = {
  pageContext: PropTypes.shape({
    next: null,
    prev: null,
  }),
}

export const pageQuery = graphql`
  query($slug: String!, $absolutePathRegex: String!) {
    images: allFile(
      filter: {
        absolutePath: { regex: $absolutePathRegex }
        extension: { regex: "/(jpg)|(png)|(tif)|(tiff)|(webp)|(jpeg)/" }
      }
      sort: { fields: name, order: ASC }
    ) {
      nodes {
        name
        childImageSharp {
          fluid(maxWidth: 1600, quality: 90) {
            ...GatsbyImageSharpFluid_withWebp
          }
        }
      }
    }
    project: mdx(fields: { slug: { eq: $slug } }) {
      body
      excerpt
      parent {
        ... on File {
          mtime
          birthtime
        }
      }
      frontmatter {
        cover {
          childImageSharp {
            resize(width: 800) {
              src
            }
          }
        }
        date(formatString: "DD.MM.YYYY")
        title
        areas
      }
    }
  }
`

Card.js the parent component: Card.js父组件:

import React from 'react'
import styled from 'styled-components'
import PropTypes from 'prop-types'
import { useSpring, animated, config } from 'react-spring'
import { rgba } from 'polished'
import Img from 'gatsby-image'
import { Link } from 'gatsby'

const CardItem = styled(Link)`
  min-height: 500px;
  position: relative;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.2);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  color: ${props => props.theme.colors.color};
  transition: all 0.3s ease-in-out;

  &:hover {
    color: white;
    transform: translateY(-6px);
  }

  @media (max-width: ${props => props.theme.breakpoints.s}) {
    min-height: 300px;
  }
`

const Cover = styled.div`
  width: 100%;
  height: 100%;
  position: absolute;
`

const Content = styled.div`
  padding: 1rem;
  position: relative;
  transition: all 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
  opacity: 0;
  background: ${props => rgba(props.theme.colors.link, 0.65)};
  height: 0;

  ${CardItem}:hover & {
    opacity: 1;
    height: 120px;
  }
`

const Bottom = styled.div`
  margin-top: 0.5rem;
  display: flex;
  align-items: center;
  font-size: 0.85rem;
  div:first-child {
    margin-right: 1rem;
  }
`

const Name = styled.h2`
  margin-bottom: 0;
  margin-top: 0;
`

const Card = ({ path, cover, date, areas, title, delay }) => {
  const springProps = useSpring({
    config: config.slow,
    delay: 200 * delay,
    from: { opacity: 0, transform: 'translate3d(0, 30px, 0)' },
    to: { opacity: 1, transform: 'translate3d(0, 0, 0)' },
  })

  return (
    <animated.div style={springProps}>
      <CardItem to={path}>
        <Cover>
          <Img fluid={cover} />
        </Cover>
        <Content>
          <Name>{title}</Name>
          <Bottom>
            <div>{date}</div>
            <div>
              {areas.map((area, index) => (
                <React.Fragment key={area}>
                  {index > 0 && ', '}
                  {area}
                </React.Fragment>
              ))}
            </div>
          </Bottom>
        </Content>
      </CardItem>
    </animated.div>
  )
}

export default Card

Card.propTypes = {
  path: PropTypes.string.isRequired,
  cover: PropTypes.object.isRequired,
  date: PropTypes.string.isRequired,
  areas: PropTypes.array.isRequired,
  title: PropTypes.string.isRequired,
  delay: PropTypes.number.isRequired,
}

I expect the images to show in their native width and height, but resized to fit the grid.我希望图像以其原始宽度和高度显示,但调整大小以适应网格。 Providing visual representation below on how it looks now and what the expected result is.在下面提供有关它现在的外观和预期结果的视觉表示。 Current result and expected result当前结果预期结果

Cheers!干杯!

Remove height:100% and position:absolute from your cover component on the homepage.从主页上的封面组件中删除height:100%position:absolute

const Cover = styled.div`
  width: 100%;
`

Also, in case you weren't aware, you can pass style and imgStyle props to Gatsby image to change it's css.此外,如果您不知道,您可以将styleimgStyle道具传递给Gatsby 图像以更改其 css。

| style            | object | Spread into the default styles of the wrapper element         |  
| imgStyle         | object | Spread into the default styles of the actual img element      |
| placeholderStyle | object | Spread into the default styles of the placeholder img element |

So in your project template you can change the object fit style like this:因此,在您的项目模板中,您可以像这样更改对象适合样式:

<Img
  alt={image.name}
  key={image.childImageSharp.fluid.src}
  fluid={image.childImageSharp.fluid}
  imgStyle={{ objectFit: 'contain' }}
/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM