svg-pathdata
Advanced tools
Comparing version 1.0.4 to 2.0.0
{ | ||
"name": "svg-pathdata", | ||
"version": "1.0.4", | ||
"version": "2.0.0", | ||
"description": "Parse, transform and encode SVG Path Data.", | ||
@@ -5,0 +5,0 @@ "main": "src/SVGPathData.js", |
@@ -24,2 +24,18 @@ 'use strict'; | ||
SVGPathData.prototype.normalizeHVZ = function() { | ||
return this.transform(SVGPathData.Transformer.NORMALIZE_HVZ); | ||
}; | ||
SVGPathData.prototype.normalizeST = function() { | ||
return this.transform(SVGPathData.Transformer.NORMALIZE_ST); | ||
}; | ||
SVGPathData.prototype.qtToC = function() { | ||
return this.transform(SVGPathData.Transformer.QT_TO_C); | ||
}; | ||
SVGPathData.prototype.sanitize = function() { | ||
return this.transform(SVGPathData.Transformer.SANITIZE); | ||
}; | ||
SVGPathData.prototype.translate = function() { | ||
@@ -141,2 +157,3 @@ return this.transform.apply(this, [SVGPathData.Transformer.TRANSLATE].concat( | ||
SVGPathData.ARC = 512; | ||
SVGPathData.LINE_COMMANDS = SVGPathData.LINE_TO | SVGPathData.HORIZ_LINE_TO | SVGPathData.VERT_LINE_TO | ||
SVGPathData.DRAWING_COMMANDS = | ||
@@ -143,0 +160,0 @@ SVGPathData.HORIZ_LINE_TO | SVGPathData.VERT_LINE_TO | SVGPathData.LINE_TO | |
@@ -72,4 +72,4 @@ 'use strict'; | ||
str += (commands[i].relative ? 'c' : 'C') + | ||
commands[i].x2 + WSP + commands[i].y2 + | ||
WSP + commands[i].x1 + WSP + commands[i].y1 + | ||
commands[i].x1 + WSP + commands[i].y1 + | ||
WSP + commands[i].x2 + WSP + commands[i].y2 + | ||
WSP + commands[i].x + WSP + commands[i].y; | ||
@@ -76,0 +76,0 @@ // Smooth curve to command |
@@ -231,4 +231,8 @@ 'use strict'; | ||
invalid: true, | ||
x2: Number(this.curNumber), | ||
x1: Number(this.curNumber), | ||
}; | ||
} else if('undefined' === typeof this.curCommand.x1) { | ||
this.curCommand.x1 = Number(this.curNumber); | ||
} else if('undefined' === typeof this.curCommand.y1) { | ||
this.curCommand.y1 = Number(this.curNumber); | ||
} else if('undefined' === typeof this.curCommand.x2) { | ||
@@ -238,6 +242,2 @@ this.curCommand.x2 = Number(this.curNumber); | ||
this.curCommand.y2 = Number(this.curNumber); | ||
} else if('undefined' === typeof this.curCommand.x1) { | ||
this.curCommand.x1 = Number(this.curNumber); | ||
} else if('undefined' === typeof this.curCommand.y1) { | ||
this.curCommand.y1 = Number(this.curNumber); | ||
} else if('undefined' === typeof this.curCommand.x) { | ||
@@ -244,0 +244,0 @@ this.curCommand.x = Number(this.curNumber); |
@@ -172,2 +172,263 @@ 'use strict'; | ||
// Convert H, V, Z and A with rX = 0 to L | ||
SVGPathDataTransformer.NORMALIZE_HVZ = function normalizeHVZGenerator() { | ||
var prevX = 0; | ||
var prevY = 0; | ||
var pathStartX = NaN; | ||
var pathStartY = NaN; | ||
return function normalizeHVZ(command) { | ||
if (isNaN(pathStartX) && !(command.type & SVGPathData.MOVE_TO)) { | ||
throw new Error('path must start with moveto'); | ||
} | ||
if (command.type & SVGPathData.HORIZ_LINE_TO) { | ||
command.type = SVGPathData.LINE_TO; | ||
command.y = command.relative ? 0 : prevY; | ||
} | ||
if (command.type & SVGPathData.VERT_LINE_TO) { | ||
command.type = SVGPathData.LINE_TO; | ||
command.x = command.relative ? 0 : prevX; | ||
} | ||
if (command.type & SVGPathData.CLOSE_PATH) { | ||
command.type = SVGPathData.LINE_TO; | ||
command.x = command.relative ? pathStartX - prevX : pathStartX; | ||
command.y = command.relative ? pathStartY - prevY : pathStartY; | ||
} | ||
if (command.type & SVGPathData.ARC && (0 === command.rX || 0 === command.rY)) { | ||
command.type = SVGPathData.LINE_TO; | ||
delete command.rX; | ||
delete command.rY; | ||
delete command.xRot; | ||
delete command.lArcFlag; | ||
delete command.sweepFlag; | ||
} | ||
// all commands have x and y now | ||
prevX = (command.relative ? prevX + command.x : command.x); | ||
prevY = (command.relative ? prevY + command.y : command.y); | ||
if (command.type & SVGPathData.MOVE_TO) { | ||
pathStartX = prevX; | ||
pathStartY = prevY; | ||
} | ||
return command; | ||
}; | ||
}; | ||
/** | ||
* Transforms smooth curves and quads to normal curves and quads (SsTt to CcQq) | ||
*/ | ||
SVGPathDataTransformer.NORMALIZE_ST = function normalizeCurvesGenerator() { | ||
var prevX = 0; | ||
var prevY = 0; | ||
var pathStartX = NaN; | ||
var pathStartY = NaN; | ||
var prevCurveC2X = NaN; | ||
var prevCurveC2Y = NaN; | ||
var prevQuadCX = NaN; | ||
var prevQuadCY = NaN; | ||
return function normalizeCurves(command) { | ||
if (isNaN(pathStartX) && !(command.type & SVGPathData.MOVE_TO)) { | ||
throw new Error('path must start with moveto'); | ||
} | ||
if (command.type & SVGPathData.SMOOTH_CURVE_TO) { | ||
command.type = SVGPathData.CURVE_TO; | ||
prevCurveC2X = isNaN(prevCurveC2X) ? prevX : prevCurveC2X; | ||
prevCurveC2Y = isNaN(prevCurveC2Y) ? prevY : prevCurveC2Y; | ||
command.x1 = command.relative ? prevX - prevCurveC2X : 2 * prevX - prevCurveC2X; | ||
command.y1 = command.relative ? prevY - prevCurveC2Y : 2 * prevY - prevCurveC2Y; | ||
} | ||
if (command.type & SVGPathData.CURVE_TO) { | ||
prevCurveC2X = command.relative ? prevX + command.x2 : command.x2; | ||
prevCurveC2Y = command.relative ? prevY + command.y2 : command.y2; | ||
} else { | ||
prevCurveC2X = NaN; | ||
prevCurveC2Y = NaN; | ||
} | ||
if (command.type & SVGPathData.SMOOTH_QUAD_TO) { | ||
command.type = SVGPathData.QUAD_TO; | ||
prevQuadCX = isNaN(prevQuadCX) ? prevX : prevQuadCX; | ||
prevQuadCY = isNaN(prevQuadCY) ? prevY : prevQuadCY; | ||
command.x1 = command.relative ? prevX - prevQuadCX : 2 * prevX - prevQuadCX; | ||
command.y1 = command.relative ? prevY - prevQuadCY : 2 * prevY - prevQuadCY; | ||
} | ||
if (command.type & SVGPathData.QUAD_TO) { | ||
prevQuadCX = command.relative ? prevX + command.x1 : command.x1; | ||
prevQuadCY = command.relative ? prevY + command.y1 : command.y1; | ||
} else { | ||
prevQuadCX = NaN; | ||
prevQuadCY = NaN; | ||
} | ||
if (command.type & SVGPathData.CLOSE_PATH) { | ||
prevX = pathStartX; | ||
prevY = pathStartY; | ||
} | ||
prevX = 'undefined' === typeof command.x ? prevX : | ||
(command.relative ? prevX + command.x : command.x); | ||
prevY = 'undefined' === typeof command.y ? prevY : | ||
(command.relative ? prevY + command.y : command.y); | ||
if (command.type & SVGPathData.MOVE_TO) { | ||
pathStartX = prevX; | ||
pathStartY = prevY; | ||
} | ||
return command; | ||
}; | ||
}; | ||
/** | ||
* A quadratic bézier curve can be represented by a cubic bézier curve which has | ||
* the same end points as the quadratic and both control points in place of the | ||
* quadratic's one. | ||
* | ||
* This transformer replaces QqTt commands with Cc commands respectively. | ||
* This is useful for reading path data into a system which only has a | ||
* representation for cubic curves. | ||
*/ | ||
SVGPathDataTransformer.QT_TO_C = function qtToCGenerator() { | ||
var prevX = 0; | ||
var prevY = 0; | ||
var pathStartX = NaN; | ||
var pathStartY = NaN; | ||
var prevQuadCX = NaN; | ||
var prevQuadCY = NaN; | ||
return function qtToC(command) { | ||
if (isNaN(pathStartX) && !(command.type & SVGPathData.MOVE_TO)) { | ||
throw new Error('path must start with moveto'); | ||
} | ||
if (command.type & SVGPathData.SMOOTH_QUAD_TO) { | ||
command.type = SVGPathData.QUAD_TO; | ||
prevQuadCX = isNaN(prevQuadCX) ? prevX : prevQuadCX; | ||
prevQuadCY = isNaN(prevQuadCY) ? prevY : prevQuadCY; | ||
command.x1 = command.relative ? prevX - prevQuadCX : 2 * prevX - prevQuadCX; | ||
command.y1 = command.relative ? prevY - prevQuadCY : 2 * prevY - prevQuadCY; | ||
} | ||
if (command.type & SVGPathData.QUAD_TO) { | ||
prevQuadCX = command.relative ? prevX + command.x1 : command.x1; | ||
prevQuadCY = command.relative ? prevY + command.y1 : command.y1; | ||
command.type = SVGPathData.CURVE_TO; | ||
command.x2 = command.x1; | ||
command.y2 = command.y1; | ||
} else { | ||
prevQuadCX = NaN; | ||
prevQuadCY = NaN; | ||
} | ||
if (command.type & SVGPathData.CLOSE_PATH) { | ||
prevX = pathStartX; | ||
prevY = pathStartY; | ||
} | ||
prevX = 'undefined' === typeof command.x ? prevX : | ||
(command.relative ? prevX + command.x : command.x); | ||
prevY = 'undefined' === typeof command.y ? prevY : | ||
(command.relative ? prevY + command.y : command.y); | ||
if (command.type & SVGPathData.MOVE_TO) { | ||
pathStartX = prevX; | ||
pathStartY = prevY; | ||
} | ||
return command; | ||
}; | ||
}; | ||
/** | ||
* remove 0-length segments | ||
*/ | ||
SVGPathDataTransformer.SANITIZE = function sanitizeGenerator() { | ||
var prevX = 0; | ||
var prevY = 0; | ||
var pathStartX = NaN; | ||
var pathStartY = NaN; | ||
var prevCurveC2X = NaN; | ||
var prevCurveC2Y = NaN; | ||
var prevQuadCX = NaN; | ||
var prevQuadCY = NaN; | ||
return function sanitize(command) { | ||
var skip = false; | ||
var x1Rel = 0; | ||
var y1Rel = 0; | ||
if (isNaN(pathStartX) && !(command.type & SVGPathData.MOVE_TO)) { | ||
throw new Error('path must start with moveto'); | ||
} | ||
if (command.type & SVGPathData.SMOOTH_CURVE_TO) { | ||
x1Rel = isNaN(prevCurveC2X) ? 0 : prevX - prevCurveC2X; | ||
y1Rel = isNaN(prevCurveC2Y) ? 0 : prevY - prevCurveC2Y; | ||
} | ||
if (command.type & (SVGPathData.CURVE_TO | SVGPathData.SMOOTH_CURVE_TO)) { | ||
prevCurveC2X = command.relative ? prevX + command.x2 : command.x2; | ||
prevCurveC2Y = command.relative ? prevY + command.y2 : command.y2; | ||
} else { | ||
prevCurveC2X = NaN; | ||
prevCurveC2Y = NaN; | ||
} | ||
if (command.type & SVGPathData.SMOOTH_QUAD_TO) { | ||
prevQuadCX = isNaN(prevQuadCX) ? prevX : 2 * prevX - prevQuadCX; | ||
prevQuadCY = isNaN(prevQuadCY) ? prevY : 2 * prevY - prevQuadCY; | ||
} else if (command.type & SVGPathData.QUAD_TO) { | ||
prevQuadCX = command.relative ? prevX + command.x1 : command.x1; | ||
prevQuadCY = command.relative ? prevY + command.y1 : command.y2; | ||
} else { | ||
prevQuadCX = NaN; | ||
prevQuadCY = NaN; | ||
} | ||
if (command.type & SVGPathData.LINE_COMMANDS || | ||
command.type & SVGPathData.ARC && (0 === command.rX || 0 === command.rY || !command.lArcFlag) || | ||
command.type & SVGPathData.CURVE_TO || command.type & SVGPathData.SMOOTH_CURVE_TO || | ||
command.type & SVGPathData.QUAD_TO || command.type & SVGPathData.SMOOTH_QUAD_TO) { | ||
var xRel = 'undefined' === typeof command.x ? 0 : | ||
(command.relative ? command.x : command.x - prevX); | ||
var yRel = 'undefined' === typeof command.y ? 0 : | ||
(command.relative ? command.y : command.y - prevY); | ||
x1Rel = !isNaN(prevQuadCX) ? prevQuadCX - prevX : | ||
'undefined' === typeof command.x1 ? x1Rel : | ||
command.relative ? command.x : | ||
command.x1 - prevX; | ||
y1Rel = !isNaN(prevQuadCY) ? prevQuadCY - prevY : | ||
'undefined' === typeof command.y1 ? y1Rel : | ||
command.relative ? command.y : | ||
command.y1 - prevY; | ||
var x2Rel = 'undefined' === typeof command.x2 ? 0 : | ||
(command.relative ? command.x : command.x2 - prevX); | ||
var y2Rel = 'undefined' === typeof command.y2 ? 0 : | ||
(command.relative ? command.y : command.y2 - prevY); | ||
if (0 === xRel && 0 === yRel && 0 === x1Rel && 0 === y1Rel && 0 === x2Rel && 0 === y2Rel) { | ||
skip = true; | ||
} | ||
} | ||
if (command.type & SVGPathData.CLOSE_PATH) { | ||
if (prevX === pathStartX && prevY === pathStartY) { | ||
skip = true; | ||
} else { | ||
prevX = pathStartX; | ||
prevY = pathStartY; | ||
} | ||
} | ||
prevX = 'undefined' === typeof command.x ? prevX : | ||
(command.relative ? prevX + command.x : command.x); | ||
prevY = 'undefined' === typeof command.y ? prevY : | ||
(command.relative ? prevY + command.y : command.y); | ||
if (command.type & SVGPathData.MOVE_TO) { | ||
pathStartX = prevX; | ||
pathStartY = prevY; | ||
} | ||
return skip ? [] : command; | ||
}; | ||
}; | ||
// SVG Transforms : http://www.w3.org/TR/SVGTiny12/coords.html#TransformList | ||
@@ -400,6 +661,6 @@ // Matrix : http://apike.ca/prog_svg_transform.html | ||
relative: false, | ||
x2: args[i], | ||
y2: args[i + 1], | ||
x1: args[i + 2], | ||
y1: args[i + 3], | ||
x1: args[i], | ||
y1: args[i + 1], | ||
x2: args[i + 2], | ||
y2: args[i + 3], | ||
x: args[i + 4], | ||
@@ -406,0 +667,0 @@ y: args[i + 5], |
@@ -52,6 +52,6 @@ var assert = ( | ||
assert.equal(commands[0].relative, false); | ||
assert.equal(commands[0].x2, '123'); | ||
assert.equal(commands[0].y2, '456'); | ||
assert.equal(commands[0].x1, '789'); | ||
assert.equal(commands[0].y1, '987'); | ||
assert.equal(commands[0].x1, '123'); | ||
assert.equal(commands[0].y1, '456'); | ||
assert.equal(commands[0].x2, '789'); | ||
assert.equal(commands[0].y2, '987'); | ||
assert.equal(commands[0].x, '654'); | ||
@@ -65,6 +65,6 @@ assert.equal(commands[0].y, '321'); | ||
assert.equal(commands[0].relative, false); | ||
assert.equal(commands[0].x2, '123'); | ||
assert.equal(commands[0].y2, '456'); | ||
assert.equal(commands[0].x1, '789'); | ||
assert.equal(commands[0].y1, '987'); | ||
assert.equal(commands[0].x1, '123'); | ||
assert.equal(commands[0].y1, '456'); | ||
assert.equal(commands[0].x2, '789'); | ||
assert.equal(commands[0].y2, '987'); | ||
assert.equal(commands[0].x, '654'); | ||
@@ -80,6 +80,6 @@ assert.equal(commands[0].y, '321'); | ||
assert.equal(commands[0].relative, false); | ||
assert.equal(commands[0].x2, '-10.0032e-5'); | ||
assert.equal(commands[0].y2, '-20.0032e-5'); | ||
assert.equal(commands[0].x1, '-30.0032e-5'); | ||
assert.equal(commands[0].y1, '-40.0032e-5'); | ||
assert.equal(commands[0].x1, '-10.0032e-5'); | ||
assert.equal(commands[0].y1, '-20.0032e-5'); | ||
assert.equal(commands[0].x2, '-30.0032e-5'); | ||
assert.equal(commands[0].y2, '-40.0032e-5'); | ||
assert.equal(commands[0].x, '-50.0032e-5'); | ||
@@ -97,6 +97,6 @@ assert.equal(commands[0].y, '-60.0032e-5'); | ||
assert.equal(commands[0].relative, false); | ||
assert.equal(commands[0].x2, '-10.0032e-5'); | ||
assert.equal(commands[0].y2, '-20.0032e-5'); | ||
assert.equal(commands[0].x1, '-30.0032e-5'); | ||
assert.equal(commands[0].y1, '-40.0032e-5'); | ||
assert.equal(commands[0].x1, '-10.0032e-5'); | ||
assert.equal(commands[0].y1, '-20.0032e-5'); | ||
assert.equal(commands[0].x2, '-30.0032e-5'); | ||
assert.equal(commands[0].y2, '-40.0032e-5'); | ||
assert.equal(commands[0].x, '-50.0032e-5'); | ||
@@ -106,6 +106,6 @@ assert.equal(commands[0].y, '-60.0032e-5'); | ||
assert.equal(commands[1].relative, false); | ||
assert.equal(commands[1].x2, '-10.0032e-5'); | ||
assert.equal(commands[1].y2, '-20.0032e-5'); | ||
assert.equal(commands[1].x1, '-30.0032e-5'); | ||
assert.equal(commands[1].y1, '-40.0032e-5'); | ||
assert.equal(commands[1].x1, '-10.0032e-5'); | ||
assert.equal(commands[1].y1, '-20.0032e-5'); | ||
assert.equal(commands[1].x2, '-30.0032e-5'); | ||
assert.equal(commands[1].y2, '-40.0032e-5'); | ||
assert.equal(commands[1].x, '-50.0032e-5'); | ||
@@ -115,6 +115,6 @@ assert.equal(commands[1].y, '-60.0032e-5'); | ||
assert.equal(commands[2].relative, false); | ||
assert.equal(commands[2].x2, '-10.0032e-5'); | ||
assert.equal(commands[2].y2, '-20.0032e-5'); | ||
assert.equal(commands[2].x1, '-30.0032e-5'); | ||
assert.equal(commands[2].y1, '-40.0032e-5'); | ||
assert.equal(commands[2].x1, '-10.0032e-5'); | ||
assert.equal(commands[2].y1, '-20.0032e-5'); | ||
assert.equal(commands[2].x2, '-30.0032e-5'); | ||
assert.equal(commands[2].y2, '-40.0032e-5'); | ||
assert.equal(commands[2].x, '-50.0032e-5'); | ||
@@ -132,6 +132,6 @@ assert.equal(commands[2].y, '-60.0032e-5'); | ||
assert.equal(commands[0].relative, false); | ||
assert.equal(commands[0].x2, '-10.0032e-5'); | ||
assert.equal(commands[0].y2, '-20.0032e-5'); | ||
assert.equal(commands[0].x1, '-30.0032e-5'); | ||
assert.equal(commands[0].y1, '-40.0032e-5'); | ||
assert.equal(commands[0].x1, '-10.0032e-5'); | ||
assert.equal(commands[0].y1, '-20.0032e-5'); | ||
assert.equal(commands[0].x2, '-30.0032e-5'); | ||
assert.equal(commands[0].y2, '-40.0032e-5'); | ||
assert.equal(commands[0].x, '-50.0032e-5'); | ||
@@ -141,6 +141,6 @@ assert.equal(commands[0].y, '-60.0032e-5'); | ||
assert.equal(commands[1].relative, true); | ||
assert.equal(commands[1].x2, '-10.0032e-5'); | ||
assert.equal(commands[1].y2, '-20.0032e-5'); | ||
assert.equal(commands[1].x1, '-30.0032e-5'); | ||
assert.equal(commands[1].y1, '-40.0032e-5'); | ||
assert.equal(commands[1].x1, '-10.0032e-5'); | ||
assert.equal(commands[1].y1, '-20.0032e-5'); | ||
assert.equal(commands[1].x2, '-30.0032e-5'); | ||
assert.equal(commands[1].y2, '-40.0032e-5'); | ||
assert.equal(commands[1].x, '-50.0032e-5'); | ||
@@ -150,6 +150,6 @@ assert.equal(commands[1].y, '-60.0032e-5'); | ||
assert.equal(commands[2].relative, false); | ||
assert.equal(commands[2].x2, '-10.0032e-5'); | ||
assert.equal(commands[2].y2, '-20.0032e-5'); | ||
assert.equal(commands[2].x1, '-30.0032e-5'); | ||
assert.equal(commands[2].y1, '-40.0032e-5'); | ||
assert.equal(commands[2].x1, '-10.0032e-5'); | ||
assert.equal(commands[2].y1, '-20.0032e-5'); | ||
assert.equal(commands[2].x2, '-30.0032e-5'); | ||
assert.equal(commands[2].y2, '-40.0032e-5'); | ||
assert.equal(commands[2].x, '-50.0032e-5'); | ||
@@ -156,0 +156,0 @@ assert.equal(commands[2].y, '-60.0032e-5'); |
@@ -272,6 +272,6 @@ var assert = ( | ||
assert.equal(commands[4].y, 220); | ||
assert.equal(commands[4].x1, -60); | ||
assert.equal(commands[4].y1, 140); | ||
assert.equal(commands[4].x2, -70); | ||
assert.equal(commands[4].y2, 130); | ||
assert.equal(commands[4].x2, -60); | ||
assert.equal(commands[4].y2, 140); | ||
assert.equal(commands[4].x1, -70); | ||
assert.equal(commands[4].y1, 130); | ||
}); | ||
@@ -560,8 +560,8 @@ | ||
assert.equal(commands[4].y, 0); | ||
assert.equal(commands[4].x1, 0); | ||
assert.equal(commands[4].y1, -200); | ||
assert.equal(commands[4].x2, -10); | ||
assert.equal(commands[4].y2, -210); | ||
assert.equal(commands[4].x2, 0); | ||
assert.equal(commands[4].y2, -200); | ||
assert.equal(commands[4].x1, -10); | ||
assert.equal(commands[4].y1, -210); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
426574
46
9476
39