Transform interpolation for CSS and SVG, plus utility functions for advanced interpolation use cases.
Interpolation between CSS 2D transform strings with proper matrix decomposition.
/**
* Returns an interpolator between two CSS 2D transform strings.
* Decomposes transforms into translate, rotate, skew, and scale components.
* @param a - Starting CSS transform string
* @param b - Ending CSS transform string
* @returns Interpolator function returning CSS transform string
*/
function interpolateTransformCss(a: string, b: string): (t: number) => string;Transform Components Supported:
translate(x, y) - Translationrotate(angle) - RotationskewX(angle) - X-axis skewscale(x, y) - ScalingMatrix Decomposition: Uses standardized CSS matrix decomposition for animation as specified by W3C.
Usage Examples:
import { interpolateTransformCss } from "d3-interpolate";
// Basic translation
const translateInterp = interpolateTransformCss(
"translate(0px, 0px)",
"translate(100px, 50px)"
);
console.log(translateInterp(0.5)); // "translate(50px, 25px)"
// Rotation interpolation
const rotateInterp = interpolateTransformCss(
"rotate(0deg)",
"rotate(90deg)"
);
console.log(rotateInterp(0.5)); // "rotate(45deg)"
// Complex multi-component transforms
const complexInterp = interpolateTransformCss(
"translate(0px, 0px) rotate(0deg) scale(1, 1)",
"translate(100px, 50px) rotate(180deg) scale(2, 1.5)"
);
console.log(complexInterp(0.5));
// "translate(50px, 25px) rotate(90deg) scale(1.5, 1.25)"
// Skew transforms
const skewInterp = interpolateTransformCss(
"skewX(0deg)",
"skewX(30deg)"
);
console.log(skewInterp(0.5)); // "skewX(15deg)"
// Mixed transform shorthand
const mixedInterp = interpolateTransformCss(
"translate(10px, 20px) scale(0.5)",
"translate(90px, 80px) scale(2) rotate(45deg)"
);
console.log(mixedInterp(0.25));
// Smooth decomposition and recompositionInterpolation between SVG 2D transform strings.
/**
* Returns an interpolator between two SVG 2D transform strings.
* Uses same decomposition as CSS but with SVG syntax.
* @param a - Starting SVG transform string
* @param b - Ending SVG transform string
* @returns Interpolator function returning SVG transform string
*/
function interpolateTransformSvg(a: string, b: string): (t: number) => string;SVG Transform Syntax:
translate(x, y) or translate(x)rotate(angle) or rotate(angle, cx, cy)skewX(angle)scale(x, y) or scale(x)Usage Examples:
import { interpolateTransformSvg } from "d3-interpolate";
// SVG translation (no units)
const svgTranslate = interpolateTransformSvg(
"translate(0, 0)",
"translate(100, 50)"
);
console.log(svgTranslate(0.5)); // "translate(50, 50)"
// SVG rotation with center point
const svgRotate = interpolateTransformSvg(
"rotate(0, 50, 50)",
"rotate(90, 50, 50)"
);
console.log(svgRotate(0.5)); // "rotate(45, 50, 50)"
// Complex SVG transform
const svgComplex = interpolateTransformSvg(
"translate(0, 0) scale(1)",
"translate(100, 100) scale(2) rotate(180)"
);
console.log(svgComplex(0.5));
// "translate(50, 50) scale(1.5) rotate(90)"
// Path animation transforms
const pathTransform = interpolateTransformSvg(
"translate(0) rotate(0) scale(1, 1)",
"translate(200) rotate(360) scale(0.5, 2)"
);Additional utility for discrete value stepping.
/**
* Returns a discrete interpolator that steps through array values.
* Effectively a quantize scale with domain [0, 1].
* @param values - Array of discrete values to step through
* @returns Interpolator function returning discrete values
*/
function interpolateDiscrete(values: any[]): (t: number) => any;Usage Examples:
import { interpolateDiscrete } from "d3-interpolate";
// Animation keyframes
const keyframes = interpolateDiscrete([
"frame1.jpg",
"frame2.jpg",
"frame3.jpg",
"frame4.jpg"
]);
console.log(keyframes(0.0)); // "frame1.jpg"
console.log(keyframes(0.3)); // "frame2.jpg"
console.log(keyframes(0.6)); // "frame3.jpg"
console.log(keyframes(0.99)); // "frame4.jpg"
// State machine transitions
const states = interpolateDiscrete(["idle", "loading", "success", "error"]);
// Discrete color themes
const themes = interpolateDiscrete(["light", "dark", "auto"]);
console.log(themes(0.33)); // "dark"Generate arrays of sampled values from interpolators.
/**
* Returns n uniformly-spaced samples from an interpolator.
* First sample at t=0, last at t=1.
* @param interpolator - Function to sample from
* @param n - Number of samples (integer ≥ 2)
* @returns Array of n sampled values
*/
function quantize(interpolator: (t: number) => any, n: number): any[];Advanced Usage Examples:
import { quantize, interpolateRgb, interpolateHsl, piecewise } from "d3-interpolate";
// Generate color ramps for data visualization
const heatmapColors = quantize(
interpolateRgb("blue", "red"),
10
);
console.log(heatmapColors); // 10-step blue to red gradient
// Multi-stop gradients
const sunset = quantize(
piecewise(interpolateHsl, ["#87CEEB", "#FFA500", "#FF4500", "#8B008B"]),
20
);
// Generate lookup tables
const easingLUT = quantize(
(t) => t * t * (3 - 2 * t), // Smoothstep function
256
);
// SVG gradient stops
const gradientStops = quantize(interpolateRgb("#ff0000", "#0000ff"), 5)
.map((color, i) => `<stop offset="${i * 25}%" stop-color="${color}"/>`)
.join('\n');
console.log(`<linearGradient>\n${gradientStops}\n</linearGradient>`);
// CSS animation keyframes
const keyframeValues = quantize(interpolateNumber(0, 360), 8);
const cssKeyframes = keyframeValues
.map((angle, i) => `${i * 100/7}% { transform: rotate(${angle}deg); }`)
.join('\n');
// Data point interpolation for smooth charts
const dataInterp = quantize(
piecewise([10, 25, 15, 30, 20]),
50 // 50 smooth points between 5 data points
);Both CSS and SVG transform interpolators use standardized matrix decomposition:
This ensures smooth, predictable animations that match browser behavior.
Standard transform order is:
Different orderings in input transforms are normalized to this standard order.
Follows W3C CSS3 2D Transforms specification for matrix decomposition, ensuring compatibility with CSS animations and SVG transforms.
CSS Transform Interpolation:
SVG Transform Interpolation:
Quantize Sampling: