loaders/ImageLoader.js

  1. import { DataImage } from '../DataImage.js';
  2. import * as THREE from 'three';
  3. /**
  4. * @module ImageLoader
  5. * @description Image loader with progress based on {@link https://github.com/mrdoob/three.js/blob/master/src/loaders/ImageLoader.js}
  6. */
  7. const ImageLoader = {
  8. /**
  9. * Load image
  10. * @example PANOLENS.ImageLoader.load( IMAGE_URL )
  11. * @method load
  12. * @param {string} url - An image url
  13. * @param {function} onLoad - On load callback
  14. * @param {function} onProgress - In progress callback
  15. * @param {function} onError - On error callback
  16. */
  17. load: function ( url, onLoad = () => {}, onProgress = () => {}, onError = () => {} ) {
  18. // Enable cache
  19. THREE.Cache.enabled = true;
  20. let cached, request, arrayBufferView, blob, urlCreator, image, reference;
  21. // Reference key
  22. for ( let iconName in DataImage ) {
  23. if ( DataImage.hasOwnProperty( iconName ) && url === DataImage[ iconName ] ) {
  24. reference = iconName;
  25. }
  26. }
  27. // Cached
  28. cached = THREE.Cache.get( reference ? reference : url );
  29. if ( cached !== undefined ) {
  30. if ( onLoad ) {
  31. requestAnimationFrame( () => {
  32. onProgress( { loaded: 1, total: 1 } );
  33. onLoad( cached );
  34. });
  35. }
  36. return cached;
  37. }
  38. // Construct a new XMLHttpRequest
  39. urlCreator = window.URL || window.webkitURL;
  40. image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );
  41. // Add to cache
  42. THREE.Cache.add( reference ? reference : url, image );
  43. const onImageLoaded = () => {
  44. urlCreator.revokeObjectURL( image.src );
  45. onLoad( image );
  46. };
  47. if ( url.indexOf( 'data:' ) === 0 ) {
  48. image.addEventListener( 'load', onImageLoaded, false );
  49. image.src = url;
  50. return image;
  51. }
  52. image.crossOrigin = this.crossOrigin !== undefined ? this.crossOrigin : '';
  53. request = new window.XMLHttpRequest();
  54. request.open( 'GET', url, true );
  55. request.responseType = 'arraybuffer';
  56. request.addEventListener( 'error', onError );
  57. request.addEventListener( 'progress', event => {
  58. if ( !event ) return;
  59. const { loaded, total, lengthComputable } = event;
  60. if ( lengthComputable ) {
  61. onProgress( { loaded, total } );
  62. }
  63. } );
  64. request.addEventListener( 'loadend', event => {
  65. if ( !event ) return;
  66. const { currentTarget: { response } } = event;
  67. arrayBufferView = new Uint8Array( response );
  68. blob = new window.Blob( [ arrayBufferView ] );
  69. image.addEventListener( 'load', onImageLoaded, false );
  70. image.src = urlCreator.createObjectURL( blob );
  71. } );
  72. request.send(null);
  73. }
  74. };
  75. export { ImageLoader };