選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

asset-manager.js 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /**
  2. * An Asset Manager for AR
  3. * @author Alexandre Martins <alemartf(at)gmail.com> (https://github.com/alemart/encantar-js)
  4. * @license LGPL-3.0-or-later
  5. */
  6. /**
  7. * The Asset Manager is used to preload resources (models, textures, etc.)
  8. * You'll typically preload resources before starting the AR session
  9. */
  10. class AssetManager
  11. {
  12. /**
  13. * Get an object URL corresponding to a preloaded asset
  14. * @param {string} filename
  15. * @returns {string}
  16. * @throws Throws an error if the asset has not been successfully preloaded
  17. */
  18. url(filename)
  19. {
  20. return this._get(filename).url;
  21. }
  22. /**
  23. * Get a File corresponding to a preloaded asset
  24. * @param {string} filename
  25. * @returns {File}
  26. * @throws Throws an error if the asset has not been successfully preloaded
  27. */
  28. file(filename)
  29. {
  30. return this._get(filename).file;
  31. }
  32. /**
  33. * Check if an asset has been preloaded successfully
  34. * @param {string} filename
  35. * @returns {boolean}
  36. */
  37. has(filename)
  38. {
  39. return this._assetMap.has(filename);
  40. }
  41. /**
  42. * Preload one or more assets
  43. * @param {string|string[]} url URL(s) of the asset(s)
  44. * @returns {Promise<void>}
  45. */
  46. preload(url)
  47. {
  48. if(Array.isArray(url))
  49. return Promise.all(url.map(url => this.preload(url)));
  50. if(typeof url != 'string')
  51. return Promise.reject(new TypeError());
  52. const filename = url.substring(1 + url.lastIndexOf('/'));
  53. if(this._assetMap.has(filename))
  54. return Promise.resolve();
  55. return new Promise(resolve => {
  56. fetch(url)
  57. .then(response => {
  58. if(!response.ok)
  59. throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  60. return response.blob();
  61. })
  62. .then(blob => {
  63. const file = new File([ blob ], filename, { type: blob.type });
  64. const url = URL.createObjectURL(file);
  65. const asset = { file, url };
  66. this._assetMap.set(filename, asset);
  67. })
  68. .catch(error => {
  69. console.warn(`Can't preload asset "${filename}"! ${error.message} (${url})`);
  70. })
  71. .finally(resolve);
  72. });
  73. }
  74. /**
  75. * Get a preloaded asset
  76. * @param {string} filename
  77. * @returns {object}
  78. * @throws {Error}
  79. * @internal
  80. */
  81. _get(filename)
  82. {
  83. const asset = this._assetMap.get(filename);
  84. if(!asset)
  85. throw new Error(`Asset "${filename}" has not been preloaded!`);
  86. return asset;
  87. }
  88. /**
  89. * Constructor
  90. */
  91. constructor()
  92. {
  93. this._assetMap = new Map();
  94. }
  95. }