UNPKG

nitropage

Version:

A free and open source, extensible visual page builder based on SolidStart.

91 lines (79 loc) 2.1 kB
import type { Dimensions } from "../server/media/crop"; export const getImageOptimizationTarget = ({ size, original, aspectRatio, dpr, }: { size: number; original: Dimensions; aspectRatio?: string; dpr?: number; }) => { const proportionalHeight = Math.round( (size / original.width) * original.height, ); const target = !aspectRatio ? { width: size, height: proportionalHeight, } : getTargetFromAspectRatio(aspectRatio, size); if (dpr === 2) { ((target.width = target.width * 2), (target.height = target.height * 2)); } return target; }; const ratioCache: Record<string, number> = {}; export const convertAspectRatio = function (aspectRatio: string) { if (ratioCache[aspectRatio]) { return ratioCache[aspectRatio]; } const parts = aspectRatio.split("/"); if (parts.length !== 2) { return 1; } const result = Number.parseInt(parts[1]) / parseInt(parts[0]); ratioCache[aspectRatio] = result; return result; }; export const getTargetFromAspectRatio = function ( aspectRatio: string, size: number, ) { const ar = convertAspectRatio(aspectRatio); if (ar > 1) { return { width: Math.round(size / ar), height: size, }; } return { width: size, height: Math.round(size * ar), }; }; /** * Shrinks the crop target size, fitting it proportionally inside the original size * * E.g. if the original size is 300/300 and target is 400/300, this returns 300/225. * With target 300/400, this returns 225/300. * * In either case, the new target size is never larger than the original size * */ export const getProportionalCropTarget = function ( original: Dimensions, target: Dimensions, ) { target = { ...target }; if (target.width > original.width) { target.height = Math.round((target.height / target.width) * original.width); target.width = original.width; } if (target.height > original.height) { target.width = Math.round((target.width / target.height) * original.height); target.height = original.height; } return target; };