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): numberParameters
| Name | Description |
|---|---|
current | The displayed value. |
target | The latest value. |
deltaMs | The time elapsed since the previous call, in milliseconds. |
timeConstantMs | The 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