diff --git a/blocks/CloudImageEditor/src/EditorImageCropper.js b/blocks/CloudImageEditor/src/EditorImageCropper.js index afc978577..eb8d89d36 100644 --- a/blocks/CloudImageEditor/src/EditorImageCropper.js +++ b/blocks/CloudImageEditor/src/EditorImageCropper.js @@ -3,7 +3,14 @@ import { debounce } from '../../utils/debounce.js'; import { throttle } from '../../utils/throttle.js'; import { CloudImageEditorBase } from './CloudImageEditorBase.js'; -import { clamp, constraintRect, isRectInsideRect, rotateSize, roundRect } from './crop-utils.js'; +import { + clamp, + constraintRect, + isRectInsideRect, + isRectMatchesAspectRatio, + rotateSize, + roundRect, +} from './crop-utils.js'; import { CROP_PADDING } from './cropper-constants.js'; import { classNames } from './lib/classNames.js'; import { pick } from './lib/pick.js'; @@ -181,18 +188,22 @@ export class EditorImageCropper extends CloudImageEditorBase { ); } - if (!cropTransformation || !isRectInsideRect(cropBox, imageBox)) { - /** @type {import('./types.js').CropPresetList[0]} */ - const cropPreset = this.$['*cropPresetList']?.[0]; - const cropRatio = cropPreset ? cropPreset.width / cropPreset.height : undefined; - const ratio = imageBox.width / imageBox.height; + /** @type {import('./types.js').CropPresetList[0] | undefined} */ + const cropPreset = this.$['*cropPresetList']?.[0]; + const cropAspectRatio = cropPreset ? cropPreset.width / cropPreset.height : undefined; + + if ( + !isRectInsideRect(cropBox, imageBox) || + (cropAspectRatio && !isRectMatchesAspectRatio(cropBox, cropAspectRatio)) + ) { + const imageAspectRatio = imageBox.width / imageBox.height; let width = imageBox.width; let height = imageBox.height; - if (cropRatio) { - if (ratio > cropRatio) { - width = Math.min(imageBox.height * cropRatio, imageBox.width); + if (cropAspectRatio) { + if (imageAspectRatio > cropAspectRatio) { + width = Math.min(imageBox.height * cropAspectRatio, imageBox.width); } else { - height = Math.min(imageBox.width / cropRatio, imageBox.height); + height = Math.min(imageBox.width / cropAspectRatio, imageBox.height); } } cropBox = { diff --git a/blocks/CloudImageEditor/src/crop-utils.js b/blocks/CloudImageEditor/src/crop-utils.js index 200c87afc..f58f9bf22 100644 --- a/blocks/CloudImageEditor/src/crop-utils.js +++ b/blocks/CloudImageEditor/src/crop-utils.js @@ -656,6 +656,15 @@ export function isRectInsideRect(rect1, rect2) { ); } +/** + * @param {import('./types.js').Rectangle} rect + * @param {number} aspectRatio + */ +export function isRectMatchesAspectRatio(rect, aspectRatio) { + const THRESHOLD = 0.1; + return Math.abs(rect.width / rect.height - aspectRatio) < THRESHOLD; +} + /** * @param {import('./types.js').ImageSize} imageSize * @param {Number} angle diff --git a/blocks/CloudImageEditorActivity/CloudImageEditorActivity.js b/blocks/CloudImageEditorActivity/CloudImageEditorActivity.js index 14bf0433b..1a23093b0 100644 --- a/blocks/CloudImageEditorActivity/CloudImageEditorActivity.js +++ b/blocks/CloudImageEditorActivity/CloudImageEditorActivity.js @@ -1,3 +1,4 @@ +// @ts-check import { ActivityBlock } from '../../abstract/ActivityBlock.js'; import { UploaderBlock } from '../../abstract/UploaderBlock.js'; import { CloudImageEditorBlock } from '../CloudImageEditor/index.js'; @@ -5,10 +6,14 @@ import { CloudImageEditorBlock } from '../CloudImageEditor/index.js'; export class CloudImageEditorActivity extends UploaderBlock { activityType = ActivityBlock.activities.CLOUD_IMG_EDIT; - init$ = { - ...this.init$, - cdnUrl: null, - }; + constructor() { + super(); + + this.init$ = { + ...this.init$, + cdnUrl: null, + }; + } initCallback() { super.initCallback(); @@ -30,10 +35,25 @@ export class CloudImageEditorActivity extends UploaderBlock { } }); }); + + this.subConfigValue('cropPreset', (cropPreset) => { + if (this._instance && this._instance.getAttribute('crop-preset') !== cropPreset) { + this._instance.setAttribute('crop-preset', cropPreset); + } + }); + + this.subConfigValue('cloudImageEditorTabs', (tabs) => { + if (this._instance && this._instance.getAttribute('tabs') !== tabs) { + this._instance.setAttribute('tabs', tabs); + } + }); } - /** @param {CustomEvent} e */ + /** @param {CustomEvent} e */ handleApply(e) { + if (!this.entry) { + return; + } let result = e.detail; this.entry.setMultipleValues({ cdnUrl: result.cdnUrl, @@ -62,14 +82,21 @@ export class CloudImageEditorActivity extends UploaderBlock { instance.setAttribute('tabs', tabs); } - instance.addEventListener('apply', (result) => this.handleApply(result)); + instance.addEventListener('apply', (result) => + this.handleApply(/** @type {CustomEvent} */ (result)) + ); instance.addEventListener('cancel', () => this.handleCancel()); this.innerHTML = ''; this.appendChild(instance); + this._mounted = true; + + /** @private */ + this._instance = instance; } unmountEditor() { + this._instance = undefined; this.innerHTML = ''; } } diff --git a/blocks/test/raw-regular.htm b/blocks/test/raw-regular.htm index 12057f945..28ed61086 100644 --- a/blocks/test/raw-regular.htm +++ b/blocks/test/raw-regular.htm @@ -30,5 +30,5 @@ - + \ No newline at end of file