- 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
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
import { imgList } from "../cache.js";
import { fetchData } from "./fetchdata.js";
import * as fileUtil from "./../../utils/file.js";
import { parseCompressedImage } from "./compressed_textures/compressed_image.js";
/**
* parse/preload an image
* @param {loader.Asset} img
* @param {Function} [onload] - function to be called when the resource is loaded
* @param {Function} [onerror] - function to be called in case of error
* @param {Object} [settings] - Additional settings to be passed when loading the asset
* @returns {number} the amount of corresponding resource parsed/preloaded
* @ignore
* @example
* preloadImages([
* { name : 'image1', src : 'images/image1.png'},
* { name : 'image2', src : 'images/image2.png'},
* { name : 'image3', src : 'images/image3.png'},
* { name : 'image4', src : 'images/image4.png'}
* ]);
*/
export function preloadImage(img, onload, onerror, settings) {
if (typeof imgList[img.name] !== "undefined") {
// already loaded
return 0;
}
let sources = Array.isArray(img.src) ? img.src : [img.src];
let isFormatSupported = false;
for (const imgPath of sources) {
const imgExt = fileUtil.getExtension(imgPath);
// loop will stop as soon as a first supported format is detected
switch (imgExt) {
// Compressed texture
case "dds":
case "pvr":
case "pkm":
case "ktx":
case "ktx2":
fetchData(imgPath, "arrayBuffer", settings)
.then(arrayBuffer => {
try {
imgList[img.name] = parseCompressedImage(arrayBuffer, imgExt);
isFormatSupported = true;
if (typeof onload === "function") {
// callback
onload();
}
} catch (e) {
// parseCompressedImage will throw an error if a format is not supported or badly formatted
}
}).catch(error => {
if (typeof onerror === "function") {
// file cannot be loaded
onerror(error);
}
});
break;
// SVG file
case "svg":
fetchData(imgPath, "text", settings)
.then(svgText => {
const svgImage = new Image();
svgImage.onload = function() {
imgList[img.name] = svgImage;
if (typeof onload === "function") {
// callback
onload();
}
};
svgImage.onerror = function(error) {
if (typeof onerror === "function") {
onerror(error);
}
};
svgImage.src = "data:image/svg+xml;charset=utf8," + encodeURIComponent(svgText);
})
.catch(error => {
if (typeof onerror === "function") {
onerror(error);
}
});
isFormatSupported = true;
break;
// default is regular images (jpg, png and friends)
default:
fetchData(imgPath, "blob", settings)
.then(blob => {
globalThis.createImageBitmap(blob)
.then((bitmap) => {
imgList[img.name] = bitmap;
if (typeof onload === "function") {
// callback
onload();
}
});
})
.catch(error => {
if (typeof onerror === "function") {
onerror(error);
}
});
isFormatSupported = true;
break;
}
// exit the loop as soon as the first supported format is detected
if (isFormatSupported === true) {
return 1;
}
}
// no compatible format was found
throw new Error(
"No suppported Image file format found for " + img.name
);
}