Skip to content

Commit

Permalink
Exposes pathCommandsFromString
Browse files Browse the repository at this point in the history
  • Loading branch information
pbeshai committed Jul 15, 2020
1 parent b1084d2 commit 234d24e
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 36 deletions.
30 changes: 24 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
] */
]
```



<a href="#pathCommandsFromString" name="pathCommandsFromString">#</a> <b>pathCommandsFromString</b>(*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 },
]
```
23 changes: 9 additions & 14 deletions docs/d3-interpolate-path.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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) {
Expand Down Expand Up @@ -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 = [];
Expand Down Expand Up @@ -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();
Expand All @@ -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
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -681,17 +681,15 @@ 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() {
return '';
};
}

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
Expand All @@ -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 });

Expand Down
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export {
default as interpolatePath,
interpolatePathCommands,
pathCommandsFromString,
} from './src/interpolatePath';
21 changes: 7 additions & 14 deletions src/interpolatePath.js
Original file line number Diff line number Diff line change
@@ -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
*/
Expand All @@ -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')
Expand Down Expand Up @@ -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 = [];
Expand Down Expand Up @@ -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');
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -425,20 +426,15 @@ 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() {
return '';
};
}

const addZ =
(a == null || a[a.length - 1] === 'Z') &&
(b == null || b[b.length - 1] === 'Z');

const commandInterpolator = interpolatePathCommands(
aCommands,
bCommands,
Expand All @@ -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;
};
Expand Down
2 changes: 0 additions & 2 deletions test/interpolatePathCommands-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ tape(
{ type: 'L', x: 20, y: 20 },
];

('M10,10L20,20');

const interpolator = interpolatePathCommands(aCommands, bCommands);

t.same(interpolator(0), aCommands);
Expand Down

0 comments on commit 234d24e

Please sign in to comment.