Easing: a function from progress to progress
GoByte Skills #21: an ease is just a function from progress to progress. Same distance, same duration, four curves, and at halftime one of them has already overshot the finish line. On purpose.
Arthur is one of GoByte's characters. This post was drafted by AI agents in Arthur's voice, then fact checked, run and edited by the GoByte team.
An ease maps linear progress to eased progress, so the same distance can feel snappy or heavy.
Transcript
Four dots race the same distance in the same time with four eases and freeze at half time, showing how far each curve has carried them, one already past the line.
const { gsap } = require("gsap");
const names = ["none", "power2.in",
"power2.out", "back.out"];
for (const name of names) {
const ease = gsap.parseEase(name);
const ys = [0, 0.25, 0.5, 0.75, 1]
.map((p) => ease(p).toFixed(3));
console.log(name.padEnd(10), ys.join(" "));
}
none 0.000 0.250 0.500 0.750 1.000
power2.in 0.000 0.016 0.125 0.422 1.000
power2.out 0.000 0.578 0.875 0.984 1.000
back.out 0.000 0.817 1.088 1.064 1.000
The mechanism#
A tween's clock never runs faster or slower. Each frame it computes linear progress p = elapsed / duration and writes from + (to - from) * ease(p). The ease is a plain function with one contract: ease(0) = 0 and ease(1) = 1. Duration and distance are fixed; the ease only decides where on the path you are at each instant. Speed is the slope of that curve.
Reading the table#
GSAP's power2 is cubic, not quadratic (power1 is quad, power2 cubic, power3 quartic). Halfway through a 1 second tween, power2.in has covered 12.5% of the distance and power2.out 87.5%. Same half second, opposite feelings. .out starts fast and lands soft, so it reads as responsive. .in starts slow and leaves fast, so it reads as heavy, like something with mass getting going.
Where it bends#
Nothing keeps the output inside [0, 1]. back.out peaks near 1.10 at p = 0.58, so a tween from 0 to 100 passes 110 before it settles. That overshoot is the point, but a property with a ceiling ignores it: opacity clamps at 1. steps(4) is a staircase, valid and discontinuous. And any function works, ease: (p) => p * p included: GSAP just calls it every frame, so a custom ease is one line you can unit test.
Rule of thumb#
Pick the curve by how the object should feel when it stops, then keep the duration. Linear motion is perfectly honest, which is exactly why it looks like a screensaver.
Your product here? Partner with us
Back to topDiscussion
No comments yet. Signed in GoByte members with a verified e-mail can join. Community guidelines
Reading is open to everyone. Commenting and voting need a GoByte account with a verified e-mail.