
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
svg-path-d
Advanced tools
SVG path data ('d' attribute) manipulation library.
A path definition is a list of path commands where each command is composed of a command letter and numbers that represent the command parameters. MDN Web Docs
npm i svg-path-d
import * as SPD from "svg-path-d";
The PathNode[] is used to represent and manipulate a sequence of path draw commands.
It can be created from a string via the fromString(pathData: string): PathNode[] method.
let heart = "M50 30a20 20 0 0140 0q0 30-40 60-40-30-40-60a20 20 0 0140 0z";
let path = SPD.fromString(heart);
It also can be programmatically generated on the fly.
function createHeart(cx: number, cy: number, r: number): SPD.PathNode[] {
return SPD.makePath([
{ name: "M", x: cx, y: cy - r },
{
name: "A",
rx: r,
ry: r,
angle: 0,
largeArcFlag: false,
sweepFlag: true,
x: cx + 2 * r,
y: cy - r
},
{
name: "Q",
x1: cx + 2 * r,
y1: cy + r / 2,
x: cx,
y: cy + 2 * r
},
{
name: "Q",
x1: cx - 2 * r,
y1: cy + r / 2,
x: cx - 2 * r,
y: cy - r
},
{
name: "A",
rx: r,
ry: r,
angle: 0,
largeArcFlag: false,
sweepFlag: true,
x: cx,
y: cy - r
},
{ name: "Z" }
]);
}
This can also be done with PathBuilder.
function createHeart(
cx: number,
cy: number,
r: number
): SPD.PathNode[] {
return new SPD.PathBuilder()
.M(cx, cy - r)
.a(r, r, 0, 0, 1, 2 * r, 0)
.q(0, (3 * r) / 2, -2 * r, 3 * r)
.q(-2 * r, (-3 * r) / 2, -2 * r, -3 * r)
.a(r, r, 0, 0, 1, 2 * r, 0)
.z().path;
}
Path manipulation (or path handling) is the process of changing, transforming, splitting or analyzing paths.
applyTranslate(item: DrawTo, dx: number, dy: number): void;applyVerticalFlip(item: DrawTo): void;applyHorizontalFlip(item: DrawTo): void;PathNode[].createTransformed(path: PathNode[], matrix: ReadonlyMatrix): PathNode[];createReversed(items: PathNode[]): PathNode[];// TODO: Add path node manipulation examples here. (splitter/promoter/bounding-rect)
There are two functions which can convert to string individual path draw commands:
asString(item: Readonly<DrawTo>, fractionDigits = -1): string;asRelativeString(item: Readonly<PathNode>, fractionDigits = -1): string;So we can convert a PathNode[] with a desired precision:
const PRECISION = 3;
function pathToString(path: SPD.PathNode[]): string {
return path.map(item => SPD.asString(item, PRECISION)).join("");
}
function pathToRelativeString(path: SPD.PathNode[]): string {
return path.map(item => SPD.asRelativeString(item, PRECISION)).join("");
}
function pathToShortestString(path: SPD.PathNode[]): string {
return path
.map(item => {
const s1 = SPD.asString(item, PRECISION);
const s2 = SPD.asRelativeString(item, PRECISION);
return s1.length < s2.length ? s1 : s2;
})
.join("");
}
const heart = "M10 30a20 20 0 01 40 0 20 20 0 01 40 0q0 30-40 60-40-30-40-60z";
const pathHeart = SPD.fromString(heart);
const pathTriangle = SPD.createReveresed(SPD.makePath(pathHeart.map(toLine)));
const triangle = pathTriangle.map(item => SPD.asString(item)).join("");
const box = SPD.getBoundingRect(pathHeart);
const appDiv: HTMLElement = document.getElementById("app");
appDiv.innerHTML = `
<h1>Heart</h1>
<div>
<svg viewBox="${toViewBox(
box.left - 1,
box.top - 1,
box.right - box.left + 2,
box.bottom - box.top + 2
)}">
<path fill="red" d="${heart + triangle}"/>
</svg>
</div>
`;
function toLine(item: SPD.PathNode): SPD.PathNode {
return SPD.isClosePath(item) || SPD.isMoveTo(item)
? { ...item }
: { name: "L", x: SPD.getX(item), y: SPD.getY(item) };
}
function toViewBox(x: number, y: number, width: number, height: number) {
return `${x} ${y} ${width} ${height}`;
}
// ...
const pathHeart = SPD.fromString(heart);
const pathTriangle = SPD.makePath(pathHeart.map(toLine));
const morph = SPD.makeInterpolator(pathHeart, pathTriangle);
const src = morph(0).join("");
const dst = morph(1).join("");
const box = SPD.getBoundingRect(pathHeart);
const appDiv: HTMLElement = document.getElementById("app");
appDiv.innerHTML = `
<h1>Heart Morph</h1>
<div>
<svg viewBox="${toViewBox(
box.left - 1,
box.top - 1,
box.right - box.left + 2,
box.bottom - box.top + 2
)}">
<path fill="red" d="${src}">
<animate id="animate1" begin="1s;animate2.end + 2s" repeatCount="1" fill="freeze" attributeName="d" dur="1s"
values="${src}; ${dst}" />
<animate id="animate2" begin="animate1.end + 2s" repeatCount="1" fill="freeze" attributeName="d" dur="1s"
values="${dst}; ${src}" />
</path>
</svg>
</div>
`;
// ...
FAQs
SVG path data (path[d] attribute content) manipulation library.
We found that svg-path-d demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.