diff --git a/README.md b/README.md index f937b9d..13895cf 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,14 @@ ImageCrop imageCrop = new ImageCrop(DownloadHandler.forClassResource(getClass(), add(imageCrop); ``` +* Constrain the size of large images + +The image is scaled down to fit the component's size, whether it is set with `height` or `max-height` (in any unit) or given by the layout. + +```java +imageCrop.getStyle().set("max-height", "70vh"); +``` + * Get cropped image ```java diff --git a/src/main/java/com/flowingcode/vaadin/addons/imagecrop/ImageCrop.java b/src/main/java/com/flowingcode/vaadin/addons/imagecrop/ImageCrop.java index 3181f1e..6b25b40 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/imagecrop/ImageCrop.java +++ b/src/main/java/com/flowingcode/vaadin/addons/imagecrop/ImageCrop.java @@ -39,7 +39,15 @@ * react-image-crop * library. * This component allows users to define and manipulate crop areas on images. - * + * + *
+ * The image is scaled down, keeping its aspect ratio, to fit the component's width + * and height, whether they are set on the component (a {@code height} or a + * {@code max-height} in any unit) or given by the layout it is in. For instance, + * {@code getStyle().set("max-height", "100vh")} keeps a large image within the + * viewport. Images smaller than these limits are shown at their natural size. + *
+ * * @author Paola De Bartolo / Flowing Code */ @NpmPackage(value = "react-image-crop", version = "11.0.6") @@ -48,8 +56,6 @@ @CssImport("react-image-crop/dist/ReactCrop.css") @CssImport("./styles/image-crop-styles.css") public class ImageCrop extends ReactAdapterComponent { - - private static final String IMG_FULL_HEIGHT_CLASS_NAME = "img-full-height"; private static final String IMG_SRC_RESOURCE_ATTRIBUTE = "img-src"; @@ -497,21 +503,6 @@ public String getCroppedImageDataUri() { return this.croppedImageDataUri; } - /** - * Sets the image to occupy the full viewport height when enabled. - * If {@code fullHeight} is {@code true}, applies a CSS class that - * sets the image height to 100vh. If {@code false}, removes the class - * to revert to the default height. - * - * @param fullHeight whether the image should fill the viewport height - */ - public void setImageFullHeight(Boolean fullHeight) { - if (fullHeight) - this.addClassName(IMG_FULL_HEIGHT_CLASS_NAME); - else - this.removeClassName(IMG_FULL_HEIGHT_CLASS_NAME); - } - /** * Decodes the cropped image data URI and returns it as a byte array. If the image data URI is not * in the format "data:image/*;base64,", it will be decoded assuming it is a Base64 encoded diff --git a/src/main/resources/META-INF/frontend/src/image-crop.tsx b/src/main/resources/META-INF/frontend/src/image-crop.tsx index cb484a2..793aa61 100644 --- a/src/main/resources/META-INF/frontend/src/image-crop.tsx +++ b/src/main/resources/META-INF/frontend/src/image-crop.tsx @@ -144,6 +144,40 @@ class ImageCropElement extends ReactAdapterElement { ) : percentCrop; + /** + * Fits the image to the height the component actually gets, however it is + * defined: a height, a max-height in any unit, or the layout. CSS alone can't + * do it, since react-image-crop inherits max-height as written, so a + * percentage would resolve against an auto-height parent and be ignored. + * + * The limit is cleared before measuring, so the component is measured without + * it, and is set in pixels only when the image is taller than the available + * space. Smaller images are never upscaled. + */ + const fitImageHeight = () => { + const cropElement = this.querySelector