Skip to content

smoothTowards function ​

Moves a value towards a target with exponential smoothing, whatever the frame rate: about 63 % of the distance is covered every timeConstantMs. Smooths a needle fed by noisy values.

ts
import { smoothTowards } from 'utils';

Signature ​

ts
export function smoothTowards(current: number, target: number, deltaMs: number, timeConstantMs: number): number

Parameters ​

NameDescription
currentThe displayed value.
targetThe latest value.
deltaMsThe time elapsed since the previous call, in milliseconds.
timeConstantMsThe time constant, in milliseconds; 0 returns target.

Returns ​

The new displayed value.

Example ​

ts
needle = smoothTowards(needle, speed, deltaMs, 150);

Tests ​

Line coverage: 100 %.

  • ✅ covers about 63 % of the distance per time constant
  • ✅ gives the same result whatever the frame rate
  • ✅ jumps to the target without a time constant

Source ​

src/math/smooth-towards.ts (on GitHub)

Source code
ts
/**
 * Moves a value towards a target with exponential smoothing, whatever the frame rate: about 63 % of the
 * distance is covered every `timeConstantMs`. Smooths a needle fed by noisy values.
 *
 * @param current - The displayed value.
 * @param target - The latest value.
 * @param deltaMs - The time elapsed since the previous call, in milliseconds.
 * @param timeConstantMs - The time constant, in milliseconds; `0` returns `target`.
 * @returns The new displayed value.
 * @example
 * needle = smoothTowards(needle, speed, deltaMs, 150);
 */
export function smoothTowards(current: number, target: number, deltaMs: number, timeConstantMs: number): number {
  if (timeConstantMs <= 0) {
    return target;
  }
  return target + (current - target) * Math.exp(-deltaMs / timeConstantMs);
}
Test file
ts
import { smoothTowards } from './smooth-towards';

describe(smoothTowards, () => {
  it('covers about 63 % of the distance per time constant', () => {
    expect(smoothTowards(0, 100, 100, 100)).toBeCloseTo(63.212, 3);
  });

  it('gives the same result whatever the frame rate', () => {
    let fast = 0;
    for (let frame = 0; frame < 10; frame++) {
      fast = smoothTowards(fast, 100, 10, 100);
    }
    expect(fast).toBeCloseTo(smoothTowards(0, 100, 100, 100), 10);
  });

  it('jumps to the target without a time constant', () => {
    expect(smoothTowards(0, 100, 16, 0)).toBe(100);
  });
});

Keywords: smooth, towards, math, function

Generated from the JSDoc of the sources.