Recalculate cropper height on window resize.
authorCyperghost <olaf_schmitz_1@t-online.de>
Mon, 9 Dec 2024 11:46:15 +0000 (12:46 +0100)
committerCyperghost <olaf_schmitz_1@t-online.de>
Mon, 9 Dec 2024 11:46:15 +0000 (12:46 +0100)
Set height on container(parent) height

ts/WoltLabSuite/Core/Component/Image/Cropper.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Component/Image/Cropper.js

index c6bc19ec80afb72d26a00f5654c5061f15e11177..9f3a22de7ae372741dd0b32f8ff1b13d952b82c0 100644 (file)
@@ -15,6 +15,7 @@ import { getPhrase } from "WoltLabSuite/Core/Language";
 import WoltlabCoreDialogElement from "WoltLabSuite/Core/Element/woltlab-core-dialog";
 import * as ExifUtil from "WoltLabSuite/Core/Image/ExifUtil";
 import ExifReader from "exifreader";
+import DomUtil from "WoltLabSuite/Core/Dom/Util";
 
 export interface CropperConfiguration {
   aspectRatio: number;
@@ -27,8 +28,8 @@ export interface CropperConfiguration {
 
 function inSelection(selection: Selection, maxSelection: Selection): boolean {
   return (
-    selection.x >= maxSelection.x &&
-    selection.y >= maxSelection.y &&
+    Math.ceil(selection.x) >= maxSelection.x &&
+    Math.ceil(selection.y) >= maxSelection.y &&
     Math.ceil(selection.x + selection.width) <= Math.ceil(maxSelection.x + maxSelection.width) &&
     Math.ceil(selection.y + selection.height) <= Math.ceil(maxSelection.y + maxSelection.height)
   );
@@ -83,6 +84,21 @@ abstract class ImageCropper {
 
     this.createCropper();
 
+    const resize = () => {
+      this.centerSelection();
+    };
+
+    window.addEventListener("resize", resize, { passive: true });
+    this.dialog.addEventListener(
+      "afterClose",
+      () => {
+        window.removeEventListener("resize", resize);
+      },
+      {
+        once: true,
+      },
+    );
+
     return new Promise<File>((resolve, reject) => {
       this.dialog!.addEventListener("primary", () => {
         void this.getCanvas()
@@ -371,6 +387,12 @@ class MinMaxImageCropper extends ImageCropper {
   }
 
   protected centerSelection(): void {
+    // Reset to get the maximum available height
+    this.cropperCanvas!.style.height = "";
+
+    const dimensions = DomUtil.outerDimensions(this.cropperCanvas!.parentElement!);
+    this.cropperCanvas!.style.height = `${dimensions.height}px`;
+
     this.cropperImage!.$center("contain");
     this.#cropperCanvasRect = this.cropperImage!.getBoundingClientRect();
 
index 46bc1e8dac0a9222c49346c7406c14c1069a3c66..7631ca3083856c2ce302ec94f396bf9f417ff847 100644 (file)
@@ -6,16 +6,17 @@
  * @license   GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @since     6.2
  */
-define(["require", "exports", "tslib", "WoltLabSuite/Core/Image/Resizer", "WoltLabSuite/Core/Component/Dialog", "cropperjs", "WoltLabSuite/Core/Language", "exifreader"], function (require, exports, tslib_1, Resizer_1, Dialog_1, cropperjs_1, Language_1, exifreader_1) {
+define(["require", "exports", "tslib", "WoltLabSuite/Core/Image/Resizer", "WoltLabSuite/Core/Component/Dialog", "cropperjs", "WoltLabSuite/Core/Language", "exifreader", "WoltLabSuite/Core/Dom/Util"], function (require, exports, tslib_1, Resizer_1, Dialog_1, cropperjs_1, Language_1, exifreader_1, Util_1) {
     "use strict";
     Object.defineProperty(exports, "__esModule", { value: true });
     exports.cropImage = cropImage;
     Resizer_1 = tslib_1.__importDefault(Resizer_1);
     cropperjs_1 = tslib_1.__importDefault(cropperjs_1);
     exifreader_1 = tslib_1.__importDefault(exifreader_1);
+    Util_1 = tslib_1.__importDefault(Util_1);
     function inSelection(selection, maxSelection) {
-        return (selection.x >= maxSelection.x &&
-            selection.y >= maxSelection.y &&
+        return (Math.ceil(selection.x) >= maxSelection.x &&
+            Math.ceil(selection.y) >= maxSelection.y &&
             Math.ceil(selection.x + selection.width) <= Math.ceil(maxSelection.x + maxSelection.width) &&
             Math.ceil(selection.y + selection.height) <= Math.ceil(maxSelection.y + maxSelection.height));
     }
@@ -62,6 +63,15 @@ define(["require", "exports", "tslib", "WoltLabSuite/Core/Image/Resizer", "WoltL
             });
             this.dialog.show((0, Language_1.getPhrase)("wcf.upload.crop.image"));
             this.createCropper();
+            const resize = () => {
+                this.centerSelection();
+            };
+            window.addEventListener("resize", resize, { passive: true });
+            this.dialog.addEventListener("afterClose", () => {
+                window.removeEventListener("resize", resize);
+            }, {
+                once: true,
+            });
             return new Promise((resolve, reject) => {
                 this.dialog.addEventListener("primary", () => {
                     void this.getCanvas()
@@ -282,6 +292,10 @@ define(["require", "exports", "tslib", "WoltLabSuite/Core/Image/Resizer", "WoltL
             });
         }
         centerSelection() {
+            // Reset to get the maximum available height
+            this.cropperCanvas.style.height = "";
+            const dimensions = Util_1.default.outerDimensions(this.cropperCanvas.parentElement);
+            this.cropperCanvas.style.height = `${dimensions.height}px`;
             this.cropperImage.$center("contain");
             this.#cropperCanvasRect = this.cropperImage.getBoundingClientRect();
             if (this.configuration.aspectRatio >= 1.0) {