From 292cf986d224e9445bff68445aad36b3e00d0e3b Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Tue, 12 Jan 2021 17:24:02 +0000 Subject: [PATCH 01/10] Use breakpoints in fluid --- .../gatsby-plugin-image/src/image-utils.ts | 1 + .../gatsby-plugin-sharp/src/image-data.ts | 16 +++++++++------ packages/gatsby-plugin-sharp/src/utils.js | 7 +++---- .../src/customize-schema.js | 20 ++++++++++++++----- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/packages/gatsby-plugin-image/src/image-utils.ts b/packages/gatsby-plugin-image/src/image-utils.ts index d5f95adce4af8..f5416456d7f9d 100644 --- a/packages/gatsby-plugin-image/src/image-utils.ts +++ b/packages/gatsby-plugin-image/src/image-utils.ts @@ -38,6 +38,7 @@ export interface ISharpGatsbyImageArgs { webpOptions?: Record avifOptions?: Record blurredOptions?: { width?: number; toFormat?: ImageFormat } + breakpoints?: Array } export interface IImageSizeArgs { diff --git a/packages/gatsby-plugin-sharp/src/image-data.ts b/packages/gatsby-plugin-sharp/src/image-data.ts index b21345b4bcb4c..d83a4c642b0a2 100644 --- a/packages/gatsby-plugin-sharp/src/image-data.ts +++ b/packages/gatsby-plugin-sharp/src/image-data.ts @@ -9,6 +9,8 @@ import { createTransformObject } from "./plugin-options" const DEFAULT_BLURRED_IMAGE_WIDTH = 20 +const DEFAULT_BREAKPOINTS = [750, 1080, 1366, 1920] + type ImageFormat = "jpg" | "png" | "webp" | "avif" | "" | "auto" export type FileNode = Node & { @@ -93,6 +95,12 @@ export async function generateImageData({ args.formats = args.formats || [`auto`, `webp`] + if (layout === `fluid`) { + args.breakpoints = args.breakpoints?.length + ? args.breakpoints + : DEFAULT_BREAKPOINTS + } + const { fit = `cover`, cropFocus = sharp.strategy.attention, @@ -104,16 +112,12 @@ export async function generateImageData({ reporter.warn( `Specifying fluid images will ignore the width and height arguments, you may want a constrained image instead. Otherwise, use the breakpoints argument.` ) - args.width = undefined + args.width = metadata.width args.height = undefined } if (!args.width && !args.height && metadata.width) { - if (layout === `fluid`) { - args.width = Math.round(metadata.width / 2) - } else { - args.width = metadata.width - } + args.width = metadata.width } if (args.aspectRatio) { diff --git a/packages/gatsby-plugin-sharp/src/utils.js b/packages/gatsby-plugin-sharp/src/utils.js index d59405ec72b30..94910f8bf4af2 100644 --- a/packages/gatsby-plugin-sharp/src/utils.js +++ b/packages/gatsby-plugin-sharp/src/utils.js @@ -128,7 +128,6 @@ export function fixedImageSizes({ height, transformOptions = {}, outputPixelDensities = DEFAULT_PIXEL_DENSITIES, - srcSetBreakpoints, reporter, }) { let aspectRatio = imgDimensions.width / imgDimensions.height @@ -204,7 +203,7 @@ export function fluidImageSizes({ height, transformOptions = {}, outputPixelDensities = DEFAULT_PIXEL_DENSITIES, - srcSetBreakpoints, + breakpoints, }) { const { fit = `cover` } = transformOptions @@ -259,8 +258,8 @@ export function fluidImageSizes({ // device size / screen resolution while (hopefully) not requiring too much // image processing time (Sharp has optimizations thankfully for creating // multiple sizes of the same input file) - if (srcSetBreakpoints?.length > 0) { - sizes = srcSetBreakpoints.filter(size => size <= imgDimensions.width) + if (breakpoints?.length > 0) { + sizes = breakpoints.filter(size => size <= imgDimensions.width) } else { sizes = densities.map(density => Math.round(density * width)) sizes = sizes.filter(size => size <= imgDimensions.width) diff --git a/packages/gatsby-transformer-sharp/src/customize-schema.js b/packages/gatsby-transformer-sharp/src/customize-schema.js index b89c7691301d0..13bc3fa5d4161 100644 --- a/packages/gatsby-transformer-sharp/src/customize-schema.js +++ b/packages/gatsby-transformer-sharp/src/customize-schema.js @@ -445,12 +445,12 @@ const imageNodeType = ({ tracedSVGOptions: { type: PotraceType, defaultValue: false, - description: `Options for traced placeholder SVGs. You also should set placeholder to "SVG".`, + description: `Options for traced placeholder SVGs. You also should set placeholder to "TRACED_SVG".`, }, formats: { type: GraphQLList(ImageFormatType), description: stripIndent` - The image formats to generate. Valid values are "AUTO" (meaning the same format as the source image), "JPG", "PNG" and "WEBP". + The image formats to generate. Valid values are "AUTO" (meaning the same format as the source image), "JPG", "PNG", "WEBP" and "AVIF". The default value is [AUTO, WEBP], and you should rarely need to change this. Take care if you specify JPG or PNG when you do not know the formats of the source images, as this could lead to unwanted results such as converting JPEGs to PNGs. Specifying both PNG and JPG is not supported and will be ignored. @@ -461,15 +461,25 @@ const imageNodeType = ({ type: GraphQLList(GraphQLFloat), description: stripIndent` A list of image pixel densities to generate. It will never generate images larger than the source, and will always include a 1x image. - Default is [ 1, 2 ] for fixed images, meaning 1x, 2x, 3x, and [0.25, 0.5, 1, 2] for fluid. In this case, an image with a fluid layout and width = 400 would generate images at 100, 200, 400 and 800px wide`, + Default is [ 1, 2 ] for FIXED images, meaning 1x and 2x and [0.25, 0.5, 1, 2] for CONSTRAINED. In this case, an image with a constrained layout + and width = 400 would generate images at 100, 200, 400 and 800px wide. Ignored for FULL_WIDTH images, which use breakpoints instead`, + }, + breakpoints: { + type: GraphQLList(GraphQLInt), + description: stripIndent` + Specifies the image widths to generate. For FIXED and CONSTRAINED images it is better to allow these to be determined automatically, + based on the image size. For FULL_WIDTH images this can be used to override the default, which is [750, 1080, 1366, 1920]. + It will never generate any images larger than the source. + `, }, sizes: { type: GraphQLString, defaultValue: ``, description: stripIndent` The "sizes" property, passed to the img tag. This describes the display size of the image. - This does not affect the generated images, but is used by the browser to decide which images to download. You can leave this blank for fixed images, or if the responsive image - container will be the full width of the screen. In these cases we will generate an appropriate value. + This does not affect the generated images, but is used by the browser to decide which images to download. + You should usually leave this blank, and a suitable value will be calculated. The exception is if a FULL_WIDTH image + does not actually span the full width of the screen, in which case you should pass the correct size here. `, }, quality: { From d8e3ef757d55d5b75a2495f159ef3d9cd7c9f19e Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Wed, 13 Jan 2021 09:51:20 +0000 Subject: [PATCH 02/10] Don't add own size to full width, unless to replace larger bp --- packages/gatsby-plugin-sharp/src/utils.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/utils.js b/packages/gatsby-plugin-sharp/src/utils.js index 610c2110b6544..1064afe7bd3fe 100644 --- a/packages/gatsby-plugin-sharp/src/utils.js +++ b/packages/gatsby-plugin-sharp/src/utils.js @@ -204,6 +204,7 @@ export function responsiveImageSizes({ transformOptions = {}, outputPixelDensities = DEFAULT_PIXEL_DENSITIES, breakpoints, + layout, }) { const { fit = `cover` } = transformOptions @@ -249,24 +250,23 @@ export function responsiveImageSizes({ width = Math.round(width) - // Create sizes (in width) for the image if no custom breakpoints are - // provided. If the max width of the container for the rendered markdown file - // is 800px, the sizes would then be: 200, 400, 800, 1600 if using - // the default outputPixelDensities - // - // This is enough sizes to provide close to the optimal image size for every - // device size / screen resolution while (hopefully) not requiring too much - // image processing time (Sharp has optimizations thankfully for creating - // multiple sizes of the same input file) if (breakpoints?.length > 0) { sizes = breakpoints.filter(size => size <= imgDimensions.width) + + // If a larger breakpoint has been filtered-out, add the actual image width instead + if ( + sizes.length < breakpoints.length && + !sizes.includes(imgDimensions.width) + ) { + sizes.push(imgDimensions.width) + } } else { sizes = densities.map(density => Math.round(density * width)) sizes = sizes.filter(size => size <= imgDimensions.width) } // ensure that the size passed in is included in the final output - if (!sizes.includes(width)) { + if (layout === `constrained` && !sizes.includes(width)) { sizes.push(width) } sizes = sizes.sort((a, b) => a - b) From 4f56351d08d7724880da8842456731b25c300d54 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Wed, 13 Jan 2021 09:51:31 +0000 Subject: [PATCH 03/10] Update tests --- .../src/__tests__/utils.js | 74 ++++++++++++++----- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/__tests__/utils.js b/packages/gatsby-plugin-sharp/src/__tests__/utils.js index 9df25e69f2be4..9b797d40c6f24 100644 --- a/packages/gatsby-plugin-sharp/src/__tests__/utils.js +++ b/packages/gatsby-plugin-sharp/src/__tests__/utils.js @@ -103,7 +103,7 @@ describe(`calculateImageSizes (fixed)`, () => { imgDimensions, } const { sizes } = calculateImageSizes(args) - expect(sizes).toEqual(expect.arrayContaining([120, 240])) + expect(sizes).toEqual([120, 240]) }) it(`should create images of different sizes based on pixel densities with a given height`, () => { @@ -114,7 +114,7 @@ describe(`calculateImageSizes (fixed)`, () => { imgDimensions, } const { sizes } = calculateImageSizes(args) - expect(sizes).toEqual(expect.arrayContaining([120, 240])) + expect(sizes).toEqual([120, 240]) }) }) @@ -172,7 +172,7 @@ describe(`calculateImageSizes (fullWidth & constrained)`, () => { imgDimensions, } const { sizes } = calculateImageSizes(args) - expect(sizes).toEqual(expect.arrayContaining([80, 160, 320, 640])) + expect(sizes).toEqual([80, 160, 320, 640]) }) it(`should create images of different sizes (0.25x, 0.5x, 1x) without any defined size provided`, () => { @@ -182,63 +182,101 @@ describe(`calculateImageSizes (fullWidth & constrained)`, () => { imgDimensions, } const { sizes } = calculateImageSizes(args) - expect(sizes).toEqual(expect.arrayContaining([200, 400, 800])) + expect(sizes).toEqual([200, 400, 800]) }) - it(`should return sizes of provided srcSetBreakpoints`, () => { - const srcSetBreakpoints = [50, 70, 150, 250, 300] + it(`should return sizes of provided breakpoints in fullWidth`, () => { + const breakpoints = [50, 70, 150, 250, 300] const width = 500 const args = { layout: `fullWidth`, width, - srcSetBreakpoints, + breakpoints, file, imgDimensions, reporter, } const { sizes } = calculateImageSizes(args) - expect(sizes).toEqual(expect.arrayContaining([50, 70, 150, 250, 300, 500])) + expect(sizes).toEqual([50, 70, 150, 250, 300]) }) - it(`should reject any srcSetBreakpoints larger than the original width`, () => { - const srcSetBreakpoints = [ + it(`should include provided width along with breakpoints in constrained`, () => { + const breakpoints = [50, 70, 150, 250, 300] + const width = 500 + const args = { + layout: `constrained`, + width, + breakpoints, + file, + imgDimensions, + reporter, + } + + const { sizes } = calculateImageSizes(args) + expect(sizes).toEqual([50, 70, 150, 250, 300, 500]) + }) + + it(`should reject any breakpoints larger than the original width`, () => { + const breakpoints = [ 50, 70, 150, 250, - 1250, // shouldn't be included, larger than original width + 1200, + 1800, // shouldn't be included, larger than original width ] const width = 1500 // also shouldn't be included const args = { layout: `fullWidth`, width, - srcSetBreakpoints, + breakpoints, + file, + imgDimensions, + reporter, + } + + const { sizes } = calculateImageSizes(args) + expect(sizes).toEqual([50, 70, 150, 250, 1200]) + }) + + it(`should add the original width instead of larger breakpoints`, () => { + const breakpoints = [ + 50, + 70, + 150, + 250, + 1800, // shouldn't be included, larger than original width + ] + const width = 1300 + const args = { + layout: `fullWidth`, + width, + breakpoints, file, imgDimensions, reporter, } const { sizes } = calculateImageSizes(args) - expect(sizes).toEqual(expect.arrayContaining([50, 70, 150, 250])) - expect(sizes).toEqual(expect.not.arrayContaining([1250, 1500])) + expect(sizes).toEqual([50, 70, 150, 250, 1200]) }) - it(`should only uses sizes from srcSetBreakpoints when outputPixelDensities are also passed in`, () => { - const srcSetBreakpoints = [400, 800] // should find these + it(`should ignore outputPixelDensities when breakpoints are passed in`, () => { + const breakpoints = [400, 800] // should find these const width = 500 const args = { layout: `fullWidth`, width, outputPixelDensities: [2, 4], // and ignore these, ie [1000, 2000] - srcSetBreakpoints, + breakpoints, file, imgDimensions, reporter, } const { sizes } = calculateImageSizes(args) - expect(sizes).toEqual(expect.arrayContaining([400, 500, 800])) + expect(sizes).toEqual([400, 800]) }) it(`should adjust fullWidth sizes according to fit type`, () => { From e36d5e4008a9fef5acd8ea275959305a11616ebe Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Wed, 13 Jan 2021 10:02:35 +0000 Subject: [PATCH 04/10] Add breakpoints to plugin helper --- .../gatsby-plugin-image/src/image-utils.ts | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/gatsby-plugin-image/src/image-utils.ts b/packages/gatsby-plugin-image/src/image-utils.ts index 27a90d710fed4..2d821b2b283a7 100644 --- a/packages/gatsby-plugin-image/src/image-utils.ts +++ b/packages/gatsby-plugin-image/src/image-utils.ts @@ -4,6 +4,7 @@ import { IGatsbyImageData } from "." import type sharp from "gatsby-plugin-sharp/safe-sharp" const DEFAULT_PIXEL_DENSITIES = [0.25, 0.5, 1, 2] +const DEFAULT_BREAKPOINTS = [750, 1080, 1366, 1920] const DEFAULT_FLUID_WIDTH = 800 const DEFAULT_FIXED_WIDTH = 400 @@ -47,6 +48,7 @@ export interface IImageSizeArgs { layout?: Layout filename: string outputPixelDensities?: Array + breakpoints?: Array fit?: Fit reporter?: IReporter sourceMetadata: { width: number; height: number } @@ -90,6 +92,7 @@ export interface IGatsbyImageHelperArgs { sourceMetadata?: { width: number; height: number; format: ImageFormat } fit?: Fit options?: Record + breakpoints?: Array } const warn = (message: string): void => console.warn(message) @@ -293,8 +296,10 @@ export function calculateImageSizes(args: IImageSizeArgs): IImageSizes { if (layout === `fixed`) { return fixedImageSizes(args) - } else if (layout === `fullWidth` || layout === `constrained`) { + } else if (layout === `constrained`) { return responsiveImageSizes(args) + } else if (layout === `fullWidth`) { + return responsiveImageSizes({ breakpoints: DEFAULT_BREAKPOINTS, ...args }) } else { reporter.warn( `No valid layout was provided for the image at ${filename}. Valid image layouts are fixed, fullWidth, and constrained.` @@ -387,6 +392,7 @@ export function responsiveImageSizes({ height, fit = `cover`, outputPixelDensities = DEFAULT_PIXEL_DENSITIES, + breakpoints, }: IImageSizeArgs): IImageSizes { let sizes let aspectRatio = imgDimensions.width / imgDimensions.height @@ -431,8 +437,20 @@ export function responsiveImageSizes({ width = Math.round(width) - sizes = densities.map(density => Math.round(density * (width as number))) - sizes = sizes.filter(size => size <= imgDimensions.width) + if (breakpoints?.length > 0) { + sizes = breakpoints.filter(size => size <= imgDimensions.width) + + // If a larger breakpoint has been filtered-out, add the actual image width instead + if ( + sizes.length < breakpoints.length && + !sizes.includes(imgDimensions.width) + ) { + sizes.push(imgDimensions.width) + } + } else { + sizes = densities.map(density => Math.round(density * (width as number))) + sizes = sizes.filter(size => size <= imgDimensions.width) + } // ensure that the size passed in is included in the final output if (!sizes.includes(width)) { From 50e30b65cf3b14140e3e62be5e9be7359d8dd272 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Wed, 13 Jan 2021 10:51:22 +0000 Subject: [PATCH 05/10] Update image utils test --- .../src/__tests__/image-utils.ts | 15 +++++++++++---- packages/gatsby-plugin-image/src/image-utils.ts | 3 ++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/gatsby-plugin-image/src/__tests__/image-utils.ts b/packages/gatsby-plugin-image/src/__tests__/image-utils.ts index 879a049a9c803..42551c5bcd452 100644 --- a/packages/gatsby-plugin-image/src/__tests__/image-utils.ts +++ b/packages/gatsby-plugin-image/src/__tests__/image-utils.ts @@ -37,6 +37,11 @@ const args: IGatsbyImageHelperArgs = { const fluidArgs: IGatsbyImageHelperArgs = { ...args, + sourceMetadata: { + width: 2000, + height: 1500, + format: `jpg`, + }, layout: `fullWidth`, } @@ -179,12 +184,14 @@ describe(`the image data helper`, () => { it(`returns URLs for fullWidth`, () => { const data = generateImageData(fluidArgs) expect(data?.images?.fallback?.src).toEqual( - `https://example.com/afile.jpg/400/300/image.jpg` + `https://example.com/afile.jpg/750/563/image.jpg` ) - expect(data.images?.sources?.[0].srcSet).toEqual( - `https://example.com/afile.jpg/100/75/image.webp 100w,\nhttps://example.com/afile.jpg/200/150/image.webp 200w,\nhttps://example.com/afile.jpg/400/300/image.webp 400w,\nhttps://example.com/afile.jpg/800/600/image.webp 800w` - ) + expect(data.images?.sources?.[0].srcSet) + .toEqual(`https://example.com/afile.jpg/750/563/image.webp 750w, +https://example.com/afile.jpg/1080/810/image.webp 1080w, +https://example.com/afile.jpg/1366/1025/image.webp 1366w, +https://example.com/afile.jpg/1920/1440/image.webp 1920w`) }) it(`converts to PNG if requested`, () => { diff --git a/packages/gatsby-plugin-image/src/image-utils.ts b/packages/gatsby-plugin-image/src/image-utils.ts index 2d821b2b283a7..6fa58f5faa09a 100644 --- a/packages/gatsby-plugin-image/src/image-utils.ts +++ b/packages/gatsby-plugin-image/src/image-utils.ts @@ -393,6 +393,7 @@ export function responsiveImageSizes({ fit = `cover`, outputPixelDensities = DEFAULT_PIXEL_DENSITIES, breakpoints, + layout, }: IImageSizeArgs): IImageSizes { let sizes let aspectRatio = imgDimensions.width / imgDimensions.height @@ -453,7 +454,7 @@ export function responsiveImageSizes({ } // ensure that the size passed in is included in the final output - if (!sizes.includes(width)) { + if (layout === `constrained` && !sizes.includes(width)) { sizes.push(width) } sizes = sizes.sort(sortNumeric) From b8f784d2006a062181043de33e87ee2c54c2b93e Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Wed, 13 Jan 2021 11:20:51 +0000 Subject: [PATCH 06/10] Update readme --- packages/gatsby-plugin-image/README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/gatsby-plugin-image/README.md b/packages/gatsby-plugin-image/README.md index ce902f9df8a51..ba828df196871 100644 --- a/packages/gatsby-plugin-image/README.md +++ b/packages/gatsby-plugin-image/README.md @@ -316,26 +316,28 @@ The optional helper function `getImage` takes a file node and returns `file?.chi These arguments can be passed to the `gatsbyImageData()` resolver: -- **width**: The display width of the generated image for layout = FIXED, if layout = CONSTRAINED it's the display width of the largest generated image. The actual largest image resolution will be this value multiplied by the largest value in outputPixelDensities. -- **height**: If set, the height of the generated image. If omitted, it is calculated from the supplied width, matching the aspect ratio of the source image. +- **width**: The display width of the generated image for layout = FIXED, if layout = CONSTRAINED it's the maximum display width. Ignored for FULL_WIDTH images. +- **height**: If set, the height of the generated image. If omitted, it is calculated from the supplied width, matching the aspect ratio of the source image. Ignored for FULL_WIDTH images. +- **aspectRatio**: Forces an image to the specified aspect ratio, cropping if needed. The value is a number, but can be clearer to express as a fraction, e.g. `aspectRatio={16/9}` - **placeholder**: Format of generated placeholder image. - - `BLURRED`: (default) a blurred, low resolution image, encoded as a base64 data URI - - `TRACED_SVG`: a low-resolution traced SVG of the image. + - `DOMINANT_COLOR`: (default) A solid color, calculated from the dominant color of the image. + - `BLURRED`: a blurred, low resolution image, encoded as a base64 data URI + - `TRACED_SVG`: a single-color traced SVG of the image. - `NONE`: no placeholder. Set "background" to use a fixed background color. - - `DOMINANT_COLOR`: a solid color, calculated from the dominant color of the image. - **layout**: The layout for the image. - `CONSTRAINED`: (default) Resizes to fit its container, up to a maximum width, at which point it will remain fixed in size. - `FIXED`: A static image size, that does not resize according to the screen width - `FULL_WIDTH`: The image resizes to fit its container. Pass a "sizes" option if it isn't going to be the full width of the screen. -- **outputPixelDensities**: A list of image pixel densities to generate, for high-resolution (retina) screens. It will never generate images larger than the source, and will always include a 1x image. - Default is `[ 0.25, 0.5, 1, 2 ]`, for fullWidth/constrained images, and `[ 1, 2 ]` for fixed. - **sizes**: The "[sizes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images)" attribute, passed to the `` tag. This describes the display size of the image. This does not affect the generated images, but is used by the browser to decide which images to download. You can leave this blank for fixed images, or if the responsive image container will be the full width of the screen. In these cases we will generate an appropriate value. If, however, you are generating responsive images that are not the full width of the screen, you should provide a sizes property for best performance. You can alternatively pass this value to the component. - **formats**: an array of file formats to generate. The default is `[AUTO, WEBP]`, which means it will generate images in the same format as the source image, as well as in the next-generation [WebP](https://developers.google.com/speed/webp) format. We strongly recommend you do not change this option, as doing so will affect performance scores. - **quality**: The default quality. This is overridden by any format-specific options -- **blurredOptions**: Options for the low-resolution placeholder image. Set placeholder to "BLURRED" to use this +- **outputPixelDensities**: A list of image pixel densities to generate, for high-resolution (retina) screens. It will never generate images larger than the source, and will always include a 1x image. + Default is `[ 0.25, 0.5, 1, 2 ]`, for `CONSTRAINED` images, and `[ 1, 2 ]` for `FIXED`. Ignored for `FULL_WIDTH`, which uses `breakpoints` instead. +- **breakpoints**: Output widths to generate for full width images. Default is `[750, 1080, 1366, 1920]`, which is suitable for most common device resolutions. It will never generate an image larger than the source image. The browser will automatically choose the most appropriate. +- **blurredOptions**: Options for the low-resolution placeholder image. Set placeholder to `BLURRED` to use this - width - toFormat -- **tracedSVGOptions**: Options for traced placeholder SVGs. You also should set placeholder to "SVG". +- **tracedSVGOptions**: Options for traced placeholder SVGs. You also should set placeholder to `TRACED_SVG`. - **jpgOptions**: Options to pass to sharp when generating JPG images. - quality - progressive From 68333f8042ba5d69e489aa8446fd2069a1da8978 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Wed, 13 Jan 2021 16:38:54 +0000 Subject: [PATCH 07/10] Update packages/gatsby-plugin-sharp/src/image-data.ts Co-authored-by: LB --- packages/gatsby-plugin-sharp/src/image-data.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby-plugin-sharp/src/image-data.ts b/packages/gatsby-plugin-sharp/src/image-data.ts index b5907d2aa300c..0018d66a7ffa3 100644 --- a/packages/gatsby-plugin-sharp/src/image-data.ts +++ b/packages/gatsby-plugin-sharp/src/image-data.ts @@ -94,7 +94,7 @@ export async function generateImageData({ args.formats = args.formats || [`auto`, `webp`] - if (layout === `fluid`) { + if (layout === `fullWidth`) { args.breakpoints = args.breakpoints?.length ? args.breakpoints : DEFAULT_BREAKPOINTS From 6ac15351397da951ff8acb0027102dd5cbc8758b Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Thu, 14 Jan 2021 11:57:30 +0000 Subject: [PATCH 08/10] Fix test --- e2e-tests/visual-regression/src/pages/images/fullWidth.js | 2 +- .../visual-regression/src/pages/static-images/fullWidth.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/e2e-tests/visual-regression/src/pages/images/fullWidth.js b/e2e-tests/visual-regression/src/pages/images/fullWidth.js index 010a3a5259131..9609bbd807020 100644 --- a/e2e-tests/visual-regression/src/pages/images/fullWidth.js +++ b/e2e-tests/visual-regression/src/pages/images/fullWidth.js @@ -9,7 +9,7 @@ const Page = () => { query { file(relativePath: { eq: "cornwall.jpg" }) { childImageSharp { - gatsbyImageData(width: 1024, layout: FULL_WIDTH) + gatsbyImageData(layout: FULL_WIDTH) } } } diff --git a/e2e-tests/visual-regression/src/pages/static-images/fullWidth.js b/e2e-tests/visual-regression/src/pages/static-images/fullWidth.js index 99fb1ca0a7834..1657f7415ff8c 100644 --- a/e2e-tests/visual-regression/src/pages/static-images/fullWidth.js +++ b/e2e-tests/visual-regression/src/pages/static-images/fullWidth.js @@ -12,7 +12,6 @@ const Page = () => { src="../../images/cornwall.jpg" loading="eager" layout="fullWidth" - width={1024} alt="cornwall" /> From 39f5d025adc1794e7db07e4975f12bd42abd1342 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Thu, 14 Jan 2021 11:57:52 +0000 Subject: [PATCH 09/10] Fix defaults --- packages/gatsby-transformer-sharp/src/customize-schema.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/gatsby-transformer-sharp/src/customize-schema.js b/packages/gatsby-transformer-sharp/src/customize-schema.js index 015b37af4ba92..675dde2a07cfe 100644 --- a/packages/gatsby-transformer-sharp/src/customize-schema.js +++ b/packages/gatsby-transformer-sharp/src/customize-schema.js @@ -430,7 +430,7 @@ const imageNodeType = ({ }, placeholder: { type: ImagePlaceholderType, - defaultValue: `blurred`, + defaultValue: `dominantColor`, description: stripIndent` Format of generated placeholder image, displayed while the main image loads. BLURRED: a blurred, low resolution image, encoded as a base64 data URI (default) @@ -444,7 +444,6 @@ const imageNodeType = ({ }, tracedSVGOptions: { type: PotraceType, - defaultValue: false, description: `Options for traced placeholder SVGs. You also should set placeholder to "TRACED_SVG".`, }, formats: { @@ -474,7 +473,6 @@ const imageNodeType = ({ }, sizes: { type: GraphQLString, - defaultValue: ``, description: stripIndent` The "sizes" property, passed to the img tag. This describes the display size of the image. This does not affect the generated images, but is used by the browser to decide which images to download. From 839e625fddace68bd714a617cb33bf6d2667a829 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Thu, 14 Jan 2021 12:00:04 +0000 Subject: [PATCH 10/10] Correctly handle default image for fullWidth --- packages/gatsby-plugin-sharp/src/image-data.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/image-data.ts b/packages/gatsby-plugin-sharp/src/image-data.ts index 0018d66a7ffa3..e3f1e8e33ddaf 100644 --- a/packages/gatsby-plugin-sharp/src/image-data.ts +++ b/packages/gatsby-plugin-sharp/src/image-data.ts @@ -86,7 +86,7 @@ export async function generateImageData({ }: IImageDataArgs): Promise { const { layout = `constrained`, - placeholder = `blurred`, + placeholder = `dominantColor`, tracedSVGOptions = {}, transformOptions = {}, quality, @@ -210,9 +210,10 @@ export async function generateImageData({ const sizes = args.sizes || getSizes(imageSizes.unscaledWidth, layout) - const primaryIndex = imageSizes.sizes.findIndex( - size => size === imageSizes.unscaledWidth - ) + const primaryIndex = + layout === `fullWidth` + ? imageSizes.sizes.length - 1 // The largest image + : imageSizes.sizes.findIndex(size => size === imageSizes.unscaledWidth) if (primaryIndex === -1) { reporter.error(