すべての画像 URL を追加してから呼び出しload()
てロードを開始できるようにするこのローダーを作成しました。
この種類のローダーを使用して進行状況のコールバックをサポートできるため、現在の進行状況をユーザーに表示できます。
クロスオリジン イメージが必要な場合は、イメージの crossOrigin タイプを設定するようにロード済みに指示するフラグを追加することで、これに対するサポートを追加できます。次の例では、すべての画像に対してこれを設定していますが、個々の画像に対してこれをサポートするように拡張できます。
ライブデモはこちら
ローダ:
/// callback - function to call when finished (mandatory)
/// progress - function to call for each image loaded (optional)
/// progress contains an argument with an "event" containing properties
/// img (the image loaded), url, current (integer) and total (integer)
function imageLoader(callback, progress, error) {
if (typeof callback !== 'function') throw 'Need a function for callback!';
var lst = [],
crossOrigin = false;
this.crossOrigin = function (state) {
if (typeof state !== 'bool') return crossOrigin;
crossOrigin = state;
return this;
}
this.add = function (url) {
lst.push(url);
return this;
}
this.load = function () {
if (lst.length > 0) {
startLoading();
}
return this;
}
function startLoading() {
var i = 0,
url,
count = lst.length,
images = [];
for (; url = lst[i]; i++) {
var img = document.createElement('img');
images.push(img);
img.onload = function () {
_handler(url, this)
};
img.onerror = function (e) {
_handlerError(url, e)
};
if (crossOrigin === true) img.crossOrigin = 'anonymous';
img.src = url;
}
function _handler(url, img) {
count--;
if (typeof progress === 'function') progress({
current: lst.length - count,
total: lst.length,
url: url,
img: img
});
if (count === 0) callback({
images: images,
urls: lst
});
}
function _handlerError(url, e) {
if (typeof error === 'function') error({
url: url,
error: e
});
console.warn('WARNING: Could not load image:', url);
_handler();
}
}
return this;
}
使用法:
var loader = new imageLoader(done, progress);
/// methods can be chained:
loader.add(url1)
.add(url2)
.add(url3)
.load();
(完全な例についてはデモを参照)
その後、ハンドラーは次のことができます。
function done(e) {
for (i = 0; i < e.images.length; i++) {
/// draw the image
ctx.drawImage(e.images[i], i * 20, i * 20, 40, 40);
}
}
function progress(e) {
///progress bar
status.style.width = ((e.current / e.total) * 100).toFixed(0) + '%';
/// current loaded image
ctx.drawImage(e.img, 0, 340, 60, 60);
}