ultisuite-client/lib/drive/docs-graphic-image-size.ts
R3D347HR4Y 303b2b1074
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
wow
2026-06-11 01:22:40 +02:00

71 lines
2.2 KiB
TypeScript

import { DOCS_GRAPHIC_DEFAULTS } from "./docs-graphic-types.ts"
import { GRAPHIC_KEYBOARD_MIN_SIZE } from "./docs-graphic-keyboard.ts"
/** Max frame width when inserting large photos into the page body. */
export const DOCS_IMAGE_INSERT_MAX_WIDTH_PX = 560
/** Max frame height when inserting very tall images. */
export const DOCS_IMAGE_INSERT_MAX_HEIGHT_PX = 720
export type ImageNaturalSize = {
width: number
height: number
}
/** Frame size that preserves the source aspect ratio, scaled down when needed. */
export function computeImageInsertFrameSize(
naturalWidth: number,
naturalHeight: number,
options: {
maxWidth?: number
maxHeight?: number
minSize?: number
} = {}
): ImageNaturalSize {
const maxWidth = options.maxWidth ?? DOCS_IMAGE_INSERT_MAX_WIDTH_PX
const maxHeight = options.maxHeight ?? DOCS_IMAGE_INSERT_MAX_HEIGHT_PX
const minSize = options.minSize ?? GRAPHIC_KEYBOARD_MIN_SIZE
if (naturalWidth <= 0 || naturalHeight <= 0) {
return {
width: DOCS_GRAPHIC_DEFAULTS.width,
height: DOCS_GRAPHIC_DEFAULTS.height,
}
}
const scale = Math.min(1, maxWidth / naturalWidth, maxHeight / naturalHeight)
let width = Math.max(minSize, Math.round(naturalWidth * scale))
let height = Math.max(minSize, Math.round(naturalHeight * scale))
// Keep ratio after integer rounding (derive height from width).
height = Math.max(minSize, Math.round(width * (naturalHeight / naturalWidth)))
if (height > maxHeight) {
height = maxHeight
width = Math.max(minSize, Math.round(height * (naturalWidth / naturalHeight)))
}
return { width, height }
}
/** Load intrinsic pixel dimensions for a data URL or remote image src. */
export function readImageNaturalSize(src: string): Promise<ImageNaturalSize> {
if (typeof Image === "undefined") {
return Promise.resolve({
width: DOCS_GRAPHIC_DEFAULTS.width,
height: DOCS_GRAPHIC_DEFAULTS.height,
})
}
return new Promise((resolve, reject) => {
const img = new Image()
img.onload = () => {
resolve({
width: img.naturalWidth,
height: img.naturalHeight,
})
}
img.onerror = () => reject(new Error("Failed to read image dimensions"))
img.src = src
})
}