An open API service indexing awesome lists of open source software.

https://github.com/nfroidure/svg-pathdata

Parse SVG PathDatas
https://github.com/nfroidure/svg-pathdata

javascript svg svg-path

Last synced: 6 months ago
JSON representation

Parse SVG PathDatas

Awesome Lists containing this project

README

          

[//]: # ( )
[//]: # (This file is automatically generated by a `metapak`)
[//]: # (module. Do not change it except between the)
[//]: # (`content:start/end` flags, your changes would)
[//]: # (be overridden.)
[//]: # ( )
# svg-pathdata
> Manipulate SVG path data (path[d] attribute content) simply and efficiently.

[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/nfroidure/svg-pathdata/blob/main/LICENSE)
[![Coverage Status](https://coveralls.io/repos/github/nfroidure/svg-pathdata/badge.svg?branch=main)](https://coveralls.io/github/nfroidure/svg-pathdata?branch=main)

[//]: # (::contents:start)

## Usage

Install the module:

```sh
npm install --save svg-pathdata
```

Then in your JavaScript files:

```js
import {
SVGPathData,
SVGPathDataTransformer,
SVGPathDataEncoder,
SVGPathDataParser,
} from 'svg-pathdata';
```

## Reading PathData

```js
const pathData = new SVGPathData(`
M 10 10
H 60
V 60
L 10 60
Z`);

console.log(pathData.commands);

// [ {type: SVGPathData.MOVE_TO, relative: false, x: 10, y: 10},
// {type: SVGPathData.HORIZ_LINE_TO, relative: false, x: 60},
// {type: SVGPathData.VERT_LINE_TO, relative: false, y: 60},
// {type: SVGPathData.LINE_TO, relative: false, x: 10, y: 60},
// {type: SVGPathData.CLOSE_PATH}]
```

## Reading PathData in chunks

```js
const parser = new SVGPathDataParser();

parser.parse(' '); // returns []
parser.parse('M 10'); // returns []
parser.parse(' 10'); // returns [{type: SVGPathData.MOVE_TO, relative: false, x: 10, y: 10 }]

parser.write('H 60'); // returns [{type: SVGPathData.HORIZ_LINE_TO, relative: false, x: 60 }]

parser.write('V'); // returns []
parser.write('60'); // returns [{type: SVGPathData.VERT_LINE_TO, relative: false, y: 60 }]

parser.write('L 10 60 \n Z');
// returns [
// {type: SVGPathData.LINE_TO, relative: false, x: 10, y: 60 },
// {type: SVGPathData.CLOSE_PATH }]

parser.finish(); // tell parser there is no more data: will throw if there are unfinished commands.
```

## Outputting PathData

```js
const pathData = new SVGPathData(`
M 10 10
H 60
V 60
L 10 60
Z`);
// returns "M10 10H60V60L10 60Z"

encodeSVGPath({ type: SVGPathData.MOVE_TO, relative: false, x: 10, y: 10 });
// returns "M10 10"

encodeSVGPath({ type: SVGPathData.HORIZ_LINE_TO, relative: false, x: 60 });
// returns "H60"

encodeSVGPath([
{ type: SVGPathData.VERT_LINE_TO, relative: false, y: 60 },
{ type: SVGPathData.LINE_TO, relative: false, x: 10, y: 60 },
{ type: SVGPathData.CLOSE_PATH },
]);
// returns "V60L10 60Z"
```

## Transforming PathData

This library can perform transformations on SVG paths. Here is
[an example of that kind of use](https://github.com/nfroidure/svgicons2svgfont/blob/aa6df0211419e9d61c417c63bcc353f0cb2ea0c8/src/index.js#L192).

### Transforming entire paths

```js
new SVGPathData(`
m 10,10
h 60
v 60
l 10,60
z`)
.toAbs()
.encode();
// return s"M10,10 H70 V70 L80,130 Z"
```

### Transforming partial data

Here, we take SVGPathData from stdin and output it transformed to stdout.

```js
const transformingParser = new SVGPathDataParser().toAbs().scale(2, 2);
transformingParser.parse('m 0 0'); // returns [{ type: SVGPathData.MOVE_TO, relative: false, x: 0, y: 0 }]
transformingParser.parse('l 2 3'); // returns [{ type: SVGPathData.LINE_TO, relative: false, x: 4, y: 6 }]
```

## Supported transformations

You can find all supported transformations in
[src/SVGPathDataTransformer.ts](https://github.com/nfroidure/SVGPathData/blob/master/src/SVGPathDataTransformer.ts#L47).
Additionally, you can create your own by writing a function with the following
signature:

```js
type TransformFunction = (command: SVGCommand) => SVGCommand | SVGCommand[];

function SET_X_TO(xValue = 10) {
return function(command) {
command.x = xValue; // transform command objects and return them
return command;
};
};

// Synchronous usage
new SVGPathData('...')
.transform(SET_X_TO(25))
.encode();

// Chunk usage
new SVGPathDataParser().transform(SET_X_TO(25));
```

## Contributing

Clone this project, run:

```sh
npm install; npm test
```

[//]: # (::contents:end)

# API
## Functions


annotateArcCommand()


https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
Fixes rX and rY.
Ensures lArcFlag and sweepFlag are 0 or 1
Adds center coordinates: command.cX, command.cY (relative or absolute, depending on command.relative)
Adds start and end arc parameters (in degrees): command.phi1, command.phi2; phi1 < phi2 iff. c.sweepFlag == true



intersectionUnitCircleLine()


Solves a quadratic system of equations of the form
a * x + b * y = c
x² + y² = 1
This can be understood as the intersection of the unit circle with a line.
=> y = (c - a x) / b
=> x² + (c - a x)² / b² = 1
=> x² b² + c² - 2 c a x + a² x² = b²
=> (a² + b²) x² - 2 a c x + (c² - b²) = 0




arePointsCollinear(p1, p2, p3)


Determines if three points are collinear (lie on the same straight line)
and the middle point is on the line segment between the first and third points



createEllipse()


Creates an ellipse path centered at (cx,cy) with radii rx and ry



createRect()


Creates a rectangle path with optional rounded corners



createPolyline()


Creates a polyline from an array of coordinates [x1,y1,x2,y2,...]



createPolygon()


Creates a closed polygon from an array of coordinates




REMOVE_COLLINEAR(commands)


Process a path and remove collinear points




REVERSE_PATH(commands, preserveSubpathOrder)


Reverses the order of path commands to go from end to start
IMPORTANT: This function expects absolute commands as input.
It doesn't convert relative to absolute - use SVGPathDataTransformer.TO_ABS() first if needed.



## annotateArcCommand()
https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
Fixes rX and rY.
Ensures lArcFlag and sweepFlag are 0 or 1
Adds center coordinates: command.cX, command.cY (relative or absolute, depending on command.relative)
Adds start and end arc parameters (in degrees): command.phi1, command.phi2; phi1 < phi2 iff. c.sweepFlag == true

**Kind**: global function

## intersectionUnitCircleLine()
Solves a quadratic system of equations of the form
a * x + b * y = c
x² + y² = 1
This can be understood as the intersection of the unit circle with a line.
=> y = (c - a x) / b
=> x² + (c - a x)² / b² = 1
=> x² b² + c² - 2 c a x + a² x² = b²
=> (a² + b²) x² - 2 a c x + (c² - b²) = 0

**Kind**: global function

## arePointsCollinear(p1, p2, p3) ⇒
Determines if three points are collinear (lie on the same straight line)
and the middle point is on the line segment between the first and third points

**Kind**: global function
**Returns**: true if the points are collinear and p2 is on the segment p1-p3

| Param | Description |
| --- | --- |
| p1 | First point [x, y] |
| p2 | Middle point that might be removed |
| p3 | Last point [x, y] |

## createEllipse()
Creates an ellipse path centered at (cx,cy) with radii rx and ry

**Kind**: global function

## createRect()
Creates a rectangle path with optional rounded corners

**Kind**: global function

## createPolyline()
Creates a polyline from an array of coordinates [x1,y1,x2,y2,...]

**Kind**: global function

## createPolygon()
Creates a closed polygon from an array of coordinates

**Kind**: global function

## REMOVE\_COLLINEAR(commands) ⇒
Process a path and remove collinear points

**Kind**: global function
**Returns**: New array with collinear points removed

| Param | Description |
| --- | --- |
| commands | Array of SVG path commands to process (must be absolute) |

## REVERSE\_PATH(commands, preserveSubpathOrder) ⇒
Reverses the order of path commands to go from end to start
IMPORTANT: This function expects absolute commands as input.
It doesn't convert relative to absolute - use SVGPathDataTransformer.TO_ABS() first if needed.

**Kind**: global function
**Returns**: New SVG commands in reverse order with absolute coordinates

| Param | Description |
| --- | --- |
| commands | SVG path commands in absolute form to reverse |
| preserveSubpathOrder | If true, keeps subpaths in their original order |

# Authors
- [Nicolas Froidure](https://insertafter.com/en/index.html)
- [Anders Kaseorg](mailto:andersk@mit.edu)

# License
[MIT](https://github.com/nfroidure/svg-pathdata/blob/main/LICENSE)