UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

134 lines (127 loc) 4.48 kB
import { Cache } from './Cache.js'; import { Loader } from './Loader.js'; /** * A loader for loading images as an [ImageBitmap]{@link https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap}. * An `ImageBitmap` provides an asynchronous and resource efficient pathway to prepare * textures for rendering. * * Note that {@link Texture#flipY} and {@link Texture#premultiplyAlpha} are ignored with image bitmaps. * They needs these configuration on bitmap creation unlike regular images need them on uploading to GPU. * * You need to set the equivalent options via {@link ImageBitmapLoader#setOptions} instead. * * Also note that unlike {@link FileLoader}, this loader does not avoid multiple concurrent requests to the same URL. * * ```js * const loader = new THREE.ImageBitmapLoader(); * loader.setOptions( { imageOrientation: 'flipY' } ); // set options if needed * const imageBitmap = await loader.loadAsync( 'image.png' ); * * const texture = new THREE.Texture( imageBitmap ); * texture.needsUpdate = true; * ``` * * @augments Loader */ class ImageBitmapLoader extends Loader { /** * Constructs a new image bitmap loader. * * @param {LoadingManager} [manager] - The loading manager. */ constructor(manager) { super(manager); /** * This flag can be used for type testing. * * @type {boolean} * @readonly * @default true */ this.isImageBitmapLoader = true; if (typeof createImageBitmap === 'undefined') { console.warn('THREE.ImageBitmapLoader: createImageBitmap() not supported.'); } if (typeof fetch === 'undefined') { console.warn('THREE.ImageBitmapLoader: fetch() not supported.'); } /** * Represents the loader options. * * @type {Object} * @default {premultiplyAlpha:'none'} */ this.options = { premultiplyAlpha: 'none' }; } /** * Sets the given loader options. The structure of the object must match the `options` parameter of * [createImageBitmap]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/createImageBitmap}. * * @param {Object} options - The loader options to set. * @return {ImageBitmapLoader} A reference to this image bitmap loader. */ setOptions(options) { this.options = options; return this; } /** * Starts loading from the given URL and pass the loaded image bitmap to the `onLoad()` callback. * * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI. * @param {function(ImageBitmap)} onLoad - Executed when the loading process has been finished. * @param {onProgressCallback} onProgress - Unsupported in this loader. * @param {onErrorCallback} onError - Executed when errors occur. * @return {ImageBitmap|undefined} The image bitmap. */ load(url, onLoad, onProgress, onError) { if (url === undefined) url = ''; if (this.path !== undefined) url = this.path + url; url = this.manager.resolveURL(url); const scope = this; const cached = Cache.get(url); if (cached !== undefined) { scope.manager.itemStart(url); // If cached is a promise, wait for it to resolve if (cached.then) { cached.then(imageBitmap => { if (onLoad) onLoad(imageBitmap); scope.manager.itemEnd(url); }).catch(e => { if (onError) onError(e); }); return; } // If cached is not a promise (i.e., it's already an imageBitmap) setTimeout(function () { if (onLoad) onLoad(cached); scope.manager.itemEnd(url); }, 0); return cached; } const fetchOptions = {}; fetchOptions.credentials = this.crossOrigin === 'anonymous' ? 'same-origin' : 'include'; fetchOptions.headers = this.requestHeader; const promise = fetch(url, fetchOptions).then(function (res) { return res.blob(); }).then(function (blob) { return createImageBitmap(blob, Object.assign(scope.options, { colorSpaceConversion: 'none' })); }).then(function (imageBitmap) { Cache.add(url, imageBitmap); if (onLoad) onLoad(imageBitmap); scope.manager.itemEnd(url); return imageBitmap; }).catch(function (e) { if (onError) onError(e); Cache.remove(url); scope.manager.itemError(url); scope.manager.itemEnd(url); }); Cache.add(url, promise); scope.manager.itemStart(url); } } export { ImageBitmapLoader };