123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- var Preloader = /** @constructor */ function() { // eslint-disable-line no-unused-vars
- const loadXHR = function(resolve, reject, file, tracker, attempts) {
- const xhr = new XMLHttpRequest();
- tracker[file] = {
- total: 0,
- loaded: 0,
- final: false,
- };
- xhr.onerror = function() {
- if (attempts <= 1) {
- reject(new Error("Failed loading file '" + file + "'"));
- } else {
- setTimeout(function () {
- loadXHR(resolve, reject, file, tracker, attempts - 1);
- }, 1000);
- }
- };
- xhr.onabort = function() {
- tracker[file].final = true;
- reject(new Error("Loading file '" + file + "' was aborted."));
- };
- xhr.onloadstart = function(ev) {
- tracker[file].total = ev.total;
- tracker[file].loaded = ev.loaded;
- };
- xhr.onprogress = function(ev) {
- tracker[file].loaded = ev.loaded;
- tracker[file].total = ev.total;
- };
- xhr.onload = function() {
- if (xhr.status >= 400) {
- if (xhr.status < 500 || attempts <= 1) {
- reject(new Error("Failed loading file '" + file + "': " + xhr.statusText));
- xhr.abort();
- } else {
- setTimeout(function () {
- loadXHR(resolve, reject, file, tracker, attempts - 1);
- }, 1000);
- }
- } else {
- tracker[file].final = true;
- resolve(xhr);
- }
- };
- // Make request.
- xhr.open('GET', file);
- if (!file.endsWith('.js')) {
- xhr.responseType = 'arraybuffer';
- }
- xhr.send();
- };
- const DOWNLOAD_ATTEMPTS_MAX = 4;
- const loadingFiles = {};
- const lastProgress = { loaded: 0, total: 0 };
- let progressFunc = null;
- const animateProgress = function() {
- var loaded = 0;
- var total = 0;
- var totalIsValid = true;
- var progressIsFinal = true;
- Object.keys(loadingFiles).forEach(function(file) {
- const stat = loadingFiles[file];
- if (!stat.final) {
- progressIsFinal = false;
- }
- if (!totalIsValid || stat.total === 0) {
- totalIsValid = false;
- total = 0;
- } else {
- total += stat.total;
- }
- loaded += stat.loaded;
- });
- if (loaded !== lastProgress.loaded || total !== lastProgress.total) {
- lastProgress.loaded = loaded;
- lastProgress.total = total;
- if (typeof progressFunc === 'function')
- progressFunc(loaded, total);
- }
- if (!progressIsFinal)
- requestAnimationFrame(animateProgress);
- }
- this.animateProgress = animateProgress;
- this.setProgressFunc = function(callback) {
- progressFunc = callback;
- }
- this.loadPromise = function(file) {
- return new Promise(function(resolve, reject) {
- loadXHR(resolve, reject, file, loadingFiles, DOWNLOAD_ATTEMPTS_MAX);
- });
- }
- this.preloadedFiles = [];
- this.preload = function(pathOrBuffer, destPath) {
- let buffer = null;
- if (typeof pathOrBuffer === 'string') {
- var me = this;
- return this.loadPromise(pathOrBuffer).then(function(xhr) {
- me.preloadedFiles.push({
- path: destPath || pathOrBuffer,
- buffer: xhr.response
- });
- return Promise.resolve();
- });
- } else if (pathOrBuffer instanceof ArrayBuffer) {
- buffer = new Uint8Array(pathOrBuffer);
- } else if (ArrayBuffer.isView(pathOrBuffer)) {
- buffer = new Uint8Array(pathOrBuffer.buffer);
- }
- if (buffer) {
- this.preloadedFiles.push({
- path: destPath,
- buffer: pathOrBuffer
- });
- return Promise.resolve();
- } else {
- return Promise.reject(new Error("Invalid object for preloading"));
- }
- };
- };
|