UNPKG

@svg-fns/layout

Version:

Lightweight SVG layout utilities — viewBox parsing, scaling, cropping, and trimming for precise content-aware rendering.

209 lines (204 loc) 6.46 kB
/** * Axis-aligned rectangle. * - `x`, `y`: top-left corner coordinates * - `width`, `height`: rectangle dimensions */ type Rect = { x: number; y: number; width: number; height: number }; /** * Padding specification for layout or box-model operations. * - Single number applies to all sides * - Object form allows per-side values */ type Padding = | number | { top: number; right: number; bottom: number; left: number }; /** * Affine transformation matrix tuple. * Matches SVGMatrix `[a b c d e f]`, representing: * * [ a c e ] * [ b d f ] * [ 0 0 1 ] * * Used for scale, rotate, skew, and translate operations. */ type Matrix = [number, number, number, number, number, number]; /** * Parse a `viewBox` string into a rect. * * @param vb viewBox attribute string * @returns Rect or null if invalid * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox */ declare const parseViewBox: (vb: string | null) => Rect | null; /** * Read current viewBox of an SVG. * * @param svg SVG element * @returns Rect or null */ declare const getViewBox: (svg: SVGSVGElement) => Rect | null; /** * Set SVG viewBox (and optionally preserveAspectRatio). * * @param svg SVG element * @param rect Rect to set * @param opts Options (round, preserveAspectRatio) */ declare const setViewBox: (svg: SVGSVGElement, { x, y, height, width }: Rect, opts?: { preserveAspectRatio?: string; round?: boolean; }) => void; /** * Parse dimension string into pixels where possible. * - Supports: unitless, px, vh, vw (requires `window`) * - Supports: em, rem (requires optional `fontSize` context) * - Throws on unsupported units or missing context * * @param v Attribute string * @param context Optional: { fontSize?: number } for em/rem * @returns number in px, or null if empty */ declare const parseDimension: (v: string | null, context?: { fontSize?: number; }) => number | null; /** * Read width/height attributes. * * @param svg SVG element * @returns { width, height } or nulls */ declare const getDimensions: (svg: SVGSVGElement, context?: { fontSize?: number; }) => { width: number | null; height: number | null; }; /** * Update width/height attributes. * * @param svg SVG element * @param width New width (optional) * @param height New height (optional) */ declare const updateDimensions: (svg: SVGSVGElement, width?: number | null, height?: number | null) => void; /** * Compute the bounding box of an SVG element with its current transform matrix applied. * * Unlike `element.getBBox()`, which ignores transforms (scale, rotate, translate), * this function projects the element's local bounding box into the SVG's coordinate * system by applying the element's `CTM` (current transformation matrix). * * @param el - Any SVGGraphicsElement (e.g., <path>, <text>, <rect>, <g>, <image>, …) * @returns The transformed bounding box as { x, y, width, height } * * @example * ```ts * const svg = document.querySelector("svg")!; * const text = svg.querySelector("text")!; * const box = getBBoxWithTransform(text); * console.log(box); // Correct bounds, accounting for transform="scale(.1)" * ``` * * @remarks * - Throws if the element does not support `getBBox()`. * - Returns the raw transformed box; if you need union across multiple elements, * compose with a `unionRects` utility. */ declare const getBBoxWithTransform: (el: SVGGraphicsElement) => Rect; /** * Compute a tight bounding box of SVG content. * - Starts with root <svg> getBBox() * - Optionally expands to children that extend beyond root * * @param svg The SVG element to compute content bounds for * @param clipToViewBox If true, only use root <svg> bbox * @returns Rect bounding all visible graphics * @see https://developer.mozilla.org/en-US/docs/Web/API/SVGGraphicsElement/getBBox */ declare const getContentBBox: (svg: SVGSVGElement, clipToViewBox?: boolean) => Rect; /** * Compute trim box (tight content box + padding). * * @param svg SVG element * @param padding Padding * @returns @link {Rect} */ declare const computeTrimBox: (svg: SVGSVGElement, padding?: Padding, clipToViewBox?: boolean) => Rect; /** * Tightly crop an SVG to content. * * @param svg SVG element * @param opts Options (padding, mutate, preserveDimensions, round) * @returns { box, apply } where apply() applies crop */ declare const tightlyCropSvg: (svg: SVGSVGElement, opts?: { padding?: Padding; mutate?: boolean; preserveDimensions?: boolean; round?: boolean; clipToViewBox?: boolean; }) => { box: Rect; apply: (target?: SVGSVGElement) => SVGSVGElement; }; /** * Translate current viewBox. * * @param svg SVG element * @param dx Delta x * @param dy Delta y * @param opts Options (mutate, round) */ declare const translateViewBox: (svg: SVGSVGElement, dx: number, dy: number, opts?: { mutate?: boolean; round?: boolean; }) => Rect | null; /** * Scale (zoom) current viewBox. * * @param svg SVG element * @param factor Zoom factor (>0) * @param cx Optional center x * @param cy Optional center y * @param opts Options (mutate, round) */ declare const scaleViewBox: (svg: SVGSVGElement, factor: number, cx?: number, cy?: number, opts?: { mutate?: boolean; round?: boolean; }) => Rect | null; /** * Apply matrix transform to viewBox. * * @param svg SVG element * @param matrix Affine matrix * @param opts Options (mutate, round) */ declare const setViewBoxTransform: (svg: SVGSVGElement, matrix: Matrix, opts?: { mutate?: boolean; round?: boolean; }) => Rect | null; /** * Center viewBox around content center. * * @param svg SVG element * @param opts Options (mutate, round) */ declare const centerSvg: (svg: SVGSVGElement, opts?: { mutate?: boolean; round?: boolean; }) => Rect | null; /** * Fit content into target rect (preserve aspect ratio). * * @param svg SVG element * @param targetW Target width * @param targetH Target height * @param opts Options (mutate, padding, round) */ declare const fitSvg: (svg: SVGSVGElement, targetW: number, targetH: number, opts?: { mutate?: boolean; padding?: Padding; round?: boolean; }) => Rect | null; export { centerSvg, computeTrimBox, fitSvg, getBBoxWithTransform, getContentBBox, getDimensions, getViewBox, parseDimension, parseViewBox, scaleViewBox, setViewBox, setViewBoxTransform, tightlyCropSvg, translateViewBox, updateDimensions };