Gathering detailed insights and metrics for svg-path-commander
Gathering detailed insights and metrics for svg-path-commander
Gathering detailed insights and metrics for svg-path-commander
Gathering detailed insights and metrics for svg-path-commander
@swenkerorg/illo-quasi
[![github actions][actions-image]][actions-url] [![coverage][codecov-image]][codecov-url] [![dependency status][deps-svg]][deps-url] [![dev dependency status][dev-deps-svg]][dev-deps-url] [![License][license-image]][license-url] [![Downloads][downloads-im
@dramaorg/delectus-culpa-reprehenderit
[![github actions][actions-image]][actions-url] [![coverage][codecov-image]][codecov-url] [![dependency status][deps-svg]][deps-url] [![dev dependency status][dev-deps-svg]][dev-deps-url] [![License][license-image]][license-url] [![Downloads][downloads-im
@crabas0npm2/laudantium-maxime-veritatis
[![github actions][actions-image]][actions-url] [![coverage][codecov-image]][codecov-url] [![dependency status][deps-svg]][deps-url] [![dev dependency status][dev-deps-svg]][dev-deps-url] [![License][license-image]][license-url] [![Downloads][downloads-im
@teamteanpm2024/non-iusto-reprehenderit
[![github actions][actions-image]][actions-url] [![coverage][codecov-image]][codecov-url] [![dependency status][deps-svg]][deps-url] [![dev dependency status][dev-deps-svg]][dev-deps-url] [![License][license-image]][license-url] [![Downloads][downloads-im
🛹 Typescript tools for advanced processing of SVG path data.
npm install svg-path-commander
Typescript
Module System
Min. Node Version
Node Version
NPM Version
91.8
Supply Chain
100
Quality
82.5
Maintenance
100
Vulnerability
100
License
TypeScript (100%)
Total Downloads
755,679
Last Day
2,457
Last Week
12,361
Last Month
50,657
Last Year
533,057
MIT License
257 Stars
291 Commits
23 Forks
6 Watchers
2 Branches
13 Contributors
Updated on May 03, 2025
Minified
Minified + Gzipped
Latest Version
2.1.10
Package Id
svg-path-commander@2.1.10
Unpacked Size
879.16 kB
Size
213.89 kB
File Count
11
NPM Version
11.0.0
Node Version
23.5.0
Published on
Feb 06, 2025
Cumulative downloads
Total Downloads
Last Day
-10.1%
2,457
Compared to previous day
Last Week
4.5%
12,361
Compared to previous week
Last Month
7.5%
50,657
Compared to previous month
Last Year
263.9%
533,057
Compared to previous year
1
A modern set of Typescript tools for manipulating the d
(description) attribute for SVGPathElement items. The library is implementing modern JavaScript API to produce reusable path strings with lossless quality. In addition, you also have a powerful tool to convert other SVG shapes like <circle>
or <rect>
to <path>
.
While you may find familiar tools inside, this library brings new additions:
getBBox
, getPointAtLength
and getTotalLength
are more reliable and much more accurate than the native methods, not to mention their high performance ratings;getPropertiesAtLength
, getSegmentOfPoint
or isPointInStroke
;The key differences with other libraries:
SVGPathCommander can use the DOMMatrix API for SVGPathElement path command transformation and implements a very fast and modernized DOMMatrix shim. There are a couple of good reasons for this implementation:
This library is available on CDN and npm.
npm install svg-path-commander
1<script src="https://cdn.jsdelivr.net/npm/svg-path-commander/dist/svg-path-commander.js">
Flip a path on the X axis:
1import SVGPathCommander from 'svg-path-commander'; 2 3const path = 'M0 0L100 0L50 100'; 4 5const flippedPathString = new SVGPathCommander(path).flipX().toString(); 6// result => 'M0 100h100L50 0'
Optimize a path string by using the round
option, to round numbers to 2 decimals and finding shorthand where possible:
1const optimizedPathString = new SVGPathCommander(path, {round: 2}).optimize().toString();
Or why not apply a 2D transformation and even a 3D transformation:
1// a transform object 2const transform = { 3 translate: 15, // X axis translation 4 rotate: 15, // Z axis rotation 5 scale: 0.75, // uniform scale on X, Y, Z axis 6 skew: 15, // skew 15deg on the X axis 7 origin: [15, 0] // if not specified, it will use the default origin value [0, 0] 8} 9const transformed2DPathString = new SVGPathCommander(path).transform(transform).toString(); 10 11// apply a 3D transformation 12const transform = { 13 translate: [15, 15, 15], // `[15, 15]` would apply a 2D translation, and only `15` for X axis translation 14 rotate: [15, 15, 15], // or only "15" for 2D rotation on Z axis 15 scale: [0.7, 0.75, 0.8], // or only "0.7" for 2D scale on all X, Y, Z axis 16 skew: [15, 15], // or only "15" for the X axis 17 origin: [15, 15, 15] // full `transform-origin` for a typical 3D transformation 18} 19const transformed3DPathString = new SVGPathCommander(path).transform(transform).toString();
Access the bbox
instance property to apply a consistent transform-origin
:
1// apply a 3D transformation with a consistent origin 2const transformed3DPath = new SVGPathCommander(path); 3const { cx, cy, cz } = transformed3DPath.bbox; 4const transform = { 5 translate: [15, 15, 15], // `[15, 15]` would apply a 2D translation, and only `15` for X axis translation 6 rotate: [15, 15, 15], // or only "15" for 2D rotation on Z axis 7 scale: [0.7, 0.75, 0.8], // or only "0.7" for 2D scale on all X, Y, Z axis 8 skew: [15, 15], // or only "15" for the X axis 9 origin: [cx, cy, cz] // the origin 10} 11const transformed3DPathString = transformed3DPath.transform(transform).toString();
SVGPathCommander comes with a full range of additional static methods, here's how to normalize a path:
1const path = 'M0 0 H50'; 2 3const normalizedPath = SVGPathCommander.normalizePath(path); 4// result => [['M', 0, 0], ['L', 50, 0]]
Reverse a path:
1const path = SVGPathCommander.parsePathString('M0 0 H50'); 2 3const reversedPath = SVGPathCommander.reversePath(path); 4// result => [['M', 50, 0], ['H', 0]]
Export to string:
1const myPathString = SVGPathCommander.pathToString([['M', 0, 0], ['L', 50, 0]]); 2// result => 'M0 0 L50 0'
Check a path string validity:
1SVGPathCommander.isValidPath(path);
2// result => boolean
Check if path is a certain kind of PathArray
:
1SVGPathCommander.isAbsoluteArray([['M', 0, 0], ['L', 50, 0]]); 2// result => true
Use treeshake and create a custom function to apply a 3D transformation using static methods:
1import { parsePathString, getPathBBox, transformPath, pathToString } from 'svg-path-commander';
2
3function myTransformFn(pathInput: string | PathArray, transformObject: TransformObject) {
4 const path = parsePathString(pathInput);
5 const { cx, cy, cz } = getPathBBox(path);
6
7 return pathToString(
8 transformPath(path, {
9 ...transformObject, origin: [cx, cy, cz]
10 })
11 )
12}
In extreme cases where performance is paramount, you can consider the parent SVG viewBox
attribute to extract a bounding box required for a consistent transform origin.
1// const svgViewBox = document.getElementById('my-svg').getAttribute('viewBox'); 2const viewBox = '0 0 24 24'; 3 4const [x, y, width, height] = viewBox.split(/\s/).map(Number); 5const origin = [ 6 x + width / 2, // CX 7 y + height / 2, // CY 8 Math.max(width, height) + Math.min(width, height) / 2, // CZ 9]; 10 11// use this origin for your shape transformation 12const myNewString = new SVGPathCommander('M0 0 H50') 13 .transform({ rotate: [35, 0, 0], origin }) 14 .toString();
Convert a shape to <path>
and transfer all non-specific attributes
1const myCircle = document.getElementById('myCircle');
2SVGPathCommander.shapeToPath(myCircle, true);
Alternatively you can create <path>
from specific attributes:
1const myRectAttr = { 2 type: 'rect', 3 x: 25, 4 y: 25, 5 width: 50, 6 height: 50, 7 rx: 5 8}; 9 10const myRectPath = SVGPathCommander.shapeToPath(myRectAttr); 11document.getElementById('mySVG').append(myRectPath);
Server-side using jsdom
:
1const { document } = new JSDOM(
2 `<html>
3 <head></head>
4 <body>
5 <svg id="mySVG" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
6 <rect id="myRect" x="0" width="100" height="100" rx="15" />
7 </svg>
8 </body>
9</html>`,
10 {
11 pretendToBeVisual: true,
12 }
13).window;
14
15const myRect = document.getElementById('myRect');
16SVGPathCommander.shapeToPath(myRect, true, document);
Get the path length:
1const myPathLength = SVGPathCommander.getTotalLength('M0 0L50 0L25 50z'); 2// result => 161.80339887498948
Get a point along the path:
1const myPoint = SVGPathCommander.getPointAtLength('M0 0L50 0L25 50z', 85); 2// result => {x: 34.34752415750147, y: 31.304951684997057}
Get the path bounding box:
1const myPathBBox = SVGPathCommander.getPathBBox('M0 0L50 0L25 50z'); 2// result => {width: 50, height: 50, x: 0, y: 0, x2: 50, y2: 50, cx: 25, cy: 25, cz: 75}
For developer guidelines, and a complete list of static methods, head over to the wiki pages.
optimize()
instance method will not merge path segments (for instance two or more cubic-bezier segments into one or more arc segments); however, the script will try to provide shorthand notations where possible, pick the shortest string for each segment, and generally try to deliver the best possible outcome;pathToString
, optimizePath
and especially roundPath
will always round values to the default of 4 decimals; EG: 0.56676 => 0.567, 0.50 => 0.5; you can change the default option with SVGPathCommander.options.round = 2
or remove the value rounding all together with SVGPathCommander.options.round = false
; you can also control this feature via instance options;getSVGMatrix
utility we developed will always compute the matrix by applying the transform functions in the following order: translate
, rotate
, skew
and scale
, which is the default composition/recomposition order specified in the W3C draft;A
(arc) path commands to C
(cubic bezier) due to the lack of resources;R
(catmulRomBezier), O
, U
(ellipse and shorthand ellipse) are not present in the current draft and are not supported;SVGPathElement.getTotalLength()
or SVGPathElement.getPointAtLength()
, the output of our static methods is within a [0.002 - 0.05] margin delta, but from our experience it's proven to be a more consistent outcome.SVGPathCommander is released under MIT Licence.
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
SAST tool detected but not run on all commits
Details
Reason
7 existing vulnerabilities detected
Details
Reason
Found 4/18 approved changesets -- score normalized to 2
Reason
2 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 2
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Score
Last Scanned on 2025-05-05
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More