From 1e23f8625f9603b25192191bb31c43ebb353d618 Mon Sep 17 00:00:00 2001 From: literat Date: Wed, 1 Nov 2023 14:36:05 +0100 Subject: [PATCH] Fix(web): Recalculate FileUploader image preview by crop values * need to use additional dimensions - natural width and height to calculate dimensions of previewed image * also need to better calculate the scale of the entire image and also position when we need to display the possible crop refs #DS-1038 --- .../assets/scripts/file-uploader-meta-data.ts | 4 +- packages/web/src/js/FileUploader.ts | 38 +++++++++++++++---- .../scss/components/FileUploader/README.md | 4 +- .../scss/components/FileUploader/index.html | 6 +-- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/apps/web-twig-demo/assets/scripts/file-uploader-meta-data.ts b/apps/web-twig-demo/assets/scripts/file-uploader-meta-data.ts index 223762bd6b..586e006c1e 100644 --- a/apps/web-twig-demo/assets/scripts/file-uploader-meta-data.ts +++ b/apps/web-twig-demo/assets/scripts/file-uploader-meta-data.ts @@ -69,8 +69,8 @@ window.addEventListener('DOMContentLoaded', () => { const customEdit = (event) => { const key = event.target.closest('li').id; const newMeta = toggleMetaData - ? { x: 30, y: 30, width: 150, height: 150 } - : { x: 22, y: 0, width: 110, height: 100 }; + ? { x: 30, y: 30, cropWidth: 150, cropHeight: 150, originalWidth: 560, originalHeight: 330 } + : { x: 22, y: 0, cropWidth: 110, cropHeight: 100, originalWidth: 560, originalHeight: 330 }; toggleMetaData = !toggleMetaData; const file = FileUploaderInstance.getFileFromQueue(key).file; FileUploaderInstance.updateQueue(key, file, newMeta, updateQueueCallback); diff --git a/packages/web/src/js/FileUploader.ts b/packages/web/src/js/FileUploader.ts index 7b6b15007e..03350d7355 100644 --- a/packages/web/src/js/FileUploader.ts +++ b/packages/web/src/js/FileUploader.ts @@ -1,6 +1,6 @@ -import { EventHandler, SelectorEngine } from './dom'; import BaseComponent from './BaseComponent'; -import { image2Base64Preview, enableToggleAutoloader } from './utils'; +import { EventHandler, SelectorEngine } from './dom'; +import { enableToggleAutoloader, image2Base64Preview } from './utils'; const NAME = 'fileUploader'; const EVENT_KEY = `.${NAME}`; @@ -31,6 +31,8 @@ const DEFAULT_ERROR_MESSAGES = { errorMaxUploadedFiles: 'You have exceeded the number of files allowed in the queue', errorFileNotSupported: 'is not a supported file. Please ensure you are uploading a supported file format.', }; +const IMAGE_PREVIEW_HEIGHT = 54; // px; @see: CSS class `.FileUploaderAttachment__image` in _FileUploaderAttachment.scss +const IMAGE_PREVIEW_BASE64_MAX_WIDTH = 500; // px export interface FileMetadata { [key: string | number]: unknown; @@ -367,7 +369,9 @@ class FileUploader extends BaseComponent { } static isCoordsInMeta = (meta: FileMetadata) => { - return ['x', 'y', 'width', 'height'].every((coord) => meta[coord] != null); + return ['x', 'y', 'cropWidth', 'cropHeight', 'originalWidth', 'originalHeight'].every( + (coord) => meta[coord] != null, + ); }; updateQueue( @@ -384,16 +388,34 @@ class FileUploader extends BaseComponent { this.fileQueue.set(name, newValue); - const itemImgElement = SelectorEngine.findOne(`#${name} .FileUploaderAttachment__image img`); + const itemImgElement = SelectorEngine.findOne(`#${name} .FileUploaderAttachment__image img`) as HTMLImageElement; const itemImageObjectFit = itemImgElement?.dataset?.spiritImageObjectFit; let cropStyles; if (meta && itemImgElement && FileUploader.isCoordsInMeta(meta)) { + const previewHeight = IMAGE_PREVIEW_HEIGHT; + const cropWidth = parseInt(meta.cropWidth as string, 10); + const cropHeight = parseInt(meta.cropHeight as string, 10); + + let scale; + if (cropHeight > cropWidth) { + // scale for portrait images + scale = previewHeight / cropWidth; + } else { + // scale for landscape images + scale = previewHeight / cropHeight; + } + + const cropX = Math.round(parseInt(meta.x as string, 10) * scale); + const cropY = Math.round(parseInt(meta.y as string, 10) * scale); + const imageWidth = Math.round(parseInt(meta.originalWidth as string, 10) * scale); + const imageHeight = Math.round(parseInt(meta.originalHeight as string, 10) * scale); + cropStyles = ` - --file-uploader-attachment-image-top: -${meta.y}px; - --file-uploader-attachment-image-left: -${meta.x}px; - --file-uploader-attachment-image-width: ${meta.width}px; - --file-uploader-attachment-image-height: ${meta.height}px; + --file-uploader-attachment-image-top: -${cropY}px; + --file-uploader-attachment-image-left: -${cropX}px; + --file-uploader-attachment-image-width: ${imageWidth}px; + --file-uploader-attachment-image-height: ${imageHeight}px; `; if (itemImageObjectFit) { diff --git a/packages/web/src/scss/components/FileUploader/README.md b/packages/web/src/scss/components/FileUploader/README.md index f024a55996..b2a5d6aa28 100644 --- a/packages/web/src/scss/components/FileUploader/README.md +++ b/packages/web/src/scss/components/FileUploader/README.md @@ -485,12 +485,12 @@ const customUpdate = (_event: MouseEvent, file: File) => { #### Updating Image Preview with cropped image When you are using FileUploader with some kind of image cropper you want to also update the image preview on FileUploader attachment when image changes. -You can do this by passing a specific object in shape of coordinates (`{ x: number, y: number, width: number, height: number }`) to the `meta` argument. +You can do this by passing a specific object in shape of coordinates (`{ x: number, y: number, cropWidth: number, cropHeight: number, originalWidth: number, originalHeight: number }`) to the `meta` argument. Then the coordinates will be applied to the preview image in the attachment. ```javascript const customUpdate = (event: MouseEvent, file: File) => { - const meta = { x: 30, y: 30, width: 150, height: 150 }; + const meta = { x: 30, y: 30, cropWidth: 150, cropHeight: 150, originalWidth: 560, originalHeight: 330 }; return FileUploader.updateQueue(file.name, file, meta); }; diff --git a/packages/web/src/scss/components/FileUploader/index.html b/packages/web/src/scss/components/FileUploader/index.html index bd615cc17e..614667d65c 100644 --- a/packages/web/src/scss/components/FileUploader/index.html +++ b/packages/web/src/scss/components/FileUploader/index.html @@ -933,7 +933,7 @@ const customEdit = (event) => { const key = event.target.closest('li').id - const newMeta = toggleMetaData ? { x: 30, y: 30, width: 150, height: 150 } : { x: 22, y: 0, width: 110, height: 100 }; + const newMeta = toggleMetaData ? { x: 30, y: 30, cropWidth: 150, cropHeight: 150, originalWidth: 560, originalHeight: 330 } : { x: 22, y: 0, cropWidth: 110, cropHeight: 100, originalWidth: 560, originalHeight: 330 }; toggleMetaData = !toggleMetaData; const file = FileUploaderInstance.getFileFromQueue(key).file; FileUploaderInstance.updateQueue(key, file, newMeta, updateQueueCallback); @@ -954,7 +954,7 @@ } CancelButton.addEventListener('click', removeFromQueue); - + FileUploaderElement.addEventListener('queuedFile.fileUploader', event => { file = event.currentFile; @@ -964,7 +964,7 @@ FileUploaderElement.addEventListener('unqueuedFile.fileUploader', (event) => { callbackOnDismiss(event.currentFile); }); - + FileUploaderElement.addEventListener('editFile.fileUploader', (event) => { customEdit(event.currentFile); });