Progressive Image Loading

by tsucres

HTML

<h2>
Progressively loaded image
</h2>
<div class="aspectRatioPlaceholder">
    <div class="aspectRatioPlaceholder-fill"></div>
    <div class="progressiveMedia full-absolute" id="ex1" data-width="3008" data-height="2000">
        <img class="progressiveMedia-thumbnail hidden"...

CSS

.aspectRatioPlaceholder {
  position: relative;
  width: 100%;
  margin: 0 auto;
  display: block; 
}
.full-absolute {
	position: absolute;
	top: 0; left: 0; right: 0; bottom: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.progressiveMedia-canvas {
	-webkit-transition: opacity 1s;
	transition: opacity 1s; 
}
.full-loaded .progressiveMedia-canvas {
	opacity: 0;
}
.hidden {
	display: none;
  	visibility: hidden;
}

JavaScript

function initImage(root_el) {
        var miniatureImg = root_el.querySelector(".progressiveMedia-thumbnail");
        var canvas = root_el.querySelector(".progressiveMedia-canvas");
        var placeholderFilDiv = root_el.previousElementSibling;
        var width = root_el.dataset.width;
        var height = root_el.dataset.height;
        drawMinatureForImage(miniatureImg, canvas, placeholderFilDiv, width, height);
}
function loadFullImage(root_el) {
		var fullImg = root_el.querySelector(".progressiveMedia-image"),
    canvas = root_el.querySelector(".progressiveMedia-canvas");
    
    fullImg.onload = function() {
    		fullImg.classList.remove("hidden");
        root_el.classList.add("full-loaded");
    }
    fullImg.src = fullImg.dataset.src;
}
    
function drawMinatureForImage(miniatureImg, canvas, placeholderFilDiv, width, height) {
    var fill = height / width * 100;
    placeholderFilDiv.style = 'padding-bottom:'+fill+'%;';

    var smImageWidth = miniatureImg.width,
    smImageheight = miniatureImg.height;

    canvas.height = smImageheight;
    canvas.width = smImageWidth;

    var img = new Image();
    img.onload = function () {
        var canvasImage = new CanvasImage(canvas, img);
        canvasImage.blur(2);
    };
    img.src = miniatureImg.src;
}

// source: pilpil.js
CanvasImage = function (canvasEL, image) {
    this.image = image;
    this.element = canvasEL;
    canvasEL.width = image.width;
    canvasEL.height = image.height;
    this.context = canvasEL.getContext('2d');
    this.context.drawImage(image, 0, 0);
};
CanvasImage.prototype = {
    blur:function(e) {
        this.context.globalAlpha = 0.5;
        for(var t = -e; t <= e; t += 2) {
            for(var n = -e; n <= e; n += 2) {
                this.context.drawImage(this.element, n, t);
                var blob = n >= 0 && t >= 0 && this.context.drawImage(this.element, -(n -1), -(t-1));
            }
        }
    }
};
var img =...