Interpolate numbers, colors, strings, arrays, objects, whatever!
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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:
Install with Tessl CLI
npx tessl i tessl/npm-d3-interpolate