All files / roosterjs-content-model-plugins/lib/imageEdit/utils generateImageSize.ts

91.67% Statements 11/12
87.5% Branches 14/16
100% Functions 1/1
91.67% Lines 11/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66                              1x                       210x   30x                     30x     30x 30x     30x 30x       30x   30x   30x                  
import type { ImageMetadataFormat } from 'roosterjs-content-model-types';
import type { GeneratedImageSize } from '../types/GeneratedImageSize';
 
/**
 * @internal
 * Calculate the target size of an image.
 * For image that is not rotated, target size is the same with resizing/cropping size.
 * For image that is rotated, target size is calculated from resizing/cropping size and its rotate angle
 * Say an image is resized to 100w*100h, cropped 25% on each side, then rotated 45deg, so that cropped size
 * will be (both height and width) 100*(1-0.25-0,25) = 50px, then final image size will be 50*sqrt(2) = 71px
 * @param editInfo The edit info to calculate size from
 * @param beforeCrop True to calculate the full size of original image before crop, false to calculate the size
 * after crop
 * @returns A GeneratedImageSize object which contains original, visible and target target width and height of the image
 */
export function getGeneratedImageSize(
    editInfo: ImageMetadataFormat,
    beforeCrop?: boolean
): GeneratedImageSize | undefined {
    const {
        widthPx: width,
        heightPx: height,
        angleRad,
        leftPercent: left,
        rightPercent: right,
        topPercent: top,
        bottomPercent: bottom,
    } = editInfo;
 
    Iif (
        height == undefined ||
        width == undefined ||
        left == undefined ||
        right == undefined ||
        top == undefined ||
        bottom == undefined
    ) {
        return;
    }
 
    const angle = angleRad ?? 0;
 
    // Original image size before crop and rotate
    const originalWidth = width / (1 - left - right);
    const originalHeight = height / (1 - top - bottom);
 
    // Visible size
    const visibleWidth = beforeCrop ? originalWidth : width;
    const visibleHeight = beforeCrop ? originalHeight : height;
 
    // Target size after crop and rotate
    const targetWidth =
        Math.abs(visibleWidth * Math.cos(angle)) + Math.abs(visibleHeight * Math.sin(angle));
    const targetHeight =
        Math.abs(visibleWidth * Math.sin(angle)) + Math.abs(visibleHeight * Math.cos(angle));
 
    return {
        targetWidth,
        targetHeight,
        originalWidth,
        originalHeight,
        visibleWidth,
        visibleHeight,
    };
}