export interface Box { width: number; height: number; } export function box(width: number, height: number): Box { return { width, height }; } export function constrain(subject: Box, container: Box): Box { if (subject.width < container.width && subject.height < container.height) { return subject; } const subjectAspectRatio = subject.width / subject.height; const containerAspectRatio = container.width / container.height; if (subjectAspectRatio < containerAspectRatio) { // ┌────┐ // │ │ subject // └────┘ // ┏━━━━━━━━━━━━┓ // ┃ ┃ container // ┗━━━━━━━━━━━━┛ const shrinkFactor = container.height / subject.height; return box(Math.ceil(subject.width * shrinkFactor), Math.ceil(subject.height * shrinkFactor)); } else { // ┌───────────┐ // │ │ subject // └───────────┘ // ┏━━━━┓ // ┃ ┃ container // ┗━━━━┛ const shrinkFactor = container.width / subject.width; return box(Math.ceil(subject.width * shrinkFactor), Math.ceil(subject.height * shrinkFactor)); } }