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.

functions.ts 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. let filterSupport: boolean | undefined;
  2. /**
  3. * Checks context filter support.
  4. *
  5. * @returns {boolean} True if the filter is supported and false if the filter is not supported by the browser.
  6. */
  7. export function checkBlurSupport() {
  8. if (typeof filterSupport === 'undefined') {
  9. const canvas = document.createElement('canvas');
  10. const ctx = canvas.getContext('2d');
  11. filterSupport = typeof ctx?.filter !== 'undefined';
  12. canvas.remove();
  13. }
  14. return filterSupport;
  15. }
  16. /**
  17. * Convert blob to base64.
  18. *
  19. * @param {Blob} blob - The link to add info with.
  20. * @returns {Promise<string>}
  21. */
  22. export const blobToData = (blob: Blob) =>
  23. new Promise(resolve => {
  24. const reader = new FileReader();
  25. reader.onloadend = () => resolve(reader.result?.toString());
  26. reader.readAsDataURL(blob);
  27. });
  28. /**
  29. * Convert blob to base64.
  30. *
  31. * @param {string} url - The image url.
  32. * @returns {Object} - Returns the converted blob to base64.
  33. */
  34. export const toDataURL = async (url: string) => {
  35. const response = await fetch(url);
  36. const blob = await response.blob();
  37. const resData = await blobToData(blob);
  38. return resData;
  39. };
  40. /**
  41. * Resize image and adjust original aspect ratio.
  42. *
  43. * @param {Object} base64image - Base64 image extraction.
  44. * @param {number} width - Value for resizing the image width.
  45. * @param {number} height - Value for resizing the image height.
  46. * @returns {Promise<string>}
  47. *
  48. */
  49. export function resizeImage(base64image: any, width = 1920, height = 1080): Promise<string> {
  50. // In order to work on Firefox browser we need to handle the asynchronous nature of image loading; We need to use
  51. // a promise mechanism. The reason why it 'works' without this mechanism in Chrome is actually 'by accident' because
  52. // the image happens to be in the cache and the browser is able to deliver the uncompressed/decoded image
  53. // before using the image in the drawImage call.
  54. return new Promise(resolve => {
  55. const img = document.createElement('img');
  56. img.onload = function() {
  57. // Create an off-screen canvas.
  58. const canvas = document.createElement('canvas');
  59. // Set its dimension to target size.
  60. const context = canvas.getContext('2d');
  61. canvas.width = width;
  62. canvas.height = height;
  63. // Draw source image into the off-screen canvas.
  64. // TODO: keep aspect ratio and implement object-fit: cover.
  65. context?.drawImage(img as any, 0, 0, width, height);
  66. // Encode image to data-uri with base64 version of compressed image.
  67. resolve(canvas.toDataURL('image/jpeg', 0.5));
  68. };
  69. img.src = base64image;
  70. });
  71. }
  72. /**
  73. * Creating a wrapper for promises on a specific time interval.
  74. *
  75. * @param {number} milliseconds - The number of milliseconds to wait the specified
  76. * {@code promise} to settle before automatically rejecting the returned
  77. * {@code Promise}.
  78. * @param {Promise} promise - The {@code Promise} for which automatic rejecting
  79. * after the specified timeout is to be implemented.
  80. * @returns {Promise}
  81. */
  82. export function timeout(milliseconds: number, promise: Promise<any>): Promise<Object> {
  83. return new Promise((resolve, reject) => {
  84. setTimeout(() => {
  85. reject(new Error('408'));
  86. return;
  87. }, milliseconds);
  88. promise.then(resolve, reject);
  89. });
  90. }