Skip to content

Commit

Permalink
feat(gatsby-image): Add art direction (#13395)
Browse files Browse the repository at this point in the history
* Add optional media key to PropTypes and Typescript declarations

* Add optional fluidImages and fixedImages props

* Add art direction to fixed and fluid images

* Add art direction to base64 and tracedSVG

* Add art direction to noscript image

* Add tests for fixedImages and fluidImages

* Respond to code review

* Use const in tests

* Additinal code review refactor

* Fix e2e tests

* Add README docs

* Fix typo and update wording in README

* Name selectors in e2e test

* Work around SVG bug by encoding spaces

* Fix breaking Placeholder change, respond to code review, and update snapshots

* Use @polarthene's Pastebin

* Update sharp snapshot test

* Reset integration tests

* Move fluidImages & fixedImages into fluid & fixed

* update tests with no media

* cleanup spreadprops

* Add warning if multiple sources with no media were used

* review changes

* fix tests
  • Loading branch information
brimtown authored and GatsbyJS Bot committed Jun 21, 2019
1 parent 784d20f commit 02edcdc
Show file tree
Hide file tree
Showing 8 changed files with 490 additions and 84 deletions.
27 changes: 7 additions & 20 deletions examples/using-gatsby-image/src/components/floating-image.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,6 @@ const Image = styled(Img)`
margin-left: ${rhythm(options.blockMarginBottom * 2)};
margin-right: -${gutter.default};
${mq.phablet} {
display: none;
}
`

const ImageDesktop = styled(Image)`
display: none;
${mq.phablet} {
display: block;
}
${mq.tablet} {
margin-right: -${gutter.tablet};
}
Expand Down Expand Up @@ -53,15 +41,14 @@ const FloatingImage = ({
https://www.gatsbyjs.org/packages/gatsby-image/#gatsby-image-props
*/}
<Image
fixed={imageMobile}
backgroundColor={backgroundColor ? backgroundColor : false}
style={{ display: `inherit` }}
title={title}
/>
<ImageDesktop
fixed={imageDesktop}
fixed={[
imageMobile,
{
...imageDesktop,
media: mq.phablet.replace(`@media`, ``).trim(),
},
]}
backgroundColor={backgroundColor ? backgroundColor : false}
style={{ display: `inherit` }}
title={title}
/>
</React.Fragment>
Expand Down
100 changes: 77 additions & 23 deletions packages/gatsby-image/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,31 +331,85 @@ You will need to add it in your graphql query as is shown in the following snipp
}
```

## Art-directing multiple images

`gatsby-image` supports showing different images at different breakpoints, which is known as [art direction](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images#Art_direction). To do this, you can define your own array of `fixed` or `fluid` images, along with a `media` key per image, and pass it to `gatsby-image`'s `fixed` or `fluid` props. The `media` key that is set on an image can be any valid CSS media query.

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

export default ({ data }) => {
// Set up the array of image data and `media` keys.
// You can have as many entries as you'd like.
const sources = [
data.mobileImage.childImageSharp.fluid,
{
...data.desktopImage.childImageSharp.fluid,
media: `(min-width: 768px)`,
},
]

return (
<div>
<h1>Hello art-directed gatsby-image</h1>
<Img fluid={sources} />
</div>
)
}

export const query = graphql`
query {
mobileImage(relativePath: { eq: "blog/avatars/kyle-mathews.jpeg" }) {
childImageSharp {
fluid(maxWidth: 1000, quality: 100) {
...GatsbyImageSharpFluid
}
}
}
desktopImage(
relativePath: { eq: "blog/avatars/kyle-mathews-desktop.jpeg" }
) {
childImageSharp {
fluid(maxWidth: 2000, quality: 100) {
...GatsbyImageSharpFluid
}
}
}
}
`
```

While you could achieve a similar effect with plain CSS media queries, `gatsby-image` accomplishes this using the `<picture>` tag, which ensures that browsers only download the image they need for a given breakpoint.

## `gatsby-image` props

| Name | Type | Description |
| ---------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `fixed` | `object` | Data returned from the `fixed` query |
| `fluid` | `object` | Data returned from the `fluid` query |
| `fadeIn` | `bool` | Defaults to fading in the image on load |
| `durationFadeIn` | `number` | fading duration is set up to 500ms by default |
| `title` | `string` | Passed to the `img` element |
| `alt` | `string` | Passed to the `img` element. Defaults to an empty string `alt=""` |
| `crossOrigin` | `string` | Passed to the `img` element |
| `className` | `string` / `object` | Passed to the wrapper element. Object is needed to support Glamor's css prop |
| `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 |
| `placeholderClassName` | `string` | A class that is passed to the placeholder `img` element |
| `backgroundColor` | `string` / `bool` | Set a colored background placeholder. If true, uses "lightgray" for the color. You can also pass in any valid color string. |
| `onLoad` | `func` | A callback that is called when the full-size image has loaded. |
| `onStartLoad` | `func` | A callback that is called when the full-size image starts loading, it gets the parameter { wasCached: boolean } provided. |
| `onError` | `func` | A callback that is called when the image fails to load. |
| `Tag` | `string` | Which HTML tag to use for wrapping elements. Defaults to `div`. |
| `objectFit` | `string` | Passed to the `object-fit-images` polyfill when importing from `gatsby-image/withIEPolyfill`. Defaults to `cover`. |
| `objectPosition` | `string` | Passed to the `object-fit-images` polyfill when importing from `gatsby-image/withIEPolyfill`. Defaults to `50% 50%`. |
| `loading` | `string` | Set the browser's native lazy loading attribute. One of `lazy`, `eager` or `auto`. Defaults to `lazy`. |
| `critical` | `bool` | Opt-out of lazy-loading behavior. Defaults to `false`. Deprecated, use `loading` instead. |
| Name | Type | Description |
| ---------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `fixed` | `object` / `array` | Data returned from the `fixed` query. When prop is an array it has to be combined with `media` keys, allows for art directing `fixed` images. |
| `fluid` | `object` / `array` | Data returned from the `fluid` query. When prop is an array it has to be combined with `media` keys, allows for art directing `fluid` images. |
| `fadeIn` | `bool` | Defaults to fading in the image on load |
| `durationFadeIn` | `number` | fading duration is set up to 500ms by default |
| `title` | `string` | Passed to the `img` element |
| `alt` | `string` | Passed to the `img` element. Defaults to an empty string `alt=""` |
| `crossOrigin` | `string` | Passed to the `img` element |
| `className` | `string` / `object` | Passed to the wrapper element. Object is needed to support Glamor's css prop |
| `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 |
| `placeholderClassName` | `string` | A class that is passed to the placeholder `img` element |
| `backgroundColor` | `string` / `bool` | Set a colored background placeholder. If true, uses "lightgray" for the color. You can also pass in any valid color string. |
| `onLoad` | `func` | A callback that is called when the full-size image has loaded. |
| `onStartLoad` | `func` | A callback that is called when the full-size image starts loading, it gets the parameter { wasCached: boolean } provided. |
| `onError` | `func` | A callback that is called when the image fails to load. |
| `Tag` | `string` | Which HTML tag to use for wrapping elements. Defaults to `div`. |
| `objectFit` | `string` | Passed to the `object-fit-images` polyfill when importing from `gatsby-image/withIEPolyfill`. Defaults to `cover`. |
| `objectPosition` | `string` | Passed to the `object-fit-images` polyfill when importing from `gatsby-image/withIEPolyfill`. Defaults to `50% 50%`. |
| `loading` | `string` | Set the browser's native lazy loading attribute. One of `lazy`, `eager` or `auto`. Defaults to `lazy`. |
| `critical` | `bool` | Opt-out of lazy-loading behavior. Defaults to `false`. Deprecated, use `loading` instead. |
| `fixedImages` | `array` | An array of objects returned from `fixed` queries. When combined with `media` keys, allows for art directing `fixed` images. |
| `fluidImages` | `array` | An array of objects returned from `fluid` queries. When combined with `media` keys, allows for art directing `fluid` images. |

## Image processing arguments

Expand Down
4 changes: 4 additions & 0 deletions packages/gatsby-image/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface FixedObject {
tracedSVG?: string
srcWebp?: string
srcSetWebp?: string
media?: string
}

export interface FluidObject {
Expand All @@ -20,13 +21,16 @@ export interface FluidObject {
tracedSVG?: string
srcWebp?: string
srcSetWebp?: string
media?: string
}

interface GatsbyImageProps {
resolutions?: FixedObject
sizes?: FluidObject
fixed?: FixedObject
fluid?: FluidObject
fixedImages?: FixedObject[]
fluidImages?: FluidObject[]
fadeIn?: boolean
title?: string
alt?: string
Expand Down
Loading

0 comments on commit 02edcdc

Please sign in to comment.