or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

basic-types.mdcollections.mdcolor-spaces.mdgeneric.mdindex.mdmathematical.mdtransforms-utilities.md
tile.json

transforms-utilities.mddocs/

Transforms and Utilities

Transform interpolation for CSS and SVG, plus utility functions for advanced interpolation use cases.

Capabilities

CSS Transform Interpolation

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) - Translation
  • rotate(angle) - Rotation
  • skewX(angle) - X-axis skew
  • scale(x, y) - Scaling

Matrix 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 recomposition

SVG Transform Interpolation

Interpolation 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)"
);

Discrete Utilities

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"

Sampling Utilities

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
);

Transform Matrix Decomposition

Both CSS and SVG transform interpolators use standardized matrix decomposition:

  1. Parse transform strings into component functions
  2. Extract translate, rotate, skew, and scale values
  3. Interpolate each component independently
  4. Recompose into valid transform string

This ensures smooth, predictable animations that match browser behavior.

Transform Order

Standard transform order is:

  1. Translate
  2. Rotate
  3. SkewX
  4. Scale

Different orderings in input transforms are normalized to this standard order.

Matrix Decomposition Algorithm

Follows W3C CSS3 2D Transforms specification for matrix decomposition, ensuring compatibility with CSS animations and SVG transforms.

Performance Considerations

Transform Interpolation

  • Matrix decomposition is computed once per interpolator creation
  • Actual interpolation is lightweight (just numeric operations)
  • Recomposition generates new strings on each call

Quantize Function

  • Samples are computed immediately (not lazily)
  • Memory usage scales with sample count
  • Best for pre-computed lookup tables or gradient generation

Defensive Copying

  • Transform interpolators return new strings (safe)
  • Quantize works best with interpolators that return new objects
  • Wrap object/array interpolators if mutation is a concern

Use Cases

CSS Transform Interpolation:

  • Smooth element animations
  • Morphing between transform states
  • Complex multi-step animations

SVG Transform Interpolation:

  • Path animations
  • Shape morphing
  • Coordinate system transitions

Quantize Sampling:

  • Color palette generation
  • Gradient stop creation
  • Lookup table construction
  • Data visualization scales