import type { ImageContent, ImageContentView } from "../content/image" export interface CroppedImage { zoom: number /** X coordinate of the crop rect on the original image */ x: number /** Y coordinate of the crop rect on the original image */ y: number /** The width of the crop rect over the original image */ cropWidth: number /** The height of the crop rect over the original image */ cropHeight: number /** Final (user defined via W input) width of the image */ width: number /** Final (user defined via H input) height of the image */ height: number } export function buildCropURL(args: { origin: ImageContent["origin"] croppedImage: CroppedImage }): string { const { origin, croppedImage } = args const { x, y, width, height, cropHeight, cropWidth } = croppedImage const url = new URL(origin.url) const hasResize = origin.height !== height || origin.width !== width const hasCrop = x !== 0 || y !== 0 || cropHeight !== origin.height || cropWidth !== origin.width if (hasCrop) { const crop = [x, y, cropWidth, cropHeight].map(Math.round).join(",") url.searchParams.set("rect", crop) url.searchParams.set("w", width.toString()) url.searchParams.set("h", height.toString()) } if (hasResize) { url.searchParams.set("w", width.toString()) url.searchParams.set("h", height.toString()) } return url.toString() } export function getCroppedImage({ contentView }: { contentView: ImageContentView }): CroppedImage { const { edit: { crop: { x, y }, zoom, }, width, height, origin: { width: originWidth, height: originHeight }, } = contentView let cropWidth let cropHeight const originAspect = originWidth / originHeight const cropAspect = width / height if (cropAspect >= originAspect) { // crop and origin image would be the same width if zoom was equal to 1 cropWidth = originWidth / zoom cropHeight = cropWidth / cropAspect } else { // crop and origin image would be the same height if zoom was equal to 1 cropHeight = originHeight / zoom cropWidth = cropHeight * cropAspect } return { x, y, width, height, zoom, cropWidth, cropHeight, } }