Interpolation methods for arrays and objects with recursive value interpolation.
Generic interpolation between arrays with recursive element interpolation.
/**
* Returns an interpolator between two arrays.
* Creates a template array the same length as b, interpolating corresponding elements.
* @param a - Starting array
* @param b - Ending array (determines result length and template)
* @returns Interpolator function returning interpolated array
*/
function interpolateArray(a: any[], b: any[]): (t: number) => any[];Algorithm:
bb, if there's a corresponding element in a, creates a generic interpolatorbPerformance Note: No defensive copy of the template array is created for performance reasons. Modifications to the returned array may affect subsequent evaluations.
Usage Examples:
import { interpolateArray } from "d3-interpolate";
// Different length arrays
const lengthInterp = interpolateArray([0, 1], [1, 10, 100]);
console.log(lengthInterp(0.0)); // [0, 1, 100]
console.log(lengthInterp(0.5)); // [0.5, 5.5, 100]
console.log(lengthInterp(1.0)); // [1, 10, 100]
// Color arrays (nested interpolation)
const colorArrayInterp = interpolateArray(
["red", "blue"],
["green", "yellow", "purple"]
);
console.log(colorArrayInterp(0.5));
// ["rgb(128, 64, 0)", "rgb(128, 128, 0)", "purple"]
// Mixed data types
const mixedInterp = interpolateArray(
[0, "10px", new Date(2020, 0, 1)],
[100, "50px", new Date(2021, 0, 1)]
);
console.log(mixedInterp(0.5));
// [50, "30px", Date(mid-2020)]
// Nested arrays
const nestedInterp = interpolateArray(
[[0, 0], [1, 1]],
[[10, 20], [30, 40], [50, 60]]
);
console.log(nestedInterp(0.5));
// [[5, 10], [16, 20.5], [50, 60]]Optimized interpolation between arrays of numbers.
/**
* Returns an interpolator between two arrays of numbers.
* Optimized for numeric arrays with direct interpolation.
* @param a - Starting number array
* @param b - Ending number array (determines result type and length)
* @returns Interpolator function returning number array of same type as b
*/
function interpolateNumberArray(a: number[], b: number[]): (t: number) => number[];Features:
ba use static values from bPerformance Note: No defensive copy is made of the template array or arguments for performance reasons.
Usage Examples:
import { interpolateNumberArray } from "d3-interpolate";
// Regular arrays
const numberInterp = interpolateNumberArray([0, 10], [100, 200, 300]);
console.log(numberInterp(0.0)); // [0, 10, 300]
console.log(numberInterp(0.5)); // [50, 105, 300]
console.log(numberInterp(1.0)); // [100, 200, 300]
// Typed arrays (Float32Array, Uint8Array, etc.)
const typedA = new Float32Array([1.0, 2.0]);
const typedB = new Float32Array([10.0, 20.0, 30.0]);
const typedInterp = interpolateNumberArray(typedA, typedB);
console.log(typedInterp(0.5)); // Float32Array [5.5, 11, 30]
// RGB color values (0-255)
const rgbInterp = interpolateNumberArray([255, 0, 0], [0, 255, 0]);
console.log(rgbInterp(0.5)); // [127.5, 127.5, 0] (red to green)
// Coordinate arrays
const coordInterp = interpolateNumberArray([0, 0], [100, 50]);
console.log(coordInterp(0.25)); // [25, 12.5]Recursive interpolation between objects with property-wise interpolation.
/**
* Returns an interpolator between two objects.
* Creates a template object with properties from b, interpolating corresponding values.
* @param a - Starting object
* @param b - Ending object (determines result properties and template)
* @returns Interpolator function returning interpolated object
*/
function interpolateObject(a: object, b: object): (t: number) => object;Algorithm:
bb, if there's a corresponding property in a, creates a generic interpolatorbPerformance Note: No defensive copy of the template object is created. Modifications to the returned object may affect subsequent evaluations.
Usage Examples:
import { interpolateObject } from "d3-interpolate";
// Basic object interpolation
const objInterp = interpolateObject(
{ x: 0, y: 1 },
{ x: 1, y: 10, z: 100 }
);
console.log(objInterp(0.0)); // { x: 0, y: 1, z: 100 }
console.log(objInterp(0.5)); // { x: 0.5, y: 5.5, z: 100 }
console.log(objInterp(1.0)); // { x: 1, y: 10, z: 100 }
// Complex nested objects
const complexInterp = interpolateObject(
{
position: { x: 0, y: 0 },
color: "red",
size: 10
},
{
position: { x: 100, y: 50 },
color: "blue",
size: 20,
opacity: 0.8
}
);
console.log(complexInterp(0.5));
// {
// position: { x: 50, y: 25 },
// color: "rgb(128, 0, 128)",
// size: 15,
// opacity: 0.8
// }
// Dataspace interpolation (useful for D3 arcs, etc.)
const arcInterp = interpolateObject(
{ startAngle: 0, endAngle: Math.PI / 2, innerRadius: 10 },
{ startAngle: Math.PI, endAngle: 2 * Math.PI, innerRadius: 20, outerRadius: 50 }
);
console.log(arcInterp(0.5));
// {
// startAngle: π/2,
// endAngle: 5π/4,
// innerRadius: 15,
// outerRadius: 50
// }
// Mixed data types in object
const mixedObjInterp = interpolateObject(
{
count: 5,
label: "5 items",
timestamp: new Date(2020, 0, 1),
active: true
},
{
count: 50,
label: "50 items",
timestamp: new Date(2021, 0, 1),
active: false,
category: "new"
}
);
console.log(mixedObjInterp(0.5));
// {
// count: 27.5,
// label: "27.5 items",
// timestamp: Date(mid-2020),
// active: false, // boolean uses end value
// category: "new"
// }Use Cases: