Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Ready 4 Review] SQIP - Vectorized primitive image previews #4205

Merged
Merged
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
033faad
first working version with Contentful assets only
Feb 23, 2018
7660c4e
add readme
Feb 23, 2018
5781b9c
respect width, height, aspect ratio, cropping, resize focus and backg…
Feb 23, 2018
f7f05da
add support for gatsby-transformer-sharp
Feb 23, 2018
b72921b
integrate in gatsbygram
axe312ger Feb 23, 2018
b6cdeab
avoid useless regeneration cus contentDigest changes
axe312ger Feb 25, 2018
d571ba8
proper way to get absolute path to ImageSharp nodes
axe312ger Feb 25, 2018
423ed1a
queue preview generation and cache results on disk
axe312ger Feb 25, 2018
d11370b
upgrade to latest node-sqip to get rid of the GoLang dependency
Mar 2, 2018
4550f94
replace custom svg data uri function with package
Mar 2, 2018
19c33d0
prepare images via sharp plugin and allow sharp transformations
axe312ger Mar 3, 2018
a386a12
load cached svg properly from disk
axe312ger Mar 3, 2018
64a6dd2
fix queue resolving to early
axe312ger Mar 3, 2018
6e8f3a4
set contentful images to 400px
axe312ger Mar 3, 2018
84ebf42
implement new sharp transformation awareness feature
axe312ger Mar 3, 2018
f2ffe45
WIP - extract generation and write first pseudo test
axe312ger Mar 3, 2018
5c11f36
fix styling for gatsbygram post detail
axe312ger Mar 3, 2018
48006eb
finalize unit tests for actual sqip implementation
axe312ger Apr 29, 2018
f058965
use 256px input image width to match sqip/primitive default
axe312ger Apr 29, 2018
365f36c
add using-sqip example page
axe312ger Apr 30, 2018
36fc041
some cleanup
axe312ger Apr 30, 2018
f8b4caa
clean up example and enhance polaroid effect
axe312ger Apr 30, 2018
a439dee
fix using-sqip dependency
axe312ger Apr 30, 2018
3fdca72
remove base64 since it was not implemented and is bad for compression
axe312ger Apr 30, 2018
fb22bcb
remove sqip from gatsbygram example
axe312ger Apr 30, 2018
b551857
simplify tests
axe312ger Apr 30, 2018
df6c807
Small change to trigger build
KyleAMathews May 1, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add support for gatsby-transformer-sharp
Benedikt Rötsch authored and axe312ger committed Apr 29, 2018

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit f7f05da7c90c7bbe9a9cee92543f45811ef5b1ec
4 changes: 4 additions & 0 deletions packages/gatsby-transformer-sqip/package.json
Original file line number Diff line number Diff line change
@@ -15,6 +15,10 @@
"babel-cli": "^6.26.0",
"cross-env": "^5.0.5"
},
"peerDependencies": {
"gatsby-source-contentful": "*",
"gatsby-transformer-sharp": "*"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to myself: set to ^current version

},
"homepage": "https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-transformer-sqip#readme",
"keywords": [
"gatsby",
121 changes: 93 additions & 28 deletions packages/gatsby-transformer-sqip/src/extend-node-type.js
Original file line number Diff line number Diff line change
@@ -2,20 +2,77 @@ const crypto = require(`crypto`)
const { createWriteStream } = require(`fs`)
const { extname, join, resolve } = require(`path`)

const axios = require(`axios`)
const {
GraphQLString,
GraphQLInt,
} = require(`graphql`)
const fs = require(`fs-extra`)
const sqip = require(`sqip`)
const { schemes: { ImageResizingBehavior, ImageCropFocusType } } = require(`gatsby-source-contentful`)

module.exports = async ({ type, store, cache }) => {
module.exports = async (args) => {
const { type: { name } } = args

if (name === `ImageSharp`) {
return sqipSharp(args)
}

if (name === `ContentfulAsset`) {
return sqipContentful(args)
}

return {}
}

async function sqipSharp ({ type, cache }) {
if (type.name !== `ImageSharp`) {
return {}
}

return {
sqip: {
type: GraphQLString,
args: {
blur: {
type: GraphQLInt,
defaultValue: 1,
},
numberOfPrimitives: {
type: GraphQLInt,
defaultValue: 10,
},
mode: {
type: GraphQLInt,
defaultValue: 0,
},
},
async resolve(image, fieldArgs, context) {
const { blur, numberOfPrimitives, mode } = fieldArgs
// not everything is available at this point of time, maybe conflicts with extend node type from gatsby-transform-sharp, so lets hack it for now...
Copy link
Contributor

@pieh pieh Feb 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const file = getNodeAndSavePathDependency(image.parent, context.path)
const absolutePath = file.absolutePath

should do the trick

original etc are dynamic fields added by gatsby-transformer-sharp - same as you add fields here and are not part of node itself

// const { original: { src }, internal: { contentDigest } } = image
// const absolutePath = join(
// process.cwd(),
// `public`,
// src
// )

const { id, internal: { contentDigest } } = image
const absolutePath = id.replace(` absPath of file >> ImageSharp`, ``)

return generateSqip({ cache, contentDigest, absolutePath, numberOfPrimitives, blur, mode })
},
},
}
}

async function sqipContentful ({ type, store, cache }) {
if (type.name !== `ContentfulAsset`) {
return {}
}

const fs = require(`fs-extra`)
const axios = require(`axios`)

const { schemes: { ImageResizingBehavior, ImageCropFocusType } } = require(`gatsby-source-contentful`)

const cacheDir = join(
store.getState().program.directory,
`.cache`,
@@ -127,38 +184,46 @@ module.exports = async ({ type, store, cache }) => {
})
}

const sqipOptions = {
filename: absolutePath,
numberOfPrimitives,
blur,
mode,
}
return generateSqip({ cache, contentDigest, absolutePath, numberOfPrimitives, blur, mode })
},
},
}
}

const optionsHash = crypto
.createHash(`md5`)
.update(JSON.stringify(sqipOptions))
.digest(`hex`)
async function generateSqip (options) {
const { cache, contentDigest, absolutePath, numberOfPrimitives, blur, mode } = options

const cacheKey = `sqip-${contentDigest}-${optionsHash}`
// @todo add check if file actually exists

let svgThumbnail = await cache.get(cacheKey)
const sqipOptions = {
filename: absolutePath,
numberOfPrimitives,
blur,
mode,
}

if (!svgThumbnail) {
console.log(`Calculating low quality svg thumbnail: ${url}`)
const result = sqip(sqipOptions)
// @todo make blur setting in sqip via PR
svgThumbnail = result.final_svg.replace(new RegExp(`<feGaussianBlur stdDeviation="[0-9]+"\\s*/>`), `<feGaussianBlur stdDeviation="${sqipOptions.blur}" />`)
const optionsHash = crypto
.createHash(`md5`)
.update(JSON.stringify(sqipOptions))
.digest(`hex`)

await cache.set(cacheKey, svgThumbnail)
console.log(`done calculating primitive ${url}`)
}
const cacheKey = `sqip-${contentDigest}-${optionsHash}`

const dataURI = encodeOptimizedSVGDataUri(svgThumbnail)
let svgThumbnail = await cache.get(cacheKey)

return dataURI
},
},
if (!svgThumbnail) {
console.log(`Calculating low quality svg thumbnail: ${absolutePath}`)
const result = sqip(sqipOptions)
// @todo make blur setting in sqip via PR
svgThumbnail = result.final_svg.replace(new RegExp(`<feGaussianBlur stdDeviation="[0-9]+"\\s*/>`), `<feGaussianBlur stdDeviation="${sqipOptions.blur}" />`)

await cache.set(cacheKey, svgThumbnail)
console.log(`done calculating primitive ${absolutePath}`)
}

const dataURI = encodeOptimizedSVGDataUri(svgThumbnail)

return dataURI
}

// https://codepen.io/tigt/post/optimizing-svgs-in-data-uris
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a copy of the sharp plugin. Should be exported, though.