Skip to content

Commit

Permalink
feat(remark-images): Added support for WebP versions in addition to f…
Browse files Browse the repository at this point in the history
…allbacks. (#6495)

* feat(remark): Added support for WebP versions in addition to fallbacks.

* Added whitespace to match the snapshot tests.

* Modified snapshot files to pass.

* More whitespace matching.
  • Loading branch information
Mike-Dax authored and m-allanson committed Jul 20, 2018
1 parent a49f240 commit 65e3a78
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 16 deletions.
1 change: 1 addition & 0 deletions packages/gatsby-plugin-sharp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ plugin for Markdown content as gatsby-remark-images).
- `aspectRatio` (float)
- `src` (string)
- `srcSet` (string)
- `srcSetType` (string)
- `sizes` (string)
- `originalImg` (string)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Object {
"src": "/static/test-1234-85b96.png",
"srcSet": "/static/test-1234-7c9f5.png 200w,
/static/test-1234-85b96.png 281w",
"srcSetType": "image/png",
}
`;

Expand All @@ -39,6 +40,7 @@ Object {
"src": "/static/test-1234-24ad8.png",
"srcSet": "/static/test-1234-06d78.png 200w,
/static/test-1234-24ad8.png 281w",
"srcSetType": "image/png",
}
`;

Expand All @@ -54,6 +56,7 @@ Object {
"sizes": "(max-width: 1px) 100vw, 1px",
"src": "/static/test-1234-18c2a.png",
"srcSet": "/static/test-1234-18c2a.png 1w",
"srcSetType": "image/png",
}
`;

Expand Down
24 changes: 23 additions & 1 deletion packages/gatsby-plugin-sharp/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ async function fluid({ file, args = {}, reporter }) {
return null
}

const { width, height, density } = metadata
const { width, height, density, format } = metadata
const pixelRatio =
options.sizeByPixelDensity && typeof density === `number` && density > 0
? density / 72
Expand Down Expand Up @@ -533,11 +533,33 @@ async function fluid({ file, args = {}, reporter }) {
.join(`,\n`)
const originalName = file.base

// figure out the srcSet format
let srcSetType = `image/${format}`

if (options.toFormat) {
switch (options.toFormat) {
case `png`:
srcSetType = `image/png`
break
case `jpg`:
srcSetType = `image/jpeg`
break
case `webp`:
srcSetType = `image/webp`
break
case ``:
case `no_change`:
default:
break
}
}

return {
base64: base64Image.src,
aspectRatio: images[0].aspectRatio,
src: fallbackSrc,
srcSet,
srcSetType,
sizes: options.sizes,
originalImg: originalImg,
originalName: originalName,
Expand Down
6 changes: 4 additions & 2 deletions packages/gatsby-remark-images/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ plugins: [
| `linkImagesToOriginal` | `true` | Add a link to each image to the original image. Sometimes people want to see a full-sized version of an image e.g. to see extra detail on a part of the image and this is a convenient and common pattern for enabling this. Set this option to false to disable this behavior. |
| `showCaptions` | `false` | Add a caption to each image with the contents of the title attribute, when this is not empty. Set this option to true to enable this behavior. |
| `sizeByPixelDensity` | `false` | Analyze images' pixel density to make decisions about target image size. This is what GitHub is doing when embedding images in tickets. This is a useful setting for documentation pages with a lot of screenshots. It can have unintended side effects on high pixel density artworks.<br/><br/>Example: A screenshot made on a retina screen with a resolution of 144 (e.g. Macbook) and a width of 100px, will be rendered at 50px. |
| `wrapperStyle` | | Add custom styles to the div wrapping the responsive images. Use the syntax for the style attribute e.g. `margin-bottom:10px; background: red;` |
| `backgroundColor` | `white` | Set the background color of the image to match the background image of your design |
| `wrapperStyle` | | Add custom styles to the div wrapping the responsive images. Use the syntax for the style attribute e.g. `margin-bottom:10px; background: red;`. |
| `backgroundColor` | `white` | Set the background color of the image to match the background image of your design. |
| `quality` | `50` | The quality level of the generated files. |
| `withWebp` | `false` | Additionally generate WebP versions alongside your chosen file format. They are added as a srcset with the appropriate mimetype and will be loaded in browsers that support the format. Pass `true` for default support, or an object of options to specifically override those for the WebP files. For example, pass `{ quality: 80 }` to have the WebP images be at quality level 80. |

[1]: https://jmperezperez.com/medium-image-progressive-loading-placeholder/
[2]: https://code.facebook.com/posts/991252547593574/the-technology-behind-preview-photos/
75 changes: 62 additions & 13 deletions packages/gatsby-remark-images/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ module.exports = (
linkImagesToOriginal: true,
showCaptions: false,
pathPrefix,
withWebp: false,
}

const options = _.defaults(pluginOptions, defaults)
Expand Down Expand Up @@ -86,6 +87,66 @@ module.exports = (
// Fade in images on load.
// https://www.perpetual-beta.org/weblog/silky-smooth-image-loading.html

const imageClass = `gatsby-resp-image-image`
const imageStyle = `width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px ${
options.backgroundColor
};`

// Create our base image tag
let imageTag = `
<img
class="${imageClass}"
style="${imageStyle}"
alt="${node.alt ? node.alt : defaultAlt}"
title="${node.title ? node.title : ``}"
src="${fallbackSrc}"
srcset="${srcSet}"
sizes="${fluidResult.sizes}"
/>
`

// if options.withWebp is enabled, generate a webp version and change the image tag to a picture tag
if (options.withWebp) {
const webpFluidResult = await fluid({
file: imageNode,
args: _.defaults(
{ toFormat: `WEBP` },
// override options if it's an object, otherwise just pass through defaults
options.withWebp === true ? {} : options.withWebp,
pluginOptions,
defaults
),
reporter,
})

if (!webpFluidResult) {
return resolve()
}

imageTag = `
<picture>
<source
srcset="${webpFluidResult.srcSet}"
sizes="${webpFluidResult.sizes}"
type="${webpFluidResult.srcSetType}"
/>
<source
srcset="${srcSet}"
sizes="${fluidResult.sizes}"
type="${fluidResult.srcSetType}"
/>
<img
class="${imageClass}"
style="${imageStyle}"
src="${fallbackSrc}"
alt="${node.alt ? node.alt : defaultAlt}"
title="${node.title ? node.title : ``}"
src="${fallbackSrc}"
/>
</picture>
`
}

// Construct new image node w/ aspect ratio placeholder
let rawHTML = `
<span
Expand All @@ -99,19 +160,7 @@ module.exports = (
style="padding-bottom: ${ratio}; position: relative; bottom: 0; left: 0; background-image: url('${
fluidResult.base64
}'); background-size: cover; display: block;"
>
<img
class="gatsby-resp-image-image"
style="width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px ${
options.backgroundColor
};"
alt="${node.alt ? node.alt : defaultAlt}"
title="${node.title ? node.title : ``}"
src="${fallbackSrc}"
srcset="${srcSet}"
sizes="${fluidResult.sizes}"
/>
</span>
>${imageTag}</span>
</span>
`

Expand Down

0 comments on commit 65e3a78

Please sign in to comment.