UNPKG

svg-pathdata

Version:

Manipulate SVG path data (path[d] attribute content) simply and efficiently.

107 lines (94 loc) 3.11 kB
import { encodeSVGPath } from './SVGPathDataEncoder.js'; import { SVGPathDataParser } from './SVGPathDataParser.js'; import { SVGPathDataTransformer } from './SVGPathDataTransformer.js'; import { TransformableSVG } from './TransformableSVG.js'; import type { SVGCommand } from './types.js'; export class SVGPathData extends TransformableSVG { commands: SVGCommand[]; constructor(content: string | SVGCommand[]) { super(); if ('string' === typeof content) { this.commands = SVGPathData.parse(content); } else { this.commands = content; } } encode() { return SVGPathData.encode(this.commands); } getBounds() { const boundsTransform = SVGPathDataTransformer.CALCULATE_BOUNDS(); this.transform(boundsTransform); return boundsTransform; } transform( transformFunction: (input: SVGCommand) => SVGCommand | SVGCommand[], ) { const newCommands: SVGCommand[] = []; for (const command of this.commands) { const transformedCommand = transformFunction(command); if (Array.isArray(transformedCommand)) { newCommands.push(...transformedCommand); } else { newCommands.push(transformedCommand); } } this.commands = newCommands; return this; } /** * Reverses the order of path commands to go from end to start * IMPORTANT: This function expects absolute commands as input. * @param preserveSubpathOrder If true, keeps subpaths in their original order */ reverse(preserveSubpathOrder = true) { this.commands = SVGPathDataTransformer.REVERSE_PATH( this.commands, preserveSubpathOrder, ); return this; } static encode(commands: SVGCommand[]) { return encodeSVGPath(commands); } static parse(path: string) { const parser = new SVGPathDataParser(); const commands: SVGCommand[] = []; parser.parse(path, commands); parser.finish(commands); return commands; } static readonly CLOSE_PATH = 1 as const; static readonly MOVE_TO = 2 as const; static readonly HORIZ_LINE_TO = 4 as const; static readonly VERT_LINE_TO = 8 as const; static readonly LINE_TO = 16 as const; static readonly CURVE_TO = 32 as const; static readonly SMOOTH_CURVE_TO = 64 as const; static readonly QUAD_TO = 128 as const; static readonly SMOOTH_QUAD_TO = 256 as const; static readonly ARC = 512 as const; static readonly LINE_COMMANDS = SVGPathData.LINE_TO | SVGPathData.HORIZ_LINE_TO | SVGPathData.VERT_LINE_TO; static readonly DRAWING_COMMANDS = SVGPathData.HORIZ_LINE_TO | SVGPathData.VERT_LINE_TO | SVGPathData.LINE_TO | SVGPathData.CURVE_TO | SVGPathData.SMOOTH_CURVE_TO | SVGPathData.QUAD_TO | SVGPathData.SMOOTH_QUAD_TO | SVGPathData.ARC; } export const COMMAND_ARG_COUNTS = { [SVGPathData.MOVE_TO]: 2, [SVGPathData.LINE_TO]: 2, [SVGPathData.HORIZ_LINE_TO]: 1, [SVGPathData.VERT_LINE_TO]: 1, [SVGPathData.CLOSE_PATH]: 0, [SVGPathData.QUAD_TO]: 4, [SVGPathData.SMOOTH_QUAD_TO]: 2, [SVGPathData.CURVE_TO]: 6, [SVGPathData.SMOOTH_CURVE_TO]: 4, [SVGPathData.ARC]: 7, };