How to Use Easing Functions in d3-ease for Smooth D3 Animations
d3-ease provides pure mathematical functions that map normalized time t ∈ [0, 1] to eased time t′ ∈ [0, 1], enabling smooth acceleration and deceleration in animations.
The d3-ease module is a self-contained library within the d3/d3 monorepo that exports a catalog of easing functions. Each function is pure—having no side effects—and can be invoked directly or passed to D3 transitions via the .ease() method. The module is re-exported through the main D3 entry point at src/index.js, making all easing functions available as d3.easeLinear, d3.easeCubic, and so on.
What Are Easing Functions in d3-ease?
Easing functions in d3-ease are mathematical curves that transform linear progress into non-linear motion. They accept a single argument t representing normalized time (typically from 0 to 1) and return a transformed value t′ that controls the rate of change.
The module is implemented in the separate d3-ease repository and integrated into the main d3 bundle via src/index.js:
export * from "d3-ease";
This architecture ensures that easing functions are decoupled from D3's selection and transition systems, allowing them to be used in any JavaScript animation context.
Basic Usage: Calling Easing Functions Directly
The simplest way to use d3-ease is to invoke a built-in function directly with a normalized time value.
Linear Easing
The easeLinear function, implemented in d3-ease/src/linear.js, returns the input unchanged:
import * as d3 from "d3";
const t = 0.5;
const eased = d3.easeLinear(t); // Returns 0.5
Cubic Easing
For smooth acceleration and deceleration, use easeCubic, easeCubicIn, easeCubicOut, or easeCubicInOut:
import * as d3 from "d3";
// Ease in: slow start, fast end
const easeIn = d3.easeCubicIn(0.5); // Returns 0.125
// Ease in-out: slow start and end, fast middle
const easeInOut = d3.easeCubicInOut(0.5); // Returns 0.5
Configurable Easing Families in d3-ease
Several easing types in d3-ease are implemented as factory functions that return customized easing functions. These are defined in separate source files within the d3-ease repository.
Polynomial Easing with Custom Exponents
The polynomial family, implemented in d3-ease/src/poly.js, allows you to specify an exponent via the .exponent() factory method:
import * as d3 from "d3";
// Create a quartic easing function (exponent 4)
const easePoly4 = d3.easePoly.exponent(4);
d3.select("rect")
.transition()
.duration(1500)
.ease(easePoly4)
.attr("width", 200);
Elastic Easing with Amplitude and Period
Elastic easing, defined in d3-ease/src/elastic.js, simulates a spring-like motion. Configure it using .amplitude() and .period():
import * as d3 from "d3";
// Configure elastic with amplitude 1.5 and period 0.6
const easeElastic = d3.easeElastic.amplitude(1.5).period(0.6);
d3.select("#ball")
.transition()
.duration(1200)
.ease(easeElastic)
.attr("cx", 300);
Back Easing with Overshoot
Back easing, implemented in d3-ease/src/back.js, produces an "anticipation" effect by overshooting the target. Control the amount with .overshoot():
import * as d3 from "d3";
// Increase the overshoot for a more pronounced anticipation
const easeBack = d3.easeBack.overshoot(2.5);
d3.selectAll(".bar")
.transition()
.duration(800)
.ease(easeBack)
.attr("height", d => d.value);
Integrating d3-ease with D3 Transitions
The most common use case for d3-ease is controlling the timing of D3 transitions. Pass any easing function to the .ease() method on a transition selection:
import * as d3 from "d3";
d3.selectAll("circle")
.transition()
.duration(1000)
.ease(d3.easeCubicInOut) // Smooth acceleration and deceleration
.attr("r", 20);
The .ease() method accepts any function that maps [0, 1] to [0, 1], making d3-ease functions fully compatible with D3's transition system as implemented in the d3-transition module.
Using d3-ease Outside of D3 Transitions
Because d3-ease functions are pure and have no dependencies on the DOM or D3 selections, they can be used in any animation context, including Canvas, WebGL, or React Native.
Here is an example using d3.easeBounceOut in a custom requestAnimationFrame loop:
import * as d3 from "d3";
function animate(targetValue, duration, easing) {
const start = performance.now();
function step(now) {
const t = Math.min((now - start) / duration, 1);
const eased = easing(t);
// Apply the eased value (e.g., to a canvas drawing)
draw(eased * targetValue);
if (t < 1) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
}
// Animate with bounce effect
animate(100, 2000, d3.easeBounceOut);
This pattern is particularly useful when working with rendering contexts outside of SVG, such as the HTML5 Canvas API or Three.js.
Summary
d3-easeis a standalone module providing pure mathematical easing functions that map normalized timet∈ [0, 1] to eased values.- Basic easing functions like
d3.easeLinearandd3.easeCubicare called directly with a time value. - Configurable families (Poly, Elastic, Back) use factory methods (
.exponent(),.amplitude(),.period(),.overshoot()) to generate customized easing functions. - Integration with D3 is seamless via the
.ease()method on transitions, as re-exported throughsrc/index.jsin the maind3repository. - Standalone usage is supported for Canvas, WebGL, or custom animation loops since the functions have no DOM dependencies.
Frequently Asked Questions
What is the difference between easeIn, easeOut, and easeInOut variants?
easeIn starts slowly and accelerates, emphasizing the beginning of the animation. easeOut starts quickly and decelerates, emphasizing the end. easeInOut combines both, accelerating at the start and decelerating at the end to create smooth motion at both endpoints. In the d3-ease source code, these variants are implemented as separate functions (e.g., easeCubicIn, easeCubicOut, easeCubicInOut) in files like src/cubic.js.
How do I choose the right easing function for my animation?
Select linear (d3.easeLinear) for constant motion or when interpolating colors. Use cubic or quad easing for general UI elements that need natural acceleration. Choose elastic or bounce for playful, attention-grabbing effects that overshoot the target. Apply back easing when you want to show anticipation (pulling back before moving forward). The d3-ease documentation in docs/d3-ease.md provides visual descriptions of each curve to help with selection.
Can I use d3-ease with libraries other than D3?
Yes. Because d3-ease functions are pure mathematical mappings with no dependencies on the DOM or D3's selection model, they work with any JavaScript animation system. You can use them with React Native's Animated API, Three.js tweens, GSAP custom eases, or raw requestAnimationFrame loops in Canvas or WebGL contexts. The functions simply take a number between 0 and 1 and return a transformed number.
Where are the easing functions implemented in the source code?
The implementations are located in the d3-ease repository. Basic functions like easeLinear reside in src/linear.js, while configurable families have dedicated files: src/poly.js contains polynomial easing with the .exponent() factory, src/elastic.js implements elastic physics with .amplitude() and .period(), and src/back.js provides the back easing with .overshoot(). These are re-exported to the main d3 bundle via src/index.js in the d3/d3 repository.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →