Skip to content

Commit

Permalink
Add snap ends option
Browse files Browse the repository at this point in the history
  • Loading branch information
andyrichardson committed Aug 18, 2022
1 parent c673a76 commit 45e1db5
Showing 1 changed file with 29 additions and 7 deletions.
36 changes: 29 additions & 7 deletions src/interpolatePath.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,19 +310,30 @@ export function pathCommandsFromString(d) {
*
* @param {Object[]} aCommandsInput Array of path commands
* @param {Object[]} bCommandsInput Array of path commands
* @param {Function} excludeSegment a function that takes a start command object and
* @param {(Function|Object)} interpolateOptions
* @param {Function} interpolateOptions.excludeSegment a function that takes a start command object and
* end command object and returns true if the segment should be excluded from splitting.
* @param {Boolean} interpolateOptions.snapEndsToInput a boolean indicating whether end of input should
* be sourced from input argument or computed.
* @returns {Function} Interpolation function that maps t ([0, 1]) to an array of path commands.
*/
export function interpolatePathCommands(
aCommandsInput,
bCommandsInput,
excludeSegment
interpolateOptions
) {
// make a copy so we don't mess with the input arrays
let aCommands = aCommandsInput == null ? [] : aCommandsInput.slice();
let bCommands = bCommandsInput == null ? [] : bCommandsInput.slice();

const { excludeSegment, snapEndsToInput } =
typeof interpolateOptions === "object"
? interpolateOptions
: {
excludeSegment: interpolateOptions,
snapEndsToInput: false,
};

// both input sets are empty, so we don't interpolate
if (!aCommands.length && !bCommands.length) {
return function nullInterpolator() {
Expand Down Expand Up @@ -384,7 +395,7 @@ export function interpolatePathCommands(

return function pathCommandInterpolator(t) {
// at 1 return the final value without the extensions used during interpolation
if (t === 1) {
if (t === 1 && snapEndsToInput) {
return bCommandsInput == null ? [] : bCommandsInput;
}

Expand Down Expand Up @@ -423,14 +434,25 @@ export function interpolatePathCommands(
*
* @param {String} a The `d` attribute for a path
* @param {String} b The `d` attribute for a path
* @param {Function} excludeSegment a function that takes a start command object and
* @param {(Function|Object)} interpolateOptions
* @param {Function} interpolateOptions.excludeSegment a function that takes a start command object and
* end command object and returns true if the segment should be excluded from splitting.
* @param {Boolean} interpolateOptions.snapEndsToInput a boolean indicating whether end of input should
* be sourced from input argument or computed.
* @returns {Function} Interpolation function that maps t ([0, 1]) to a path `d` string.
*/
export default function interpolatePath(a, b, excludeSegment) {
export default function interpolatePath(a, b, interpolateOptions) {
let aCommands = pathCommandsFromString(a);
let bCommands = pathCommandsFromString(b);

const { excludeSegment, snapEndsToInput } =
typeof interpolateOptions === "object"
? interpolateOptions
: {
excludeSegment: interpolateOptions,
snapEndsToInput: false,
};

if (!aCommands.length && !bCommands.length) {
return function nullInterpolator() {
return '';
Expand All @@ -445,8 +467,8 @@ export default function interpolatePath(a, b, excludeSegment) {

return function pathStringInterpolator(t) {
// at 1 return the final value without the extensions used during interpolation
if (t === 1) {
return b == null ? '' : b;
if (t === 1 && snapEndsToInput) {
return b == null ? "" : b;
}

const interpolatedCommands = commandInterpolator(t);
Expand Down

0 comments on commit 45e1db5

Please sign in to comment.