Everyone likes smooth loading. Lately I tried to make the background-image
of the menu to load progressively(also to the cover if you view the blog on mobile).
If you take a look at how Medium does progressive image loading(or check out this article), you'll notice that they use JavaScript and canvas to blur and store thumbnails. It seems a bit overkill to me. And when you need to do it on a background-image
with background-position
, things become even more complicated.
So I needed to figure out a simpler solution. Here's what I came up with:
As the article above mentioned:
By default, when a browser renders a small image scaled up, it applies a light blur effect to smooth the artefacts of the image. The effect can also be turned off for images like QR codes.
But the default blur effect still feels blocky.
To make it smoother, I applied blur effect to the thumbnails while generating them, using GraphicsMagick for node:
const gm = require('gm')
gm(coverPath)
.resize(30) // or .resize(null, 30) for portrait
.blur(5)
.noProfile()
.write(thumbnailPath, function (err) {
if (err) { console.warn(err) }
// ...
})
// or to base64
gm(coverPath)
.resize(30) // or .resize(null, 30) for portrait
.blur(5)
.noProfile()
.toBuffer(function (err, buffer) {
if (err) { console.warn(err) }
var base64 = 'data:image/' + ext + ';base64,' + buffer.toString('base64')
// ...
})
This looks acceptable to me. No need for a canvas or blur function. Already felt relieved! :smile:
This method divides a component into four layers: container, thumbnail, mask and content.
background-image
.Use z-index
to separate the layers.
When full-size image is loaded, hide the thumbnail. You can use this technic(with jQuery/Zepto):
var $container = $('.container')
// Matchs the "url(...)"
var bigBgSrc = $container.css('background-image').match(/url\((.+?)\)/i)
if (bigBgSrc) {
// Removes quotations
bigBgSrc = bigBgSrc[1].replace(/'|"/g, '')
$('<img>')
.on('load', function () {
$container.find('.thumbnail')
.addClass('thumbnail--hide') // Hides thumbnail
})
.prop('src', bigBgSrc)
}
A live example:
No-js support is extremely easy. Just hide the thumbnail.
html.no-js .thumbnail {
display: none !important;
}
For my blog I also made a Sass Mixin/Extend with this method.
评论没有加载,检查你的局域网
Cannot load comments. Check you network.