vis.js is a dynamic, browser-based visualization library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
3.9 KiB

  1. import CachedImage from './CachedImage';
  2. /**
  3. * This class loads images and keeps them stored.
  4. * class Images
  5. */
  6. class Images {
  7. /**
  8. * Create a Images
  9. * @callback callback
  10. * @param {function} callback
  11. * @constructor Images
  12. */
  13. constructor(callback){
  14. this.images = {};
  15. this.imageBroken = {};
  16. this.callback = callback;
  17. }
  18. /**
  19. * @param {string} url The original Url that failed to load, if the broken image is successfully loaded it will be added to the cache using this Url as the key so that subsequent requests for this Url will return the broken image
  20. * @param {string} brokenUrl Url the broken image to try and load
  21. * @param {Image} imageToLoadBrokenUrlOn The image object
  22. */
  23. _tryloadBrokenUrl (url, brokenUrl, imageToLoadBrokenUrlOn) {
  24. //If these parameters aren't specified then exit the function because nothing constructive can be done
  25. if (url === undefined || imageToLoadBrokenUrlOn === undefined) return;
  26. if (brokenUrl === undefined) {
  27. console.warn("No broken url image defined");
  28. return;
  29. }
  30. //Clear the old subscription to the error event and put a new in place that only handle errors in loading the brokenImageUrl
  31. imageToLoadBrokenUrlOn.onerror = () => {
  32. console.error("Could not load brokenImage:", brokenUrl);
  33. // cache item will contain empty image, this should be OK for default
  34. };
  35. //Set the source of the image to the brokenUrl, this is actually what kicks off the loading of the broken image
  36. imageToLoadBrokenUrlOn.image.src = brokenUrl;
  37. }
  38. /**
  39. *
  40. * @param {vis.Image} imageToRedrawWith
  41. * @private
  42. */
  43. _redrawWithImage (imageToRedrawWith) {
  44. if (this.callback) {
  45. this.callback(imageToRedrawWith);
  46. }
  47. }
  48. /**
  49. * @param {string} url Url of the image
  50. * @param {string} brokenUrl Url of an image to use if the url image is not found
  51. * @return {Image} img The image object
  52. */
  53. load (url, brokenUrl) {
  54. //Try and get the image from the cache, if successful then return the cached image
  55. var cachedImage = this.images[url];
  56. if (cachedImage) return cachedImage;
  57. //Create a new image
  58. var img = new CachedImage();
  59. // Need to add to cache here, otherwise final return will spawn different copies of the same image,
  60. // Also, there will be multiple loads of the same image.
  61. this.images[url] = img;
  62. //Subscribe to the event that is raised if the image loads successfully
  63. img.image.onload = () => {
  64. // Properly init the cached item and then request a redraw
  65. this._fixImageCoordinates(img.image);
  66. img.init();
  67. this._redrawWithImage(img);
  68. };
  69. //Subscribe to the event that is raised if the image fails to load
  70. img.image.onerror = () => {
  71. console.error("Could not load image:", url);
  72. //Try and load the image specified by the brokenUrl using
  73. this._tryloadBrokenUrl(url, brokenUrl, img);
  74. };
  75. //Set the source of the image to the url, this is what actually kicks off the loading of the image
  76. img.image.src = url;
  77. //Return the new image
  78. return img;
  79. }
  80. /**
  81. * IE11 fix -- thanks dponch!
  82. *
  83. * Local helper function
  84. * @param {vis.Image} imageToCache
  85. * @private
  86. */
  87. _fixImageCoordinates(imageToCache) {
  88. if (imageToCache.width === 0) {
  89. document.body.appendChild(imageToCache);
  90. imageToCache.width = imageToCache.offsetWidth;
  91. imageToCache.height = imageToCache.offsetHeight;
  92. document.body.removeChild(imageToCache);
  93. }
  94. }
  95. }
  96. export default Images;