diff --git a/README.md b/README.md
index 8a3365c..dbc2b73 100644
--- a/README.md
+++ b/README.md
@@ -137,17 +137,35 @@ const b = [
const interpolator = interpolatePathCommands(a, b);
-let result = interpolator(0);
-/* => [
+> interpolator(0);
+[
{ type: 'M', x: 0, y: 0 },
{ type: 'L', x: 5, y: 5 },
{ type: 'L', x: 10, y: 10 },
-] */
+]
-result = interpolator(0.5);
-/* => [
+> interpolator(0.5);
+[
{ type: 'M', x: 5, y: 5 },
{ type: 'L', x: 12.5, y: 12.5 },
{ type: 'L', x: 105, y: 105 },
-] */
+]
+```
+
+
+
+# pathCommandsFromString(*pathDString*)
+
+Converts a path `d` string into an array of path command objects to work with [**interpolatePathCommands**](#interpolatePathCommands).
+
+Example usage:
+
+```js
+const a = 'M0,0L10,10';
+
+> pathCommandsFromString(a)
+[
+ { type: 'M', x: 0, y: 0 },
+ { type: 'L', x: 10, y: 10 },
+]
```
diff --git a/docs/d3-interpolate-path.js b/docs/d3-interpolate-path.js
index 2722878..c96be2a 100644
--- a/docs/d3-interpolate-path.js
+++ b/docs/d3-interpolate-path.js
@@ -294,7 +294,7 @@ function splitCurve(commandStart, commandEnd, segmentCount) {
return splitCurveAsPoints(points, segmentCount).map(pointsToCommand);
}
-var commandTokenRegex = /[MLCSTQAHVmlcstqahv]|-?[\d.e+-]+/g;
+var commandTokenRegex = /[MLCSTQAHVZmlcstqahv]|-?[\d.e+-]+/g;
/**
* List of params for each command type in a path `d` attribute
*/
@@ -308,7 +308,8 @@ var typeMap = {
S: ['x2', 'y2', 'x', 'y'],
Q: ['x1', 'y1', 'x', 'y'],
T: ['x', 'y'],
- A: ['rx', 'ry', 'xAxisRotation', 'largeArcFlag', 'sweepFlag', 'x', 'y']
+ A: ['rx', 'ry', 'xAxisRotation', 'largeArcFlag', 'sweepFlag', 'x', 'y'],
+ Z: []
}; // Add lower case entries too matching uppercase (e.g. 'm' == 'M')
Object.keys(typeMap).forEach(function (key) {
@@ -522,7 +523,7 @@ function extend(commandsToExtend, referenceCommands, excludeSegment) {
*/
-function makeCommands(d) {
+function pathCommandsFromString(d) {
// split into valid tokens
var tokens = (d || '').match(commandTokenRegex) || [];
var commands = [];
@@ -568,7 +569,6 @@ function makeCommands(d) {
* @returns {Function} Interpolation function that maps t ([0, 1]) to an array of path commands.
*/
-
function interpolatePathCommands(aCommandsInput, bCommandsInput, excludeSegment) {
// make a copy so we don't mess with the input arrays
var aCommands = aCommandsInput == null ? [] : aCommandsInput.slice();
@@ -578,7 +578,7 @@ function interpolatePathCommands(aCommandsInput, bCommandsInput, excludeSegment)
return function nullInterpolator() {
return [];
};
- } // do we add Z during interpolation? yes if either one has it. (we'd expect both to have it or not)
+ } // do we add Z during interpolation? yes if both have it. (we'd expect both to have it or not)
var addZ = (aCommands.length === 0 || aCommands[aCommands.length - 1].type === 'Z') && (bCommands.length === 0 || bCommands[bCommands.length - 1].type === 'Z'); // we temporarily remove Z
@@ -638,7 +638,7 @@ function interpolatePathCommands(aCommandsInput, bCommandsInput, excludeSegment)
if (t > 0) {
for (var i = 0; i < interpolatedCommands.length; ++i) {
- if (interpolatedCommands[i].type === 'Z') continue;
+ // if (interpolatedCommands[i].type === 'Z') continue;
var aCommand = aCommands[i];
var bCommand = bCommands[i];
var interpolatedCommand = interpolatedCommands[i];
@@ -681,9 +681,8 @@ function interpolatePathCommands(aCommandsInput, bCommandsInput, excludeSegment)
*/
function interpolatePath(a, b, excludeSegment) {
- // note this removes Z
- var aCommands = makeCommands(a);
- var bCommands = makeCommands(b);
+ var aCommands = pathCommandsFromString(a);
+ var bCommands = pathCommandsFromString(b);
if (!aCommands.length && !bCommands.length) {
return function nullInterpolator() {
@@ -691,7 +690,6 @@ function interpolatePath(a, b, excludeSegment) {
};
}
- var addZ = (a == null || a[a.length - 1] === 'Z') && (b == null || b[b.length - 1] === 'Z');
var commandInterpolator = interpolatePathCommands(aCommands, bCommands, excludeSegment);
return function pathStringInterpolator(t) {
// at 1 return the final value without the extensions used during interpolation
@@ -717,16 +715,13 @@ function interpolatePath(a, b, excludeSegment) {
_iterator2.f();
}
- if (addZ) {
- interpolatedString += 'Z';
- }
-
return interpolatedString;
};
}
exports.interpolatePath = interpolatePath;
exports.interpolatePathCommands = interpolatePathCommands;
+exports.pathCommandsFromString = pathCommandsFromString;
Object.defineProperty(exports, '__esModule', { value: true });
diff --git a/index.js b/index.js
index 0e9c5c5..a99f00f 100644
--- a/index.js
+++ b/index.js
@@ -1,4 +1,5 @@
export {
default as interpolatePath,
interpolatePathCommands,
+ pathCommandsFromString,
} from './src/interpolatePath';
diff --git a/src/interpolatePath.js b/src/interpolatePath.js
index 3125baf..78a0101 100644
--- a/src/interpolatePath.js
+++ b/src/interpolatePath.js
@@ -1,6 +1,6 @@
import splitCurve from './split';
-const commandTokenRegex = /[MLCSTQAHVmlcstqahv]|-?[\d.e+-]+/g;
+const commandTokenRegex = /[MLCSTQAHVZmlcstqahv]|-?[\d.e+-]+/g;
/**
* List of params for each command type in a path `d` attribute
*/
@@ -14,6 +14,7 @@ const typeMap = {
Q: ['x1', 'y1', 'x', 'y'],
T: ['x', 'y'],
A: ['rx', 'ry', 'xAxisRotation', 'largeArcFlag', 'sweepFlag', 'x', 'y'],
+ Z: [],
};
// Add lower case entries too matching uppercase (e.g. 'm' == 'M')
@@ -264,7 +265,7 @@ function extend(commandsToExtend, referenceCommands, excludeSegment) {
*
* @param {String|null} d A path `d` string
*/
-function makeCommands(d) {
+export function pathCommandsFromString(d) {
// split into valid tokens
const tokens = (d || '').match(commandTokenRegex) || [];
const commands = [];
@@ -329,7 +330,7 @@ export function interpolatePathCommands(
};
}
- // do we add Z during interpolation? yes if either one has it. (we'd expect both to have it or not)
+ // do we add Z during interpolation? yes if both have it. (we'd expect both to have it or not)
const addZ =
(aCommands.length === 0 || aCommands[aCommands.length - 1].type === 'Z') &&
(bCommands.length === 0 || bCommands[bCommands.length - 1].type === 'Z');
@@ -390,7 +391,7 @@ export function interpolatePathCommands(
// we can skip at t=0 since we copied aCommands to begin
if (t > 0) {
for (let i = 0; i < interpolatedCommands.length; ++i) {
- if (interpolatedCommands[i].type === 'Z') continue;
+ // if (interpolatedCommands[i].type === 'Z') continue;
const aCommand = aCommands[i];
const bCommand = bCommands[i];
@@ -425,9 +426,8 @@ export function interpolatePathCommands(
* @returns {Function} Interpolation function that maps t ([0, 1]) to a path `d` string.
*/
export default function interpolatePath(a, b, excludeSegment) {
- // note this removes Z
- let aCommands = makeCommands(a);
- let bCommands = makeCommands(b);
+ let aCommands = pathCommandsFromString(a);
+ let bCommands = pathCommandsFromString(b);
if (!aCommands.length && !bCommands.length) {
return function nullInterpolator() {
@@ -435,10 +435,6 @@ export default function interpolatePath(a, b, excludeSegment) {
};
}
- const addZ =
- (a == null || a[a.length - 1] === 'Z') &&
- (b == null || b[b.length - 1] === 'Z');
-
const commandInterpolator = interpolatePathCommands(
aCommands,
bCommands,
@@ -458,9 +454,6 @@ export default function interpolatePath(a, b, excludeSegment) {
for (const interpolatedCommand of interpolatedCommands) {
interpolatedString += commandToString(interpolatedCommand);
}
- if (addZ) {
- interpolatedString += 'Z';
- }
return interpolatedString;
};
diff --git a/test/interpolatePathCommands-test.js b/test/interpolatePathCommands-test.js
index 3c3f63c..f896cc5 100644
--- a/test/interpolatePathCommands-test.js
+++ b/test/interpolatePathCommands-test.js
@@ -78,8 +78,6 @@ tape(
{ type: 'L', x: 20, y: 20 },
];
- ('M10,10L20,20');
-
const interpolator = interpolatePathCommands(aCommands, bCommands);
t.same(interpolator(0), aCommands);