UNPKG

@amandaghassaei/flat-svg

Version:

A TypeScript library for converting nested SVGs into a flat list of elements, paths, or segments and applying style-based filters.

156 lines (143 loc) 5.81 kB
// Internal-only types. Not re-exported from index.ts — kept isolated so renames // here aren't breaking changes for consumers. import { SVG_PATH_CMD_ARC, SVG_PATH_CMD_CLOSE, SVG_PATH_CMD_CURVETO, SVG_PATH_CMD_HLINETO, SVG_PATH_CMD_LINETO, SVG_PATH_CMD_MOVETO, SVG_PATH_CMD_QUADRATIC, SVG_PATH_CMD_VLINETO, SVG_STYLE_COLOR, SVG_STYLE_FILL, SVG_STYLE_STROKE_COLOR, SVG_STYLE_STROKE_DASH_ARRAY, } from './constants-private'; import { SVG_LINE, SVG_RECT, SVG_POLYLINE, SVG_POLYGON, SVG_CIRCLE, SVG_ELLIPSE, SVG_PATH, } from './constants-public'; import { Colord } from 'colord'; import { FlatSVGTransform, FlatSVGStyle, SVGLineProperties, SVGRectProperties, SVGPolylineProperties, SVGPolygonProperties, SVGCircleProperties, SVGEllipseProperties, SVGPathProperties, FlatSVGPoint, } from './types-public'; /** * Mutable variant of `FlatSVGPoint`. For in-place arithmetic (applyTransform writes * back into its argument) and for builders before publishing as a readonly FlatSVGPoint. */ export type MutablePoint = [number, number]; /** * Result of converting a <polygon>/<polyline> with a points attribute. A path * d-string for the normal case; `{ strayPoint }` for single-point degenerates * (caller flags as a stray vertex instead of a path); `undefined` for invalid * input (with a warning pushed onto parsingWarnings). */ export type PointsConversionResult = string | { readonly strayPoint: FlatSVGPoint } | undefined; /** * Strips top-level `readonly` so builders can populate incrementally, then * publish through the readonly public type at the boundary. Distributes across * discriminated unions. */ export type Mutable<T> = { -readonly [K in keyof T]: T[K] }; /** * State accumulated down the element tree during _deepIterChildren. All fields * optional and readonly — callbacks must not mutate, since refs are shared * with sibling/descendant elements that haven't diverged yet. */ export interface InheritedContext { readonly transform?: Readonly<FlatSVGTransform>; // Chain of ancestor <g> ids/classes — excludes the current element's own. // Outermost ancestor first, space-joined. readonly ancestorIds?: string; readonly ancestorClasses?: string; readonly properties?: Readonly<FlatSVGStyle>; readonly clipPaths?: ReadonlyArray<string>; readonly masks?: ReadonlyArray<string>; readonly filters?: ReadonlyArray<string>; } /** * `FlatSVGTransform` plus a `warnings` side-channel — used by `parseTransformString` * to ride parse warnings back alongside the matrix. */ export interface TransformParsed extends FlatSVGTransform { warnings?: string[], } /** Per-item cache of parsed style values; populated lazily by `_filterByStyle`. */ export interface ComputedProperties { [SVG_STYLE_STROKE_COLOR]?: Colord, [SVG_STYLE_FILL]?: Colord, [SVG_STYLE_COLOR]?: Colord, [SVG_STYLE_STROKE_DASH_ARRAY]?: number[]; } /** * Type-level mirror of `SUPPORTED_GEOMETRY_TAG_NAMES` — the SVG tag names * flat-svg knows how to convert to paths and segments. */ export type GeometryElementTagName = typeof SVG_LINE | typeof SVG_RECT | typeof SVG_POLYLINE | typeof SVG_POLYGON | typeof SVG_CIRCLE | typeof SVG_ELLIPSE | typeof SVG_PATH; /** SVGElementProperties shape per geometry tag, parallel to `GeometryElementTagName`. */ export type GeometryElementProperties = SVGLineProperties | SVGRectProperties | SVGPolylineProperties | SVGPolygonProperties | SVGCircleProperties | SVGEllipseProperties | SVGPathProperties; // svgpath segment tuples, narrowed to what flat-svg actually observes: // every parser runs through `.abs()` (rewrites all commands to absolute, // including lowercase z → Z) and — for <path> input — `.unshort()` (expands // S→C, T→Q). Other call sites feed only M/L/Z hand-built strings. So the // relative arms (m/l/h/v/c/s/q/t/a) and S/T never reach `_buildSegments`. type MoveToAbs = [typeof SVG_PATH_CMD_MOVETO, number, number]; type LineToAbs = [typeof SVG_PATH_CMD_LINETO, number, number]; type HorizontalLineToAbs = [typeof SVG_PATH_CMD_HLINETO, number]; type VerticalLineToAbs = [typeof SVG_PATH_CMD_VLINETO, number]; type CurveToAbs = [typeof SVG_PATH_CMD_CURVETO, number, number, number, number, number, number]; type QuadraticBézierCurveToAbs = [typeof SVG_PATH_CMD_QUADRATIC, number, number, number, number]; type EllipticalArcAbs = [typeof SVG_PATH_CMD_ARC, number, number, number, number, number, number, number]; type ClosePath = [typeof SVG_PATH_CMD_CLOSE]; type Segment = MoveToAbs | LineToAbs | HorizontalLineToAbs | VerticalLineToAbs | CurveToAbs | QuadraticBézierCurveToAbs | EllipticalArcAbs | ClosePath; /** * svgpath's parser, redeclared to expose three runtime fields its upstream * types omit: * `.segments` — Segment[] read in `_buildPaths` for MOVETO_ONLY detection * `.err` — parse-error string, checked in `_buildPaths` / convertToPath * `.__stack` — internal lazy-transform stack (unused by flat-svg) * May drift silently if svgpath changes method shapes — revisit periodically. */ export type PathParser = { (path: string): PathParser; new (path: string): PathParser; from(path: string | PathParser): PathParser; abs(): PathParser; rel(): PathParser; scale(sx: number, sy?: number): PathParser; translate(x: number, y?: number): PathParser; rotate(angle: number, rx?: number, ry?: number): PathParser; skewX(degrees: number): PathParser; skewY(degrees: number): PathParser; matrix(m: number[]): PathParser; transform(str: string): PathParser; unshort(): PathParser; unarc(): PathParser; toString(): string; round(precision: number): PathParser; iterate(iterator: (segment: Segment, index: number, x: number, y: number) => void, keepLazyStack?: boolean): PathParser; segments: Segment[]; __stack?: any[]; err?: string; };