Skip to content

Easing functions (tween)

Seven easing families, each with an easeIn and an easeOut form. They are pure maths — no DOM, no RAF loop of their own. You feed the current time in from your own animation frame and get back the value that frame should use.

Parameters follow Robert Penner's classic convention:

  • t — current time (how much has elapsed)
  • b — beginning value
  • c — change in value (the end value is b + c)
  • d — duration

Every function clamps internally on t >= d, so calling past the end returns the final value rather than extrapolating out of range.

Usage

ts
import { cubic } from 'ranuts/utils';

const start = performance.now();
const tick = (now: number) => {
  const x = cubic.easeOut(now - start, 0, 300, 600); // 0 → 300 over 600ms
  el.style.transform = `translateX(${x}px)`;
  if (now - start < 600) requestAnimationFrame(tick);
};
requestAnimationFrame(tick);

Available curves

ExportCurveFeel
quadquadratic ()The gentlest acceleration; a safe default
cubiccubic ()Noticeably snappier than quad
quartquartic (t⁴)Strong acceleration
quintquintic (t⁵)Very strong; the end dominates the motion
sinesinusoidalSoftest of all — barely reads as an ease
expoexponentialNearly still, then a sudden run
circcircularSlow start, very abrupt finish

API

Every export has the same shape:

ts
interface SpeedType {
  easeIn: EasingFn;
  easeOut: EasingFn;
}

type EasingFn = (t: number, b: number, c: number, d: number) => number;

easeIn / easeOut

Parameters

ParameterDescriptionTypeDefault
tElapsed timenumberRequired
bBeginning valuenumberRequired
cChange in value (end = b + c)numberRequired
dDurationnumberRequired

Return

ArgumentDescriptionType
valueThe value at time tnumber

Notes

easeIn starts slow and accelerates; easeOut starts fast and decelerates. For UI that responds to a user action, easeOut usually reads better — the element moves immediately and settles, rather than hesitating first.

With thanks to zhangxinxu/Tween.

Released under the MIT License.