File: development/js/utils/loader.js
import type from './type';
import objects from './object';
/**
* Async image loading utility
*
* @module Utils
* @class Utils.Loader
* @static
*/
/* Loading of images
----------------- */
function isImgFile (s) {
return type.isString(s) && !!/\.(jpg|jpeg|png|svg|gif)$/.test(s);
}
function imgReady (n) {
if (n.complete) {
if (n.naturalWidth) {
return n.naturalWidth + n.naturalHeight > 0;
}
return n.width + n.height > 0;
}
}
function loadImgRecursive (img, done, fail, always, attempts) {
if (!type.isNode(img) || img.nodeName !== 'IMG') {
throw 'Unable to load, expected first argument to be <img> but saw: ' + img;
}
if (imgReady(img)) {
done(img);
return always();
}
if (attempts <= 0) {
fail('Max number of load attempts reached for ' + img.src);
return always();
}
// call recursive until loaded or max attempts is reached
setTimeout(function() {
loadImgRecursive(img, done, fail, always, attempts - 1);
}, 250);
}
/**
Allows to load a single image. One may pass a object of options as argument
to specify parameters like a success and failure handler or the max number
of attempts to load the image.
@method loadImage
@for Utils.Loader
@param {object} options Configuration object
@param {string} options.url URL of image to load
@param {function} [options.loaded] Function to call on success
@param {function} [options.failed] Function to call on failure
@param {function} [options.always] Function to call regardless if success or failure
@param {number} [options.cycles = 100] Maximum number of attempts to load
@example
import loadImage from './utils/loader';
loadImage({
url: 'path/to/image.jpg',
loaded: function (img) {
// success, img is the <img> node
},
failed: function (errorMsg) {
// process error message
},
always: function () {
// executed in any case (success or failure)
}
});
**/
const loadImage = function loadImage (options) {
var _img = isImgFile(options.url) ? document.createElement('img') : null,
_opts = objects.extend({}, options);
if (!_img) {
throw 'Utils.loadImage(:options) expects to find URL in options but found none';
}
if (!type.isFunction(_opts.loaded)) {
_opts.loaded = function () {};
}
if (!type.isFunction(_opts.failed)) {
_opts.failed = function () {};
}
if (!type.isFunction(_opts.always)) {
_opts.always = function () {};
}
if (!type.isNumber(_opts.cycles)) {
_opts.cycles = 100;
}
_img.alt = '';
_img.src = _opts.url;
loadImgRecursive(
_img,
_opts.loaded,
_opts.failed,
_opts.always,
_opts.cycles
);
}
export default loadImage;