From 7ac4d154b4d4a96d9650777a138ea0d8a105f736 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 25 Sep 2024 14:40:58 +0200 Subject: [PATCH] feat: add maxWidth to imageSize function --- .../core/utils/media/image-size.function.ts | 43 +++++++++++++------ .../extensions/umb/media-upload.extension.ts | 8 +--- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/media/image-size.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/media/image-size.function.ts index cbd93b58fe..8958da1c0b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/media/image-size.function.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/media/image-size.function.ts @@ -1,25 +1,40 @@ /** * Get the dimensions of an image from a URL. * @param {string} url The URL of the image. It can be a local file (blob url) or a remote file. - * @returns {Promise<{width: number, height: number}>} The width and height of the image as downloaded from the URL. + * @param {{maxWidth?: number}} opts Options for the image size. + * @param {number} opts.maxWidth The maximum width of the image. If the image is wider than this, it will be scaled down to this width while keeping the aspect ratio. + * @returns {Promise<{width: number, height: number, naturalWidth: number, naturalHeight: number}>} The width and height of the image as downloaded from the URL. The width and height can differ from the natural numbers if maxImageWidth is given. */ -export function imageSize(url: string): Promise<{ width: number; height: number }> { +export function imageSize( + url: string, + opts?: { maxWidth?: number }, +): Promise<{ width: number; height: number; naturalWidth: number; naturalHeight: number }> { const img = new Image(); - const promise = new Promise<{ width: number; height: number }>((resolve, reject) => { - img.onload = () => { - // Natural size is the actual image size regardless of rendering. - // The 'normal' `width`/`height` are for the **rendered** size. - const width = img.naturalWidth; - const height = img.naturalHeight; + const promise = new Promise<{ width: number; height: number; naturalWidth: number; naturalHeight: number }>( + (resolve, reject) => { + img.onload = () => { + // Natural size is the actual image size regardless of rendering. + // The 'normal' `width`/`height` are for the **rendered** size. + const naturalWidth = img.naturalWidth; + const naturalHeight = img.naturalHeight; + let width = naturalWidth; + let height = naturalHeight; - // Resolve promise with the width and height - resolve({ width, height }); - }; + if (opts?.maxWidth && opts.maxWidth > 0 && width > opts?.maxWidth) { + const ratio = opts.maxWidth / naturalWidth; + width = opts.maxWidth; + height = Math.round(naturalHeight * ratio); + } - // Reject promise on error - img.onerror = reject; - }); + // Resolve promise with the width and height + resolve({ width, height, naturalWidth, naturalHeight }); + }; + + // Reject promise on error + img.onerror = reject; + }, + ); // Setting the source makes it start downloading and eventually call `onload` img.src = url; diff --git a/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/extensions/umb/media-upload.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/extensions/umb/media-upload.extension.ts index ec9e7cfd5d..2cfd79dca1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/extensions/umb/media-upload.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/extensions/umb/media-upload.extension.ts @@ -99,13 +99,7 @@ export default class UmbTiptapMediaUploadExtension extends UmbTiptapExtensionApi return; } - let { width, height } = await imageSize(URL.createObjectURL(upload.file)); - - if (maxImageSize > 0 && width > maxImageSize) { - const ratio = maxImageSize / width; - width = maxImageSize; - height = Math.round(height * ratio); - } + const { width, height } = await imageSize(URL.createObjectURL(upload.file), { maxWidth: maxImageSize }); editor .chain()