I only just started using Hugo, and am learning JS as I use it, so suggestions for improvement are welcome!
I started off with this post, and then read a bit more and added more features. it also uses the Lozad JS library, so you’ll need to have that loaded.
This is what I use:
{{<srcset_image classes="vertical" name="new_profile_pic_edited.jpg" alt="Profile Picture" caption="Once upon a time in a cafe in Seattle... ">}}
Shortcode:
{{ $caption := .Get "caption"}}
{{ $classes := .Get "classes"}}
{{ $image := (.Page.Resources.GetMatch (.Get "name")) }}
{{ $placeholder := $image.Resize "48x q20" }}
{{ with $.Page.Resources.GetMatch (.Get "name") }}
<figure class="progressive_figure {{$classes}}" data-imgset="{{ (.Resize "640x").RelPermalink }} 320w,
{{ (.Resize "1024x").RelPermalink }} 600w,
{{ (.Resize "1600x").RelPermalink }} 2x"
data-src="{{ (.Resize "1600x").RelPermalink}}" >
<div class="placeholder">
<img class="img-small" src="{{ $placeholder.RelPermalink }}" alt="{{$altText}}" />
</div>
<figcaption>{{ $caption }}</figcaption>
</figure>
{{ else }}
could not find image
{{ end }}
Javascript:
/* ---- BEGIN LAZY LOADING ----- */
const observer = lozad(); // lazy loads elements with default selector as '.lozad'
// Progressive section
window.onload = function() {
var placeholder = document.querySelectorAll('.progressive_figure');
placeholder.forEach(element => {
var smallImage = element.getElementsByClassName('img-small')[0];
// Load placeholder image
var img = new Image();
img.src = smallImage.getAttribute('src')
img.onload = function () {
smallImage.classList.add('loaded')
// Load large image
var largeImage = new Image();
largeImage.srcset = element.getAttribute('data-imgset');
largeImage.src = element.getAttribute('data-src');
largeImage.classList.add('img-large')
largeImage.classList.add('lozad')
largeImage.onload = function () {
largeImage.classList.add('loaded');
smallImage.replaceWith(largeImage);
}
}
})};
observer.observe();
CSS:
.img-small {
filter: blur(25px);
border: 1px solid $light-grey;
border-radius: 5px;
}
.placeholder {
background-color: rgba($color: #000000, $alpha: 0);
background-size: cover;
background-repeat: no-repeat;
position: relative;
overflow: hidden;
}
.placeholder {
overflow: auto;
border: 1px solid $light-grey;
border-radius: 5px;
}
.placeholder .img-large {
transition: opacity 0.2s linear;
}
.placeholder img.loaded {
opacity: 1;
}
.placeholder {
display: block;
}
In action:
At the About section of my own website. I’ve only enabled it on the About page for now, because I imported my blog from Wordpress and the other entries are a markdown mess!