-
Notifications
You must be signed in to change notification settings - Fork 0
/
AssetLoader.js
70 lines (69 loc) · 2.76 KB
/
AssetLoader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { COMPLETE, noop } from './constants.js';
export class AssetLoader extends EventTarget {
constructor(options) {
super();
const {requestLogFunction=noop, errorFunction=noop, progressFunction=noop, completeLogFunction=noop} = options;
this.requestLogFunction = requestLogFunction;
this.errorFunction = errorFunction;
this.progressFunction = progressFunction;
this.completeLogFunction = completeLogFunction;
this.fileTotal;
this.fileCount;
this.headerCount;
this.areHeadersCounted;
this.downloadTotal;
this.progressArray = [];
this.blobArray = [];
}
loadArray(urlArray) {
this.fileTotal = urlArray.length;
this.fileCount = 0;
this.headerCount = 0;
this.areHeadersCounted = false;
this.downloadTotal = 0;
for (let i=0; i<this.fileTotal; i++) {
const url = urlArray[i];
this.requestLogFunction(url);
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onreadystatechange = (evt) => this.sumContentLength(xhr);
xhr.onerror = () => this.onError(i);
xhr.onprogress = (evt) => this.calcProgress(i, evt);
xhr.onload = () => this.onLoad(xhr, i, url);
xhr.send();
}
}
sumContentLength(xhr) {
if (xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
this.headerCount++;
if (this.headerCount == this.fileTotal) this.areHeadersCounted = true;
var contentLength = xhr.getResponseHeader('Content-Length');
if (contentLength !== null) this.downloadTotal += parseInt(contentLength, 10);
else console.log('Content-Length header not found in response.');
}
}
onError(url) {this.errorFunction(url);}
calcProgress(i, evt) {
if (this.progressFunction !== noop) {
this.progressArray[i] = evt.loaded;
if (this.areHeadersCounted) {
const totalProgress = this.progressArray.reduce((total, loaded) => total + loaded, 0);
const progress = totalProgress / this.downloadTotal;
this.progressFunction(progress);
}
}
};
onLoad (xhr, i, url) {
if (xhr.status === 200) {
this.fileCount++;
const blob = xhr.response;
this.blobArray[i] = blob;
this.completeLogFunction(i);
if (this.fileCount === this.fileTotal) this.dispatchEvent(new Event(COMPLETE));
} else this.onError(url);
};
dispose() {
this.blobArray.length = this.progressArray.length = 0;
}
}