export interface ModalSize { width: number height: number } export interface ModalOffset { offsetX: number offsetY: number } export interface ModalRect { left: number top: number width: number height: number } export interface CreateDefaultModalSizeInput { viewportWidth: number viewportHeight: number margin: number minWidth: number minHeight: number } export interface CreateDefaultModalRectInput extends CreateDefaultModalSizeInput {} export interface ClampModalSizeInput extends ModalSize { minWidth: number minHeight: number maxWidth: number maxHeight: number } export interface ClampModalOffsetInput extends ModalSize { offsetX: number offsetY: number viewportWidth: number viewportHeight: number margin: number } export interface ClampModalRectInput extends ModalRect { minWidth: number minHeight: number viewportWidth: number viewportHeight: number margin: number } export function clampModalSize(input: ClampModalSizeInput): ModalSize { return { width: Math.max(input.minWidth, Math.min(input.width, input.maxWidth)), height: Math.max(input.minHeight, Math.min(input.height, input.maxHeight)), } } export function createDefaultModalSize(input: CreateDefaultModalSizeInput): ModalSize { const maxWidth = Math.max(input.minWidth, input.viewportWidth - input.margin * 2) const maxHeight = Math.max(input.minHeight, input.viewportHeight - input.margin * 2) return clampModalSize({ width: maxWidth, height: maxHeight, minWidth: input.minWidth, minHeight: input.minHeight, maxWidth, maxHeight, }) } export function createDefaultModalRect(input: CreateDefaultModalRectInput): ModalRect { const size = createDefaultModalSize(input) return { left: input.margin, top: input.margin, width: size.width, height: size.height, } } export function clampModalOffset(input: ClampModalOffsetInput): ModalOffset { const centerX = (input.viewportWidth - input.width) / 2 const centerY = (input.viewportHeight - input.height) / 2 const minOffsetX = input.margin - centerX const maxOffsetX = input.viewportWidth - input.margin - (centerX + input.width) const minOffsetY = input.margin - centerY const maxOffsetY = input.viewportHeight - input.margin - (centerY + input.height) return { offsetX: Math.max(minOffsetX, Math.min(input.offsetX, maxOffsetX)), offsetY: Math.max(minOffsetY, Math.min(input.offsetY, maxOffsetY)), } } export function clampModalRect(input: ClampModalRectInput): ModalRect { const maxWidth = Math.max(input.minWidth, input.viewportWidth - input.margin * 2) const maxHeight = Math.max(input.minHeight, input.viewportHeight - input.margin * 2) const size = clampModalSize({ width: input.width, height: input.height, minWidth: input.minWidth, minHeight: input.minHeight, maxWidth, maxHeight, }) const maxLeft = input.viewportWidth - input.margin - size.width const maxTop = input.viewportHeight - input.margin - size.height return { left: Math.max(input.margin, Math.min(input.left, maxLeft)), top: Math.max(input.margin, Math.min(input.top, maxTop)), width: size.width, height: size.height, } }