From: Alexander Ebert Date: Thu, 19 Dec 2024 19:14:42 +0000 (+0100) Subject: Reverse the event logic X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=3285e2e3a0de61ffbe9ffa76fdd4834a0ce4ab35;p=GitHub%2FWoltLab%2FWCF.git Reverse the event logic This also avoids calling into `$moveTo` from within the `change` event which could cause a nasty loop. --- diff --git a/ts/WoltLabSuite/Core/Component/Image/Cropper.ts b/ts/WoltLabSuite/Core/Component/Image/Cropper.ts index 85d8319da6..3b230dc3e6 100644 --- a/ts/WoltLabSuite/Core/Component/Image/Cropper.ts +++ b/ts/WoltLabSuite/Core/Component/Image/Cropper.ts @@ -200,35 +200,11 @@ abstract class ImageCropper { this.centerSelection(); - // Limit the selection to the canvas boundaries - this.cropperSelection!.addEventListener("change", (event: CustomEvent) => { - // see https://fengyuanchen.github.io/cropperjs/v2/api/cropper-selection.html#limit-boundaries - const cropperCanvasRect = this.cropperCanvas!.getBoundingClientRect(); - const selection = event.detail as Selection; - - const maxSelection: Selection = { - x: 0, - y: 0, - width: cropperCanvasRect.width, - height: cropperCanvasRect.height, - }; - - if (!inSelection(selection, maxSelection)) { - event.preventDefault(); - - // Try to clamp the position to the boundaries. - this.cropperSelection!.$moveTo( - clampValue(selection.x, selection.width, maxSelection.width), - clampValue(selection.y, selection.height, maxSelection.height), - ); - } - }); - - // Limit the selection to the min/max size this.cropperSelection!.addEventListener("change", (event: CustomEvent) => { const selection = event.detail as Selection; this.cropperCanvasRect = this.cropperCanvas!.getBoundingClientRect(); + // Limit the selection to the min/max size. const selectionRatio = Math.min( this.cropperCanvasRect.width / this.width, this.cropperCanvasRect.height / this.height, @@ -246,6 +222,33 @@ abstract class ImageCropper { if (width < minWidth || height < minHeight || width > maxWidth || height > maxHeight) { event.preventDefault(); + + // Stop the event handling here otherwise the following code would try + // to adjust the position on an invalid size that could potentially + // violate the boundaries. + return; + } + + // Limit the selection to the canvas boundaries. + // see https://fengyuanchen.github.io/cropperjs/v2/api/cropper-selection.html#limit-boundaries + const maxSelection: Selection = { + x: 0, + y: 0, + width: this.cropperCanvasRect!.width, + height: this.cropperCanvasRect!.height, + }; + + if (!inSelection(selection, maxSelection)) { + event.preventDefault(); + + // Clamp the position to the boundaries of the canvas. + this.cropperSelection!.x = clampValue(selection.x, selection.width, maxSelection.width); + this.cropperSelection!.y = clampValue(selection.y, selection.height, maxSelection.height); + + this.cropperSelection!.width = selection.width; + this.cropperSelection!.height = selection.height; + + this.cropperSelection!.$render(); } }); } diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Image/Cropper.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Image/Cropper.js index 6f209bc62d..28648311ed 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Image/Cropper.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Image/Cropper.js @@ -150,27 +150,10 @@ define(["require", "exports", "tslib", "WoltLabSuite/Core/Image/Resizer", "WoltL this.cropperImage.$rotate(`${this.orientation}deg`); } this.centerSelection(); - // Limit the selection to the canvas boundaries - this.cropperSelection.addEventListener("change", (event) => { - // see https://fengyuanchen.github.io/cropperjs/v2/api/cropper-selection.html#limit-boundaries - const cropperCanvasRect = this.cropperCanvas.getBoundingClientRect(); - const selection = event.detail; - const maxSelection = { - x: 0, - y: 0, - width: cropperCanvasRect.width, - height: cropperCanvasRect.height, - }; - if (!inSelection(selection, maxSelection)) { - event.preventDefault(); - // Try to clamp the position to the boundaries. - this.cropperSelection.$moveTo(clampValue(selection.x, selection.width, maxSelection.width), clampValue(selection.y, selection.height, maxSelection.height)); - } - }); - // Limit the selection to the min/max size this.cropperSelection.addEventListener("change", (event) => { const selection = event.detail; this.cropperCanvasRect = this.cropperCanvas.getBoundingClientRect(); + // Limit the selection to the min/max size. const selectionRatio = Math.min(this.cropperCanvasRect.width / this.width, this.cropperCanvasRect.height / this.height); // Round all values to integers to avoid dealing with the wonderful world // of IEEE 754 numbers. @@ -182,6 +165,27 @@ define(["require", "exports", "tslib", "WoltLabSuite/Core/Image/Resizer", "WoltL const height = Math.round(selection.height); if (width < minWidth || height < minHeight || width > maxWidth || height > maxHeight) { event.preventDefault(); + // Stop the event handling here otherwise the following code would try + // to adjust the position on an invalid size that could potentially + // violate the boundaries. + return; + } + // Limit the selection to the canvas boundaries. + // see https://fengyuanchen.github.io/cropperjs/v2/api/cropper-selection.html#limit-boundaries + const maxSelection = { + x: 0, + y: 0, + width: this.cropperCanvasRect.width, + height: this.cropperCanvasRect.height, + }; + if (!inSelection(selection, maxSelection)) { + event.preventDefault(); + // Clamp the position to the boundaries of the canvas. + this.cropperSelection.x = clampValue(selection.x, selection.width, maxSelection.width); + this.cropperSelection.y = clampValue(selection.y, selection.height, maxSelection.height); + this.cropperSelection.width = selection.width; + this.cropperSelection.height = selection.height; + this.cropperSelection.$render(); } }); }