From 96a236ba41a8569d0b9b5755ddc74c02dc6e4a59 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sat, 14 Oct 2017 04:45:12 +0200 Subject: [PATCH 01/33] =?UTF-8?q?First=20shot=20at=20SVG=20=E2=80=9Etraced?= =?UTF-8?q?=20placeholders=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using node-potrace (and Jimp…) and SVGO. Only working with `resolutions` right now, also didn’t check SVG size yet. --- examples/image-processing/src/pages/index.js | 22 +++++++++++++++ packages/gatsby-plugin-sharp/package.json | 4 ++- packages/gatsby-plugin-sharp/src/index.js | 27 ++++++++++++++++++- .../src/extend-node-type.js | 21 +++++++++++++++ 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/examples/image-processing/src/pages/index.js b/examples/image-processing/src/pages/index.js index 39f917029e41b..d2df35ee288b5 100644 --- a/examples/image-processing/src/pages/index.js +++ b/examples/image-processing/src/pages/index.js @@ -12,6 +12,7 @@ class Index extends React.Component { const cropBottomLeft = this.props.data.cropBottomLeft.resize const cropEntropy = this.props.data.cropEntropy.resize const cropCenter = this.props.data.cropCenter.resize + const tracedSVG = this.props.data.tracedSVG.resolutions return (
@@ -43,6 +44,15 @@ class Index extends React.Component {

+

Potrace

+ + + +

{ @@ -552,9 +565,21 @@ async function resolutions({ file, args = {} }) { src: fallbackSrc, srcSet, originalName: originalName, + tracedSVG: tracedSVG, } } +async function traceSVG(file, args) { + return await trace(file.absolutePath, args) + .then(svg => optimize(svg)) + .then(svg => `data:image/svg+xml;utf8,${svg.toString(`base64`)}`) +} + +const optimize = svg => + new Promise((resolve, reject) => { + svgo.optimize(svg, ({ data }) => resolve(data)) + }) + exports.queueImageResizing = queueImageResizing exports.base64 = base64 exports.responsiveSizes = responsiveSizes diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index ba0d4cc8f2be3..c315663974d7f 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -57,6 +57,18 @@ const DuotoneGradientType = new GraphQLInputObjectType({ }, }) +const PotraceType = new GraphQLInputObjectType({ + name: `Potrace`, + fields: () => { + return { + background: { type: GraphQLString }, + color: { type: GraphQLString }, + turdSize: { type: GraphQLFloat }, + optTolerance: { type: GraphQLFloat }, + } + }, +}) + module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { if (type.name !== `ImageSharp`) { return {} @@ -109,6 +121,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { src: { type: GraphQLString }, srcSet: { type: GraphQLString }, originalName: { type: GraphQLString }, + tracedSVG: { type: GraphQLString }, }, }), args: { @@ -131,6 +144,14 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { type: DuotoneGradientType, defaultValue: false, }, + trace: { + type: PotraceType, + defaultValue: { + color: `#ddd`, + turdSize: 100, + optTolerance: 0.4, + }, + }, quality: { type: GraphQLInt, defaultValue: 50, From 819de3f4df587ee933a3a01e675665000747a5c4 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sat, 14 Oct 2017 20:14:31 +0200 Subject: [PATCH 02/33] Add fragments --- .../gatsby-transformer-sharp/src/fragments.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/packages/gatsby-transformer-sharp/src/fragments.js b/packages/gatsby-transformer-sharp/src/fragments.js index 754aa4f748fc2..00a1c457391ea 100644 --- a/packages/gatsby-transformer-sharp/src/fragments.js +++ b/packages/gatsby-transformer-sharp/src/fragments.js @@ -9,6 +9,16 @@ export const gatsbyImageSharpResolutions = graphql` } ` +export const gatsbyImageSharpResolutionsTracedSVG = graphql` + fragment GatsbyImageSharpResolutions_tracedSVG on ImageSharpResolutions { + tracedSVG + width + height + src + srcSet + } +` + export const gatsbyImageSharpResolutionsNoBase64 = graphql` fragment GatsbyImageSharpResolutions_noBase64 on ImageSharpResolutions { width @@ -28,6 +38,16 @@ export const gatsbyImageSharpSizes = graphql` } ` +export const gatsbyImageSharpSizesTracedSVG = graphql` + fragment GatsbyImageSharpSizes_tracedSVG on ImageSharpSizes { + tracedSVG + aspectRatio + src + srcSet + sizes + } +` + export const gatsbyImageSharpSizesNoBase64 = graphql` fragment GatsbyImageSharpSizes_noBase64 on ImageSharpSizes { aspectRatio From 00b69c0b186b08e41cca0a8c1cae4ee930d695bd Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sat, 14 Oct 2017 22:32:59 +0200 Subject: [PATCH 03/33] Yo! --- examples/image-processing/src/pages/index.js | 24 +------------------ packages/gatsby-image/src/index.js | 22 +++++++++++++++++ .../src/extend-node-type.js | 11 ++++++++- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/examples/image-processing/src/pages/index.js b/examples/image-processing/src/pages/index.js index d2df35ee288b5..1e34980af8a26 100644 --- a/examples/image-processing/src/pages/index.js +++ b/examples/image-processing/src/pages/index.js @@ -12,7 +12,6 @@ class Index extends React.Component { const cropBottomLeft = this.props.data.cropBottomLeft.resize const cropEntropy = this.props.data.cropEntropy.resize const cropCenter = this.props.data.cropCenter.resize - const tracedSVG = this.props.data.tracedSVG.resolutions return (
@@ -44,15 +43,6 @@ class Index extends React.Component {

-

Potrace

- - - -

)} + {/* Show the traced SVG image. */} + {image.tracedSVG && ( + {alt} + )} + {/* Show a solid background color. */} {bgColor && (
)} + {/* Show the traced SVG image. */} + {image.tracedSVG && ( + {alt} + )} + {/* Show a solid background color. */} {bgColor && (
{ name: `ImageSharpResolutions`, fields: { base64: { type: GraphQLString }, + tracedSVG: { type: GraphQLString }, aspectRatio: { type: GraphQLFloat }, width: { type: GraphQLFloat }, height: { type: GraphQLFloat }, src: { type: GraphQLString }, srcSet: { type: GraphQLString }, originalName: { type: GraphQLString }, - tracedSVG: { type: GraphQLString }, }, }), args: { @@ -182,6 +182,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { name: `ImageSharpSizes`, fields: { base64: { type: GraphQLString }, + tracedSVG: { type: GraphQLString }, aspectRatio: { type: GraphQLFloat }, src: { type: GraphQLString }, srcSet: { type: GraphQLString }, @@ -210,6 +211,14 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { type: DuotoneGradientType, defaultValue: false, }, + trace: { + type: PotraceType, + defaultValue: { + color: `#ddd`, + turdSize: 100, + optTolerance: 0.4, + }, + }, quality: { type: GraphQLInt, defaultValue: 50, From 1c2fbc3335d173fc4cdb8e2db6535dab4a8aaad8 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sun, 15 Oct 2017 00:12:42 +0200 Subject: [PATCH 04/33] Memoize --- packages/gatsby-plugin-sharp/src/index.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index dbd071c457557..35201ac806ffa 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -530,7 +530,7 @@ async function resolutions({ file, args = {} }) { const base64Image = await base64({ file, args: base64Args }) // Get traced SVG base64 - const tracedSVG = await traceSVG(file, options.trace) + const tracedSVG = await traceSVG({ file, args: options.trace }) const fallbackSrc = images[0].src const srcSet = images @@ -569,12 +569,21 @@ async function resolutions({ file, args = {} }) { } } -async function traceSVG(file, args) { +async function notMemoizedtraceSVG({ file, args }) { return await trace(file.absolutePath, args) .then(svg => optimize(svg)) .then(svg => `data:image/svg+xml;utf8,${svg.toString(`base64`)}`) } +const memoizedTraceSVG = _.memoize( + notMemoizedtraceSVG, + ({ file, args }) => `${file.id}${JSON.stringify(args)}` +) + +async function traceSVG(args) { + return await memoizedTraceSVG(args) +} + const optimize = svg => new Promise((resolve, reject) => { svgo.optimize(svg, ({ data }) => resolve(data)) From ce59c9ab35c1566c02724b6c1a6d36f4118d1a6b Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sun, 15 Oct 2017 00:31:29 +0200 Subject: [PATCH 05/33] Support sizes() --- examples/image-processing/src/pages/index.js | 3 ++- packages/gatsby-plugin-sharp/src/index.js | 13 +++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/examples/image-processing/src/pages/index.js b/examples/image-processing/src/pages/index.js index 1e34980af8a26..586db8232e8ea 100644 --- a/examples/image-processing/src/pages/index.js +++ b/examples/image-processing/src/pages/index.js @@ -306,9 +306,10 @@ export const pageQuery = graphql` sizes: imageSharp(id: { regex: "/fecolormatrix-kanye-west.jpg/" }) { sizes( duotone: { highlight: "#f00e2e", shadow: "#192550" } + trace: { color: "#f00e2e" } toFormat: PNG ) { - ...GatsbyImageSharpSizes + ...GatsbyImageSharpSizes_tracedSVG } } resolution: imageSharp(id: { regex: "/lol.jpg/" }) { diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index 35201ac806ffa..ee1fbd8adc6d5 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -357,10 +357,15 @@ async function responsiveSizes({ file, args = {} }) { pngCompressionLevel: 9, grayscale: false, duotone: false, + trace: { + color: `#ddd`, + turdSize: 100, + optTolerance: 0.4, + }, pathPrefix: ``, toFormat: ``, } - const options = _.defaults({}, args, defaultArgs) + const options = _.defaultsDeep({}, args, defaultArgs) options.maxWidth = parseInt(options.maxWidth, 10) // Account for images with a high pixel density. We assume that these types of @@ -434,6 +439,9 @@ async function responsiveSizes({ file, args = {} }) { // Get base64 version const base64Image = await base64({ file, args: base64Args }) + // Get traced SVG base64 + const tracedSVG = await traceSVG({ file, args: options.trace }) + // Construct src and srcSet strings. const originalImg = _.maxBy(images, image => image.width).src const fallbackSrc = _.minBy(images, image => @@ -446,6 +454,7 @@ async function responsiveSizes({ file, args = {} }) { return { base64: base64Image.src, + tracedSVG: tracedSVG, aspectRatio: images[0].aspectRatio, src: fallbackSrc, srcSet, @@ -559,13 +568,13 @@ async function resolutions({ file, args = {} }) { return { base64: base64Image.src, + tracedSVG: tracedSVG, aspectRatio: images[0].aspectRatio, width: images[0].width, height: images[0].height, src: fallbackSrc, srcSet, originalName: originalName, - tracedSVG: tracedSVG, } } From 8389ea3276a6cbca6c075046ce338882cd06470f Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sun, 15 Oct 2017 01:33:36 +0200 Subject: [PATCH 06/33] Expose potrace options --- examples/image-processing/src/pages/index.js | 6 ++++- .../src/extend-node-type.js | 22 +++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/examples/image-processing/src/pages/index.js b/examples/image-processing/src/pages/index.js index 586db8232e8ea..36b76b782f3d2 100644 --- a/examples/image-processing/src/pages/index.js +++ b/examples/image-processing/src/pages/index.js @@ -306,7 +306,11 @@ export const pageQuery = graphql` sizes: imageSharp(id: { regex: "/fecolormatrix-kanye-west.jpg/" }) { sizes( duotone: { highlight: "#f00e2e", shadow: "#192550" } - trace: { color: "#f00e2e" } + trace: { + color: "#f00e2e" + turnPolicy: TURNPOLICY_MINORITY + blackOnWhite: false + } toFormat: PNG ) { ...GatsbyImageSharpSizes_tracedSVG diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index cd5591b5e5db8..170794bef3078 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -19,6 +19,7 @@ const sharp = require(`sharp`) const fsExtra = require(`fs-extra`) const sizeOf = require(`image-size`) const path = require(`path`) +const Potrace = require(`potrace`).Potrace const ImageFormatType = new GraphQLEnumType({ name: `ImageFormat`, @@ -61,10 +62,27 @@ const PotraceType = new GraphQLInputObjectType({ name: `Potrace`, fields: () => { return { - background: { type: GraphQLString }, - color: { type: GraphQLString }, + turnPolicy: { + type: new GraphQLEnumType({ + name: `PotraceTurnPolicy`, + values: { + TURNPOLICY_BLACK: { value: Potrace.TURNPOLICY_BLACK }, + TURNPOLICY_WHITE: { value: Potrace.TURNPOLICY_WHITE }, + TURNPOLICY_LEFT: { value: Potrace.TURNPOLICY_LEFT }, + TURNPOLICY_RIGHT: { value: Potrace.TURNPOLICY_RIGHT }, + TURNPOLICY_MINORITY: { value: Potrace.TURNPOLICY_MINORITY }, + TURNPOLICY_MAJORITY: { value: Potrace.TURNPOLICY_MAJORITY }, + }, + }), + }, turdSize: { type: GraphQLFloat }, + alphaMax: { type: GraphQLFloat }, + optCurve: { type: GraphQLBoolean }, optTolerance: { type: GraphQLFloat }, + threshold: { type: GraphQLInt }, + blackOnWhite: { type: GraphQLBoolean }, + color: { type: GraphQLString }, + background: { type: GraphQLString }, } }, }) From 795e02d1c12c8a8a84aa1c0a03998c67a8c4750c Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sun, 15 Oct 2017 01:57:32 +0200 Subject: [PATCH 07/33] Add turnPolicy default Following to https://twitter.com/Martin_Adams/status/918481948217049088 --- packages/gatsby-plugin-sharp/src/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index ee1fbd8adc6d5..60244054b9c8e 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -359,8 +359,9 @@ async function responsiveSizes({ file, args = {} }) { duotone: false, trace: { color: `#ddd`, - turdSize: 100, optTolerance: 0.4, + turdSize: 100, + turnPolicy: potrace.Potrace.TURNPOLICY_MAJORITY, }, pathPrefix: ``, toFormat: ``, @@ -477,8 +478,9 @@ async function resolutions({ file, args = {} }) { duotone: false, trace: { color: `#ddd`, - turdSize: 100, optTolerance: 0.4, + turdSize: 100, + turnPolicy: potrace.Potrace.TURNPOLICY_MAJORITY, }, pathPrefix: ``, toFormat: ``, From c214ea96db8715cdf267e607018bddf74618a917 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sun, 15 Oct 2017 02:10:15 +0200 Subject: [PATCH 08/33] First shot at readme --- packages/gatsby-image/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/gatsby-image/README.md b/packages/gatsby-image/README.md index 1c71dd4d43669..50cb659776c53 100644 --- a/packages/gatsby-image/README.md +++ b/packages/gatsby-image/README.md @@ -16,7 +16,7 @@ But creating optimized images for websites has long been a thorny problem. Ideal * Generate multiple smaller images so smartphones and tablets don't download desktop-sized images * Strip all unnecessary metadata and optimize JPEG and PNG compression * Efficiently lazy load images to speed initial page load and save bandwidth -* Use the "blur-up" technique to show a preview of the image while it loads +* Use the "blur-up" technique or a "[traced placeholder](https://github.com/gatsbyjs/gatsby/issues/2435)" SVG to show a preview of the image while it loads * Hold the image position so your page doesn't jump while images load Doing this consistantly across a site feels like sisyphean labor. You manually optimize your images and then… several images are swapped in at the last minute or a design-tweak shaves 100px of width off your images. @@ -94,8 +94,10 @@ Their fragments are: * `GatsbyImageSharpResolutions` * `GatsbyImageSharpResolutions_noBase64` +* `GatsbyImageSharpResolutions_tracedSVG` * `GatsbyImageSharpSizes` * `GatsbyImageSharpSizes_noBase64` +* `GatsbyImageSharpSizes_tracedSVG` ### gatsby-source-contentful @@ -104,7 +106,7 @@ Their fragments are: * `GatsbyContentfulSizes` * `GatsbyContentfulSizes_noBase64` -If you don't want to use the blur-up effect, choose the fragment with `noBase64` at the end. +If you don't want to use the blur-up effect, choose the fragment with `noBase64` at the end. If you want to use the traced placeholder SVGs, choose the fragment with `tracedSVG` at the end. ## "Resolutions" queries @@ -120,7 +122,7 @@ Pass in the data returned from the `resolutions` object in your query via the `r # Other options include height (set both width and height to crop), # grayscale, duotone, rotate, etc. resolutions(width: 400) { - # Choose either the fragment including a small base64ed image or one without. + # Choose either the fragment including a small base64ed image, a traced placeholder SVG, or one without. ...GatsbyImageSharpResolutions } } @@ -143,7 +145,7 @@ Pass in the data returned from the `sizes` object in your query via the `sizes` # Other options include maxHeight (set both maxWidth and maxHeight to crop), # grayscale, duotone, rotate, etc. sizes(maxWidth: 700) { - # Choose either the fragment including a small base64ed image or one without. + # Choose either the fragment including a small base64ed image, a traced placeholder SVG, or one without. ...GatsbyImageSharpSizes_noBase64 } } From beaa8bce816c65e6b44840448de9d2434520c6ee Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sun, 15 Oct 2017 18:41:57 +0200 Subject: [PATCH 09/33] =?UTF-8?q?Add=20missing=20defaultValue=20=E2=80=9Et?= =?UTF-8?q?urnPolicy=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/gatsby-transformer-sharp/src/extend-node-type.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index 170794bef3078..ead282886f108 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -166,8 +166,9 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { type: PotraceType, defaultValue: { color: `#ddd`, - turdSize: 100, optTolerance: 0.4, + turnPolicy: Potrace.TURNPOLICY_MAJORITY, + turdSize: 100, }, }, quality: { @@ -233,8 +234,9 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { type: PotraceType, defaultValue: { color: `#ddd`, - turdSize: 100, optTolerance: 0.4, + turdSize: 100, + turnPolicy: Potrace.TURNPOLICY_MAJORITY, }, }, quality: { From 89f9d10dd5e5b7c91f8e385b586cc5768d80021f Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sun, 15 Oct 2017 18:46:10 +0200 Subject: [PATCH 10/33] =?UTF-8?q?Remove=20invalid=20=E2=80=9E;utf8?= =?UTF-8?q?=E2=80=9C=20param?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/gatsby-plugin-sharp/src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index 60244054b9c8e..2c69388a09b80 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -583,7 +583,7 @@ async function resolutions({ file, args = {} }) { async function notMemoizedtraceSVG({ file, args }) { return await trace(file.absolutePath, args) .then(svg => optimize(svg)) - .then(svg => `data:image/svg+xml;utf8,${svg.toString(`base64`)}`) + .then(svg => `data:image/svg+xml,${svg.toString(`base64`)}`) } const memoizedTraceSVG = _.memoize( From da19d0622158ac3fb0ea88b86d26cab60cd408e7 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sun, 15 Oct 2017 19:01:50 +0200 Subject: [PATCH 11/33] =?UTF-8?q?Remove=20default=20=E2=80=9Etrace?= =?UTF-8?q?=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/gatsby-plugin-sharp/src/index.js | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index 2c69388a09b80..a83f5ff8b48c1 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -357,12 +357,7 @@ async function responsiveSizes({ file, args = {} }) { pngCompressionLevel: 9, grayscale: false, duotone: false, - trace: { - color: `#ddd`, - optTolerance: 0.4, - turdSize: 100, - turnPolicy: potrace.Potrace.TURNPOLICY_MAJORITY, - }, + trace: false, pathPrefix: ``, toFormat: ``, } @@ -476,12 +471,7 @@ async function resolutions({ file, args = {} }) { pngCompressionLevel: 9, grayscale: false, duotone: false, - trace: { - color: `#ddd`, - optTolerance: 0.4, - turdSize: 100, - turnPolicy: potrace.Potrace.TURNPOLICY_MAJORITY, - }, + trace: false, pathPrefix: ``, toFormat: ``, } From 6f050d06d63369fef44bf631d6f8783767e60307 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sun, 15 Oct 2017 20:43:34 +0200 Subject: [PATCH 12/33] =?UTF-8?q?Revert=20=E2=80=9ARemove=20default=20?= =?UTF-8?q?=E2=80=9Etrace=E2=80=9C=E2=80=99,=20fix=20default=20color=20of?= =?UTF-8?q?=20traced=20SVG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit da19d0622158ac3fb0ea88b86d26cab60cd408e7. Default color of traced SVG now matches default „backgroundColor“ of the gatsby-image placeholder. --- packages/gatsby-plugin-sharp/src/index.js | 14 ++++++++++++-- .../src/extend-node-type.js | 4 ++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index a83f5ff8b48c1..b6629f6d3b3b4 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -357,7 +357,12 @@ async function responsiveSizes({ file, args = {} }) { pngCompressionLevel: 9, grayscale: false, duotone: false, - trace: false, + trace: { + color: `lightgray`, + optTolerance: 0.4, + turdSize: 100, + turnPolicy: potrace.Potrace.TURNPOLICY_MAJORITY, + }, pathPrefix: ``, toFormat: ``, } @@ -471,7 +476,12 @@ async function resolutions({ file, args = {} }) { pngCompressionLevel: 9, grayscale: false, duotone: false, - trace: false, + trace: { + color: `lightgray`, + optTolerance: 0.4, + turdSize: 100, + turnPolicy: potrace.Potrace.TURNPOLICY_MAJORITY, + }, pathPrefix: ``, toFormat: ``, } diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index ead282886f108..0ddd2023025b8 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -165,7 +165,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { trace: { type: PotraceType, defaultValue: { - color: `#ddd`, + color: `lightgray`, optTolerance: 0.4, turnPolicy: Potrace.TURNPOLICY_MAJORITY, turdSize: 100, @@ -233,7 +233,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { trace: { type: PotraceType, defaultValue: { - color: `#ddd`, + color: `lightgray`, optTolerance: 0.4, turdSize: 100, turnPolicy: Potrace.TURNPOLICY_MAJORITY, From 8b5388853c4742801c34c2d0a9a855a7e0ae0852 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sun, 15 Oct 2017 21:09:02 +0200 Subject: [PATCH 13/33] =?UTF-8?q?D=E2=80=99oh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/gatsby-plugin-sharp/src/index.js | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index b6629f6d3b3b4..a83f5ff8b48c1 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -357,12 +357,7 @@ async function responsiveSizes({ file, args = {} }) { pngCompressionLevel: 9, grayscale: false, duotone: false, - trace: { - color: `lightgray`, - optTolerance: 0.4, - turdSize: 100, - turnPolicy: potrace.Potrace.TURNPOLICY_MAJORITY, - }, + trace: false, pathPrefix: ``, toFormat: ``, } @@ -476,12 +471,7 @@ async function resolutions({ file, args = {} }) { pngCompressionLevel: 9, grayscale: false, duotone: false, - trace: { - color: `lightgray`, - optTolerance: 0.4, - turdSize: 100, - turnPolicy: potrace.Potrace.TURNPOLICY_MAJORITY, - }, + trace: false, pathPrefix: ``, toFormat: ``, } From 2e2fe51997c6eae7d33233b96b9ae415fd0fb851 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sun, 15 Oct 2017 21:13:02 +0200 Subject: [PATCH 14/33] Move require potrace/SVGO --- packages/gatsby-plugin-sharp/src/index.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index a83f5ff8b48c1..cfad7a33e2566 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -9,15 +9,10 @@ const imagemin = require(`imagemin`) const imageminPngquant = require(`imagemin-pngquant`) const queue = require(`async/queue`) const path = require(`path`) -const potrace = require(`potrace`) -const SVGO = require(`svgo`) const duotone = require(`./duotone`) const { boundActionCreators } = require(`gatsby/dist/redux/actions`) -const svgo = new SVGO() -const trace = Promise.promisify(potrace.trace) - // Promisify the sharp prototype (methods) to promisify the alternative (for // raw) callback-accepting toBuffer(...) method Promise.promisifyAll(sharp.prototype, { multiArgs: true }) @@ -571,6 +566,8 @@ async function resolutions({ file, args = {} }) { } async function notMemoizedtraceSVG({ file, args }) { + const potrace = require(`potrace`) + const trace = Promise.promisify(potrace.trace) return await trace(file.absolutePath, args) .then(svg => optimize(svg)) .then(svg => `data:image/svg+xml,${svg.toString(`base64`)}`) @@ -585,10 +582,13 @@ async function traceSVG(args) { return await memoizedTraceSVG(args) } -const optimize = svg => - new Promise((resolve, reject) => { +const optimize = svg => { + const SVGO = require(`svgo`) + const svgo = new SVGO() + return new Promise((resolve, reject) => { svgo.optimize(svg, ({ data }) => resolve(data)) }) +} exports.queueImageResizing = queueImageResizing exports.base64 = base64 From 8029eb6139a8b54e8b9fac6f253d4db6d5e4404e Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Sun, 15 Oct 2017 23:01:34 +0200 Subject: [PATCH 15/33] =?UTF-8?q?Move=20=E2=80=9Etrace=E2=80=9C=20default?= =?UTF-8?q?=20values=20to=20type=20definition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/extend-node-type.js | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index 0ddd2023025b8..8d13f2cea26c5 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -73,15 +73,16 @@ const PotraceType = new GraphQLInputObjectType({ TURNPOLICY_MINORITY: { value: Potrace.TURNPOLICY_MINORITY }, TURNPOLICY_MAJORITY: { value: Potrace.TURNPOLICY_MAJORITY }, }, + defaultValue: Potrace.TURNPOLICY_MAJORITY, }), }, - turdSize: { type: GraphQLFloat }, + turdSize: { type: GraphQLFloat, defaultValue: 100 }, alphaMax: { type: GraphQLFloat }, optCurve: { type: GraphQLBoolean }, - optTolerance: { type: GraphQLFloat }, + optTolerance: { type: GraphQLFloat, defaultValue: 0.4 }, threshold: { type: GraphQLInt }, blackOnWhite: { type: GraphQLBoolean }, - color: { type: GraphQLString }, + color: { type: GraphQLString, defaultValue: `lightgray` }, background: { type: GraphQLString }, } }, @@ -164,12 +165,6 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { }, trace: { type: PotraceType, - defaultValue: { - color: `lightgray`, - optTolerance: 0.4, - turnPolicy: Potrace.TURNPOLICY_MAJORITY, - turdSize: 100, - }, }, quality: { type: GraphQLInt, @@ -232,12 +227,6 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { }, trace: { type: PotraceType, - defaultValue: { - color: `lightgray`, - optTolerance: 0.4, - turdSize: 100, - turnPolicy: Potrace.TURNPOLICY_MAJORITY, - }, }, quality: { type: GraphQLInt, From 4d294f37e2da48e82ae698d8978106e2b3bce994 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Mon, 16 Oct 2017 00:15:01 +0200 Subject: [PATCH 16/33] Fix SVGs for IE Following https://codepen.io/tigt/post/optimizing-svgs-in-data-uris --- packages/gatsby-plugin-sharp/src/index.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index cfad7a33e2566..9bd91f6fd93f4 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -570,7 +570,7 @@ async function notMemoizedtraceSVG({ file, args }) { const trace = Promise.promisify(potrace.trace) return await trace(file.absolutePath, args) .then(svg => optimize(svg)) - .then(svg => `data:image/svg+xml,${svg.toString(`base64`)}`) + .then(svg => encodeOptimizedSVGDataUri(svg)) } const memoizedTraceSVG = _.memoize( @@ -582,6 +582,19 @@ async function traceSVG(args) { return await memoizedTraceSVG(args) } +// https://codepen.io/tigt/post/optimizing-svgs-in-data-uris +function encodeOptimizedSVGDataUri(svgString) { + var uriPayload = encodeURIComponent(svgString) // encode URL-unsafe characters + .replace(/%0A/g, ``) // remove newlines + .replace(/%20/g, ` `) // put spaces back in + .replace(/%3D/g, `=`) // ditto equals signs + .replace(/%3A/g, `:`) // ditto colons + .replace(/%2F/g, `/`) // ditto slashes + .replace(/%22/g, `'`) // replace quotes with apostrophes (may break certain SVGs) + + return `data:image/svg+xml,` + uriPayload +} + const optimize = svg => { const SVGO = require(`svgo`) const svgo = new SVGO() From 5be8a59667aeaefcf7c33c55b7cdc0bdcc04cefe Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Tue, 17 Oct 2017 17:45:49 +0200 Subject: [PATCH 17/33] Fix potrace default options --- packages/gatsby-plugin-sharp/src/index.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index 9bd91f6fd93f4..38e52c8b4716a 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -352,7 +352,12 @@ async function responsiveSizes({ file, args = {} }) { pngCompressionLevel: 9, grayscale: false, duotone: false, - trace: false, + trace: { + color: `lightgray`, + optTolerance: 0.4, + turdSize: 100, + turnPolicy: `majority`, + }, pathPrefix: ``, toFormat: ``, } @@ -466,7 +471,12 @@ async function resolutions({ file, args = {} }) { pngCompressionLevel: 9, grayscale: false, duotone: false, - trace: false, + trace: { + color: `lightgray`, + optTolerance: 0.4, + turdSize: 100, + turnPolicy: `majority`, + }, pathPrefix: ``, toFormat: ``, } From c12f4e8cd1a66a77c58fff6ad4963b697542cd66 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Wed, 18 Oct 2017 23:46:19 +0200 Subject: [PATCH 18/33] =?UTF-8?q?Add=20resolve=20function=20for=20?= =?UTF-8?q?=E2=80=9EtracedSVG=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/gatsby-plugin-sharp/src/index.js | 21 +------------------ .../src/extend-node-type.js | 20 ++++++++++++++++-- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index 38e52c8b4716a..aad2ee58e9434 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -352,12 +352,6 @@ async function responsiveSizes({ file, args = {} }) { pngCompressionLevel: 9, grayscale: false, duotone: false, - trace: { - color: `lightgray`, - optTolerance: 0.4, - turdSize: 100, - turnPolicy: `majority`, - }, pathPrefix: ``, toFormat: ``, } @@ -435,9 +429,6 @@ async function responsiveSizes({ file, args = {} }) { // Get base64 version const base64Image = await base64({ file, args: base64Args }) - // Get traced SVG base64 - const tracedSVG = await traceSVG({ file, args: options.trace }) - // Construct src and srcSet strings. const originalImg = _.maxBy(images, image => image.width).src const fallbackSrc = _.minBy(images, image => @@ -450,7 +441,6 @@ async function responsiveSizes({ file, args = {} }) { return { base64: base64Image.src, - tracedSVG: tracedSVG, aspectRatio: images[0].aspectRatio, src: fallbackSrc, srcSet, @@ -471,12 +461,6 @@ async function resolutions({ file, args = {} }) { pngCompressionLevel: 9, grayscale: false, duotone: false, - trace: { - color: `lightgray`, - optTolerance: 0.4, - turdSize: 100, - turnPolicy: `majority`, - }, pathPrefix: ``, toFormat: ``, } @@ -535,9 +519,6 @@ async function resolutions({ file, args = {} }) { // Get base64 version const base64Image = await base64({ file, args: base64Args }) - // Get traced SVG base64 - const tracedSVG = await traceSVG({ file, args: options.trace }) - const fallbackSrc = images[0].src const srcSet = images .map((image, i) => { @@ -565,7 +546,6 @@ async function resolutions({ file, args = {} }) { return { base64: base64Image.src, - tracedSVG: tracedSVG, aspectRatio: images[0].aspectRatio, width: images[0].width, height: images[0].height, @@ -615,6 +595,7 @@ const optimize = svg => { exports.queueImageResizing = queueImageResizing exports.base64 = base64 +exports.traceSVG = traceSVG exports.responsiveSizes = responsiveSizes exports.responsiveResolution = resolutions exports.sizes = responsiveSizes diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index 8d13f2cea26c5..27d1e8158c5aa 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -13,6 +13,7 @@ const { base64, sizes, resolutions, + traceSVG, } = require(`gatsby-plugin-sharp`) const sharp = require(`sharp`) @@ -93,6 +94,15 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { return {} } + const getTracedSVG = (image, fieldArgs) => { + const publicPath = path.join(process.cwd(), `public`, image.originalImg) + const promise = traceSVG({ + file: { absolutePath: publicPath }, + args: { ...fieldArgs, pathPrefix }, + }) + return promise + } + return { original: { type: new GraphQLObjectType({ @@ -134,7 +144,10 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { name: `ImageSharpResolutions`, fields: { base64: { type: GraphQLString }, - tracedSVG: { type: GraphQLString }, + tracedSVG: { + type: GraphQLString, + resolve: (image, fieldArgs) => getTracedSVG(image, fieldArgs), + }, aspectRatio: { type: GraphQLFloat }, width: { type: GraphQLFloat }, height: { type: GraphQLFloat }, @@ -196,7 +209,10 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { name: `ImageSharpSizes`, fields: { base64: { type: GraphQLString }, - tracedSVG: { type: GraphQLString }, + tracedSVG: { + type: GraphQLString, + resolve: (image, fieldArgs) => getTracedSVG(image, fieldArgs), + }, aspectRatio: { type: GraphQLFloat }, src: { type: GraphQLString }, srcSet: { type: GraphQLString }, From 1e56b4c4760c2f6d42f661103f7ffa974ab83fa4 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Wed, 18 Oct 2017 23:48:38 +0200 Subject: [PATCH 19/33] =?UTF-8?q?D=E2=80=99oh=20:(?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/gatsby-transformer-sharp/src/extend-node-type.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index 27d1e8158c5aa..4d80e07e4881f 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -146,7 +146,6 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { base64: { type: GraphQLString }, tracedSVG: { type: GraphQLString, - resolve: (image, fieldArgs) => getTracedSVG(image, fieldArgs), }, aspectRatio: { type: GraphQLFloat }, width: { type: GraphQLFloat }, From 80e1bd5ce1e943ae88c8343a3ebcda8cb59b02d1 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Thu, 19 Oct 2017 00:06:40 +0200 Subject: [PATCH 20/33] Fix memoize, use image.src available in sizes and resolutions --- packages/gatsby-plugin-sharp/src/index.js | 2 +- packages/gatsby-transformer-sharp/src/extend-node-type.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index aad2ee58e9434..d0ac5ac58d9d3 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -565,7 +565,7 @@ async function notMemoizedtraceSVG({ file, args }) { const memoizedTraceSVG = _.memoize( notMemoizedtraceSVG, - ({ file, args }) => `${file.id}${JSON.stringify(args)}` + ({ file, args }) => `${file.absolutePath}${JSON.stringify(args)}` ) async function traceSVG(args) { diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index 4d80e07e4881f..4ea518754c509 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -95,7 +95,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { } const getTracedSVG = (image, fieldArgs) => { - const publicPath = path.join(process.cwd(), `public`, image.originalImg) + const publicPath = path.join(process.cwd(), `public`, image.src) const promise = traceSVG({ file: { absolutePath: publicPath }, args: { ...fieldArgs, pathPrefix }, @@ -146,6 +146,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { base64: { type: GraphQLString }, tracedSVG: { type: GraphQLString, + resolve: (image, fieldArgs) => getTracedSVG(image, fieldArgs), }, aspectRatio: { type: GraphQLFloat }, width: { type: GraphQLFloat }, From fc334bc975d2d2812c197fd581b16740b6ede739 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Thu, 19 Oct 2017 01:40:44 +0200 Subject: [PATCH 21/33] =?UTF-8?q?Pass=20=E2=80=9Etrace=E2=80=9C=20args=20t?= =?UTF-8?q?o=20=E2=80=9EtracedSVG=E2=80=9C=20subfield?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/gatsby-plugin-sharp/src/index.js | 13 ++++- .../src/extend-node-type.js | 55 +++++++++++-------- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index d0ac5ac58d9d3..21615e651d4d8 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -355,7 +355,7 @@ async function responsiveSizes({ file, args = {} }) { pathPrefix: ``, toFormat: ``, } - const options = _.defaultsDeep({}, args, defaultArgs) + const options = _.defaults({}, args, defaultArgs) options.maxWidth = parseInt(options.maxWidth, 10) // Account for images with a high pixel density. We assume that these types of @@ -464,7 +464,7 @@ async function resolutions({ file, args = {} }) { pathPrefix: ``, toFormat: ``, } - const options = _.defaultsDeep({}, args, defaultArgs) + const options = _.defaults({}, args, defaultArgs) options.width = parseInt(options.width, 10) // Create sizes for different resolutions — we do 1x, 1.5x, 2x, and 3x. @@ -558,7 +558,14 @@ async function resolutions({ file, args = {} }) { async function notMemoizedtraceSVG({ file, args }) { const potrace = require(`potrace`) const trace = Promise.promisify(potrace.trace) - return await trace(file.absolutePath, args) + let defaultArgs = { + color: `lightgray`, + optTolerance: 0.4, + turdSize: 100, + turnPolicy: `majority`, + } + const options = _.defaults({}, args, defaultArgs) + return await trace(file.absolutePath, options) .then(svg => optimize(svg)) .then(svg => encodeOptimizedSVGDataUri(svg)) } diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index 4ea518754c509..d74ac4e81e377 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -74,16 +74,15 @@ const PotraceType = new GraphQLInputObjectType({ TURNPOLICY_MINORITY: { value: Potrace.TURNPOLICY_MINORITY }, TURNPOLICY_MAJORITY: { value: Potrace.TURNPOLICY_MAJORITY }, }, - defaultValue: Potrace.TURNPOLICY_MAJORITY, }), }, - turdSize: { type: GraphQLFloat, defaultValue: 100 }, + turdSize: { type: GraphQLFloat }, alphaMax: { type: GraphQLFloat }, optCurve: { type: GraphQLBoolean }, - optTolerance: { type: GraphQLFloat, defaultValue: 0.4 }, + optTolerance: { type: GraphQLFloat }, threshold: { type: GraphQLInt }, blackOnWhite: { type: GraphQLBoolean }, - color: { type: GraphQLString, defaultValue: `lightgray` }, + color: { type: GraphQLString }, background: { type: GraphQLString }, } }, @@ -94,11 +93,10 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { return {} } - const getTracedSVG = (image, fieldArgs) => { - const publicPath = path.join(process.cwd(), `public`, image.src) + const getTracedSVG = parent => { const promise = traceSVG({ - file: { absolutePath: publicPath }, - args: { ...fieldArgs, pathPrefix }, + file: { absolutePath: path.join(process.cwd(), `public`, parent.src) }, + args: { ...parent.fieldArgs.trace }, }) return promise } @@ -146,7 +144,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { base64: { type: GraphQLString }, tracedSVG: { type: GraphQLString, - resolve: (image, fieldArgs) => getTracedSVG(image, fieldArgs), + resolve: parent => getTracedSVG(parent), }, aspectRatio: { type: GraphQLFloat }, width: { type: GraphQLFloat }, @@ -178,6 +176,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { }, trace: { type: PotraceType, + defaultValue: false, }, quality: { type: GraphQLInt, @@ -196,13 +195,17 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { defaultValue: 0, }, }, - resolve(image, fieldArgs, context) { - const promise = resolutions({ - file: getNodeAndSavePathDependency(image.parent, context.path), - args: { ...fieldArgs, pathPrefix }, - }) - return promise - }, + resolve: (image, fieldArgs, context) => + Promise.resolve( + resolutions({ + file: getNodeAndSavePathDependency(image.parent, context.path), + args: { ...fieldArgs, pathPrefix }, + }) + ).then(o => + Object.assign({}, o, { + fieldArgs, + }) + ), }, sizes: { type: new GraphQLObjectType({ @@ -211,7 +214,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { base64: { type: GraphQLString }, tracedSVG: { type: GraphQLString, - resolve: (image, fieldArgs) => getTracedSVG(image, fieldArgs), + resolve: parent => getTracedSVG(parent), }, aspectRatio: { type: GraphQLFloat }, src: { type: GraphQLString }, @@ -243,6 +246,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { }, trace: { type: PotraceType, + defaultValue: false, }, quality: { type: GraphQLInt, @@ -261,12 +265,17 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { defaultValue: 0, }, }, - resolve(image, fieldArgs, context) { - return sizes({ - file: getNodeAndSavePathDependency(image.parent, context.path), - args: { ...fieldArgs, pathPrefix }, - }) - }, + resolve: (image, fieldArgs, context) => + Promise.resolve( + sizes({ + file: getNodeAndSavePathDependency(image.parent, context.path), + args: { ...fieldArgs, pathPrefix }, + }) + ).then(o => + Object.assign({}, o, { + fieldArgs, + }) + ), }, responsiveResolution: { deprecationReason: `We dropped the "responsive" part of the name to make it shorter https://github.com/gatsbyjs/gatsby/pull/2320/`, From 20299562e528939f3480d5dacfc5d99884338217 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Thu, 19 Oct 2017 03:27:10 +0200 Subject: [PATCH 22/33] Brute-force fix things --- packages/gatsby-transformer-sharp/src/extend-node-type.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index d74ac4e81e377..2e32a15b54cc0 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -95,7 +95,9 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { const getTracedSVG = parent => { const promise = traceSVG({ - file: { absolutePath: path.join(process.cwd(), `public`, parent.src) }, + file: { + absolutePath: parent.image.parent.split(` `)[0], + }, args: { ...parent.fieldArgs.trace }, }) return promise @@ -204,6 +206,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { ).then(o => Object.assign({}, o, { fieldArgs, + image, }) ), }, @@ -274,6 +277,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { ).then(o => Object.assign({}, o, { fieldArgs, + image, }) ), }, From ce8635b15a9f04331432aacdc6826c7b91402d73 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Fri, 20 Oct 2017 01:27:14 +0200 Subject: [PATCH 23/33] =?UTF-8?q?Rename=20arg=20=E2=80=9Etrace=E2=80=9C=20?= =?UTF-8?q?->=20=E2=80=9EtraceSVG=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/image-processing/src/pages/index.js | 2 +- packages/gatsby-transformer-sharp/src/extend-node-type.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/image-processing/src/pages/index.js b/examples/image-processing/src/pages/index.js index 36b76b782f3d2..e9c05e5375bf6 100644 --- a/examples/image-processing/src/pages/index.js +++ b/examples/image-processing/src/pages/index.js @@ -306,7 +306,7 @@ export const pageQuery = graphql` sizes: imageSharp(id: { regex: "/fecolormatrix-kanye-west.jpg/" }) { sizes( duotone: { highlight: "#f00e2e", shadow: "#192550" } - trace: { + traceSVG: { color: "#f00e2e" turnPolicy: TURNPOLICY_MINORITY blackOnWhite: false diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index 2e32a15b54cc0..260d5d7056b35 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -98,7 +98,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { file: { absolutePath: parent.image.parent.split(` `)[0], }, - args: { ...parent.fieldArgs.trace }, + args: { ...parent.fieldArgs.traceSVG }, }) return promise } @@ -176,7 +176,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { type: DuotoneGradientType, defaultValue: false, }, - trace: { + traceSVG: { type: PotraceType, defaultValue: false, }, @@ -247,7 +247,7 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { type: DuotoneGradientType, defaultValue: false, }, - trace: { + traceSVG: { type: PotraceType, defaultValue: false, }, From 74d77c0a2325b336652d5c8e3c13bb68e2b9b8f4 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Fri, 20 Oct 2017 02:12:48 +0200 Subject: [PATCH 24/33] READMEs --- packages/gatsby-image/README.md | 2 ++ packages/gatsby-plugin-sharp/README.md | 46 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/packages/gatsby-image/README.md b/packages/gatsby-image/README.md index 50cb659776c53..c36d34781d1d5 100644 --- a/packages/gatsby-image/README.md +++ b/packages/gatsby-image/README.md @@ -108,6 +108,8 @@ Their fragments are: If you don't want to use the blur-up effect, choose the fragment with `noBase64` at the end. If you want to use the traced placeholder SVGs, choose the fragment with `tracedSVG` at the end. +_Please see the [gatsby-plugin-sharp](https://www.gatsbyjs.org/packages/gatsby-plugin-sharp/#tracedsvg) documentation for more information on `tracedSVG` and its configuration options._ + ## "Resolutions" queries ### Component diff --git a/packages/gatsby-plugin-sharp/README.md b/packages/gatsby-plugin-sharp/README.md index 14e81c147a3ba..b28aaede2fc66 100644 --- a/packages/gatsby-plugin-sharp/README.md +++ b/packages/gatsby-plugin-sharp/README.md @@ -163,6 +163,46 @@ the source image colors will be converted to match a gradient color chosen based on each pixel's [relative luminance][4]. Logic is borrowed from [react-duotone][5]. +#### tracedSVG + +Generates a traced SVG of your image (see [the original GitHub issue][9]) and +returns the SVG as "[optimized URL-encoded][10]" `data:` URI. +It it used in [gatsby-image](https://www.gatsbyjs.org/packages/gatsby-image/) to +provide an alternative to the default inline base64 placeholder image. + +Uses [node-potrace][11] and [SVGO][12] under the hood. +Default settings for node-potrace: + +```javascript + { + color: `lightgray`, + optTolerance: 0.4, + turdSize: 100, + turnPolicy: TURNPOLICY_MAJORITY, + } +``` + +All [node-potrace `Potrace` parameters][13] are exposed and can be set via the +`traceSVG` argument: + +```javascript +responsiveResolution( + traceSVG: { + color: "#f00e2e" + turnPolicy: TURNPOLICY_MINORITY + blackOnWhite: false + } +) { + src + srcSet + tracedSVG +} +``` + +Heads up: `tracedSVG` currently traces the _original_ image source. Depending +on your source image size and settings, please make sure that the generated SVG +is of reasonable size, especially when using it as a placeholder. + [1]: https://alistapart.com/article/finessing-fecolormatrix [2]: http://blog.72lions.com/blog/2015/7/7/duotone-in-js [3]: https://ines.io/blog/dynamic-duotone-svg-jade @@ -171,3 +211,9 @@ Logic is borrowed from [react-duotone][5]. [6]: http://sharp.dimens.io/en/stable/api-resize/#crop [7]: http://sharp.dimens.io/en/stable/api-operation/#rotate [8]: http://sharp.dimens.io/en/stable/api-colour/#greyscale +[9]: https://github.com/gatsbyjs/gatsby/issues/2435 +[10]: https://codepen.io/tigt/post/optimizing-svgs-in-data-uris +[11]: https://github.com/tooolbox/node-potrace +[12]: https://github.com/svg/svgo +[13]: https://github.com/tooolbox/node-potrace#parameters +[14]: https://github.com/oliver-moran/jimp From 3cd39306920c47c651fb2e9c1071e464ef9fd509 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Fri, 20 Oct 2017 02:55:16 +0200 Subject: [PATCH 25/33] Minor README change --- packages/gatsby-plugin-sharp/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/gatsby-plugin-sharp/README.md b/packages/gatsby-plugin-sharp/README.md index b28aaede2fc66..a8370fdf03354 100644 --- a/packages/gatsby-plugin-sharp/README.md +++ b/packages/gatsby-plugin-sharp/README.md @@ -165,7 +165,7 @@ Logic is borrowed from [react-duotone][5]. #### tracedSVG -Generates a traced SVG of your image (see [the original GitHub issue][9]) and +Generates a traced SVG of the image (see [the original GitHub issue][9]) and returns the SVG as "[optimized URL-encoded][10]" `data:` URI. It it used in [gatsby-image](https://www.gatsbyjs.org/packages/gatsby-image/) to provide an alternative to the default inline base64 placeholder image. @@ -200,7 +200,7 @@ responsiveResolution( ``` Heads up: `tracedSVG` currently traces the _original_ image source. Depending -on your source image size and settings, please make sure that the generated SVG +on source image size and settings, please make sure that the generated SVG is of reasonable size, especially when using it as a placeholder. [1]: https://alistapart.com/article/finessing-fecolormatrix From 0778ee1d66033afe03221b65e3289b9c49fd74a7 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Fri, 20 Oct 2017 02:56:01 +0200 Subject: [PATCH 26/33] Add example page for tracedSVG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … currently generating SVGs up to 1.4MB :/ ;) --- .../using-gatsby-image/src/pages/index.js | 6 + .../src/pages/traced-svg.js | 117 ++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 examples/using-gatsby-image/src/pages/traced-svg.js diff --git a/examples/using-gatsby-image/src/pages/index.js b/examples/using-gatsby-image/src/pages/index.js index 1a99d9b889d97..40fa5175ff920 100644 --- a/examples/using-gatsby-image/src/pages/index.js +++ b/examples/using-gatsby-image/src/pages/index.js @@ -58,6 +58,9 @@ class IndexComponent extends React.Component {
  • Background color
  • +
  • + Traced SVG +
  • Out of the box it:

      @@ -73,6 +76,9 @@ class IndexComponent extends React.Component { Uses the "blur-up" effect i.e. it loads a tiny version of the image to show while the full image is loading +
    • + Alternatively provides a "traced placeholder" SVG of the image. +
    • Lazy loads images which reduces bandwidth and speeds the initial load time diff --git a/examples/using-gatsby-image/src/pages/traced-svg.js b/examples/using-gatsby-image/src/pages/traced-svg.js new file mode 100644 index 0000000000000..cac3273185df8 --- /dev/null +++ b/examples/using-gatsby-image/src/pages/traced-svg.js @@ -0,0 +1,117 @@ +import React from "react" +import Img from "gatsby-image" + +import { rhythm, options } from "../utils/typography" + +const TracedSVG = ({ data }) => ( +
      +

      Viribus quid

      +

      Hippason sinu

      + + +

      + Lorem markdownum nocens, est aut tergo, inmansuetique bella. Neve illud + contrarius ad es prior.{` `} + Planguntur quondam, sua ferunt + uterum semina advertere si fraudesque terram hosti subiecta, nec. Audenti + refugitque manibusque aliis infelicem sed mihi aevis! Que ipso templa; tua + triformis animumque ad coluit in aliquid. +

      +
        +
      • Infamia lumina sequuntur ulla
      • +
      • Aquarum rutilos
      • +
      • Hinc vimque
      • +
      +

      Et solebat pectus fletus erat furit officium

      +

      + Proteus ut dis nec exsecrantia data: agrestes, truculenta Peleus. Et + diffidunt, talia intravit Thaumantias; figere et et qui socio + qui, tuo servet unda hoc{` `} + classi? Causam quemque? Subigebant cornibus + fibras ut per nare nati, cunctis et illa verba inrita. +

      +
        +
      1. Furori adacto
      2. +
      3. Nocent imagine precari id ante sic
      4. +
      5. Ipsos sine Iuno placabitis silet relinquent blandarum
      6. +
      7. Et pars tabe sociorum et luna illum
      8. +
      9. Et frustra pestifero et inquit cornua victa
      10. +
      11. Constitit nomine senta suspirat et signis genuisse
      12. +
      + +

      Levia mihi

      +

      + Precor Ortygiam, prudens diro stabant prodis moenia; aut tergo{` `} + loquax et data sua rite in vulnere. Esse + lumina plaustrum lacus necopina, iam umbrae nec clipeo sentit{` `} + sinistra. +

      +

      + Pendebat nitidum vidistis ecce crematisregia fera et lucemque crines.{` `} + Est sopita satis quod harena + Antimachumque tulit fusile. Fieri qui que prosit equidem, meis praescia + monebat cacumina tergo acerbo saepe nullaque. +

      +
      +) + +export default TracedSVG + +export const query = graphql` + query TracedSVGQuery { + reddImageMobile: imageSharp(id: { regex: "/redd/" }) { + resolutions(width: 125) { + ...GatsbyImageSharpResolutions_tracedSVG + } + } + reddImage: imageSharp(id: { regex: "/redd/" }) { + resolutions(width: 200) { + ...GatsbyImageSharpResolutions_tracedSVG + } + } + kenImage: imageSharp(id: { regex: "/ken-treloar/" }) { + sizes( + maxWidth: 600 + traceSVG: { + turnPolicy: TURNPOLICY_MINORITY + blackOnWhite: true + turdSize: 100 + threshold: 100 + optTolerance: 1000 + } + ) { + ...GatsbyImageSharpSizes_tracedSVG + } + } + } +` From 8e32e7b5d5cbd17ae488a3762ecb5ac7551ded67 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Thu, 19 Oct 2017 20:23:49 -0700 Subject: [PATCH 27/33] Resize images before tracing the SVG --- packages/gatsby-plugin-sharp/src/index.js | 59 ++++++++- .../src/extend-node-type.js | 114 ++++++++++++------ 2 files changed, 132 insertions(+), 41 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index 21615e651d4d8..5b9354d0ea022 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -555,7 +555,7 @@ async function resolutions({ file, args = {} }) { } } -async function notMemoizedtraceSVG({ file, args }) { +async function notMemoizedtraceSVG({ file, args, fileArgs }) { const potrace = require(`potrace`) const trace = Promise.promisify(potrace.trace) let defaultArgs = { @@ -564,8 +564,61 @@ async function notMemoizedtraceSVG({ file, args }) { turdSize: 100, turnPolicy: `majority`, } - const options = _.defaults({}, args, defaultArgs) - return await trace(file.absolutePath, options) + + const defaultFileResizeArgs = { + width: 400, + quality: 50, + jpegProgressive: true, + pngCompressionLevel: 9, + grayscale: false, + duotone: false, + toFormat: ``, + } + const options = _.defaults(fileArgs, defaultFileResizeArgs) + let pipeline = sharp(file.absolutePath).rotate() + + pipeline + .resize(options.width, options.height) + .crop(options.cropFocus) + .png({ + compressionLevel: options.pngCompressionLevel, + adaptiveFiltering: false, + force: args.toFormat === `png`, + }) + .jpeg({ + quality: options.quality, + progressive: options.jpegProgressive, + force: args.toFormat === `jpg`, + }) + + // grayscale + if (options.grayscale) { + pipeline = pipeline.grayscale() + } + + // rotate + if (options.rotate && options.rotate !== 0) { + pipeline = pipeline.rotate(options.rotate) + } + + // duotone + if (options.duotone) { + pipeline = await duotone(options.duotone, file.extension, pipeline) + } + + const tmpDir = require(`os`).tmpdir() + const tmpFilePath = `${tmpDir}/${file.name}-${crypto + .createHash(`md5`) + .update(JSON.stringify(fileArgs)) + .digest(`hex`)}.${file.extension}` + + await new Promise(resolve => + pipeline.toFile(tmpFilePath, (err, info) => { + resolve() + }) + ) + + return trace(tmpFilePath, options) .then(svg => optimize(svg)) .then(svg => encodeOptimizedSVGDataUri(svg)) } diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index 260d5d7056b35..43f676fa3a164 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -93,15 +93,12 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { return {} } - const getTracedSVG = parent => { - const promise = traceSVG({ - file: { - absolutePath: parent.image.parent.split(` `)[0], - }, - args: { ...parent.fieldArgs.traceSVG }, + const getTracedSVG = async ({ file, image, fieldArgs }) => + traceSVG({ + file, + args: { ...fieldArgs.traceSVG }, + fileArgs: fieldArgs, }) - return promise - } return { original: { @@ -197,18 +194,22 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { defaultValue: 0, }, }, - resolve: (image, fieldArgs, context) => - Promise.resolve( + resolve: (image, fieldArgs, context) => { + const file = getNodeAndSavePathDependency(image.parent, context.path) + const args = { ...fieldArgs, pathPrefix } + return Promise.resolve( resolutions({ - file: getNodeAndSavePathDependency(image.parent, context.path), - args: { ...fieldArgs, pathPrefix }, + file, + args, }) ).then(o => Object.assign({}, o, { - fieldArgs, + fieldArgs: args, image, + file, }) - ), + ) + }, }, sizes: { type: new GraphQLObjectType({ @@ -268,18 +269,22 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { defaultValue: 0, }, }, - resolve: (image, fieldArgs, context) => - Promise.resolve( + resolve: (image, fieldArgs, context) => { + const file = getNodeAndSavePathDependency(image.parent, context.path) + const args = { ...fieldArgs, pathPrefix } + return Promise.resolve( sizes({ - file: getNodeAndSavePathDependency(image.parent, context.path), - args: { ...fieldArgs, pathPrefix }, + file, + args, }) - ).then(o => - Object.assign({}, o, { - fieldArgs, + ).then(o => { + return Object.assign({}, o, { + fieldArgs: args, image, + file, }) - ), + }) + }, }, responsiveResolution: { deprecationReason: `We dropped the "responsive" part of the name to make it shorter https://github.com/gatsbyjs/gatsby/pull/2320/`, @@ -332,12 +337,21 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { defaultValue: 0, }, }, - resolve(image, fieldArgs, context) { - const promise = resolutions({ - file: getNodeAndSavePathDependency(image.parent, context.path), - args: { ...fieldArgs, pathPrefix }, - }) - return promise + resolve: (image, fieldArgs, context) => { + const file = getNodeAndSavePathDependency(image.parent, context.path) + const args = { ...fieldArgs, pathPrefix } + return Promise.resolve( + resolutions({ + file, + args, + }) + ).then(o => + Object.assign({}, o, { + fieldArgs: args, + image, + file, + }) + ) }, }, responsiveSizes: { @@ -391,11 +405,21 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { defaultValue: 0, }, }, - resolve(image, fieldArgs, context) { - return sizes({ - file: getNodeAndSavePathDependency(image.parent, context.path), - args: { ...fieldArgs, pathPrefix }, - }) + resolve: (image, fieldArgs, context) => { + const file = getNodeAndSavePathDependency(image.parent, context.path) + const args = { ...fieldArgs, pathPrefix } + return Promise.resolve( + sizes({ + file, + args, + }) + ).then(o => + Object.assign({}, o, { + fieldArgs: args, + image, + file, + }) + ) }, }, resize: { @@ -403,6 +427,10 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { name: `ImageSharpResize`, fields: { src: { type: GraphQLString }, + tracedSVG: { + type: GraphQLString, + resolve: parent => getTracedSVG(parent), + }, width: { type: GraphQLInt }, height: { type: GraphQLInt }, aspectRatio: { type: GraphQLFloat }, @@ -441,6 +469,10 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { type: GraphQLBoolean, defaultValue: false, }, + traceSVG: { + type: PotraceType, + defaultValue: false, + }, toFormat: { type: ImageFormatType, defaultValue: ``, @@ -454,9 +486,10 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { defaultValue: 0, }, }, - resolve(image, fieldArgs, context) { + resolve: (image, fieldArgs, context) => { + const file = getNodeAndSavePathDependency(image.parent, context.path) + const args = { ...fieldArgs, pathPrefix } return new Promise(resolve => { - const file = getNodeAndSavePathDependency(image.parent, context.path) if (fieldArgs.base64) { resolve( base64({ @@ -464,10 +497,15 @@ module.exports = ({ type, pathPrefix, getNodeAndSavePathDependency }) => { }) ) } else { - resolve( - queueImageResizing({ + const o = queueImageResizing({ + file, + args, + }) + return resolve( + Object.assign({}, o, { + image, file, - args: { ...fieldArgs, pathPrefix }, + fieldArgs: args, }) ) } From 53d7b4fa38b908b3ad66e017a88e0298b7cf0d2d Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Thu, 19 Oct 2017 20:31:33 -0700 Subject: [PATCH 28/33] Temp copy fragments --- scripts/publish-site.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/publish-site.sh b/scripts/publish-site.sh index afeab5785fa82..c7d07229ffb16 100644 --- a/scripts/publish-site.sh +++ b/scripts/publish-site.sh @@ -16,6 +16,8 @@ yarn echo "=== Copying built Gatsby to website." gatsby-dev --scan-once --quiet +cp ../../packages/gatsby-transformer-sharp/src/fragments.js node_modules/gatsby-transformer-sharp/src/fragments.js + echo "=== Building website" # Once we get better cache invalidation, remove the following # line. From ff3c6b472fc9d91c6d16e3724fbec9891f7fbb47 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Thu, 19 Oct 2017 20:40:33 -0700 Subject: [PATCH 29/33] Make the default background color light gray --- packages/gatsby-transformer-sharp/src/extend-node-type.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index 43f676fa3a164..09d8ab7b4f9c9 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -83,7 +83,7 @@ const PotraceType = new GraphQLInputObjectType({ threshold: { type: GraphQLInt }, blackOnWhite: { type: GraphQLBoolean }, color: { type: GraphQLString }, - background: { type: GraphQLString }, + background: { type: GraphQLString, defaultValue: `#d3d3d3` }, } }, }) From 750d702a76618f2582865c4af91bc86dc1893842 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Fri, 20 Oct 2017 11:20:08 +0200 Subject: [PATCH 30/33] Bring back trace args/defaults --- packages/gatsby-plugin-sharp/src/index.js | 7 ++++--- packages/gatsby-transformer-sharp/src/extend-node-type.js | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index 5b9354d0ea022..fc18fd1692446 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -558,12 +558,13 @@ async function resolutions({ file, args = {} }) { async function notMemoizedtraceSVG({ file, args, fileArgs }) { const potrace = require(`potrace`) const trace = Promise.promisify(potrace.trace) - let defaultArgs = { + const defaultArgs = { color: `lightgray`, optTolerance: 0.4, turdSize: 100, - turnPolicy: `majority`, + turnPolicy: potrace.Potrace.TURNPOLICY_MAJORITY, } + const optionsSVG = _.defaults(args, defaultArgs) const defaultFileResizeArgs = { width: 400, @@ -618,7 +619,7 @@ async function notMemoizedtraceSVG({ file, args, fileArgs }) { }) ) - return trace(tmpFilePath, options) + return trace(tmpFilePath, optionsSVG) .then(svg => optimize(svg)) .then(svg => encodeOptimizedSVGDataUri(svg)) } diff --git a/packages/gatsby-transformer-sharp/src/extend-node-type.js b/packages/gatsby-transformer-sharp/src/extend-node-type.js index 09d8ab7b4f9c9..43f676fa3a164 100644 --- a/packages/gatsby-transformer-sharp/src/extend-node-type.js +++ b/packages/gatsby-transformer-sharp/src/extend-node-type.js @@ -83,7 +83,7 @@ const PotraceType = new GraphQLInputObjectType({ threshold: { type: GraphQLInt }, blackOnWhite: { type: GraphQLBoolean }, color: { type: GraphQLString }, - background: { type: GraphQLString, defaultValue: `#d3d3d3` }, + background: { type: GraphQLString }, } }, }) From ede2e3c033e4f7f59cbcc2ee74984998bb37fda9 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Fri, 20 Oct 2017 11:22:02 +0200 Subject: [PATCH 31/33] Demo color + background Remove unnecessary/confusing options --- examples/using-gatsby-image/src/pages/traced-svg.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/examples/using-gatsby-image/src/pages/traced-svg.js b/examples/using-gatsby-image/src/pages/traced-svg.js index cac3273185df8..6bf49789e7d99 100644 --- a/examples/using-gatsby-image/src/pages/traced-svg.js +++ b/examples/using-gatsby-image/src/pages/traced-svg.js @@ -102,13 +102,7 @@ export const query = graphql` kenImage: imageSharp(id: { regex: "/ken-treloar/" }) { sizes( maxWidth: 600 - traceSVG: { - turnPolicy: TURNPOLICY_MINORITY - blackOnWhite: true - turdSize: 100 - threshold: 100 - optTolerance: 1000 - } + traceSVG: { color: "lightblue", background: "lightcyan" } ) { ...GatsbyImageSharpSizes_tracedSVG } From c0fd0caafcbec40ca90e2505625245a0965ce654 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Fri, 20 Oct 2017 11:45:02 +0200 Subject: [PATCH 32/33] =?UTF-8?q?Enable=20multipass,=20set=20float=20preci?= =?UTF-8?q?sion=20=F0=9F=99=8F=20@EmilTholin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/gatsby-plugin-sharp/src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index fc18fd1692446..81d7f928f98e8 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -648,7 +648,7 @@ function encodeOptimizedSVGDataUri(svgString) { const optimize = svg => { const SVGO = require(`svgo`) - const svgo = new SVGO() + const svgo = new SVGO({ multipass: true, floatPrecision: 1 }) return new Promise((resolve, reject) => { svgo.optimize(svg, ({ data }) => resolve(data)) }) From eb5c7b9a739b814ba8db89f5db62a0e1db948e02 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Fri, 20 Oct 2017 14:40:33 +0200 Subject: [PATCH 33/33] Remove disclaimer from README --- packages/gatsby-plugin-sharp/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/gatsby-plugin-sharp/README.md b/packages/gatsby-plugin-sharp/README.md index a8370fdf03354..cf5bd30ef7388 100644 --- a/packages/gatsby-plugin-sharp/README.md +++ b/packages/gatsby-plugin-sharp/README.md @@ -199,10 +199,6 @@ responsiveResolution( } ``` -Heads up: `tracedSVG` currently traces the _original_ image source. Depending -on source image size and settings, please make sure that the generated SVG -is of reasonable size, especially when using it as a placeholder. - [1]: https://alistapart.com/article/finessing-fecolormatrix [2]: http://blog.72lions.com/blog/2015/7/7/duotone-in-js [3]: https://ines.io/blog/dynamic-duotone-svg-jade