hyapp-h5/common/game-preloader.js
2026-06-11 23:09:39 +08:00

256 lines
7.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function () {
var imageCache = {};
var binaryCache = {};
var imagePattern = /\.(png|jpe?g|gif|webp|svg|avif)(\?|#|$)/i;
var svgaPattern = /\.svga(\?|#|$)/i;
function each(nodes, iteratee) {
Array.prototype.forEach.call(nodes || [], iteratee);
}
function normalizeURL(url, baseURL) {
var value = String(url || '').trim();
if (
!value ||
value.indexOf('data:') === 0 ||
value.indexOf('blob:') === 0
) {
return '';
}
try {
return new URL(value, baseURL || window.location.href).href;
} catch (_) {
return '';
}
}
function addURL(list, seen, url, baseURL) {
var normalized = normalizeURL(url, baseURL);
if (!normalized || seen[normalized]) return;
seen[normalized] = true;
list.push(normalized);
}
function collectFromCSSText(list, seen, text) {
var pattern = /url\((['"]?)(.*?)\1\)/g;
var match;
while ((match = pattern.exec(text || ''))) {
addURL(list, seen, match[2]);
}
}
function collectSrcSet(list, seen, value) {
String(value || '')
.split(',')
.forEach(function (item) {
addURL(list, seen, item.trim().split(/\s+/)[0]);
});
}
function collectDocumentURLs(list, seen) {
each(document.querySelectorAll('img[src]'), function (img) {
addURL(list, seen, img.getAttribute('src'));
});
each(document.querySelectorAll('source[srcset]'), function (source) {
collectSrcSet(list, seen, source.getAttribute('srcset'));
});
each(document.querySelectorAll('style'), function (node) {
collectFromCSSText(list, seen, node.textContent || '');
});
each(document.querySelectorAll('[style]'), function (node) {
collectFromCSSText(list, seen, node.getAttribute('style') || '');
});
each(document.styleSheets, function (sheet) {
try {
each(sheet.cssRules || [], function (rule) {
collectFromCSSText(list, seen, rule.cssText || '');
});
} catch (_) {}
});
}
function collectResourceURLs(assetURLs) {
var list = [];
var seen = {};
(assetURLs || []).forEach(function (url) {
addURL(list, seen, url);
});
collectDocumentURLs(list, seen);
return list;
}
function isImageURL(url) {
return imagePattern.test(String(url || ''));
}
function isSVGAURL(url) {
return svgaPattern.test(String(url || ''));
}
function preloadImage(url) {
var normalized = normalizeURL(url);
if (!normalized) return Promise.resolve(false);
if (imageCache[normalized]) return imageCache[normalized];
imageCache[normalized] = new Promise(function (resolve) {
var image = new Image();
image.onload = function () {
resolve(true);
};
image.onerror = function () {
resolve(false);
};
image.decoding = 'async';
image.src = normalized;
if (image.complete) resolve(true);
});
return imageCache[normalized];
}
function preloadBinary(url) {
var normalized = normalizeURL(url);
if (!normalized) return Promise.resolve(false);
if (binaryCache[normalized]) return binaryCache[normalized];
binaryCache[normalized] = window
.fetch(normalized, { cache: 'force-cache' })
.then(function (response) {
return response.ok;
})
.catch(function () {
return false;
});
return binaryCache[normalized];
}
function preloadSVGA(url, options) {
options = options || {};
if (
window.HyAppEffectPlayer &&
typeof window.HyAppEffectPlayer.preload === 'function'
) {
return window.HyAppEffectPlayer.preload(url, {
type: 'svga',
svgaScript: options.svgaScript,
waitForWindowLoad: options.waitForWindowLoad === true,
})
.then(function () {
return true;
})
.catch(function () {
return preloadBinary(url);
});
}
return preloadBinary(url);
}
function preloadResource(url, options) {
if (isSVGAURL(url)) return preloadSVGA(url, options && options.svga);
if (isImageURL(url)) return preloadImage(url);
return preloadBinary(url);
}
function setProgress(progress) {
var options =
typeof progress === 'number'
? { progress: progress }
: progress || {};
var root = options.root || document.documentElement;
var safeProgress = Math.min(
Math.max(Number(options.progress) || 0, 0),
1
);
var progressNode =
options.progressNode ||
document.querySelector('[data-role="loading-progress"]');
root.style.setProperty('--loading-progress', safeProgress.toFixed(4));
if (progressNode) {
progressNode.setAttribute(
'aria-valuenow',
String(Math.round(safeProgress * 100))
);
}
}
function runTasks(tasks, onProgress) {
var completed = 0;
var total = Math.max((tasks && tasks.length) || 0, 1);
var update =
typeof onProgress === 'function'
? onProgress
: function (value) {
setProgress(value);
};
update(0);
if (!tasks || !tasks.length) {
update(1);
return Promise.resolve([]);
}
// 资源预加载是体验优化,单个资源失败不应该卡死大厅;失败项会返回 false进度仍然推进。
return Promise.all(
tasks.map(function (task) {
return Promise.resolve()
.then(task)
.catch(function () {
return false;
})
.then(function (value) {
completed += 1;
update(completed / total);
return value;
});
})
);
}
function complete(options) {
options = options || {};
var loadingScreen =
options.loadingScreen ||
document.querySelector('[data-role="loading-screen"]');
setProgress({
root: options.root,
progress: 1,
progressNode: options.progressNode,
});
if (loadingScreen) {
loadingScreen.classList.add('is-complete');
loadingScreen.setAttribute('aria-hidden', 'true');
}
if (options.frame) {
options.frame.classList.remove('is-preloading');
}
}
function once(task) {
var promise = null;
return function () {
if (!promise) {
promise = Promise.resolve().then(task);
}
return promise;
};
}
function delay(ms) {
return new Promise(function (resolve) {
window.setTimeout(resolve, ms);
});
}
window.HyAppGamePreloader = {
addURL: addURL,
collectResourceURLs: collectResourceURLs,
complete: complete,
delay: delay,
isImageURL: isImageURL,
isSVGAURL: isSVGAURL,
normalizeURL: normalizeURL,
once: once,
preloadBinary: preloadBinary,
preloadImage: preloadImage,
preloadResource: preloadResource,
preloadSVGA: preloadSVGA,
runTasks: runTasks,
setProgress: setProgress,
};
})();