The native elements <img>
, interface HTMLImageElement
, although it does (inherited from HTMLElement
) event properties like onload
, do not have native means to merge progress.
You can then use the API XMLHttpRequest
to download the image and measure progress during this process.
A very common example:
const url = 'https://images.unsplash.com/photo-1544867160-9a42c8d11d40';
loadImgSrc(url, (e) => {
console.log('Progresso:', e);
}).then((blobUrl) => {
console.log('Carregada.');
const img = new Image();
img.src = blobUrl;
document.body.appendChild(img);
}).catch((err) => {
console.error(err);
});
function loadImgSrc(url, onProgress) {
const req = new XMLHttpRequest();
req.open('GET', url, true);
req.responseType = 'arraybuffer';
req.onprogress = function(e) {
onProgress(e.loaded / e.total, e);
};
return new Promise((resolve, reject) => {
req.onload = function(e) {
const blob = new Blob([this.response]);
resolve(window.URL.createObjectURL(blob));
};
req.onerror = reject;
req.send();
});
}
Note that we are using the event progress
(attached to the property onprogress
) to calculate a percentage progress. For this, we divide loaded
for total
, which are properties present in the first parameter (event
).
After the image is uploaded, we use the API Blob
together with URL.createObjectURL
to create a blob URI, which will reference the already loaded image.
This implementation was based on in this Stackoverflow question in English. See it for several other examples.
But be careful that this may end up complicating things. Generally, images are not that heavy and calculating progress in this way can end up being an exaggeration. In most cases, the mere onload
already works.
Why the negative one? I recognize that in web design normally images are and should be of quick load and so a mechanism of this does not make sense but in applications gis and medical applications images can have absurd sizes and take a considerable amount of time to load.
– Augusto Vasques