Skip to content

Commit

Permalink
Fix(web): Recalculate FileUploader image preview by crop values
Browse files Browse the repository at this point in the history
  * 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
  • Loading branch information
literat committed Nov 2, 2023
1 parent e07eb5a commit 1e23f86
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 15 deletions.
4 changes: 2 additions & 2 deletions apps/web-twig-demo/assets/scripts/file-uploader-meta-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
38 changes: 30 additions & 8 deletions packages/web/src/js/FileUploader.ts
Original file line number Diff line number Diff line change
@@ -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}`;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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(
Expand All @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions packages/web/src/scss/components/FileUploader/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
Expand Down
6 changes: 3 additions & 3 deletions packages/web/src/scss/components/FileUploader/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ <h3 id="attachments-fileUploaderWithMetaData" hidden>Attachments</h3>

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);
Expand All @@ -954,7 +954,7 @@ <h3 id="attachments-fileUploaderWithMetaData" hidden>Attachments</h3>
}

CancelButton.addEventListener('click', removeFromQueue);

FileUploaderElement.addEventListener('queuedFile.fileUploader', event => {
file = event.currentFile;

Expand All @@ -964,7 +964,7 @@ <h3 id="attachments-fileUploaderWithMetaData" hidden>Attachments</h3>
FileUploaderElement.addEventListener('unqueuedFile.fileUploader', (event) => {
callbackOnDismiss(event.currentFile);
});

FileUploaderElement.addEventListener('editFile.fileUploader', (event) => {
customEdit(event.currentFile);
});
Expand Down

0 comments on commit 1e23f86

Please sign in to comment.