diff --git a/packages/gatsby-remark-images/.babelrc b/packages/gatsby-remark-images/.babelrc
index 9f5de61e0d79e..c5aaeee07bfaf 100644
--- a/packages/gatsby-remark-images/.babelrc
+++ b/packages/gatsby-remark-images/.babelrc
@@ -1,5 +1,5 @@
{
"presets": [
- ["babel-preset-gatsby-package"]
+ ["babel-preset-gatsby-package", { "browser": true }]
]
}
diff --git a/packages/gatsby-remark-images/.gitignore b/packages/gatsby-remark-images/.gitignore
index f566442b32d84..dcc20e9f74bf9 100644
--- a/packages/gatsby-remark-images/.gitignore
+++ b/packages/gatsby-remark-images/.gitignore
@@ -1,3 +1,5 @@
+/constants.js
+/gatsby-browser.js
/index.js
/__tests__/*
tests
\ No newline at end of file
diff --git a/packages/gatsby-remark-images/src/__tests__/__snapshots__/index.js.snap b/packages/gatsby-remark-images/src/__tests__/__snapshots__/index.js.snap
index ea1d0153fdfef..8408dd6ad2456 100644
--- a/packages/gatsby-remark-images/src/__tests__/__snapshots__/index.js.snap
+++ b/packages/gatsby-remark-images/src/__tests__/__snapshots__/index.js.snap
@@ -1,119 +1,97 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`it handles goofy nesting properly 1`] = `
-"
-
-
+
-
-
- "
+ "
`;
exports[`it leaves images that are already linked alone 1`] = `
-"
-
-
+
-
-
- "
+ "
`;
exports[`it leaves linked HTML img tags alone 1`] = `
"
-
-
-
-
+
+
-
"
`;
exports[`it leaves single-line linked HTML img tags alone 1`] = `
-"
-
-
-
-
-
- "
+"
+
+
+ "
`;
exports[`it transforms HTML img tags 1`] = `
-"
-
-
-
-
-
-
+"
+
+
+
-
-
- "
+ "
`;
exports[`it transforms images in markdown 1`] = `
-"
-
-
-
-
+
-
-
-
- "
+ "
`;
diff --git a/packages/gatsby-remark-images/src/constants.js b/packages/gatsby-remark-images/src/constants.js
new file mode 100644
index 0000000000000..69e5d9b58c01d
--- /dev/null
+++ b/packages/gatsby-remark-images/src/constants.js
@@ -0,0 +1,3 @@
+exports.imageClass = `gatsby-resp-image-image`
+exports.imageWrapperClass = `gatsby-resp-image-wrapper`
+exports.imageBackgroundClass = `gatsby-resp-image-background-image`
diff --git a/packages/gatsby-remark-images/src/gatsby-browser.js b/packages/gatsby-remark-images/src/gatsby-browser.js
new file mode 100644
index 0000000000000..fb8fcbc95670b
--- /dev/null
+++ b/packages/gatsby-remark-images/src/gatsby-browser.js
@@ -0,0 +1,35 @@
+const {
+ imageClass,
+ imageBackgroundClass,
+ imageWrapperClass,
+} = require(`./constants`)
+
+exports.onRouteUpdate = () => {
+ const imageWrappers = document.querySelectorAll(`.${imageWrapperClass}`)
+
+ // https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/
+ // for cross-browser looping through NodeList without polyfills
+ for (let i = 0; i < imageWrappers.length; i++) {
+ const imageWrapper = imageWrappers[i]
+
+ const backgroundElement = imageWrapper.querySelector(
+ `.${imageBackgroundClass}`
+ )
+ const imageElement = imageWrapper.querySelector(`.${imageClass}`)
+
+ const onImageLoad = () => {
+ backgroundElement.style.transition = `opacity 0.5s 0.5s`
+ backgroundElement.style.opacity = 0
+ imageElement.style.transition = `opacity 0.5s`
+ imageElement.style.opacity = 1
+ imageElement.removeEventListener(`load`, onImageLoad)
+ }
+
+ if (imageElement.complete) {
+ backgroundElement.style.opacity = 0
+ } else {
+ imageElement.style.opacity = 0
+ imageElement.addEventListener(`load`, onImageLoad)
+ }
+ }
+}
diff --git a/packages/gatsby-remark-images/src/index.js b/packages/gatsby-remark-images/src/index.js
index afb3aed2af772..795bccf80c569 100644
--- a/packages/gatsby-remark-images/src/index.js
+++ b/packages/gatsby-remark-images/src/index.js
@@ -1,4 +1,8 @@
-// const select = require(`unist-util-select`)
+const {
+ imageClass,
+ imageBackgroundClass,
+ imageWrapperClass,
+} = require(`./constants`)
const visitWithParents = require(`unist-util-visit-parents`)
const path = require(`path`)
const isRelativeUrl = require(`is-relative-url`)
@@ -90,9 +94,6 @@ module.exports = (
return resolve()
}
- // Calculate the paddingBottom %
- const ratio = `${(1 / fluidResult.aspectRatio) * 100}%`
-
const originalImg = fluidResult.originalImg
const fallbackSrc = fluidResult.src
const srcSet = fluidResult.srcSet
@@ -104,14 +105,18 @@ module.exports = (
const fileNameNoExt = fileName.replace(/\.[^/.]+$/, ``)
const defaultAlt = fileNameNoExt.replace(/[^A-Z0-9]/gi, ` `)
- // TODO
- // Fade in images on load.
- // https://www.perpetual-beta.org/weblog/silky-smooth-image-loading.html
-
- const imageClass = `gatsby-resp-image-image`
- const imageStyle = `width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px ${
- options.backgroundColor
- };`
+ const imageStyle = `
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ vertical-align: middle;
+ position: absolute;
+ top: 0;
+ left: 0;
+ box-shadow: inset 0px 0px 0px 400px ${options.backgroundColor};`.replace(
+ /\s*(\S+:)\s*/g,
+ `$1`
+ )
// Create our base image tag
let imageTag = `
@@ -124,7 +129,7 @@ module.exports = (
srcset="${srcSet}"
sizes="${fluidResult.sizes}"
/>
- `
+ `.trim()
// if options.withWebp is enabled, generate a webp version and change the image tag to a picture tag
if (options.withWebp) {
@@ -162,29 +167,31 @@ module.exports = (
src="${fallbackSrc}"
alt="${node.alt ? node.alt : defaultAlt}"
title="${node.title ? node.title : ``}"
- src="${fallbackSrc}"
/>
- `
+ `.trim()
}
+ const ratio = `${(1 / fluidResult.aspectRatio) * 100}%`
+
// Construct new image node w/ aspect ratio placeholder
const showCaptions = options.showCaptions && node.title
let rawHTML = `
${imageTag}
+ >
+ ${imageTag}
- `
+ `.trim()
// Make linking to original image optional.
if (!inLink && options.linkImagesToOriginal) {
@@ -196,19 +203,19 @@ module.exports = (
target="_blank"
rel="noopener"
>
- ${rawHTML}
+ ${rawHTML}
- `
+ `.trim()
}
// Wrap in figure and use title as caption
if (showCaptions) {
rawHTML = `
- ${rawHTML}
- ${node.title}
+ ${rawHTML}
+ ${node.title}
- `
+ `.trim()
}
return rawHTML