imagePreloader.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. import { isSafari } from './common';
  2. import createNS from './helpers/svg_elements';
  3. import dataManager from './DataManager';
  4. import createTag from './helpers/html_elements';
  5. const ImagePreloader = (function () {
  6. var proxyImage = (function () {
  7. var canvas = createTag('canvas');
  8. canvas.width = 1;
  9. canvas.height = 1;
  10. var ctx = canvas.getContext('2d');
  11. ctx.fillStyle = 'rgba(0,0,0,0)';
  12. ctx.fillRect(0, 0, 1, 1);
  13. return canvas;
  14. }());
  15. function imageLoaded() {
  16. this.loadedAssets += 1;
  17. if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
  18. if (this.imagesLoadedCb) {
  19. this.imagesLoadedCb(null);
  20. }
  21. }
  22. }
  23. function footageLoaded() {
  24. this.loadedFootagesCount += 1;
  25. if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
  26. if (this.imagesLoadedCb) {
  27. this.imagesLoadedCb(null);
  28. }
  29. }
  30. }
  31. function getAssetsPath(assetData, assetsPath, originalPath) {
  32. var path = '';
  33. if (assetData.e) {
  34. path = assetData.p;
  35. } else if (assetsPath) {
  36. var imagePath = assetData.p;
  37. if (imagePath.indexOf('images/') !== -1) {
  38. imagePath = imagePath.split('/')[1];
  39. }
  40. path = assetsPath + imagePath;
  41. } else {
  42. path = originalPath;
  43. path += assetData.u ? assetData.u : '';
  44. path += assetData.p;
  45. }
  46. return path;
  47. }
  48. function testImageLoaded(img) {
  49. var _count = 0;
  50. var intervalId = setInterval(function () {
  51. var box = img.getBBox();
  52. if (box.width || _count > 500) {
  53. this._imageLoaded();
  54. clearInterval(intervalId);
  55. }
  56. _count += 1;
  57. }.bind(this), 50);
  58. }
  59. function createImageData(assetData) {
  60. var path = getAssetsPath(assetData, this.assetsPath, this.path);
  61. var img = createNS('image');
  62. if (isSafari) {
  63. this.testImageLoaded(img);
  64. } else {
  65. img.addEventListener('load', this._imageLoaded, false);
  66. }
  67. img.addEventListener('error', function () {
  68. ob.img = proxyImage;
  69. this._imageLoaded();
  70. }.bind(this), false);
  71. img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
  72. if (this._elementHelper.append) {
  73. this._elementHelper.append(img);
  74. } else {
  75. this._elementHelper.appendChild(img);
  76. }
  77. var ob = {
  78. img: img,
  79. assetData: assetData,
  80. };
  81. return ob;
  82. }
  83. function createImgData(assetData) {
  84. var path = getAssetsPath(assetData, this.assetsPath, this.path);
  85. var img = createTag('img');
  86. img.crossOrigin = 'anonymous';
  87. img.addEventListener('load', this._imageLoaded, false);
  88. img.addEventListener('error', function () {
  89. ob.img = proxyImage;
  90. this._imageLoaded();
  91. }.bind(this), false);
  92. img.src = path;
  93. var ob = {
  94. img: img,
  95. assetData: assetData,
  96. };
  97. return ob;
  98. }
  99. function createFootageData(data) {
  100. var ob = {
  101. assetData: data,
  102. };
  103. var path = getAssetsPath(data, this.assetsPath, this.path);
  104. dataManager.loadData(path, function (footageData) {
  105. ob.img = footageData;
  106. this._footageLoaded();
  107. }.bind(this), function () {
  108. ob.img = {};
  109. this._footageLoaded();
  110. }.bind(this));
  111. return ob;
  112. }
  113. function loadAssets(assets, cb) {
  114. this.imagesLoadedCb = cb;
  115. var i;
  116. var len = assets.length;
  117. for (i = 0; i < len; i += 1) {
  118. if (!assets[i].layers) {
  119. if (!assets[i].t || assets[i].t === 'seq') {
  120. this.totalImages += 1;
  121. this.images.push(this._createImageData(assets[i]));
  122. } else if (assets[i].t === 3) {
  123. this.totalFootages += 1;
  124. this.images.push(this.createFootageData(assets[i]));
  125. }
  126. }
  127. }
  128. }
  129. function setPath(path) {
  130. this.path = path || '';
  131. }
  132. function setAssetsPath(path) {
  133. this.assetsPath = path || '';
  134. }
  135. function getAsset(assetData) {
  136. var i = 0;
  137. var len = this.images.length;
  138. while (i < len) {
  139. if (this.images[i].assetData === assetData) {
  140. return this.images[i].img;
  141. }
  142. i += 1;
  143. }
  144. return null;
  145. }
  146. function destroy() {
  147. this.imagesLoadedCb = null;
  148. this.images.length = 0;
  149. }
  150. function loadedImages() {
  151. return this.totalImages === this.loadedAssets;
  152. }
  153. function loadedFootages() {
  154. return this.totalFootages === this.loadedFootagesCount;
  155. }
  156. function setCacheType(type, elementHelper) {
  157. if (type === 'svg') {
  158. this._elementHelper = elementHelper;
  159. this._createImageData = this.createImageData.bind(this);
  160. } else {
  161. this._createImageData = this.createImgData.bind(this);
  162. }
  163. }
  164. function ImagePreloaderFactory() {
  165. this._imageLoaded = imageLoaded.bind(this);
  166. this._footageLoaded = footageLoaded.bind(this);
  167. this.testImageLoaded = testImageLoaded.bind(this);
  168. this.createFootageData = createFootageData.bind(this);
  169. this.assetsPath = '';
  170. this.path = '';
  171. this.totalImages = 0;
  172. this.totalFootages = 0;
  173. this.loadedAssets = 0;
  174. this.loadedFootagesCount = 0;
  175. this.imagesLoadedCb = null;
  176. this.images = [];
  177. }
  178. ImagePreloaderFactory.prototype = {
  179. loadAssets: loadAssets,
  180. setAssetsPath: setAssetsPath,
  181. setPath: setPath,
  182. loadedImages: loadedImages,
  183. loadedFootages: loadedFootages,
  184. destroy: destroy,
  185. getAsset: getAsset,
  186. createImgData: createImgData,
  187. createImageData: createImageData,
  188. imageLoaded: imageLoaded,
  189. footageLoaded: footageLoaded,
  190. setCacheType: setCacheType,
  191. };
  192. return ImagePreloaderFactory;
  193. }());
  194. export default ImagePreloader;