React Gatsbyjs 根据纵横比向 gatsby-image 添加类
Posted
技术标签:
【中文标题】React Gatsbyjs 根据纵横比向 gatsby-image 添加类【英文标题】:React Gatsbyjs add class to gatsby-image based on aspect ratio 【发布时间】:2019-11-11 22:27:19 【问题描述】:gatsby-image 使用 gatsby-image-wrapper div 包装每个图像,该 div 填充 100% 的可用视口宽度。这个包装器 div 可以很容易地使用 CSS 设置样式,但 没有办法将横向、纵向或方形图像区别对待。
如果您想让横向图像填充可用宽度的 80%-100%,但纵向和方形图像填充不超过视口宽度的 40-50%。
因此,理想情况下,每个 gatsby-image-wrapper div 都会根据其纵横比添加一个类,可以是; landscape
、portrait
或 square
。
一种方法是使用 childImageSharp 附带的纵横比编写一些条件语句:
edges
node
name
childImageSharp
fluid(maxWidth: 915, quality: 90)
aspectRatio
...GatsbyImageSharpFluid_withWebp
当我映射所有画廊图像时,我可以获取纵横比并使用 className 将其添加到每个 gatsby-image-wrapper 但它的原始格式不是很有用,因为 aspectRatio 的返回数据是像 @987654326 这样的数字@ 用于纵向图像或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 设置样式。
【问题讨论】:
【参考方案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>
。
【讨论】:
谢谢 Derek,你的回答让这个工作正常了。我不得不使用小于/大于操作符来获得预期的结果。这是我根据你的代码得到的: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 />; ;
以上是关于React Gatsbyjs 根据纵横比向 gatsby-image 添加类的主要内容,如果未能解决你的问题,请参考以下文章