-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(gatsby-image): Add art direction #13395
feat(gatsby-image): Add art direction #13395
Conversation
packages/gatsby-image/src/__tests__/__snapshots__/index.js.snap
Outdated
Show resolved
Hide resolved
I've done some manual QA on this by plugging it into a staging build of shopflamingo.com and testing across Chrome and Safari. Is there a better way to set up some shareable test links for this? Also, would this PR be the place to add additions to the docs / the demo site? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Phew, that took a while! 😛 I think I've covered everything pretty well.
Also, would this PR be the place to add additions to the docs / the demo site?
I'd prefer that as a separate PR after this one personally. It could reference this merge commit / PR, but should otherwise be kept separate due to size of this one.
Is there a better way to set up some shareable test links for this?
I'm sure there is a better way but in the past I've copied the package from the fork into it's own repo and referenced it in package.json, then hosted on Netlify.
@@ -381,6 +479,8 @@ class Image extends React.Component { | |||
|
|||
if (fixed) { | |||
const image = fixed | |||
const imageVariants = fixedImages || [fixed] | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that in the fixed section, there is code you've not handled which references image
. divStyle
, bgColor
and the Img
tag(although I can't recall the impact of width/height attributes defined on an img element, have you confirmed variants with different width/height as fixed elements render correctly?
Adjusting the width/height attributes on the fixed image in this demo doesn't appear to have any effect, so I guess it's just the other two that should be taken into consideration?
fluid
section also references the images aspectRatio
for the paddingBottom
style. That's a case which may have gone missed?
Review Summary: TL;DR: version, links to parts of the review for further information. Questions / Concerns
Change suggestions
MiscNot required for the PR to be approved, but related for future work:
|
…scape resolutions This wouldn't be needed once gatsbyjs/gatsby#13395 is available
Reviewing the changes branch commits 6282c75: packages/gatsby-image/src/index.js - Line #19: // Find the source of an image to use as a key in the image cache.
// Use `fixed` or `fluid` if specified, or the first image in
// either `fixedImages` or `fluidImages`
const getImageSrc = props =>
props.fluid
? props.fluid.src
: props.fixed
? props.fixed.src
: props.fluidImages
? props.fluidImages[0].src
: props.fixedImages[0].src Refactoring the ternary logic from the two locations into a function is good, but this nested ternary approach, not so much. Would it be simpler to read if you instead destructure the props and use the const getImageData = ({fluid, fixed, fluidImages, fixedImages}) => (
fluid || fixed || fluidImages[0] || fixedImages[0]
)
const src = getImageData(convertedProps).src or const getImageSrc = ({fluid, fixed, fluidImages, fixedImages}) => {
const data = fluid || fixed || fluidImages[0] || fixedImages[0]
return data.src
}
const src = getImageSrc(convertedProps) packages/gatsby-image/src/index.js - Line #155: let initialSources = ``
if (props.srcSetWebp) {
initialSources += generateNoscriptSource(props, true)
}
if (props.media) {
initialSources += generateNoscriptSource(props)
}
const variantSources =
props.imageVariants.length > 0
? generateNoscriptSources(props.imageVariants)
: ``
return `<picture>${initialSources}${variantSources}<img ${width}${height}${sizes}${srcSet}${src}${alt}${title}${crossOrigin}style="position:absolute;top:0;left:0;opacity:1;width:100%;height:100%;object-fit:cover;object-position:center"/></picture>` Any reason for splitting packages/gatsby-image/src/index.js - Line #362: // First image data is supplied to `image`, if an array the rest will go to `variants`
const [image, ...imageVariants] = fluidImages ? fluidImages : [fluid] Slight mistake here as this was due to taking one of my suggestions. Other than that, all change requests are resolved. These concerns are still valid:
There is another issue regarding the cache key, but as it also affects the current |
…tsby into feat/add-image-art-direction
Sorry @polarathene , I had missed that you had reviewed this before I integrated those changes into this branch! Yes, those sections you called out were the places I felt like had regressed in the latest part. Will update those further 😄. For the other two remaining issues: Check for Safari RegressionsI imagine the Safari validation will be fairly straightforward, and I will do that after this latest round of updates. Check how properties adapt in different circumstancesI've been wondering how best to validate some of this. I had planned to make a sort of Gatsby Image Playground that tries out several of these options (both I think I need to explore some of those combinations a bit more, and figure out which places we may need to handle, which places we'd want to document, and if there are any combinations that wouldn't be supported. At least for the |
@brimtown would love to pair with you sometime on this! This is a really exciting PR! |
packages/gatsby-image/src/index.js
Outdated
(fixedImages && fixedImages[0]) | ||
// Use `the first image in either `fixed` or `fluid` | ||
const getImageSrcKey = ({ fluid, fixed }) => { | ||
const data = (fluid.length && fluid[0]) || (fixed.length && fixed[0]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the length check necessary? It'll likely fail iirc checking the because of length
property if the prop itself is undefined? Or is thisconvertProps()
that it's safe to always assume an array value present?
I would add that we have both inImageCache()
and activateCacheForImage()
both calling this method after first doing:
const convertedProps = convertProps(props)
We might as well just move that duplication into this method and drop the need to pass in props?
const data = (fluid.length && fluid[0]) || (fixed.length && fixed[0]) | |
const convertedProps = convertProps(props) | |
const data = (fluid.length && fluid[0]) || (fixed.length && fixed[0]) |
EDIT: I see that your convertProps()
method returns an array regardless, so if it's empty a 0 falsey value for fluid will select fixed instead. My bad :)
Review done. Some questions for @wardpeet regarding some commits he made, along with some suggestions. What is with the Danger failure? Was it trying to merge on green?
|
No clue about dangerjs. It happend when I pushed. We can just ignore it |
I think I have resolved all review comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's get this merged! Thank you for the reviews & hard work on this one!
Holy buckets, @brimtown — we just merged your PR to Gatsby! 💪💜 Gatsby is built by awesome people like you. Let us say “thanks” in two ways:
If there’s anything we can do to help, please don’t hesitate to reach out to us: tweet at @gatsbyjs and we’ll come a-runnin’. Thanks again! |
Hi @brimtown , thanks for this ! I just upgraded the package to get access to this and I find myself stuck with a rather annoying issue. From my understanding, Art direction means we can display different images at different breakpoints, which means we can have different aspect ratios through viewport sizes. The issue I think is the following : Given this sources array :
I would expect the aspect ratio to be at 0.75 below 768px, and be updated to 1.77778 over, but currently it's just taking the image.aspectRatio, which is fluid[0], therefore not updating the aspect ratio. Am I just not doing the right thing ? Thanks! |
Hi @antoinegrelard ! Yes, this is a current limitation with the code as is. Since Regardless, I believe @polarathene had some ideas how to handle from Gatsby itself. I will open the issue on this and tag you in it, and it should be fixable 👍 . In the meantime, we've worked around this in our own app code with a snippet like this: // These styles fix a problem in `gatsby-image` where using
// art direction with images that have different aspect ratios
// defaults to using the aspect ratio of the first image passed
// to `fluidSources`. This is hardcoded to work for two images,
// but could be generalized to work for more. Ideally this
// will be fixed upstream in the future.
const ResponsiveImage = styled(GatsbyImage)`
${({ sources }) => `
& > div:first-child {
padding-bottom: ${100 / sources[0].aspectRatio}% !important;
${mediaQueries.DESKTOP
padding-bottom: ${100 / sources[1].aspectRatio}% !important;
`}
}
`}
`; If you know how many variations you'll need, hardcoding it with something like this works fairly well. You could also map over Glad you're using the feature! I think once this gets fixed, we can share it more broadly in a blog post and improve some of the documentation here. EDIT: I'd also be curious to know from your example if leaving off the |
…scape resolutions This wouldn't be needed once gatsbyjs/gatsby#13395 is available
…scape resolutions This wouldn't be needed once gatsbyjs/gatsby#13395 is available
Description
This PR adds art direction capabilities to
gatsby-image
.See issue #13164 for additional background and discussion.
Decisions Made
fixedImages
andfluidImages
props, instead of overloading the existingfixed
andfluid
<sources>
if there is more than one variant. This keeps the snapshots for the existing tests the same, except for the addition for a single<picture>
tag for base64 / tracedSVG placeholders.src
as the key for the image cache, instead of creating new entries in the cache persource
I'm open to revisiting any of these, as each one is a tradeoff.
Related Issues
Fixes #13164, #4491, #7313